From 8bf1bf57fd7604592b21766f33e38b03201ffdfa Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Wed, 17 Feb 2016 17:56:28 -0600 Subject: [PATCH 1/3] Fix GL4 alpha test, use blend disable flag If color clear is enabled, grab the color target no matter what. Update texture readback code on copy (but not enabled) Track PA_SC_VIZ_QUERY in UpdateRasterizerState --- src/xenia/gpu/gl4/gl4_command_processor.cc | 68 ++++++++++++++++++---- src/xenia/gpu/gl4/gl4_command_processor.h | 1 + 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/src/xenia/gpu/gl4/gl4_command_processor.cc b/src/xenia/gpu/gl4/gl4_command_processor.cc index 85de39460..2305b38b4 100644 --- a/src/xenia/gpu/gl4/gl4_command_processor.cc +++ b/src/xenia/gpu/gl4/gl4_command_processor.cc @@ -1037,6 +1037,7 @@ GL4CommandProcessor::UpdateStatus GL4CommandProcessor::UpdateRasterizerState( XE_GPU_REG_PA_SC_SCREEN_SCISSOR_BR); dirty |= SetShadowRegister(®s.multi_prim_ib_reset_index, XE_GPU_REG_VGT_MULTI_PRIM_IB_RESET_INDX); + dirty |= SetShadowRegister(®s.pa_sc_viz_query, XE_GPU_REG_PA_SC_VIZ_QUERY); dirty |= regs.prim_type != prim_type; if (!dirty) { return UpdateStatus::kCompatible; @@ -1048,6 +1049,12 @@ GL4CommandProcessor::UpdateStatus GL4CommandProcessor::UpdateRasterizerState( draw_batcher_.Flush(DrawBatcher::FlushMode::kStateChange); + // viz query enabled + // assert_zero(regs.pa_sc_viz_query & 0x01); + + // Kill pix post early-z test + // assert_zero(regs.pa_sc_viz_query & 0x80); + // Scissoring. // TODO(benvanik): is this used? we are using scissoring for window scissor. if (regs.pa_sc_screen_scissor_tl != 0 && @@ -1129,7 +1136,7 @@ GL4CommandProcessor::UpdateStatus GL4CommandProcessor::UpdateBlendState() { // Deprecated in GL, implemented in shader. // if(ALPHATESTENABLE && frag_out.a [<=/ALPHAFUNC] ALPHAREF) discard; uint32_t color_control = reg_file[XE_GPU_REG_RB_COLORCONTROL].u32; - draw_batcher_.set_alpha_test((color_control & 0x4) != 0, // ALPAHTESTENABLE + draw_batcher_.set_alpha_test((color_control & 0x8) != 0, // ALPAHTESTENABLE color_control & 0x7, // ALPHAFUNC reg_file[XE_GPU_REG_RB_ALPHA_REF].f32); @@ -1196,10 +1203,11 @@ GL4CommandProcessor::UpdateStatus GL4CommandProcessor::UpdateBlendState() { auto blend_op_alpha = blend_op_map[(blend_control & 0x00E00000) >> 21]; // A2XX_RB_COLORCONTROL_BLEND_DISABLE ?? Can't find this! // Just guess based on actions. - bool blend_enable = - !((src_blend == GL_ONE) && (dest_blend == GL_ZERO) && - (blend_op == GL_FUNC_ADD) && (src_blend_alpha == GL_ONE) && - (dest_blend_alpha == GL_ZERO) && (blend_op_alpha == GL_FUNC_ADD)); + // bool blend_enable = + // !((src_blend == GL_ONE) && (dest_blend == GL_ZERO) && + // (blend_op == GL_FUNC_ADD) && (src_blend_alpha == GL_ONE) && + // (dest_blend_alpha == GL_ZERO) && (blend_op_alpha == GL_FUNC_ADD)); + bool blend_enable = !(color_control & 0x20); if (blend_enable) { glEnablei(GL_BLEND, i); glBlendEquationSeparatei(i, blend_op, blend_op_alpha); @@ -1579,7 +1587,7 @@ bool GL4CommandProcessor::IssueCopy() { TextureFormat src_format = TextureFormat::kUnknown; GLuint color_targets[4] = {kAnyTarget, kAnyTarget, kAnyTarget, kAnyTarget}; GLuint depth_target = kAnyTarget; - if (copy_src_select <= 3) { + if (copy_src_select <= 3 || color_clear_enabled) { // Source from a color target. uint32_t color_info[4] = { regs[XE_GPU_REG_RB_COLOR_INFO].u32, regs[XE_GPU_REG_RB_COLOR1_INFO].u32, @@ -1591,7 +1599,10 @@ bool GL4CommandProcessor::IssueCopy() { (color_info[copy_src_select] >> 16) & 0xF); color_targets[copy_src_select] = GetColorRenderTarget( surface_pitch, surface_msaa, color_base, color_format); - src_format = ColorRenderTargetToTextureFormat(color_format); + + if (copy_src_select <= 3) { + src_format = ColorRenderTargetToTextureFormat(color_format); + } } // Grab the depth/stencil if we're sourcing from it or clear is enabled. @@ -1616,77 +1627,97 @@ bool GL4CommandProcessor::IssueCopy() { return false; } + active_framebuffer_ = source_framebuffer; + GLenum read_format; GLenum read_type; + size_t read_size = 0; switch (copy_dest_format) { case ColorFormat::k_1_5_5_5: read_format = GL_RGB5_A1; read_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + read_size = 16; break; case ColorFormat::k_2_10_10_10: read_format = GL_RGB10_A2; read_type = GL_UNSIGNED_INT_10_10_10_2; + read_size = 32; break; case ColorFormat::k_4_4_4_4: read_format = GL_RGBA4; read_type = GL_UNSIGNED_SHORT_4_4_4_4; + read_size = 16; break; case ColorFormat::k_5_6_5: read_format = GL_RGB565; read_type = GL_UNSIGNED_SHORT_5_6_5; + read_size = 16; break; case ColorFormat::k_8: read_format = GL_R8; read_type = GL_UNSIGNED_BYTE; + read_size = 8; break; case ColorFormat::k_8_8: read_format = GL_RG8; read_type = GL_UNSIGNED_BYTE; + read_size = 16; break; case ColorFormat::k_8_8_8_8: read_format = copy_dest_swap ? GL_BGRA : GL_RGBA; read_type = GL_UNSIGNED_BYTE; + read_size = 32; break; case ColorFormat::k_16: read_format = GL_R16; read_type = GL_UNSIGNED_SHORT; + read_size = 16; break; case ColorFormat::k_16_FLOAT: read_format = GL_R16F; read_type = GL_HALF_FLOAT; + read_size = 16; break; case ColorFormat::k_16_16: read_format = GL_RG16; read_type = GL_UNSIGNED_SHORT; + read_size = 32; break; case ColorFormat::k_16_16_FLOAT: read_format = GL_RG16F; read_type = GL_HALF_FLOAT; + read_size = 32; break; case ColorFormat::k_16_16_16_16: read_format = GL_RGBA16; read_type = GL_UNSIGNED_SHORT; + read_size = 32; break; case ColorFormat::k_16_16_16_16_FLOAT: read_format = GL_RGBA16F; read_type = GL_HALF_FLOAT; + read_size = 32; break; case ColorFormat::k_32_FLOAT: read_format = GL_R32F; read_type = GL_FLOAT; + read_size = 32; break; case ColorFormat::k_32_32_FLOAT: read_format = GL_RG32F; read_type = GL_FLOAT; + read_size = 64; break; case ColorFormat::k_32_32_32_32_FLOAT: read_format = GL_RGBA32F; read_type = GL_FLOAT; + read_size = 128; break; case ColorFormat::k_10_11_11: case ColorFormat::k_11_11_10: read_format = GL_R11F_G11F_B10F; read_type = GL_UNSIGNED_INT_10F_11F_11F_REV; + read_size = 32; break; default: assert_unhandled_case(copy_dest_format); @@ -1792,7 +1823,8 @@ bool GL4CommandProcessor::IssueCopy() { // Destination pointer in guest memory. // We have GL throw bytes directly into it. // TODO(benvanik): copy to staging texture then PBO back? - // void* ptr = memory_->TranslatePhysical(copy_dest_base); + void* ptr = memory_->TranslatePhysical(copy_dest_base); + size_t size = copy_dest_pitch * copy_dest_height * (read_size / 8); auto blitter = static_cast(context_.get())->blitter(); @@ -1811,7 +1843,10 @@ bool GL4CommandProcessor::IssueCopy() { copy_dest_swap ? true : false, color_targets[copy_src_select], src_rect, dest_rect); if (!FLAGS_disable_framebuffer_readback) { - // glReadPixels(x, y, w, h, read_format, read_type, ptr); + // std::memset(ptr, 0xDE, + // copy_dest_pitch * copy_dest_height * (read_size / 8)); + // glReadPixels(0, 0, copy_dest_pitch, copy_dest_height, read_format, + // read_type, ptr); } } else { // Source from the bound depth/stencil target. @@ -1821,7 +1856,10 @@ bool GL4CommandProcessor::IssueCopy() { dest_block_width, dest_block_height, src_format, copy_dest_swap ? true : false, depth_target, src_rect, dest_rect); if (!FLAGS_disable_framebuffer_readback) { - // glReadPixels(x, y, w, h, GL_DEPTH_STENCIL, read_type, ptr); + // std::memset(ptr, 0xDE, + // copy_dest_pitch * copy_dest_height * (read_size / 8)); + // glReadPixels(0, 0, copy_dest_pitch, copy_dest_height, + // GL_DEPTH_STENCIL, read_type, ptr); } } break; @@ -1838,7 +1876,10 @@ bool GL4CommandProcessor::IssueCopy() { copy_dest_swap ? true : false, color_targets[copy_src_select], src_rect, dest_rect); if (!FLAGS_disable_framebuffer_readback) { - // glReadPixels(x, y, w, h, read_format, read_type, ptr); + // std::memset(ptr, 0xDE, + // copy_dest_pitch * copy_dest_height * (read_size / 8)); + // glReadPixels(0, 0, copy_dest_pitch, copy_dest_height, read_format, + // read_type, ptr); } } else { // Source from the bound depth/stencil target. @@ -1847,7 +1888,10 @@ bool GL4CommandProcessor::IssueCopy() { dest_block_width, dest_block_height, src_format, copy_dest_swap ? true : false, depth_target, src_rect, dest_rect); if (!FLAGS_disable_framebuffer_readback) { - // glReadPixels(x, y, w, h, GL_DEPTH_STENCIL, read_type, ptr); + // std::memset(ptr, 0xDE, + // copy_dest_pitch * copy_dest_height * (read_size / 8)); + // glReadPixels(0, 0, copy_dest_pitch, copy_dest_height, + // GL_DEPTH_STENCIL, read_type, ptr); } } break; diff --git a/src/xenia/gpu/gl4/gl4_command_processor.h b/src/xenia/gpu/gl4/gl4_command_processor.h index 13ac5f57f..1ebd12a1e 100644 --- a/src/xenia/gpu/gl4/gl4_command_processor.h +++ b/src/xenia/gpu/gl4/gl4_command_processor.h @@ -192,6 +192,7 @@ class GL4CommandProcessor : public CommandProcessor { uint32_t pa_sc_screen_scissor_tl; uint32_t pa_sc_screen_scissor_br; uint32_t multi_prim_ib_reset_index; + uint32_t pa_sc_viz_query; PrimitiveType prim_type; UpdateRasterizerStateRegisters() { Reset(); } From b14c4ad681e7e118cb6cca316a8be7fe45491b8f Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Wed, 17 Feb 2016 17:57:56 -0600 Subject: [PATCH 2/3] Disable write watch kill in ConvertTexture --- src/xenia/gpu/gl4/texture_cache.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/xenia/gpu/gl4/texture_cache.cc b/src/xenia/gpu/gl4/texture_cache.cc index 2344c6459..ddc175e10 100644 --- a/src/xenia/gpu/gl4/texture_cache.cc +++ b/src/xenia/gpu/gl4/texture_cache.cc @@ -575,10 +575,13 @@ GLuint TextureCache::ConvertTexture(Blitter* blitter, uint32_t guest_address, } // HACK: remove texture from write watch list so readback won't kill us. + //* if (texture_entry->write_watch_handle) { memory_->CancelWriteWatch(texture_entry->write_watch_handle); texture_entry->write_watch_handle = 0; } + //*/ + return texture_entry->handle; } From 27bace0e5cd30361be8013a51102aab173d40b9c Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Wed, 17 Feb 2016 18:04:10 -0600 Subject: [PATCH 3/3] Actually disable writewatch kill in ConvertTexture --- src/xenia/gpu/gl4/texture_cache.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/xenia/gpu/gl4/texture_cache.cc b/src/xenia/gpu/gl4/texture_cache.cc index ddc175e10..0e1132218 100644 --- a/src/xenia/gpu/gl4/texture_cache.cc +++ b/src/xenia/gpu/gl4/texture_cache.cc @@ -575,7 +575,8 @@ GLuint TextureCache::ConvertTexture(Blitter* blitter, uint32_t guest_address, } // HACK: remove texture from write watch list so readback won't kill us. - //* + // Not needed now, as readback is disabled. + /* if (texture_entry->write_watch_handle) { memory_->CancelWriteWatch(texture_entry->write_watch_handle); texture_entry->write_watch_handle = 0;