From 03d4f8088387c0975e2c9ad4d2ac4a2e603ddd41 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Thu, 22 Oct 2020 19:31:28 +1000 Subject: [PATCH] GPU: Move enums/types into separate file --- src/core/CMakeLists.txt | 1 + src/core/core.vcxproj | 1 + src/core/core.vcxproj.filters | 3 +- src/core/gpu.cpp | 12 +- src/core/gpu.h | 180 +------------- src/core/gpu_commands.cpp | 22 +- src/core/gpu_hw.cpp | 59 ++--- src/core/gpu_hw.h | 16 +- src/core/gpu_hw_d3d11.cpp | 12 +- src/core/gpu_hw_opengl.cpp | 6 +- src/core/gpu_hw_opengl.h | 2 +- src/core/gpu_hw_shadergen.cpp | 20 +- src/core/gpu_hw_shadergen.h | 2 +- src/core/gpu_hw_vulkan.cpp | 8 +- src/core/gpu_sw.cpp | 50 ++-- src/core/gpu_sw.h | 6 +- src/core/gpu_types.h | 224 ++++++++++++++++++ .../libretro_host_interface.cpp | 4 +- src/duckstation-sdl/sdl_host_interface.cpp | 2 +- 19 files changed, 343 insertions(+), 287 deletions(-) create mode 100644 src/core/gpu_types.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index e59db183e..086a5a76a 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -41,6 +41,7 @@ add_library(core gpu_hw_vulkan.h gpu_sw.cpp gpu_sw.h + gpu_types.h gte.cpp gte.h gte_types.h diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj index d386bbcf8..bd9dce6df 100644 --- a/src/core/core.vcxproj +++ b/src/core/core.vcxproj @@ -189,6 +189,7 @@ + diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters index d01f8c308..bd9fa7850 100644 --- a/src/core/core.vcxproj.filters +++ b/src/core/core.vcxproj.filters @@ -104,5 +104,6 @@ + - \ No newline at end of file + diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index 4ce3ae239..05cb6ae99 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -1306,18 +1306,18 @@ void GPU::FlushRender() {} void GPU::SetDrawMode(u16 value) { - DrawMode::Reg new_mode_reg{static_cast(value & DrawMode::Reg::MASK)}; + GPUDrawModeReg new_mode_reg{static_cast(value & GPUDrawModeReg::MASK)}; if (!m_set_texture_disable_mask) new_mode_reg.texture_disable = false; if (new_mode_reg.bits == m_draw_mode.mode_reg.bits) return; - if ((new_mode_reg.bits & DrawMode::Reg::TEXTURE_PAGE_MASK) != - (m_draw_mode.mode_reg.bits & DrawMode::Reg::TEXTURE_PAGE_MASK)) + if ((new_mode_reg.bits & GPUDrawModeReg::TEXTURE_PAGE_MASK) != + (m_draw_mode.mode_reg.bits & GPUDrawModeReg::TEXTURE_PAGE_MASK)) { - m_draw_mode.texture_page_x = new_mode_reg.GetTexturePageXBase(); - m_draw_mode.texture_page_y = new_mode_reg.GetTexturePageYBase(); + m_draw_mode.texture_page_x = new_mode_reg.GetTexturePageBaseX(); + m_draw_mode.texture_page_y = new_mode_reg.GetTexturePageBaseY(); m_draw_mode.texture_page_changed = true; } @@ -1328,7 +1328,7 @@ void GPU::SetDrawMode(u16 value) // Bits 0..10 are returned in the GPU status register. m_GPUSTAT.bits = - (m_GPUSTAT.bits & ~(DrawMode::Reg::GPUSTAT_MASK)) | (ZeroExtend32(new_mode_reg.bits) & DrawMode::Reg::GPUSTAT_MASK); + (m_GPUSTAT.bits & ~(GPUDrawModeReg::GPUSTAT_MASK)) | (ZeroExtend32(new_mode_reg.bits) & GPUDrawModeReg::GPUSTAT_MASK); m_GPUSTAT.texture_disable = m_draw_mode.mode_reg.texture_disable; } diff --git a/src/core/gpu.h b/src/core/gpu.h index ee217670e..979318326 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -2,6 +2,7 @@ #include "common/bitfield.h" #include "common/fifo_queue.h" #include "common/rectangle.h" +#include "gpu_types.h" #include "timers.h" #include "types.h" #include @@ -37,66 +38,12 @@ public: GPUREADtoCPU = 3 }; - enum class Primitive : u8 - { - Reserved = 0, - Polygon = 1, - Line = 2, - Rectangle = 3 - }; - - enum class DrawRectangleSize : u8 - { - Variable = 0, - R1x1 = 1, - R8x8 = 2, - R16x16 = 3 - }; - - enum class TextureMode : u8 - { - Palette4Bit = 0, - Palette8Bit = 1, - Direct16Bit = 2, - Reserved_Direct16Bit = 3, - - // Not register values. - RawTextureBit = 4, - RawPalette4Bit = RawTextureBit | Palette4Bit, - RawPalette8Bit = RawTextureBit | Palette8Bit, - RawDirect16Bit = RawTextureBit | Direct16Bit, - Reserved_RawDirect16Bit = RawTextureBit | Reserved_Direct16Bit, - - Disabled = 8 // Not a register value - }; - - enum class TransparencyMode : u8 - { - HalfBackgroundPlusHalfForeground = 0, - BackgroundPlusForeground = 1, - BackgroundMinusForeground = 2, - BackgroundPlusQuarterForeground = 3, - - Disabled = 4 // Not a register value - }; - enum : u32 { - VRAM_WIDTH = 1024, - VRAM_HEIGHT = 512, - VRAM_SIZE = VRAM_WIDTH * VRAM_HEIGHT * sizeof(u16), - VRAM_WIDTH_MASK = VRAM_WIDTH - 1, - VRAM_HEIGHT_MASK = VRAM_HEIGHT - 1, - VRAM_COORD_MASK = 0x3FF, MAX_FIFO_SIZE = 4096, - TEXTURE_PAGE_WIDTH = 256, - TEXTURE_PAGE_HEIGHT = 256, - MAX_PRIMITIVE_WIDTH = 1024, - MAX_PRIMITIVE_HEIGHT = 512, DOT_TIMER_INDEX = 0, HBLANK_TIMER_INDEX = 1, MAX_RESOLUTION_SCALE = 16, - DITHER_MATRIX_SIZE = 4 }; enum : u16 @@ -109,12 +56,6 @@ public: PAL_TOTAL_LINES = 314, }; - // 4x4 dither matrix. - static constexpr s32 DITHER_MATRIX[DITHER_MATRIX_SIZE][DITHER_MATRIX_SIZE] = {{-4, +0, -3, +1}, // row 0 - {+2, -2, +3, -1}, // row 1 - {-3, +1, -4, +0}, // row 2 - {+4, -1, +2, -2}}; // row 3 - // Base class constructor. GPU(); virtual ~GPU(); @@ -264,60 +205,6 @@ protected: static bool DumpVRAMToFile(const char* filename, u32 width, u32 height, u32 stride, const void* buffer, bool remove_alpha); - union RenderCommand - { - u32 bits; - - BitField color_for_first_vertex; - BitField raw_texture_enable; // not valid for lines - BitField transparency_enable; - BitField texture_enable; - BitField rectangle_size; // only for rectangles - BitField quad_polygon; // only for polygons - BitField polyline; // only for lines - BitField shading_enable; // 0 - flat, 1 = gouroud - BitField primitive; - - /// Returns true if texturing should be enabled. Depends on the primitive type. - bool IsTexturingEnabled() const { return (primitive != Primitive::Line) ? texture_enable : false; } - - /// Returns true if dithering should be enabled. Depends on the primitive type. - bool IsDitheringEnabled() const - { - switch (primitive) - { - case Primitive::Polygon: - return shading_enable || (texture_enable && !raw_texture_enable); - - case Primitive::Line: - return true; - - case Primitive::Rectangle: - default: - return false; - } - } - }; - - union VertexPosition - { - u32 bits; - - BitField x; - BitField y; - }; - - // Sprites/rectangles should be clipped to 12 bits before drawing. - static constexpr s32 TruncateVertexPosition(s32 x) { return SignExtendN<11, s32>(x); } - - struct NativeVertex - { - s16 x; - s16 y; - u32 color; - u16 texcoord; - }; - union VRAMPixel { u16 bits; @@ -508,8 +395,8 @@ protected: u32 bits; BitField texture_page_x_base; BitField texture_page_y_base; - BitField semi_transparency_mode; - BitField texture_color_mode; + BitField semi_transparency_mode; + BitField texture_color_mode; BitField dither_enable; BitField draw_to_displayed_field; BitField set_mask_while_drawing; @@ -567,36 +454,8 @@ protected: static constexpr u16 PALETTE_MASK = UINT16_C(0b0111111111111111); static constexpr u32 TEXTURE_WINDOW_MASK = UINT32_C(0b11111111111111111111); - // bits in GP0(E1h) or texpage part of polygon - union Reg - { - static constexpr u16 MASK = 0b1111111111111; - static constexpr u16 TEXTURE_PAGE_MASK = UINT16_C(0b0000000000011111); - - // Polygon texpage commands only affect bits 0-8, 11 - static constexpr u16 POLYGON_TEXPAGE_MASK = 0b0000100111111111; - - // Bits 0..5 are returned in the GPU status register, latched at E1h/polygon draw time. - static constexpr u32 GPUSTAT_MASK = 0b11111111111; - - u16 bits; - - BitField texture_page_x_base; - BitField texture_page_y_base; - BitField transparency_mode; - BitField texture_mode; - BitField dither_enable; - BitField draw_to_displayed_field; - BitField texture_disable; - BitField texture_x_flip; - BitField texture_y_flip; - - u32 GetTexturePageXBase() const { return ZeroExtend32(texture_page_x_base.GetValue()) * 64; } - u32 GetTexturePageYBase() const { return ZeroExtend32(texture_page_y_base.GetValue()) * 256; } - }; - // original values - Reg mode_reg; + GPUDrawModeReg mode_reg; u16 palette_reg; // from vertex u32 texture_window_value; @@ -614,33 +473,6 @@ protected: bool texture_page_changed; bool texture_window_changed; - /// Returns the texture/palette rendering mode. - TextureMode GetTextureMode() const { return mode_reg.texture_mode; } - - /// Returns the semi-transparency mode when enabled. - TransparencyMode GetTransparencyMode() const { return mode_reg.transparency_mode; } - - /// Returns true if the texture mode requires a palette. - bool IsUsingPalette() const { return (mode_reg.bits & (2 << 7)) == 0; } - - /// Returns a rectangle comprising the texture page area. - Common::Rectangle GetTexturePageRectangle() const - { - static constexpr std::array texture_page_widths = { - {TEXTURE_PAGE_WIDTH / 4, TEXTURE_PAGE_WIDTH / 2, TEXTURE_PAGE_WIDTH, TEXTURE_PAGE_WIDTH}}; - return Common::Rectangle::FromExtents(texture_page_x, texture_page_y, - texture_page_widths[static_cast(mode_reg.texture_mode.GetValue())], - TEXTURE_PAGE_HEIGHT); - } - - /// Returns a rectangle comprising the texture palette area. - Common::Rectangle GetTexturePaletteRectangle() const - { - static constexpr std::array palette_widths = {{16, 256, 0, 0}}; - return Common::Rectangle::FromExtents(texture_palette_x, texture_palette_y, - palette_widths[static_cast(mode_reg.texture_mode.GetValue())], 1); - } - bool IsTexturePageChanged() const { return texture_page_changed; } void SetTexturePageChanged() { texture_page_changed = true; } void ClearTexturePageChangedFlag() { texture_page_changed = false; } @@ -757,7 +589,7 @@ protected: HeapFIFOQueue m_fifo; std::vector m_blit_buffer; u32 m_blit_remaining_words; - RenderCommand m_render_command{}; + GPURenderCommand m_render_command{}; ALWAYS_INLINE u32 FifoPop() { return Truncate32(m_fifo.Pop()); } ALWAYS_INLINE u32 FifoPeek() { return Truncate32(m_fifo.Peek()); } @@ -806,6 +638,4 @@ private: static const GP0CommandHandlerTable s_GP0_command_handler_table; }; -IMPLEMENT_ENUM_CLASS_BITWISE_OPERATORS(GPU::TextureMode); - extern std::unique_ptr g_gpu; diff --git a/src/core/gpu_commands.cpp b/src/core/gpu_commands.cpp index db69c3081..23ac32136 100644 --- a/src/core/gpu_commands.cpp +++ b/src/core/gpu_commands.cpp @@ -132,16 +132,16 @@ GPU::GP0CommandHandlerTable GPU::GenerateGP0CommandHandlerTable() table[0x1F] = &GPU::HandleInterruptRequestCommand; for (u32 i = 0x20; i <= 0x7F; i++) { - const RenderCommand rc{i << 24}; + const GPURenderCommand rc{i << 24}; switch (rc.primitive) { - case Primitive::Polygon: + case GPUPrimitive::Polygon: table[i] = &GPU::HandleRenderPolygonCommand; break; - case Primitive::Line: + case GPUPrimitive::Line: table[i] = rc.polyline ? &GPU::HandleRenderPolyLineCommand : &GPU::HandleRenderLineCommand; break; - case Primitive::Rectangle: + case GPUPrimitive::Rectangle: table[i] = &GPU::HandleRenderRectangleCommand; break; default: @@ -314,7 +314,7 @@ bool GPU::HandleSetMaskBitCommand() bool GPU::HandleRenderPolygonCommand() { - const RenderCommand rc{FifoPeek(0)}; + const GPURenderCommand rc{FifoPeek(0)}; // shaded vertices use the colour from the first word for the first vertex const u32 words_per_vertex = 1 + BoolToUInt32(rc.texture_enable) + BoolToUInt32(rc.shading_enable); @@ -341,8 +341,8 @@ bool GPU::HandleRenderPolygonCommand() if (rc.texture_enable) { const u16 texpage_attribute = Truncate16((rc.shading_enable ? FifoPeek(5) : FifoPeek(4)) >> 16); - SetDrawMode((texpage_attribute & DrawMode::Reg::POLYGON_TEXPAGE_MASK) | - (m_draw_mode.mode_reg.bits & ~DrawMode::Reg::POLYGON_TEXPAGE_MASK)); + SetDrawMode((texpage_attribute & GPUDrawModeReg::POLYGON_TEXPAGE_MASK) | + (m_draw_mode.mode_reg.bits & ~GPUDrawModeReg::POLYGON_TEXPAGE_MASK)); SetTexturePalette(Truncate16(FifoPeek(2) >> 16)); } @@ -358,9 +358,9 @@ bool GPU::HandleRenderPolygonCommand() bool GPU::HandleRenderRectangleCommand() { - const RenderCommand rc{FifoPeek(0)}; + const GPURenderCommand rc{FifoPeek(0)}; const u32 total_words = - 2 + BoolToUInt32(rc.texture_enable) + BoolToUInt32(rc.rectangle_size == DrawRectangleSize::Variable); + 2 + BoolToUInt32(rc.texture_enable) + BoolToUInt32(rc.rectangle_size == GPUDrawRectangleSize::Variable); CHECK_COMMAND_SIZE(total_words); @@ -390,7 +390,7 @@ bool GPU::HandleRenderRectangleCommand() bool GPU::HandleRenderLineCommand() { - const RenderCommand rc{FifoPeek(0)}; + const GPURenderCommand rc{FifoPeek(0)}; const u32 total_words = rc.shading_enable ? 4 : 3; CHECK_COMMAND_SIZE(total_words); @@ -413,7 +413,7 @@ bool GPU::HandleRenderLineCommand() bool GPU::HandleRenderPolyLineCommand() { // always read the first two vertices, we test for the terminator after that - const RenderCommand rc{FifoPeek(0)}; + const GPURenderCommand rc{FifoPeek(0)}; const u32 min_words = rc.shading_enable ? 3 : 4; CHECK_COMMAND_SIZE(min_words); diff --git a/src/core/gpu_hw.cpp b/src/core/gpu_hw.cpp index 5996a0fa5..0145a8da0 100644 --- a/src/core/gpu_hw.cpp +++ b/src/core/gpu_hw.cpp @@ -414,13 +414,13 @@ void GPU_HW::LoadVertices() if (m_GPUSTAT.check_mask_before_draw) m_current_depth++; - const RenderCommand rc{m_render_command.bits}; + const GPURenderCommand rc{m_render_command.bits}; const u32 texpage = ZeroExtend32(m_draw_mode.mode_reg.bits) | (ZeroExtend32(m_draw_mode.palette_reg) << 16); const float depth = GetCurrentNormalizedVertexDepth(); switch (rc.primitive) { - case Primitive::Polygon: + case GPUPrimitive::Polygon: { DebugAssert(GetBatchVertexSpace() >= (rc.quad_polygon ? 6u : 3u)); @@ -437,7 +437,7 @@ void GPU_HW::LoadVertices() { const u32 color = (shaded && i > 0) ? (FifoPop() & UINT32_C(0x00FFFFFF)) : first_color; const u64 maddr_and_pos = m_fifo.Pop(); - const VertexPosition vp{Truncate32(maddr_and_pos)}; + const GPUVertexPosition vp{Truncate32(maddr_and_pos)}; const u16 texcoord = textured ? Truncate16(FifoPop()) : 0; const s32 native_x = m_drawing_offset.x + vp.x; const s32 native_y = m_drawing_offset.y + vp.y; @@ -538,12 +538,12 @@ void GPU_HW::LoadVertices() } break; - case Primitive::Rectangle: + case GPUPrimitive::Rectangle: { const u32 color = rc.color_for_first_vertex; - const VertexPosition vp{FifoPop()}; - const s32 pos_x = TruncateVertexPosition(m_drawing_offset.x + vp.x); - const s32 pos_y = TruncateVertexPosition(m_drawing_offset.y + vp.y); + const GPUVertexPosition vp{FifoPop()}; + const s32 pos_x = TruncateGPUVertexPosition(m_drawing_offset.x + vp.x); + const s32 pos_y = TruncateGPUVertexPosition(m_drawing_offset.y + vp.y); const auto [texcoord_x, texcoord_y] = UnpackTexcoord(rc.texture_enable ? Truncate16(FifoPop()) : 0); u16 orig_tex_left = ZeroExtend16(texcoord_x); @@ -552,15 +552,15 @@ void GPU_HW::LoadVertices() s32 rectangle_height; switch (rc.rectangle_size) { - case DrawRectangleSize::R1x1: + case GPUDrawRectangleSize::R1x1: rectangle_width = 1; rectangle_height = 1; break; - case DrawRectangleSize::R8x8: + case GPUDrawRectangleSize::R8x8: rectangle_width = 8; rectangle_height = 8; break; - case DrawRectangleSize::R16x16: + case GPUDrawRectangleSize::R16x16: rectangle_width = 16; rectangle_height = 16; break; @@ -632,14 +632,14 @@ void GPU_HW::LoadVertices() } break; - case Primitive::Line: + case GPUPrimitive::Line: { if (!rc.polyline) { DebugAssert(GetBatchVertexSpace() >= 2); u32 start_color, end_color; - VertexPosition start_pos, end_pos; + GPUVertexPosition start_pos, end_pos; if (rc.shading_enable) { start_color = rc.color_for_first_vertex; @@ -694,7 +694,7 @@ void GPU_HW::LoadVertices() const bool shaded = rc.shading_enable; u32 buffer_pos = 0; - const VertexPosition start_vp{m_blit_buffer[buffer_pos++]}; + const GPUVertexPosition start_vp{m_blit_buffer[buffer_pos++]}; s32 start_x = start_vp.x + m_drawing_offset.x; s32 start_y = start_vp.y + m_drawing_offset.y; u32 start_color = rc.color_for_first_vertex; @@ -702,7 +702,7 @@ void GPU_HW::LoadVertices() for (u32 i = 1; i < num_vertices; i++) { const u32 end_color = shaded ? (m_blit_buffer[buffer_pos++] & UINT32_C(0x00FFFFFF)) : start_color; - const VertexPosition vp{m_blit_buffer[buffer_pos++]}; + const GPUVertexPosition vp{m_blit_buffer[buffer_pos++]}; const s32 end_x = m_drawing_offset.x + vp.x; const s32 end_y = m_drawing_offset.y + vp.y; @@ -828,8 +828,8 @@ void GPU_HW::IncludeVRAMDityRectangle(const Common::Rectangle& rect) // the vram area can include the texture page, but the game can leave it as-is. in this case, set it as dirty so the // shadow texture is updated if (!m_draw_mode.IsTexturePageChanged() && - (m_draw_mode.GetTexturePageRectangle().Intersects(rect) || - (m_draw_mode.IsUsingPalette() && m_draw_mode.GetTexturePaletteRectangle().Intersects(rect)))) + (m_draw_mode.mode_reg.GetTexturePageRectangle().Intersects(rect) || + (m_draw_mode.mode_reg.IsUsingPalette() && m_draw_mode.mode_reg.GetTexturePaletteRectangle().Intersects(rect)))) { m_draw_mode.SetTexturePageChanged(); } @@ -853,13 +853,13 @@ void GPU_HW::EnsureVertexBufferSpaceForCurrentCommand() u32 required_vertices; switch (m_render_command.primitive) { - case Primitive::Polygon: + case GPUPrimitive::Polygon: required_vertices = m_render_command.quad_polygon ? 6 : 3; break; - case Primitive::Rectangle: + case GPUPrimitive::Rectangle: required_vertices = MAX_VERTICES_FOR_RECTANGLE; break; - case Primitive::Line: + case GPUPrimitive::Line: default: required_vertices = m_render_command.polyline ? (GetPolyLineVertexCount() * 6u) : 6u; break; @@ -923,9 +923,9 @@ void GPU_HW::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 void GPU_HW::DispatchRenderCommand() { - const RenderCommand rc{m_render_command.bits}; + const GPURenderCommand rc{m_render_command.bits}; - TextureMode texture_mode; + GPUTextureMode texture_mode; if (rc.IsTexturingEnabled()) { // texture page changed - check that the new page doesn't intersect the drawing area @@ -933,8 +933,9 @@ void GPU_HW::DispatchRenderCommand() { m_draw_mode.ClearTexturePageChangedFlag(); if (m_vram_dirty_rect.Valid() && - (m_draw_mode.GetTexturePageRectangle().Intersects(m_vram_dirty_rect) || - (m_draw_mode.IsUsingPalette() && m_draw_mode.GetTexturePaletteRectangle().Intersects(m_vram_dirty_rect)))) + (m_draw_mode.mode_reg.GetTexturePageRectangle().Intersects(m_vram_dirty_rect) || + (m_draw_mode.mode_reg.IsUsingPalette() && + m_draw_mode.mode_reg.GetTexturePaletteRectangle().Intersects(m_vram_dirty_rect)))) { // Log_DevPrintf("Invalidating VRAM read cache due to drawing area overlap"); if (!IsFlushed()) @@ -944,21 +945,21 @@ void GPU_HW::DispatchRenderCommand() } } - texture_mode = m_draw_mode.GetTextureMode(); + texture_mode = m_draw_mode.mode_reg.texture_mode; if (rc.raw_texture_enable) { texture_mode = - static_cast(static_cast(texture_mode) | static_cast(TextureMode::RawTextureBit)); + static_cast(static_cast(texture_mode) | static_cast(GPUTextureMode::RawTextureBit)); } } else { - texture_mode = TextureMode::Disabled; + texture_mode = GPUTextureMode::Disabled; } // has any state changed which requires a new batch? - const TransparencyMode transparency_mode = - rc.transparency_enable ? m_draw_mode.GetTransparencyMode() : TransparencyMode::Disabled; + const GPUTransparencyMode transparency_mode = + rc.transparency_enable ? m_draw_mode.mode_reg.transparency_mode : GPUTransparencyMode::Disabled; const bool dithering_enable = (!m_true_color && rc.IsDitheringEnabled()) ? m_GPUSTAT.dither_enable : false; if (m_batch.texture_mode != texture_mode || m_batch.transparency_mode != transparency_mode || dithering_enable != m_batch.dithering) @@ -969,7 +970,7 @@ void GPU_HW::DispatchRenderCommand() EnsureVertexBufferSpaceForCurrentCommand(); // transparency mode change - if (m_batch.transparency_mode != transparency_mode && transparency_mode != TransparencyMode::Disabled) + if (m_batch.transparency_mode != transparency_mode && transparency_mode != GPUTransparencyMode::Disabled) { static constexpr float transparent_alpha[4][2] = {{0.5f, 0.5f}, {1.0f, 1.0f}, {1.0f, 1.0f}, {0.25f, 1.0f}}; m_batch_ubo_data.u_src_alpha_factor = transparent_alpha[static_cast(transparency_mode)][0]; diff --git a/src/core/gpu_hw.h b/src/core/gpu_hw.h index 31c16a2be..c06f14069 100644 --- a/src/core/gpu_hw.h +++ b/src/core/gpu_hw.h @@ -94,8 +94,8 @@ protected: struct BatchConfig { - TextureMode texture_mode; - TransparencyMode transparency_mode; + GPUTextureMode texture_mode; + GPUTransparencyMode transparency_mode; bool dithering; bool interlacing; bool set_mask_while_drawing; @@ -105,15 +105,15 @@ protected: // 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; + return transparency_mode == GPUTransparencyMode::BackgroundMinusForeground && + texture_mode != GPUTextureMode::Disabled; } // Returns the render mode for this batch. BatchRenderMode GetRenderMode() const { - return transparency_mode == TransparencyMode::Disabled ? BatchRenderMode::TransparencyDisabled : - BatchRenderMode::TransparentAndOpaque; + return transparency_mode == GPUTransparencyMode::Disabled ? BatchRenderMode::TransparencyDisabled : + BatchRenderMode::TransparentAndOpaque; } }; @@ -233,7 +233,7 @@ protected: } /// Returns true if alpha blending should be enabled for drawing the current batch. - ALWAYS_INLINE bool UseAlphaBlending(TransparencyMode transparency_mode, BatchRenderMode render_mode) const + ALWAYS_INLINE bool UseAlphaBlending(GPUTransparencyMode transparency_mode, BatchRenderMode render_mode) const { if (m_texture_filtering == GPUTextureFilter::Bilinear || m_texture_filtering == GPUTextureFilter::JINC2 || m_texture_filtering == GPUTextureFilter::xBR) @@ -241,7 +241,7 @@ protected: return true; } - if (transparency_mode == TransparencyMode::Disabled || render_mode == BatchRenderMode::OnlyOpaque) + if (transparency_mode == GPUTransparencyMode::Disabled || render_mode == BatchRenderMode::OnlyOpaque) return false; return true; diff --git a/src/core/gpu_hw_d3d11.cpp b/src/core/gpu_hw_d3d11.cpp index c209a8a1c..ba46706dd 100644 --- a/src/core/gpu_hw_d3d11.cpp +++ b/src/core/gpu_hw_d3d11.cpp @@ -347,7 +347,7 @@ bool GPU_HW_D3D11::CreateStateObjects() for (u8 transparency_mode = 0; transparency_mode < 5; transparency_mode++) { bl_desc = CD3D11_BLEND_DESC(CD3D11_DEFAULT()); - if (transparency_mode != static_cast(TransparencyMode::Disabled) || + if (transparency_mode != static_cast(GPUTransparencyMode::Disabled) || m_texture_filtering != GPUTextureFilter::Nearest) { bl_desc.RenderTarget[0].BlendEnable = TRUE; @@ -356,7 +356,7 @@ bool GPU_HW_D3D11::CreateStateObjects() bl_desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; bl_desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; bl_desc.RenderTarget[0].BlendOp = - (transparency_mode == static_cast(TransparencyMode::BackgroundMinusForeground)) ? + (transparency_mode == static_cast(GPUTransparencyMode::BackgroundMinusForeground)) ? D3D11_BLEND_OP_REV_SUBTRACT : D3D11_BLEND_OP_ADD; bl_desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; @@ -462,7 +462,7 @@ bool GPU_HW_D3D11::CompileShaders() for (u8 interlacing = 0; interlacing < 2; interlacing++) { const std::string ps = shadergen.GenerateBatchFragmentShader( - static_cast(render_mode), static_cast(texture_mode), + static_cast(render_mode), static_cast(texture_mode), ConvertToBoolUnchecked(dithering), ConvertToBoolUnchecked(interlacing)); m_batch_pixel_shaders[render_mode][texture_mode][dithering][interlacing] = @@ -610,7 +610,7 @@ void GPU_HW_D3D11::DrawUtilityShader(ID3D11PixelShader* shader, const void* unif void GPU_HW_D3D11::DrawBatchVertices(BatchRenderMode render_mode, u32 base_vertex, u32 num_vertices) { - const bool textured = (m_batch.texture_mode != TextureMode::Disabled); + const bool textured = (m_batch.texture_mode != GPUTextureMode::Disabled); m_context->VSSetShader(m_batch_vertex_shaders[BoolToUInt8(textured)].Get(), nullptr, 0); @@ -619,8 +619,8 @@ void GPU_HW_D3D11::DrawBatchVertices(BatchRenderMode render_mode, u32 base_verte .Get(), nullptr, 0); - const TransparencyMode transparency_mode = - (render_mode == BatchRenderMode::OnlyOpaque) ? TransparencyMode::Disabled : m_batch.transparency_mode; + const GPUTransparencyMode transparency_mode = + (render_mode == BatchRenderMode::OnlyOpaque) ? GPUTransparencyMode::Disabled : m_batch.transparency_mode; m_context->OMSetBlendState(m_batch_blend_states[static_cast(transparency_mode)].Get(), nullptr, 0xFFFFFFFFu); m_context->OMSetDepthStencilState( m_batch.check_mask_before_draw ? m_depth_test_less_state.Get() : m_depth_test_always_state.Get(), 0); diff --git a/src/core/gpu_hw_opengl.cpp b/src/core/gpu_hw_opengl.cpp index 6b4aad62a..32eefe421 100644 --- a/src/core/gpu_hw_opengl.cpp +++ b/src/core/gpu_hw_opengl.cpp @@ -396,10 +396,10 @@ bool GPU_HW_OpenGL::CompilePrograms() { for (u8 interlacing = 0; interlacing < 2; interlacing++) { - const bool textured = (static_cast(texture_mode) != TextureMode::Disabled); + const bool textured = (static_cast(texture_mode) != GPUTextureMode::Disabled); const std::string batch_vs = shadergen.GenerateBatchVertexShader(textured); const std::string fs = shadergen.GenerateBatchFragmentShader( - static_cast(render_mode), static_cast(texture_mode), + static_cast(render_mode), static_cast(texture_mode), ConvertToBoolUnchecked(dithering), ConvertToBoolUnchecked(interlacing)); const auto link_callback = [this, textured, use_binding_layout](GL::Program& prog) { @@ -592,7 +592,7 @@ void GPU_HW_OpenGL::SetBlendMode() if (UseAlphaBlending(m_current_transparency_mode, m_current_render_mode)) { glEnable(GL_BLEND); - glBlendEquationSeparate(m_current_transparency_mode == TransparencyMode::BackgroundMinusForeground ? + glBlendEquationSeparate(m_current_transparency_mode == GPUTransparencyMode::BackgroundMinusForeground ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD, GL_FUNC_ADD); diff --git a/src/core/gpu_hw_opengl.h b/src/core/gpu_hw_opengl.h index 7b748a69c..d9528d706 100644 --- a/src/core/gpu_hw_opengl.h +++ b/src/core/gpu_hw_opengl.h @@ -99,6 +99,6 @@ private: bool m_use_ssbo_for_vram_writes = false; bool m_current_check_mask_before_draw = false; - TransparencyMode m_current_transparency_mode = TransparencyMode::Disabled; + GPUTransparencyMode m_current_transparency_mode = GPUTransparencyMode::Disabled; BatchRenderMode m_current_render_mode = BatchRenderMode::TransparencyDisabled; }; diff --git a/src/core/gpu_hw_shadergen.cpp b/src/core/gpu_hw_shadergen.cpp index c6d6de5f8..59c2414b6 100644 --- a/src/core/gpu_hw_shadergen.cpp +++ b/src/core/gpu_hw_shadergen.cpp @@ -19,7 +19,7 @@ void GPU_HW_ShaderGen::WriteCommonFunctions(std::stringstream& ss) DefineMacro(ss, "MULTISAMPLING", UsingMSAA()); ss << "CONSTANT uint RESOLUTION_SCALE = " << m_resolution_scale << "u;\n"; - ss << "CONSTANT uint2 VRAM_SIZE = uint2(" << GPU::VRAM_WIDTH << ", " << GPU::VRAM_HEIGHT << ") * RESOLUTION_SCALE;\n"; + ss << "CONSTANT uint2 VRAM_SIZE = uint2(" << VRAM_WIDTH << ", " << VRAM_HEIGHT << ") * RESOLUTION_SCALE;\n"; ss << "CONSTANT float2 RCP_VRAM_SIZE = float2(1.0, 1.0) / float2(VRAM_SIZE);\n"; ss << "CONSTANT uint MULTISAMPLES = " << m_multisamples << "u;\n"; ss << "CONSTANT bool PER_SAMPLE_SHADING = " << (m_per_sample_shading ? "true" : "false") << ";\n"; @@ -650,12 +650,11 @@ void FilteredSampleFromVRAM(uint4 texpage, float2 coords, float4 uv_limits, } std::string GPU_HW_ShaderGen::GenerateBatchFragmentShader(GPU_HW::BatchRenderMode transparency, - GPU::TextureMode texture_mode, bool dithering, - bool interlacing) + GPUTextureMode texture_mode, bool dithering, bool interlacing) { - const GPU::TextureMode actual_texture_mode = texture_mode & ~GPU::TextureMode::RawTextureBit; - const bool raw_texture = (texture_mode & GPU::TextureMode::RawTextureBit) == GPU::TextureMode::RawTextureBit; - const bool textured = (texture_mode != GPU::TextureMode::Disabled); + const GPUTextureMode actual_texture_mode = texture_mode & ~GPUTextureMode::RawTextureBit; + const bool raw_texture = (texture_mode & GPUTextureMode::RawTextureBit) == GPUTextureMode::RawTextureBit; + const bool textured = (texture_mode != GPUTextureMode::Disabled); const bool use_dual_source = m_supports_dual_source_blend && ((transparency != GPU_HW::BatchRenderMode::TransparencyDisabled && transparency != GPU_HW::BatchRenderMode::OnlyOpaque) || @@ -668,10 +667,9 @@ std::string GPU_HW_ShaderGen::GenerateBatchFragmentShader(GPU_HW::BatchRenderMod DefineMacro(ss, "TRANSPARENCY_ONLY_TRANSPARENT", transparency == GPU_HW::BatchRenderMode::OnlyTransparent); DefineMacro(ss, "TEXTURED", textured); DefineMacro(ss, "PALETTE", - actual_texture_mode == GPU::TextureMode::Palette4Bit || - actual_texture_mode == GPU::TextureMode::Palette8Bit); - DefineMacro(ss, "PALETTE_4_BIT", actual_texture_mode == GPU::TextureMode::Palette4Bit); - DefineMacro(ss, "PALETTE_8_BIT", actual_texture_mode == GPU::TextureMode::Palette8Bit); + actual_texture_mode == GPUTextureMode::Palette4Bit || actual_texture_mode == GPUTextureMode::Palette8Bit); + DefineMacro(ss, "PALETTE_4_BIT", actual_texture_mode == GPUTextureMode::Palette4Bit); + DefineMacro(ss, "PALETTE_8_BIT", actual_texture_mode == GPUTextureMode::Palette8Bit); DefineMacro(ss, "RAW_TEXTURE", raw_texture); DefineMacro(ss, "DITHERING", dithering); DefineMacro(ss, "DITHERING_SCALED", m_scaled_dithering); @@ -693,7 +691,7 @@ std::string GPU_HW_ShaderGen::GenerateBatchFragmentShader(GPU_HW::BatchRenderMod { if (i > 0) ss << ", "; - ss << GPU::DITHER_MATRIX[i / 4][i % 4]; + ss << DITHER_MATRIX[i / 4][i % 4]; } if (m_glsl) ss << " );\n"; diff --git a/src/core/gpu_hw_shadergen.h b/src/core/gpu_hw_shadergen.h index 998d53d96..b041908e7 100644 --- a/src/core/gpu_hw_shadergen.h +++ b/src/core/gpu_hw_shadergen.h @@ -11,7 +11,7 @@ public: ~GPU_HW_ShaderGen(); std::string GenerateBatchVertexShader(bool textured); - std::string GenerateBatchFragmentShader(GPU_HW::BatchRenderMode transparency, GPU::TextureMode texture_mode, + std::string GenerateBatchFragmentShader(GPU_HW::BatchRenderMode transparency, GPUTextureMode texture_mode, bool dithering, bool interlacing); std::string GenerateInterlacedFillFragmentShader(); std::string GenerateDisplayFragmentShader(bool depth_24bit, GPU_HW::InterlacedRenderMode interlace_mode, diff --git a/src/core/gpu_hw_vulkan.cpp b/src/core/gpu_hw_vulkan.cpp index 2d77fdd2b..90724b8bc 100644 --- a/src/core/gpu_hw_vulkan.cpp +++ b/src/core/gpu_hw_vulkan.cpp @@ -642,7 +642,7 @@ bool GPU_HW_Vulkan::CompilePipelines() for (u8 interlacing = 0; interlacing < 2; interlacing++) { const std::string fs = shadergen.GenerateBatchFragmentShader( - static_cast(render_mode), static_cast(texture_mode), + static_cast(render_mode), static_cast(texture_mode), ConvertToBoolUnchecked(dithering), ConvertToBoolUnchecked(interlacing)); VkShaderModule shader = g_vulkan_shader_cache->GetFragmentShader(fs); @@ -671,7 +671,7 @@ bool GPU_HW_Vulkan::CompilePipelines() { for (u8 interlacing = 0; interlacing < 2; interlacing++) { - const bool textured = (static_cast(texture_mode) != TextureMode::Disabled); + const bool textured = (static_cast(texture_mode) != GPUTextureMode::Disabled); gpbuilder.SetPipelineLayout(m_batch_pipeline_layout); gpbuilder.SetRenderPass(m_vram_render_pass, 0); @@ -697,7 +697,7 @@ bool GPU_HW_Vulkan::CompilePipelines() gpbuilder.SetNoBlendingState(); gpbuilder.SetMultisamples(m_multisamples, m_per_sample_shading); - if ((static_cast(transparency_mode) != TransparencyMode::Disabled && + if ((static_cast(transparency_mode) != GPUTransparencyMode::Disabled && (static_cast(render_mode) != BatchRenderMode::TransparencyDisabled && static_cast(render_mode) != BatchRenderMode::OnlyOpaque)) || m_texture_filtering != GPUTextureFilter::Nearest) @@ -705,7 +705,7 @@ bool GPU_HW_Vulkan::CompilePipelines() gpbuilder.SetBlendAttachment( 0, true, VK_BLEND_FACTOR_ONE, m_supports_dual_source_blend ? VK_BLEND_FACTOR_SRC1_ALPHA : VK_BLEND_FACTOR_SRC_ALPHA, - (static_cast(transparency_mode) == TransparencyMode::BackgroundMinusForeground && + (static_cast(transparency_mode) == GPUTransparencyMode::BackgroundMinusForeground && static_cast(render_mode) != BatchRenderMode::TransparencyDisabled && static_cast(render_mode) != BatchRenderMode::OnlyOpaque) ? VK_BLEND_OP_REVERSE_SUBTRACT : diff --git a/src/core/gpu_sw.cpp b/src/core/gpu_sw.cpp index e398bb91c..3d383f053 100644 --- a/src/core/gpu_sw.cpp +++ b/src/core/gpu_sw.cpp @@ -532,12 +532,12 @@ void GPU_SW::UpdateDisplay() void GPU_SW::DispatchRenderCommand() { - const RenderCommand rc{m_render_command.bits}; + const GPURenderCommand rc{m_render_command.bits}; const bool dithering_enable = rc.IsDitheringEnabled() && m_GPUSTAT.dither_enable; switch (rc.primitive) { - case Primitive::Polygon: + case GPUPrimitive::Polygon: { const u32 first_color = rc.color_for_first_vertex; const bool shaded = rc.shading_enable; @@ -553,7 +553,7 @@ void GPU_SW::DispatchRenderCommand() vert.g = Truncate8(color_rgb >> 8); vert.b = Truncate8(color_rgb >> 16); - const VertexPosition vp{FifoPop()}; + const GPUVertexPosition vp{FifoPop()}; vert.x = m_drawing_offset.x + vp.x; vert.y = m_drawing_offset.y + vp.y; @@ -580,10 +580,10 @@ void GPU_SW::DispatchRenderCommand() } break; - case Primitive::Rectangle: + case GPUPrimitive::Rectangle: { const auto [r, g, b] = UnpackColorRGB24(rc.color_for_first_vertex); - const VertexPosition vp{FifoPop()}; + const GPUVertexPosition vp{FifoPop()}; const u32 texcoord_and_palette = rc.texture_enable ? FifoPop() : 0; const auto [texcoord_x, texcoord_y] = UnpackTexcoord(Truncate16(texcoord_and_palette)); @@ -591,15 +591,15 @@ void GPU_SW::DispatchRenderCommand() u32 height; switch (rc.rectangle_size) { - case DrawRectangleSize::R1x1: + case GPUDrawRectangleSize::R1x1: width = 1; height = 1; break; - case DrawRectangleSize::R8x8: + case GPUDrawRectangleSize::R8x8: width = 8; height = 8; break; - case DrawRectangleSize::R16x16: + case GPUDrawRectangleSize::R16x16: width = 16; height = 16; break; @@ -629,7 +629,7 @@ void GPU_SW::DispatchRenderCommand() } break; - case Primitive::Line: + case GPUPrimitive::Line: { const u32 first_color = rc.color_for_first_vertex; const bool shaded = rc.shading_enable; @@ -642,7 +642,7 @@ void GPU_SW::DispatchRenderCommand() // first vertex SWVertex* p0 = &vertices[0]; SWVertex* p1 = &vertices[1]; - p0->SetPosition(VertexPosition{rc.polyline ? m_blit_buffer[buffer_pos++] : Truncate32(FifoPop())}, + p0->SetPosition(GPUVertexPosition{rc.polyline ? m_blit_buffer[buffer_pos++] : Truncate32(FifoPop())}, m_drawing_offset.x, m_drawing_offset.y); p0->SetColorRGB24(first_color); @@ -653,12 +653,12 @@ void GPU_SW::DispatchRenderCommand() if (rc.polyline) { p1->SetColorRGB24(shaded ? (m_blit_buffer[buffer_pos++] & UINT32_C(0x00FFFFFF)) : first_color); - p1->SetPosition(VertexPosition{m_blit_buffer[buffer_pos++]}, m_drawing_offset.x, m_drawing_offset.y); + p1->SetPosition(GPUVertexPosition{m_blit_buffer[buffer_pos++]}, m_drawing_offset.x, m_drawing_offset.y); } else { p1->SetColorRGB24(shaded ? (FifoPop() & UINT32_C(0x00FFFFFF)) : first_color); - p1->SetPosition(VertexPosition{Truncate32(FifoPop())}, m_drawing_offset.x, m_drawing_offset.y); + p1->SetPosition(GPUVertexPosition{Truncate32(FifoPop())}, m_drawing_offset.x, m_drawing_offset.y); } // down here because of the FIFO pops @@ -710,9 +710,9 @@ void ALWAYS_INLINE_RELEASE GPU_SW::ShadePixel(u32 x, u32 y, u8 color_r, u8 color texcoord_y = (texcoord_y & m_draw_mode.texture_window_and_y) | m_draw_mode.texture_window_or_y; VRAMPixel texture_color; - switch (m_draw_mode.GetTextureMode()) + switch (m_draw_mode.mode_reg.texture_mode) { - case GPU::TextureMode::Palette4Bit: + case GPUTextureMode::Palette4Bit: { const u16 palette_value = GetPixel((m_draw_mode.texture_page_x + ZeroExtend32(texcoord_x / 4)) % VRAM_WIDTH, (m_draw_mode.texture_page_y + ZeroExtend32(texcoord_y)) % VRAM_HEIGHT); @@ -722,7 +722,7 @@ void ALWAYS_INLINE_RELEASE GPU_SW::ShadePixel(u32 x, u32 y, u8 color_r, u8 color } break; - case GPU::TextureMode::Palette8Bit: + case GPUTextureMode::Palette8Bit: { const u16 palette_value = GetPixel((m_draw_mode.texture_page_x + ZeroExtend32(texcoord_x / 2)) % VRAM_WIDTH, (m_draw_mode.texture_page_y + ZeroExtend32(texcoord_y)) % VRAM_HEIGHT); @@ -786,18 +786,18 @@ void ALWAYS_INLINE_RELEASE GPU_SW::ShadePixel(u32 x, u32 y, u8 color_r, u8 color color.Set(func(bg_color.r.GetValue(), color.r.GetValue()), func(bg_color.g.GetValue(), color.g.GetValue()), \ func(bg_color.b.GetValue(), color.b.GetValue()), color.c.GetValue()) - switch (m_draw_mode.GetTransparencyMode()) + switch (m_draw_mode.mode_reg.transparency_mode) { - case GPU::TransparencyMode::HalfBackgroundPlusHalfForeground: + case GPUTransparencyMode::HalfBackgroundPlusHalfForeground: BLEND_RGB(BLEND_AVERAGE); break; - case GPU::TransparencyMode::BackgroundPlusForeground: + case GPUTransparencyMode::BackgroundPlusForeground: BLEND_RGB(BLEND_ADD); break; - case GPU::TransparencyMode::BackgroundMinusForeground: + case GPUTransparencyMode::BackgroundMinusForeground: BLEND_RGB(BLEND_SUBTRACT); break; - case GPU::TransparencyMode::BackgroundPlusQuarterForeground: + case GPUTransparencyMode::BackgroundPlusQuarterForeground: BLEND_RGB(BLEND_QUARTER); break; default: @@ -828,8 +828,8 @@ template void GPU_SW::DrawRectangle(s32 origin_x, s32 origin_y, u32 width, u32 height, u8 r, u8 g, u8 b, u8 origin_texcoord_x, u8 origin_texcoord_y) { - const s32 start_x = TruncateVertexPosition(m_drawing_offset.x + origin_x); - const s32 start_y = TruncateVertexPosition(m_drawing_offset.y + origin_y); + const s32 start_x = TruncateGPUVertexPosition(m_drawing_offset.x + origin_x); + const s32 start_y = TruncateGPUVertexPosition(m_drawing_offset.y + origin_y); { const u32 clip_left = static_cast(std::clamp(start_x, m_drawing_area.left, m_drawing_area.right)); @@ -986,7 +986,7 @@ void GPU_SW::DrawSpan(s32 y, s32 x_start, s32 x_bound, i_group ig, const i_delta s32 x_ig_adjust = x_start; s32 w = x_bound - x_start; - s32 x = TruncateVertexPosition(x_start); + s32 x = TruncateGPUVertexPosition(x_start); if (x < static_cast(m_drawing_area.left)) { @@ -1178,7 +1178,7 @@ void GPU_SW::DrawTriangle(const SWVertex* v0, const SWVertex* v1, const SWVertex lc -= ls; rc -= rs; - s32 y = TruncateVertexPosition(yi); + s32 y = TruncateGPUVertexPosition(yi); if (y < static_cast(m_drawing_area.top)) break; @@ -1194,7 +1194,7 @@ void GPU_SW::DrawTriangle(const SWVertex* v0, const SWVertex* v1, const SWVertex { while (yi < yb) { - s32 y = TruncateVertexPosition(yi); + s32 y = TruncateGPUVertexPosition(yi); if (y > static_cast(m_drawing_area.bottom)) break; diff --git a/src/core/gpu_sw.h b/src/core/gpu_sw.h index d8ad4f463..0b9326db4 100644 --- a/src/core/gpu_sw.h +++ b/src/core/gpu_sw.h @@ -36,10 +36,10 @@ protected: u8 r, g, b; u8 u, v; - ALWAYS_INLINE void SetPosition(VertexPosition p, s32 offset_x, s32 offset_y) + ALWAYS_INLINE void SetPosition(GPUVertexPosition p, s32 offset_x, s32 offset_y) { - x = TruncateVertexPosition(offset_x + p.x); - y = TruncateVertexPosition(offset_y + p.y); + x = TruncateGPUVertexPosition(offset_x + p.x); + y = TruncateGPUVertexPosition(offset_y + p.y); } ALWAYS_INLINE void SetColorRGB24(u32 color) { std::tie(r, g, b) = UnpackColorRGB24(color); } diff --git a/src/core/gpu_types.h b/src/core/gpu_types.h new file mode 100644 index 000000000..1df6cbc8b --- /dev/null +++ b/src/core/gpu_types.h @@ -0,0 +1,224 @@ +#pragma once +#include "common/bitfield.h" +#include "common/rectangle.h" +#include "types.h" +#include + +enum : u32 +{ + VRAM_WIDTH = 1024, + VRAM_HEIGHT = 512, + VRAM_SIZE = VRAM_WIDTH * VRAM_HEIGHT * sizeof(u16), + VRAM_WIDTH_MASK = VRAM_WIDTH - 1, + VRAM_HEIGHT_MASK = VRAM_HEIGHT - 1, + VRAM_COORD_MASK = 0x3FF, + TEXTURE_PAGE_WIDTH = 256, + TEXTURE_PAGE_HEIGHT = 256, + MAX_PRIMITIVE_WIDTH = 1024, + MAX_PRIMITIVE_HEIGHT = 512, + DITHER_MATRIX_SIZE = 4 +}; + +enum class GPUPrimitive : u8 +{ + Reserved = 0, + Polygon = 1, + Line = 2, + Rectangle = 3 +}; + +enum class GPUDrawRectangleSize : u8 +{ + Variable = 0, + R1x1 = 1, + R8x8 = 2, + R16x16 = 3 +}; + +enum class GPUTextureMode : u8 +{ + Palette4Bit = 0, + Palette8Bit = 1, + Direct16Bit = 2, + Reserved_Direct16Bit = 3, + + // Not register values. + RawTextureBit = 4, + RawPalette4Bit = RawTextureBit | Palette4Bit, + RawPalette8Bit = RawTextureBit | Palette8Bit, + RawDirect16Bit = RawTextureBit | Direct16Bit, + Reserved_RawDirect16Bit = RawTextureBit | Reserved_Direct16Bit, + + Disabled = 8 // Not a register value +}; + +IMPLEMENT_ENUM_CLASS_BITWISE_OPERATORS(GPUTextureMode); + +enum class GPUTransparencyMode : u8 +{ + HalfBackgroundPlusHalfForeground = 0, + BackgroundPlusForeground = 1, + BackgroundMinusForeground = 2, + BackgroundPlusQuarterForeground = 3, + + Disabled = 4 // Not a register value +}; + +enum class GPUInterlacedDisplayMode : u8 +{ + None, + InterleavedFields, + SeparateFields +}; + +union GPURenderCommand +{ + u32 bits; + + BitField color_for_first_vertex; + BitField raw_texture_enable; // not valid for lines + BitField transparency_enable; + BitField texture_enable; + BitField rectangle_size; // only for rectangles + BitField quad_polygon; // only for polygons + BitField polyline; // only for lines + BitField shading_enable; // 0 - flat, 1 = gouroud + BitField primitive; + + /// Returns true if texturing should be enabled. Depends on the primitive type. + ALWAYS_INLINE bool IsTexturingEnabled() const { return (primitive != GPUPrimitive::Line) ? texture_enable : false; } + + /// Returns true if dithering should be enabled. Depends on the primitive type. + ALWAYS_INLINE bool IsDitheringEnabled() const + { + switch (primitive) + { + case GPUPrimitive::Polygon: + return shading_enable || (texture_enable && !raw_texture_enable); + + case GPUPrimitive::Line: + return true; + + case GPUPrimitive::Rectangle: + default: + return false; + } + } +}; + +// Helper/format conversion functions. +static constexpr u32 RGBA5551ToRGBA8888(u16 color) +{ + u8 r = Truncate8(color & 31); + u8 g = Truncate8((color >> 5) & 31); + u8 b = Truncate8((color >> 10) & 31); + u8 a = Truncate8((color >> 15) & 1); + + // 00012345 -> 1234545 + b = (b << 3) | (b & 0b111); + g = (g << 3) | (g & 0b111); + r = (r << 3) | (r & 0b111); + a = a ? 255 : 0; + + return ZeroExtend32(r) | (ZeroExtend32(g) << 8) | (ZeroExtend32(b) << 16) | (ZeroExtend32(a) << 24); +} + +static constexpr u16 RGBA8888ToRGBA5551(u32 color) +{ + const u16 r = Truncate16((color >> 3) & 0x1Fu); + const u16 g = Truncate16((color >> 11) & 0x1Fu); + const u16 b = Truncate16((color >> 19) & 0x1Fu); + const u16 a = Truncate16((color >> 31) & 0x01u); + + return r | (g << 5) | (b << 10) | (a << 15); +} + +union GPUVertexPosition +{ + u32 bits; + + BitField x; + BitField y; +}; + +// Sprites/rectangles should be clipped to 12 bits before drawing. +static constexpr s32 TruncateGPUVertexPosition(s32 x) +{ + return SignExtendN<11, s32>(x); +} + +// bits in GP0(E1h) or texpage part of polygon +union GPUDrawModeReg +{ + static constexpr u16 MASK = 0b1111111111111; + static constexpr u16 TEXTURE_PAGE_MASK = UINT16_C(0b0000000000011111); + + // Polygon texpage commands only affect bits 0-8, 11 + static constexpr u16 POLYGON_TEXPAGE_MASK = 0b0000100111111111; + + // Bits 0..5 are returned in the GPU status register, latched at E1h/polygon draw time. + static constexpr u32 GPUSTAT_MASK = 0b11111111111; + + u16 bits; + + BitField texture_page_x_base; + BitField texture_page_y_base; + BitField transparency_mode; + BitField texture_mode; + BitField dither_enable; + BitField draw_to_displayed_field; + BitField texture_disable; + BitField texture_x_flip; + BitField texture_y_flip; + + ALWAYS_INLINE u16 GetTexturePageBaseX() const { return ZeroExtend16(texture_page_x_base.GetValue()) * 64; } + ALWAYS_INLINE u16 GetTexturePageBaseY() const { return ZeroExtend16(texture_page_y_base.GetValue()) * 256; } + + /// Returns true if the texture mode requires a palette. + bool IsUsingPalette() const { return (bits & (2 << 7)) == 0; } + + /// Returns a rectangle comprising the texture page area. + Common::Rectangle GetTexturePageRectangle() const + { + static constexpr std::array texture_page_widths = { + {TEXTURE_PAGE_WIDTH / 4, TEXTURE_PAGE_WIDTH / 2, TEXTURE_PAGE_WIDTH, TEXTURE_PAGE_WIDTH} }; + return Common::Rectangle::FromExtents(GetTexturePageBaseX(), GetTexturePageBaseY(), + texture_page_widths[static_cast(texture_mode.GetValue())], + TEXTURE_PAGE_HEIGHT); + } + + /// Returns a rectangle comprising the texture palette area. + Common::Rectangle GetTexturePaletteRectangle() const + { + static constexpr std::array palette_widths = { {16, 256, 0, 0} }; + return Common::Rectangle::FromExtents(GetTexturePageBaseX(), GetTexturePageBaseY(), + palette_widths[static_cast(texture_mode.GetValue())], 1); + } +}; + +union GPUTexturePaletteReg +{ + static constexpr u16 MASK = UINT16_C(0b0111111111111111); + + u16 bits; + + BitField x; + BitField y; + + ALWAYS_INLINE u32 GetXBase() const { return static_cast(x) * 16u; } + ALWAYS_INLINE u32 GetYBase() const { return static_cast(y); } +}; + +struct GPUTextureWindow +{ + u8 and_x; + u8 and_y; + u8 or_x; + u8 or_y; +}; + +// 4x4 dither matrix. +static constexpr s32 DITHER_MATRIX[DITHER_MATRIX_SIZE][DITHER_MATRIX_SIZE] = { {-4, +0, -3, +1}, // row 0 + {+2, -2, +3, -1}, // row 1 + {-3, +1, -4, +0}, // row 2 + {+4, -1, +2, -2} }; // row 3 diff --git a/src/duckstation-libretro/libretro_host_interface.cpp b/src/duckstation-libretro/libretro_host_interface.cpp index 7110e3190..7ccfd64b7 100644 --- a/src/duckstation-libretro/libretro_host_interface.cpp +++ b/src/duckstation-libretro/libretro_host_interface.cpp @@ -230,8 +230,8 @@ void LibretroHostInterface::GetSystemAVInfo(struct retro_system_av_info* info, b info->geometry.aspect_ratio = m_last_aspect_ratio; info->geometry.base_width = 320; info->geometry.base_height = 240; - info->geometry.max_width = GPU::VRAM_WIDTH * resolution_scale; - info->geometry.max_height = GPU::VRAM_HEIGHT * resolution_scale; + info->geometry.max_width = VRAM_WIDTH * resolution_scale; + info->geometry.max_height = VRAM_HEIGHT * resolution_scale; info->timing.fps = System::GetThrottleFrequency(); info->timing.sample_rate = static_cast(AUDIO_SAMPLE_RATE); diff --git a/src/duckstation-sdl/sdl_host_interface.cpp b/src/duckstation-sdl/sdl_host_interface.cpp index 432d378f8..c9899586e 100644 --- a/src/duckstation-sdl/sdl_host_interface.cpp +++ b/src/duckstation-sdl/sdl_host_interface.cpp @@ -960,7 +960,7 @@ void SDLHostInterface::DrawQuickSettingsMenu() for (u32 scale = 1; scale <= GPU::MAX_RESOLUTION_SCALE; scale++) { char buf[32]; - std::snprintf(buf, sizeof(buf), "%ux (%ux%u)", scale, scale * GPU::VRAM_WIDTH, scale * GPU::VRAM_HEIGHT); + std::snprintf(buf, sizeof(buf), "%ux (%ux%u)", scale, scale * VRAM_WIDTH, scale * VRAM_HEIGHT); if (ImGui::MenuItem(buf, nullptr, current_internal_resolution == scale)) {