Duckstation/src/core/gpu_hw.h

117 lines
3.5 KiB
C
Raw Normal View History

2019-09-12 02:53:04 +00:00
#pragma once
#include "gpu.h"
#include <sstream>
#include <string>
2019-10-03 06:46:13 +00:00
#include <tuple>
2019-09-12 02:53:04 +00:00
#include <vector>
class GPU_HW : public GPU
{
public:
GPU_HW();
virtual ~GPU_HW();
2019-10-04 10:33:37 +00:00
virtual void Reset() override;
2019-09-12 02:53:04 +00:00
protected:
2019-11-01 11:47:45 +00:00
enum class HWPrimitive : u8
{
Lines = 0,
LineStrip = 1,
Triangles = 2,
TriangleStrip = 3
};
enum class HWBatchRenderMode : u8
{
TransparencyDisabled,
TransparentAndOpaque,
OnlyOpaque,
OnlyTransparent
};
2019-09-12 02:53:04 +00:00
struct HWVertex
{
s32 x;
s32 y;
u32 color;
u32 texpage;
u32 texcoord;
// 16-bit texcoords are needed for 256 extent rectangles
static u32 PackTexcoord(u16 x, u16 y) { return ZeroExtend32(x) | (ZeroExtend32(y) << 16); }
2019-09-12 02:53:04 +00:00
};
struct HWRenderBatch
{
2019-11-01 11:47:45 +00:00
HWPrimitive primitive;
TextureMode texture_mode;
u32 texture_page_x;
u32 texture_page_y;
u32 texture_palette_x;
u32 texture_palette_y;
TransparencyMode transparency_mode;
2019-10-05 13:25:06 +00:00
std::array<u8, 4> texture_window_values;
std::vector<HWVertex> vertices;
2019-11-01 11:47:45 +00:00
// We need two-pass rendering when using BG-FG blending and texturing, as the transparency can be enabled
// on a per-pixel basis, and the opaque pixels shouldn't be blended at all.
bool NeedsTwoPassRendering() const
{
return transparency_mode == GPU::TransparencyMode::BackgroundMinusForeground &&
texture_mode != TextureMode::Disabled;
}
// Returns the render mode for this batch.
HWBatchRenderMode GetRenderMode() const
{
return transparency_mode == TransparencyMode::Disabled ? HWBatchRenderMode::TransparencyDisabled :
HWBatchRenderMode::TransparentAndOpaque;
}
};
static constexpr u32 VERTEX_BUFFER_SIZE = 1 * 1024 * 1024;
static constexpr u32 MAX_BATCH_VERTEX_COUNT = VERTEX_BUFFER_SIZE / sizeof(HWVertex);
static constexpr u32 TEXTURE_TILE_SIZE = 256;
static constexpr u32 TEXTURE_TILE_X_COUNT = VRAM_WIDTH / TEXTURE_TILE_SIZE;
static constexpr u32 TEXTURE_TILE_Y_COUNT = VRAM_HEIGHT / TEXTURE_TILE_SIZE;
static constexpr u32 TEXTURE_TILE_COUNT = TEXTURE_TILE_X_COUNT * TEXTURE_TILE_Y_COUNT;
2019-09-14 06:43:39 +00:00
static constexpr std::tuple<float, float, float, float> RGBA8ToFloat(u32 rgba)
{
return std::make_tuple(static_cast<float>(rgba & UINT32_C(0xFF)) * (1.0f / 255.0f),
static_cast<float>((rgba >> 16) & UINT32_C(0xFF)) * (1.0f / 255.0f),
static_cast<float>((rgba >> 8) & UINT32_C(0xFF)) * (1.0f / 255.0f),
static_cast<float>(rgba >> 24) * (1.0f / 255.0f));
}
virtual void InvalidateVRAMReadCache();
bool IsFlushed() const { return m_batch.vertices.empty(); }
2019-10-13 07:33:20 +00:00
void DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32* command_ptr) override;
2019-09-12 02:53:04 +00:00
2019-09-12 14:18:13 +00:00
void CalcScissorRect(int* left, int* top, int* right, int* bottom);
2019-10-03 06:46:13 +00:00
std::tuple<s32, s32> ScaleVRAMCoordinates(s32 x, s32 y) const
{
return std::make_tuple(x * s32(m_resolution_scale), y * s32(m_resolution_scale));
}
2019-09-12 02:53:04 +00:00
std::string GenerateVertexShader(bool textured);
2019-11-01 11:47:45 +00:00
std::string GenerateFragmentShader(HWBatchRenderMode transparency, TextureMode texture_mode);
std::string GenerateScreenQuadVertexShader();
2019-09-14 06:43:39 +00:00
std::string GenerateFillFragmentShader();
2019-10-23 05:36:37 +00:00
std::string GenerateDisplayFragmentShader(bool depth_24bit, bool interlaced);
2019-09-12 02:53:04 +00:00
HWRenderBatch m_batch = {};
private:
2019-11-01 11:47:45 +00:00
static HWPrimitive GetPrimitiveForCommand(RenderCommand rc);
void GenerateShaderHeader(std::stringstream& ss);
2019-10-13 07:33:20 +00:00
void LoadVertices(RenderCommand rc, u32 num_vertices, const u32* command_ptr);
2019-09-12 02:53:04 +00:00
};