diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index a585f328..f199860a 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp @@ -27,8 +27,10 @@ static constexpr spv::ExecutionMode GetInputPrimitiveType(AmdGpu::PrimitiveType case AmdGpu::PrimitiveType::TriangleList: case AmdGpu::PrimitiveType::TriangleStrip: return spv::ExecutionMode::Triangles; + case AmdGpu::PrimitiveType::AdjTriangleList: + return spv::ExecutionMode::InputTrianglesAdjacency; default: - UNREACHABLE(); + UNREACHABLE_MSG("Unknown input primitive type {}", u32(type)); } } @@ -41,7 +43,7 @@ static constexpr spv::ExecutionMode GetOutputPrimitiveType(AmdGpu::GsOutputPrimi case AmdGpu::GsOutputPrimitiveType::TriangleStrip: return spv::ExecutionMode::OutputTriangleStrip; default: - UNREACHABLE(); + UNREACHABLE_MSG("Unknown output primitive type {}", u32(type)); } } diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index f5b60d51..c753b4a4 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -34,14 +34,17 @@ std::string_view StageName(Stage stage) { throw InvalidArgument("Invalid stage {}", u32(stage)); } -static constexpr u32 NumVertices(AmdGpu::GsOutputPrimitiveType type) { +static constexpr u32 NumVertices(AmdGpu::PrimitiveType type) { switch (type) { - case AmdGpu::GsOutputPrimitiveType::PointList: + case AmdGpu::PrimitiveType::PointList: return 1u; - case AmdGpu::GsOutputPrimitiveType::LineStrip: + case AmdGpu::PrimitiveType::LineList: return 2u; - case AmdGpu::GsOutputPrimitiveType::TriangleStrip: + case AmdGpu::PrimitiveType::TriangleList: + case AmdGpu::PrimitiveType::TriangleStrip: return 3u; + case AmdGpu::PrimitiveType::AdjTriangleList: + return 6u; default: UNREACHABLE(); } @@ -321,16 +324,15 @@ void EmitContext::DefineInputs() { MemberDecorate(gl_per_vertex, 2, spv::Decoration::BuiltIn, static_cast(spv::BuiltIn::ClipDistance)); Decorate(gl_per_vertex, spv::Decoration::Block); - const auto vertices_in = - TypeArray(gl_per_vertex, ConstU32(NumVertices(runtime_info.gs_info.out_primitive[0]))); + const auto num_verts_in = NumVertices(runtime_info.gs_info.in_primitive); + const auto vertices_in = TypeArray(gl_per_vertex, ConstU32(num_verts_in)); gl_in = Name(DefineVar(vertices_in, spv::StorageClass::Input), "gl_in"); interfaces.push_back(gl_in); const auto num_params = runtime_info.gs_info.in_vertex_data_size / 4 - 1u; for (int param_id = 0; param_id < num_params; ++param_id) { const IR::Attribute param{IR::Attribute::Param0 + param_id}; - const Id type{ - TypeArray(F32[4], ConstU32(NumVertices(runtime_info.gs_info.out_primitive[0])))}; + const Id type{TypeArray(F32[4], ConstU32(num_verts_in))}; const Id id{DefineInput(type, param_id)}; Name(id, fmt::format("in_attr{}", param_id)); input_params[param_id] = {id, input_f32, F32[1], 4}; diff --git a/src/shader_recompiler/frontend/copy_shader.cpp b/src/shader_recompiler/frontend/copy_shader.cpp index a194aec9..363c1c82 100644 --- a/src/shader_recompiler/frontend/copy_shader.cpp +++ b/src/shader_recompiler/frontend/copy_shader.cpp @@ -15,18 +15,18 @@ CopyShaderData ParseCopyShader(const std::span& code) { ASSERT_MSG(code[0] == token_mov_vcchi, "First instruction is not s_mov_b32 vcc_hi, #imm"); std::array offsets{}; - std::fill(offsets.begin(), offsets.end(), -1); + offsets.fill(-1); + + std::array sources{}; + sources.fill(-1); CopyShaderData data{}; - Gcn::OperandField sgpr{}; auto last_attr{IR::Attribute::Position0}; - s32 soffset{0}; while (!code_slice.atEnd()) { auto inst = decoder.decodeInstruction(code_slice); switch (inst.opcode) { case Gcn::Opcode::S_MOVK_I32: { - sgpr = inst.dst[0].field; - soffset = inst.control.sopk.simm; + sources[inst.dst[0].code] = inst.control.sopk.simm; break; } case Gcn::Opcode::EXP: { @@ -46,8 +46,9 @@ CopyShaderData ParseCopyShader(const std::span& code) { case Gcn::Opcode::BUFFER_LOAD_DWORD: { offsets[inst.src[1].code] = inst.control.mubuf.offset; if (inst.src[3].field != Gcn::OperandField::ConstZero) { - ASSERT(inst.src[3].field == sgpr); - offsets[inst.src[1].code] += soffset; + const u32 index = inst.src[3].code; + ASSERT(sources[index] != -1); + offsets[inst.src[1].code] += sources[index]; } break; } @@ -59,6 +60,7 @@ CopyShaderData ParseCopyShader(const std::span& code) { if (last_attr != IR::Attribute::Position0) { data.num_attrs = static_cast(last_attr) - static_cast(IR::Attribute::Param0) + 1; } + return data; }