diff --git a/src/xenia/gpu/d3d12/pipeline_cache.cc b/src/xenia/gpu/d3d12/pipeline_cache.cc index 91ac56a91..83b195c1e 100644 --- a/src/xenia/gpu/d3d12/pipeline_cache.cc +++ b/src/xenia/gpu/d3d12/pipeline_cache.cc @@ -2390,6 +2390,10 @@ void PipelineCache::CreateDxbcGeometryShader( // to again. // Also, FXC generates only movs (from statically or dynamically indexed // v[#][#], from r#, or from a literal) to o# for some reason. + // emit_then_cut_stream must not be used - it crashes the shader compiler of + // AMD Software: Adrenalin Edition 23.3.2 on RDNA 3 if it's conditional (after + // a `retc` or inside an `if`), and it doesn't seem to be generated by FXC or + // DXC at all. // Discard the whole primitive if any vertex has a NaN position (may also be // set to NaN for emulation of vertex killing with the OR operator). @@ -2535,11 +2539,9 @@ void PipelineCache::CreateDxbcGeometryShader( dxbc::Src::V2D( 0, input_register_clip_and_cull_distances + (j >> 2))); } - if (i < 3) { - a.OpEmitStream(stream); - } + a.OpEmitStream(stream); } - a.OpEmitThenCutStream(stream); + a.OpCutStream(stream); } break; case PipelineGeometryShader::kRectangleList: { @@ -2685,7 +2687,8 @@ void PipelineCache::CreateDxbcGeometryShader( clip_distance_mask), dxbc::Src::R(1)); } - a.OpEmitThenCutStream(stream); + a.OpEmitStream(stream); + a.OpCutStream(stream); } break; case PipelineGeometryShader::kQuadList: { @@ -2716,11 +2719,9 @@ void PipelineCache::CreateDxbcGeometryShader( input_vertex_index, input_register_clip_and_cull_distances + (j >> 2))); } - if (i < 3) { - a.OpEmitStream(stream); - } + a.OpEmitStream(stream); } - a.OpEmitThenCutStream(stream); + a.OpCutStream(stream); } break; default: diff --git a/src/xenia/gpu/dxbc.h b/src/xenia/gpu/dxbc.h index 2c9f5eeab..42d8d89d8 100644 --- a/src/xenia/gpu/dxbc.h +++ b/src/xenia/gpu/dxbc.h @@ -2196,6 +2196,8 @@ class Assembler { ++stat_.instruction_count; ++stat_.cut_instruction_count; } + // Don't use emit_then_cut_stream - crashes AMD Software: Adrenalin Edition + // 23.3.2 shader compiler on RDNA 3 if used conditionally. void OpEmitThenCutStream(const Dest& stream) { uint32_t operands_length = stream.GetLength(); code_.reserve(code_.size() + 1 + operands_length);