mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2024-12-29 11:06:07 +00:00
shader_recompiler: Support for more offset layouts (#1270)
This commit is contained in:
parent
4ce95e55e0
commit
310814ac71
|
@ -27,8 +27,10 @@ static constexpr spv::ExecutionMode GetInputPrimitiveType(AmdGpu::PrimitiveType
|
||||||
case AmdGpu::PrimitiveType::TriangleList:
|
case AmdGpu::PrimitiveType::TriangleList:
|
||||||
case AmdGpu::PrimitiveType::TriangleStrip:
|
case AmdGpu::PrimitiveType::TriangleStrip:
|
||||||
return spv::ExecutionMode::Triangles;
|
return spv::ExecutionMode::Triangles;
|
||||||
|
case AmdGpu::PrimitiveType::AdjTriangleList:
|
||||||
|
return spv::ExecutionMode::InputTrianglesAdjacency;
|
||||||
default:
|
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:
|
case AmdGpu::GsOutputPrimitiveType::TriangleStrip:
|
||||||
return spv::ExecutionMode::OutputTriangleStrip;
|
return spv::ExecutionMode::OutputTriangleStrip;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE_MSG("Unknown output primitive type {}", u32(type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,14 +34,17 @@ std::string_view StageName(Stage stage) {
|
||||||
throw InvalidArgument("Invalid stage {}", u32(stage));
|
throw InvalidArgument("Invalid stage {}", u32(stage));
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr u32 NumVertices(AmdGpu::GsOutputPrimitiveType type) {
|
static constexpr u32 NumVertices(AmdGpu::PrimitiveType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case AmdGpu::GsOutputPrimitiveType::PointList:
|
case AmdGpu::PrimitiveType::PointList:
|
||||||
return 1u;
|
return 1u;
|
||||||
case AmdGpu::GsOutputPrimitiveType::LineStrip:
|
case AmdGpu::PrimitiveType::LineList:
|
||||||
return 2u;
|
return 2u;
|
||||||
case AmdGpu::GsOutputPrimitiveType::TriangleStrip:
|
case AmdGpu::PrimitiveType::TriangleList:
|
||||||
|
case AmdGpu::PrimitiveType::TriangleStrip:
|
||||||
return 3u;
|
return 3u;
|
||||||
|
case AmdGpu::PrimitiveType::AdjTriangleList:
|
||||||
|
return 6u;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -321,16 +324,15 @@ void EmitContext::DefineInputs() {
|
||||||
MemberDecorate(gl_per_vertex, 2, spv::Decoration::BuiltIn,
|
MemberDecorate(gl_per_vertex, 2, spv::Decoration::BuiltIn,
|
||||||
static_cast<std::uint32_t>(spv::BuiltIn::ClipDistance));
|
static_cast<std::uint32_t>(spv::BuiltIn::ClipDistance));
|
||||||
Decorate(gl_per_vertex, spv::Decoration::Block);
|
Decorate(gl_per_vertex, spv::Decoration::Block);
|
||||||
const auto vertices_in =
|
const auto num_verts_in = NumVertices(runtime_info.gs_info.in_primitive);
|
||||||
TypeArray(gl_per_vertex, ConstU32(NumVertices(runtime_info.gs_info.out_primitive[0])));
|
const auto vertices_in = TypeArray(gl_per_vertex, ConstU32(num_verts_in));
|
||||||
gl_in = Name(DefineVar(vertices_in, spv::StorageClass::Input), "gl_in");
|
gl_in = Name(DefineVar(vertices_in, spv::StorageClass::Input), "gl_in");
|
||||||
interfaces.push_back(gl_in);
|
interfaces.push_back(gl_in);
|
||||||
|
|
||||||
const auto num_params = runtime_info.gs_info.in_vertex_data_size / 4 - 1u;
|
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) {
|
for (int param_id = 0; param_id < num_params; ++param_id) {
|
||||||
const IR::Attribute param{IR::Attribute::Param0 + param_id};
|
const IR::Attribute param{IR::Attribute::Param0 + param_id};
|
||||||
const Id type{
|
const Id type{TypeArray(F32[4], ConstU32(num_verts_in))};
|
||||||
TypeArray(F32[4], ConstU32(NumVertices(runtime_info.gs_info.out_primitive[0])))};
|
|
||||||
const Id id{DefineInput(type, param_id)};
|
const Id id{DefineInput(type, param_id)};
|
||||||
Name(id, fmt::format("in_attr{}", param_id));
|
Name(id, fmt::format("in_attr{}", param_id));
|
||||||
input_params[param_id] = {id, input_f32, F32[1], 4};
|
input_params[param_id] = {id, input_f32, F32[1], 4};
|
||||||
|
|
|
@ -15,18 +15,18 @@ CopyShaderData ParseCopyShader(const std::span<const u32>& code) {
|
||||||
ASSERT_MSG(code[0] == token_mov_vcchi, "First instruction is not s_mov_b32 vcc_hi, #imm");
|
ASSERT_MSG(code[0] == token_mov_vcchi, "First instruction is not s_mov_b32 vcc_hi, #imm");
|
||||||
|
|
||||||
std::array<s32, 32> offsets{};
|
std::array<s32, 32> offsets{};
|
||||||
std::fill(offsets.begin(), offsets.end(), -1);
|
offsets.fill(-1);
|
||||||
|
|
||||||
|
std::array<s32, 256> sources{};
|
||||||
|
sources.fill(-1);
|
||||||
|
|
||||||
CopyShaderData data{};
|
CopyShaderData data{};
|
||||||
Gcn::OperandField sgpr{};
|
|
||||||
auto last_attr{IR::Attribute::Position0};
|
auto last_attr{IR::Attribute::Position0};
|
||||||
s32 soffset{0};
|
|
||||||
while (!code_slice.atEnd()) {
|
while (!code_slice.atEnd()) {
|
||||||
auto inst = decoder.decodeInstruction(code_slice);
|
auto inst = decoder.decodeInstruction(code_slice);
|
||||||
switch (inst.opcode) {
|
switch (inst.opcode) {
|
||||||
case Gcn::Opcode::S_MOVK_I32: {
|
case Gcn::Opcode::S_MOVK_I32: {
|
||||||
sgpr = inst.dst[0].field;
|
sources[inst.dst[0].code] = inst.control.sopk.simm;
|
||||||
soffset = inst.control.sopk.simm;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Gcn::Opcode::EXP: {
|
case Gcn::Opcode::EXP: {
|
||||||
|
@ -46,8 +46,9 @@ CopyShaderData ParseCopyShader(const std::span<const u32>& code) {
|
||||||
case Gcn::Opcode::BUFFER_LOAD_DWORD: {
|
case Gcn::Opcode::BUFFER_LOAD_DWORD: {
|
||||||
offsets[inst.src[1].code] = inst.control.mubuf.offset;
|
offsets[inst.src[1].code] = inst.control.mubuf.offset;
|
||||||
if (inst.src[3].field != Gcn::OperandField::ConstZero) {
|
if (inst.src[3].field != Gcn::OperandField::ConstZero) {
|
||||||
ASSERT(inst.src[3].field == sgpr);
|
const u32 index = inst.src[3].code;
|
||||||
offsets[inst.src[1].code] += soffset;
|
ASSERT(sources[index] != -1);
|
||||||
|
offsets[inst.src[1].code] += sources[index];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -59,6 +60,7 @@ CopyShaderData ParseCopyShader(const std::span<const u32>& code) {
|
||||||
if (last_attr != IR::Attribute::Position0) {
|
if (last_attr != IR::Attribute::Position0) {
|
||||||
data.num_attrs = static_cast<u32>(last_attr) - static_cast<u32>(IR::Attribute::Param0) + 1;
|
data.num_attrs = static_cast<u32>(last_attr) - static_cast<u32>(IR::Attribute::Param0) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue