diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index 5a6ed434c..046fa714c 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -49,8 +49,6 @@ void GPU::SoftReset() m_GPUREAD_buffer.clear(); m_render_state = {}; m_render_state.texture_page_changed = true; - m_render_state.texture_color_mode_changed = true; - m_render_state.transparency_mode_changed = true; UpdateGPUSTAT(); UpdateCRTCConfig(); } @@ -80,10 +78,6 @@ bool GPU::DoState(StateWrapper& sw) sw.Do(&m_render_state.texpage_attribute); sw.Do(&m_render_state.texlut_attribute); sw.Do(&m_render_state.texture_window_value); - sw.Do(&m_render_state.texture_page_changed); - sw.Do(&m_render_state.texture_color_mode_changed); - sw.Do(&m_render_state.transparency_mode_changed); - sw.Do(&m_render_state.texture_window_changed); sw.Do(&m_drawing_area.left); sw.Do(&m_drawing_area.top); @@ -119,8 +113,6 @@ bool GPU::DoState(StateWrapper& sw) if (sw.IsReading()) { m_render_state.texture_page_changed = true; - m_render_state.texture_color_mode_changed = true; - m_render_state.transparency_mode_changed = true; m_render_state.texture_window_changed = true; UpdateDrawingArea(); UpdateGPUSTAT(); @@ -709,15 +701,8 @@ void GPU::RenderState::SetFromPageAttribute(u16 value) texture_page_changed |= (old_page_attribute & PAGE_ATTRIBUTE_TEXTURE_PAGE_MASK) != (value & PAGE_ATTRIBUTE_TEXTURE_PAGE_MASK); - const TextureColorMode old_color_mode = texture_color_mode; - texture_color_mode = (static_cast((value >> 7) & UINT16_C(0x03))); - if (texture_color_mode == TextureColorMode::Reserved_Direct16Bit) - texture_color_mode = TextureColorMode::Direct16Bit; - texture_color_mode_changed |= old_color_mode != texture_color_mode; - - const TransparencyMode old_transparency_mode = transparency_mode; + texture_color_mode = (static_cast((value >> 7) & UINT16_C(0x03))); transparency_mode = (static_cast((value >> 5) & UINT16_C(0x03))); - transparency_mode_changed = old_transparency_mode != transparency_mode; } void GPU::RenderState::SetFromPaletteAttribute(u16 value) diff --git a/src/core/gpu.h b/src/core/gpu.h index 9ec483326..25d7ced5c 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -138,20 +138,33 @@ protected: R16x16 = 3 }; - enum class TextureColorMode : u8 + enum class TextureMode : u8 { Palette4Bit = 0, Palette8Bit = 1, Direct16Bit = 2, - Reserved_Direct16Bit = 3 + 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_STATIC_FRIEND_ENUM_CLASS_BITWISE_OPERATORS(TextureMode); + enum class TransparencyMode : u8 { HalfBackgroundPlusHalfForeground = 0, BackgroundPlusForeground = 1, BackgroundMinusForeground = 2, - BackgroundPlusQuarterForeground = 3 + BackgroundPlusQuarterForeground = 3, + + Disabled = 4 // Not a register value }; union RenderCommand @@ -159,7 +172,7 @@ protected: u32 bits; BitField color_for_first_vertex; - BitField texture_blend_disable; // not valid for lines + BitField raw_texture_enable; // not valid for lines BitField transparency_enable; BitField texture_enable; BitField rectangle_size; // only for rectangles @@ -170,7 +183,7 @@ protected: // Helper functions. bool IsTextureEnabled() const { return (primitive != Primitive::Line && texture_enable); } - bool IsTextureBlendingEnabled() const { return (IsTextureEnabled() && !texture_blend_disable); } + bool IsTextureBlendingEnabled() const { return (IsTextureEnabled() && !raw_texture_enable); } bool IsTransparencyEnabled() const { return transparency_enable; } }; @@ -269,7 +282,7 @@ protected: BitField texture_page_x_base; BitField texture_page_y_base; BitField semi_transparency_mode; - BitField texture_color_mode; + BitField texture_color_mode; BitField dither_enable; BitField draw_to_display_area; BitField draw_set_mask_bit; @@ -305,7 +318,7 @@ protected: u32 texture_page_y; u32 texture_palette_x; u32 texture_palette_y; - TextureColorMode texture_color_mode; + TextureMode texture_color_mode; TransparencyMode transparency_mode; u8 texture_window_mask_x; // in 8 pixel steps u8 texture_window_mask_y; // in 8 pixel steps @@ -320,21 +333,11 @@ protected: u32 texture_window_value; bool texture_page_changed = false; - bool texture_color_mode_changed = false; - bool transparency_mode_changed = false; bool texture_window_changed = false; - bool IsChanged() const { return texture_page_changed || texture_color_mode_changed || transparency_mode_changed; } - bool IsTexturePageChanged() const { return texture_page_changed; } void ClearTexturePageChangedFlag() { texture_page_changed = false; } - bool IsTextureColorModeChanged() const { return texture_color_mode_changed; } - void ClearTextureColorModeChangedFlag() { texture_color_mode_changed = false; } - - bool IsTransparencyModeChanged() const { return transparency_mode_changed; } - void ClearTransparencyModeChangedFlag() { transparency_mode_changed = false; } - bool IsTextureWindowChanged() const { return texture_window_changed; } void ClearTextureWindowChangedFlag() { texture_window_changed = false; } diff --git a/src/core/gpu_hw.cpp b/src/core/gpu_hw.cpp index f34e71810..db32f689a 100644 --- a/src/core/gpu_hw.cpp +++ b/src/core/gpu_hw.cpp @@ -241,21 +241,23 @@ void main() return ss.str(); } -std::string GPU_HW::GenerateFragmentShader(TransparencyRenderMode transparency, bool textured, - TextureColorMode texture_color_mode, bool blending) +std::string GPU_HW::GenerateFragmentShader(HWBatchRenderMode transparency, TextureMode texture_mode) { + const TextureMode actual_texture_mode = texture_mode & ~TextureMode::RawTextureBit; + const bool raw_texture = (texture_mode & TextureMode::RawTextureBit) == TextureMode::RawTextureBit; + std::stringstream ss; GenerateShaderHeader(ss); - DefineMacro(ss, "TRANSPARENT", transparency != TransparencyRenderMode::Off); - DefineMacro(ss, "TRANSPARENT_ONLY_OPAQUE", transparency == TransparencyRenderMode::OnlyOpaque); - DefineMacro(ss, "TRANSPARENT_ONLY_TRANSPARENT", transparency == TransparencyRenderMode::OnlyTransparent); - DefineMacro(ss, "TEXTURED", textured); + DefineMacro(ss, "TRANSPARENCY", transparency != HWBatchRenderMode::TransparencyDisabled); + DefineMacro(ss, "TRANSPARENCY_ONLY_OPAQUE", transparency == HWBatchRenderMode::OnlyOpaque); + DefineMacro(ss, "TRANSPARENCY_ONLY_TRANSPARENCY", transparency == HWBatchRenderMode::OnlyTransparent); + DefineMacro(ss, "TEXTURED", actual_texture_mode != TextureMode::Disabled); DefineMacro(ss, "PALETTE", - textured && (texture_color_mode == GPU::TextureColorMode::Palette4Bit || - texture_color_mode == GPU::TextureColorMode::Palette8Bit)); - DefineMacro(ss, "PALETTE_4_BIT", textured && texture_color_mode == GPU::TextureColorMode::Palette4Bit); - DefineMacro(ss, "PALETTE_8_BIT", textured && texture_color_mode == GPU::TextureColorMode::Palette8Bit); - DefineMacro(ss, "BLENDING", blending); + 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); + DefineMacro(ss, "RAW_TEXTURE", raw_texture); ss << R"( in vec3 v_col0; @@ -334,24 +336,24 @@ void main() discard; vec3 color; - #if BLENDING - color = vec3((ivec3(v_col0 * 255.0) * ivec3(texcol.rgb * 255.0)) >> 7) / 255.0; - #else + #if RAW_TEXTURE color = texcol.rgb; + #else + color = vec3((ivec3(v_col0 * 255.0) * ivec3(texcol.rgb * 255.0)) >> 7) / 255.0; #endif - #if TRANSPARENT + #if TRANSPARENCY // Apply semitransparency. If not a semitransparent texel, destination alpha is ignored. if (texcol.a != 0) { - #if TRANSPARENT_ONLY_OPAQUE + #if TRANSPARENCY_ONLY_OPAQUE discard; #endif o_col0 = vec4(color * u_transparent_alpha.x, u_transparent_alpha.y); } else { - #if TRANSPARENT_ONLY_TRANSPARENT + #if TRANSPARENCY_ONLY_TRANSPARENCY discard; #endif o_col0 = vec4(color, 0.0); @@ -361,7 +363,7 @@ void main() o_col0 = vec4(color, texcol.a); #endif #else - #if TRANSPARENT + #if TRANSPARENCY o_col0 = vec4(v_col0 * u_transparent_alpha.x, u_transparent_alpha.y); #else // Mask bit is cleared for untextured polygons. @@ -491,20 +493,21 @@ void main() return ss.str(); } -GPU_HW::HWRenderBatch::Primitive GPU_HW::GetPrimitiveForCommand(RenderCommand rc) +GPU_HW::HWPrimitive GPU_HW::GetPrimitiveForCommand(RenderCommand rc) { if (rc.primitive == Primitive::Line) - return rc.polyline ? HWRenderBatch::Primitive::LineStrip : HWRenderBatch::Primitive::Lines; + return rc.polyline ? HWPrimitive::LineStrip : HWPrimitive::Lines; else if ((rc.primitive == Primitive::Polygon && rc.quad_polygon) || rc.primitive == Primitive::Rectangle) - return HWRenderBatch::Primitive::TriangleStrip; + return HWPrimitive::TriangleStrip; else - return HWRenderBatch::Primitive::Triangles; + return HWPrimitive::Triangles; } void GPU_HW::InvalidateVRAMReadCache() {} void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32* command_ptr) { + TextureMode texture_mode; if (rc.texture_enable) { // extract texture lut/page @@ -529,39 +532,37 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32 default: break; } + + texture_mode = m_render_state.texture_color_mode; + if (rc.raw_texture_enable) + texture_mode |= TextureMode::RawTextureBit; } else { m_render_state.SetFromPageAttribute(Truncate16(m_GPUSTAT.bits)); + texture_mode = TextureMode::Disabled; } // has any state changed which requires a new batch? - const bool rc_transparency_enable = rc.IsTransparencyEnabled(); - const bool rc_texture_enable = rc.IsTextureEnabled(); - const bool rc_texture_blend_enable = rc.IsTextureBlendingEnabled(); - const HWRenderBatch::Primitive rc_primitive = GetPrimitiveForCommand(rc); - const u32 max_added_vertices = num_vertices + 2; - const bool buffer_overflow = (m_batch.vertices.size() + max_added_vertices) >= MAX_BATCH_VERTEX_COUNT; - const bool rc_changed = - m_batch.render_command_bits != rc.bits && - (m_batch.transparency_enable != rc_transparency_enable || m_batch.texture_enable != rc_texture_enable || - m_batch.texture_blending_enable != rc_texture_blend_enable || m_batch.primitive != rc_primitive); - const bool restart_line_strip = (rc_primitive == HWRenderBatch::Primitive::LineStrip); - const bool needs_flush = - !IsFlushed() && (m_render_state.IsTextureColorModeChanged() || m_render_state.IsTransparencyModeChanged() || - m_render_state.IsTextureWindowChanged() || buffer_overflow || rc_changed || restart_line_strip); - if (needs_flush) - FlushRender(); + const TransparencyMode transparency_mode = + rc.transparency_enable ? m_render_state.transparency_mode : TransparencyMode::Disabled; + const HWPrimitive rc_primitive = GetPrimitiveForCommand(rc); + if (!IsFlushed()) + { + const u32 max_added_vertices = num_vertices + 2; + const bool buffer_overflow = (m_batch.vertices.size() + max_added_vertices) >= MAX_BATCH_VERTEX_COUNT; + if (buffer_overflow || rc_primitive == HWPrimitive::LineStrip || m_batch.texture_mode != texture_mode || + m_batch.transparency_mode != transparency_mode || m_batch.primitive != rc_primitive || + m_render_state.IsTexturePageChanged() || m_render_state.IsTextureWindowChanged()) + { + FlushRender(); + } + } // update state - if (rc_changed) - { - m_batch.render_command_bits = rc.bits; - m_batch.primitive = rc_primitive; - m_batch.transparency_enable = rc_transparency_enable; - m_batch.texture_enable = rc_texture_enable; - m_batch.texture_blending_enable = rc_texture_blend_enable; - } + m_batch.primitive = rc_primitive; + m_batch.texture_mode = texture_mode; + m_batch.transparency_mode = transparency_mode; if (m_render_state.IsTexturePageChanged()) { @@ -588,18 +589,6 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32 m_render_state.ClearTexturePageChangedFlag(); } - if (m_render_state.IsTextureColorModeChanged()) - { - m_batch.texture_color_mode = m_render_state.texture_color_mode; - m_render_state.ClearTextureColorModeChangedFlag(); - } - - if (m_render_state.IsTransparencyModeChanged()) - { - m_batch.transparency_mode = m_render_state.transparency_mode; - m_render_state.ClearTransparencyModeChangedFlag(); - } - if (m_render_state.IsTextureWindowChanged()) { m_batch.texture_window_values[0] = m_render_state.texture_window_mask_x; diff --git a/src/core/gpu_hw.h b/src/core/gpu_hw.h index 527460611..54618e9d8 100644 --- a/src/core/gpu_hw.h +++ b/src/core/gpu_hw.h @@ -14,6 +14,22 @@ public: virtual void Reset() override; protected: + enum class HWPrimitive : u8 + { + Lines = 0, + LineStrip = 1, + Triangles = 2, + TriangleStrip = 3 + }; + + enum class HWBatchRenderMode : u8 + { + TransparencyDisabled, + TransparentAndOpaque, + OnlyOpaque, + OnlyTransparent + }; + struct HWVertex { s32 x; @@ -28,20 +44,8 @@ protected: struct HWRenderBatch { - enum class Primitive : u8 - { - Lines = 0, - LineStrip = 1, - Triangles = 2, - TriangleStrip = 3 - }; - - u32 render_command_bits; - Primitive primitive; - bool transparency_enable; - bool texture_enable; - bool texture_blending_enable; - TextureColorMode texture_color_mode; + HWPrimitive primitive; + TextureMode texture_mode; u32 texture_page_x; u32 texture_page_y; u32 texture_palette_x; @@ -50,14 +54,21 @@ protected: std::array texture_window_values; std::vector vertices; - }; - enum class TransparencyRenderMode - { - Off, - TransparentAndOpaque, - OnlyOpaque, - OnlyTransparent + // 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; @@ -89,8 +100,7 @@ protected: } std::string GenerateVertexShader(bool textured); - std::string GenerateFragmentShader(TransparencyRenderMode transparency, bool textured, - TextureColorMode texture_color_mode, bool blending); + std::string GenerateFragmentShader(HWBatchRenderMode transparency, TextureMode texture_mode); std::string GenerateScreenQuadVertexShader(); std::string GenerateFillFragmentShader(); std::string GenerateDisplayFragmentShader(bool depth_24bit, bool interlaced); @@ -98,7 +108,7 @@ protected: HWRenderBatch m_batch = {}; private: - static HWRenderBatch::Primitive GetPrimitiveForCommand(RenderCommand rc); + static HWPrimitive GetPrimitiveForCommand(RenderCommand rc); void GenerateShaderHeader(std::stringstream& ss); diff --git a/src/core/gpu_hw_opengl.cpp b/src/core/gpu_hw_opengl.cpp index 86bc4f584..c37447f1b 100644 --- a/src/core/gpu_hw_opengl.cpp +++ b/src/core/gpu_hw_opengl.cpp @@ -230,22 +230,14 @@ void GPU_HW_OpenGL::CreateVertexBuffer() bool GPU_HW_OpenGL::CompilePrograms() { - for (u32 transparent = 0; transparent < 4; transparent++) + for (u32 render_mode = 0; render_mode < 4; render_mode++) { - for (u32 textured = 0; textured < 2; textured++) + for (u32 texture_mode = 0; texture_mode < 9; texture_mode++) { - for (u32 format = 0; format < 3; format++) + if (!CompileProgram(m_render_programs[render_mode][texture_mode], static_cast(render_mode), + static_cast(texture_mode))) { - for (u32 blending = 0; blending < 2; blending++) - { - // TODO: eliminate duplicate shaders here - if (!CompileProgram(m_render_programs[transparent][textured][format][blending], - static_cast(transparent), ConvertToBoolUnchecked(textured), - static_cast(format), ConvertToBoolUnchecked(blending))) - { - return false; - } - } + return false; } } } @@ -276,11 +268,11 @@ bool GPU_HW_OpenGL::CompilePrograms() return true; } -bool GPU_HW_OpenGL::CompileProgram(GL::Program& prog, TransparencyRenderMode transparent, bool textured, - TextureColorMode texture_color_mode, bool blending) +bool GPU_HW_OpenGL::CompileProgram(GL::Program& prog, HWBatchRenderMode render_mode, TextureMode texture_mode) { + const bool textured = texture_mode != TextureMode::Disabled; const std::string vs = GenerateVertexShader(textured); - const std::string fs = GenerateFragmentShader(transparent, textured, texture_color_mode, blending); + const std::string fs = GenerateFragmentShader(render_mode, texture_mode); if (!prog.Compile(vs.c_str(), fs.c_str())) return false; @@ -313,15 +305,13 @@ bool GPU_HW_OpenGL::CompileProgram(GL::Program& prog, TransparencyRenderMode tra return true; } -void GPU_HW_OpenGL::SetDrawState(TransparencyRenderMode render_mode) +void GPU_HW_OpenGL::SetDrawState(HWBatchRenderMode render_mode) { - const GL::Program& prog = - m_render_programs[static_cast(render_mode)][BoolToUInt32(m_batch.texture_enable)] - [static_cast(m_batch.texture_color_mode)][BoolToUInt32(m_batch.texture_blending_enable)]; + const GL::Program& prog = m_render_programs[static_cast(render_mode)][static_cast(m_batch.texture_mode)]; prog.Bind(); prog.Uniform2i(0, m_drawing_offset.x, m_drawing_offset.y); - if (m_batch.transparency_enable) + if (m_batch.transparency_mode != TransparencyMode::Disabled) { static constexpr float transparent_alpha[4][2] = {{0.5f, 0.5f}, {1.0f, 1.0f}, {1.0f, 1.0f}, {0.25f, 1.0f}}; prog.Uniform2fv(1, transparent_alpha[static_cast(m_batch.transparency_mode)]); @@ -332,14 +322,14 @@ void GPU_HW_OpenGL::SetDrawState(TransparencyRenderMode render_mode) prog.Uniform2fv(1, disabled_alpha); } - if (m_batch.texture_enable) + if (m_batch.texture_mode != TextureMode::Disabled) { prog.Uniform4ui(2, m_batch.texture_window_values[0], m_batch.texture_window_values[1], m_batch.texture_window_values[2], m_batch.texture_window_values[3]); m_vram_read_texture->Bind(); } - if (render_mode == TransparencyRenderMode::Off || render_mode == TransparencyRenderMode::OnlyOpaque) + if (m_batch.transparency_mode == TransparencyMode::Disabled || render_mode == HWBatchRenderMode::OnlyOpaque) { glDisable(GL_BLEND); } @@ -644,18 +634,16 @@ void GPU_HW_OpenGL::FlushRender() static constexpr std::array gl_primitives = {{GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP}}; - if (m_batch.transparency_enable && m_batch.texture_enable && - m_batch.transparency_mode == GPU::TransparencyMode::BackgroundMinusForeground) + if (m_batch.NeedsTwoPassRendering()) { - SetDrawState(TransparencyRenderMode::OnlyTransparent); + SetDrawState(HWBatchRenderMode::OnlyTransparent); glDrawArrays(gl_primitives[static_cast(m_batch.primitive)], 0, static_cast(m_batch.vertices.size())); - SetDrawState(TransparencyRenderMode::OnlyOpaque); + SetDrawState(HWBatchRenderMode::OnlyOpaque); glDrawArrays(gl_primitives[static_cast(m_batch.primitive)], 0, static_cast(m_batch.vertices.size())); } else { - SetDrawState(m_batch.transparency_enable ? TransparencyRenderMode::TransparentAndOpaque : - TransparencyRenderMode::Off); + SetDrawState(m_batch.GetRenderMode()); glDrawArrays(gl_primitives[static_cast(m_batch.primitive)], 0, static_cast(m_batch.vertices.size())); } diff --git a/src/core/gpu_hw_opengl.h b/src/core/gpu_hw_opengl.h index c44475fd4..0f9991270 100644 --- a/src/core/gpu_hw_opengl.h +++ b/src/core/gpu_hw_opengl.h @@ -53,9 +53,8 @@ private: void CreateVertexBuffer(); bool CompilePrograms(); - bool CompileProgram(GL::Program& prog, TransparencyRenderMode transparent, bool textured, - TextureColorMode texture_color_mode, bool blending); - void SetDrawState(TransparencyRenderMode render_mode); + bool CompileProgram(GL::Program& prog, HWBatchRenderMode render_mode, TextureMode texture_mode); + void SetDrawState(HWBatchRenderMode render_mode); // downsample texture - used for readbacks at >1xIR. std::unique_ptr m_vram_texture; @@ -71,8 +70,8 @@ private: bool m_drawing_area_changed = true; bool m_show_renderer_statistics = false; - std::array, 3>, 2>, 4> m_render_programs; - std::array, 2> m_display_programs; // [depth_24][interlaced] + std::array, 4> m_render_programs; // [render_mode][texture_mode] + std::array, 2> m_display_programs; // [depth_24][interlaced] GLStats m_stats = {}; GLStats m_last_stats = {}; diff --git a/src/core/gpu_sw.cpp b/src/core/gpu_sw.cpp index 31e00cd06..d85ce6762 100644 --- a/src/core/gpu_sw.cpp +++ b/src/core/gpu_sw.cpp @@ -417,7 +417,7 @@ void GPU_SW::ShadePixel(RenderCommand rc, u32 x, u32 y, u8 color_r, u8 color_g, VRAMPixel texture_color; switch (m_render_state.texture_color_mode) { - case GPU::TextureColorMode::Palette4Bit: + case GPU::TextureMode::Palette4Bit: { const u16 palette_value = GetPixel(std::min(m_render_state.texture_page_x + ZeroExtend32(texcoord_x / 4), VRAM_WIDTH - 1), @@ -429,7 +429,7 @@ void GPU_SW::ShadePixel(RenderCommand rc, u32 x, u32 y, u8 color_r, u8 color_g, } break; - case GPU::TextureColorMode::Palette8Bit: + case GPU::TextureMode::Palette8Bit: { const u16 palette_value = GetPixel(std::min(m_render_state.texture_page_x + ZeroExtend32(texcoord_x / 2), VRAM_WIDTH - 1), @@ -455,7 +455,7 @@ void GPU_SW::ShadePixel(RenderCommand rc, u32 x, u32 y, u8 color_r, u8 color_g, transparent = texture_color.c; - if (rc.texture_blend_disable) + if (rc.raw_texture_enable) { color.bits = texture_color.bits; }