From b2d8837e524e7f9ac87bd662162d886191fb0dde Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 22 Jan 2016 18:47:27 -0600 Subject: [PATCH 1/2] Fix depth clear when not sourcing from a depth target. --- src/xenia/gpu/gl4/gl4_command_processor.cc | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/xenia/gpu/gl4/gl4_command_processor.cc b/src/xenia/gpu/gl4/gl4_command_processor.cc index b494ff77c..31499a021 100644 --- a/src/xenia/gpu/gl4/gl4_command_processor.cc +++ b/src/xenia/gpu/gl4/gl4_command_processor.cc @@ -1625,16 +1625,22 @@ bool GL4CommandProcessor::IssueCopy() { color_targets[copy_src_select] = GetColorRenderTarget( surface_pitch, surface_msaa, color_base, color_format); src_format = ColorRenderTargetToTextureFormat(color_format); - } else { - // Source from depth/stencil. + } + + // Grab the depth/stencil if we're sourcing from it or clear is enabled. + if (copy_src_select > 3 || depth_clear_enabled) { uint32_t depth_info = regs[XE_GPU_REG_RB_DEPTH_INFO].u32; uint32_t depth_base = depth_info & 0xFFF; auto depth_format = static_cast((depth_info >> 16) & 0x1); depth_target = GetDepthRenderTarget(surface_pitch, surface_msaa, depth_base, depth_format); - src_format = DepthRenderTargetToTextureFormat(depth_format); + + if (copy_src_select > 3) { + src_format = DepthRenderTargetToTextureFormat(depth_format); + } } + auto source_framebuffer = GetFramebuffer(color_targets, depth_target); if (!source_framebuffer) { // If we get here we are likely missing some state checks. @@ -1910,10 +1916,7 @@ bool GL4CommandProcessor::IssueCopy() { old_color_mask[2], old_color_mask[3]); } - // TODO(benvanik): figure out real condition here (maybe when color cleared?) - // HACK: things seem to need their depth buffer cleared a lot more - // than as indicated by the depth_clear_enabled flag. - if (depth_target != kAnyTarget) { + if (depth_clear_enabled && depth_target != kAnyTarget) { // Clear the current depth buffer. // TODO(benvanik): verify format. GLfloat depth = {(copy_depth_clear & 0xFFFFFF00) / @@ -1928,6 +1931,7 @@ bool GL4CommandProcessor::IssueCopy() { glDepthMask(GL_TRUE); glStencilMask(0xFF); // HACK: this should work, but throws INVALID_ENUM on nvidia drivers. + // GLEW signature differs from OpenGL docs? // glClearNamedFramebufferfi(source_framebuffer->framebuffer, // GL_DEPTH_STENCIL, depth, stencil); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, source_framebuffer->framebuffer); From 8a89a93eab41ad6b98a5866f3b05f50813bfbe1f Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 22 Jan 2016 18:49:17 -0600 Subject: [PATCH 2/2] Fix improperly reading 2_10_10_10 bitfields (or so I hope) Check at runtime if a vertex fetch index doesn't match gl_VertexID Fix trying to instantiate a vec1 --- src/xenia/gpu/glsl_shader_translator.cc | 48 +++++++++++++++---------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/src/xenia/gpu/glsl_shader_translator.cc b/src/xenia/gpu/glsl_shader_translator.cc index cf050038a..5508ff73c 100644 --- a/src/xenia/gpu/glsl_shader_translator.cc +++ b/src/xenia/gpu/glsl_shader_translator.cc @@ -209,18 +209,18 @@ vec3 get_10_11_11_s(const int data_in) { vec4 get_2_10_10_10_u(const uint data_in) { vec4 vec; - vec.x = bitfieldExtract(data_in, 0, 10); - vec.y = bitfieldExtract(data_in, 10, 10); - vec.z = bitfieldExtract(data_in, 20, 10); - vec.w = bitfieldExtract(data_in, 30, 2 ); + vec.w = bitfieldExtract(data_in, 0, 2 ); + vec.x = bitfieldExtract(data_in, 2, 10); + vec.y = bitfieldExtract(data_in, 12, 10); + vec.z = bitfieldExtract(data_in, 22, 10); return vec; } vec4 get_2_10_10_10_s(const int data_in) { vec4 vec; - vec.x = bitfieldExtract(data_in, 0, 10); - vec.y = bitfieldExtract(data_in, 10, 10); - vec.z = bitfieldExtract(data_in, 20, 10); - vec.w = bitfieldExtract(data_in, 30, 2 ); + vec.w = bitfieldExtract(data_in, 0, 2 ); + vec.x = bitfieldExtract(data_in, 2, 10); + vec.y = bitfieldExtract(data_in, 12, 10); + vec.z = bitfieldExtract(data_in, 22, 10); return vec; } @@ -326,6 +326,7 @@ void main() { // Temporary registers. if (is_vertex_shader()) { EmitSource(" vec4 r[64];\n"); + EmitSource(" r[0].x = gl_VertexID;\n"); } else { // Bring interpolators from vertex shader into temporary registers. EmitSource(" vec4 r[64];\n"); @@ -571,14 +572,6 @@ void GlslShaderTranslator::ProcessVertexFetchInstruction( EmitSource("// "); instr.Disassemble(&source_); - if (instr.operands[0].storage_index != 0) { - // Unimplemented for now. - EmitUnimplementedTranslationError(); - EmitSourceDepth("pv.xyzw = vec4(0.0, 0.0, 0.0, 0.0);\n"); - EmitStoreVectorResult(instr.result); - return; - } - if (instr.is_predicated) { EmitSourceDepth("if (%cp0) {\n", instr.predicate_condition ? ' ' : '!'); Indent(); @@ -594,6 +587,9 @@ void GlslShaderTranslator::ProcessVertexFetchInstruction( switch (instr.opcode) { case FetchOpcode::kVertexFetch: { + EmitSourceDepth("if (src0.x == gl_VertexID) {\n"); + Indent(); + EmitSourceDepth("pv."); for (int i = 0; i < GetVertexFormatComponentCount(instr.attributes.data_format); @@ -615,6 +611,16 @@ void GlslShaderTranslator::ProcessVertexFetchInstruction( EmitSource(" = vf%u_%d;\n", instr.operands[1].storage_index, instr.attributes.offset); } + + Unindent(); + EmitSourceDepth("} else {\n"); + Indent(); + + EmitSourceDepth("// UNIMPLEMENTED: Indexed fetch.\n"); + EmitSourceDepth("pv = vec4(0.0, 0.0, 0.0, 1.0);\n"); + + Unindent(); + EmitSourceDepth("}\n"); } break; default: assert_always(); @@ -918,7 +924,10 @@ void GlslShaderTranslator::EmitStoreResult(const InstructionResult& result, EmitSource("clamp("); } if (has_const_writes) { - EmitSource("vec%d(", component_write_count); + if (component_write_count > 1) { + EmitSource("vec%d(", component_write_count); + } + bool has_written = false; for (int j = 0; j < 4; ++j) { if (result.write_mask[j]) { @@ -939,7 +948,10 @@ void GlslShaderTranslator::EmitStoreResult(const InstructionResult& result, } } } - EmitSource(")"); + + if (component_write_count > 1) { + EmitSource(")"); + } } else { EmitSource(temp); if (!result.is_standard_swizzle()) {