mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
shader: share control flow labels
This commit is contained in:
@@ -319,8 +319,7 @@ std::vector<uint32_t> EmitProgram(const IR::Program& program,
|
|||||||
ValidateNativeProgram(program);
|
ValidateNativeProgram(program);
|
||||||
IR::ValidateProgram(program, true);
|
IR::ValidateProgram(program, true);
|
||||||
EmitterState state(program, input_info);
|
EmitterState state(program, input_info);
|
||||||
state.stage = program.stage;
|
state.stage = program.stage;
|
||||||
state.wave_size = program.wave_size;
|
|
||||||
const auto* workgroup = ShaderWorkgroupInput(program.stage, input_info);
|
const auto* workgroup = ShaderWorkgroupInput(program.stage, input_info);
|
||||||
state.lane_count =
|
state.lane_count =
|
||||||
workgroup != nullptr && program.wave_size == 64u && workgroup->host_subgroup_size == 32u
|
workgroup != nullptr && program.wave_size == 64u && workgroup->host_subgroup_size == 32u
|
||||||
|
|||||||
@@ -6,13 +6,6 @@
|
|||||||
|
|
||||||
namespace Libs::Graphics::ShaderRecompiler::Spirv::Emitter {
|
namespace Libs::Graphics::ShaderRecompiler::Spirv::Emitter {
|
||||||
|
|
||||||
uint32_t PixelParameterMappedLocation(const EmitterState& state, uint32_t attr) {
|
|
||||||
if (state.stage != ShaderType::Pixel) {
|
|
||||||
return attr;
|
|
||||||
}
|
|
||||||
return ShaderPixelParameterMappedLocation(*state.input_info.pixel, attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t PixelParameterLocation(const EmitterState& state, uint32_t attr) {
|
uint32_t PixelParameterLocation(const EmitterState& state, uint32_t attr) {
|
||||||
std::array<uint32_t, 32> active_inputs {};
|
std::array<uint32_t, 32> active_inputs {};
|
||||||
uint32_t active_count = 0;
|
uint32_t active_count = 0;
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ uint32_t EmitBallotLaneActiveBool(EmitterState& state, uint32_t active_ballot, u
|
|||||||
const auto low = state.builder.AllocateId();
|
const auto low = state.builder.AllocateId();
|
||||||
state.builder.AddFunction({OpCompositeExtract, TypeU32(state), low, active_ballot, 0});
|
state.builder.AddFunction({OpCompositeExtract, TypeU32(state), low, active_ballot, 0});
|
||||||
uint32_t mask = low;
|
uint32_t mask = low;
|
||||||
if (state.wave_size == 64u) {
|
if (state.program.wave_size == 64u) {
|
||||||
const auto high = state.builder.AllocateId();
|
const auto high = state.builder.AllocateId();
|
||||||
const auto in_high = state.builder.AllocateId();
|
const auto in_high = state.builder.AllocateId();
|
||||||
const auto selected = state.builder.AllocateId();
|
const auto selected = state.builder.AllocateId();
|
||||||
@@ -235,7 +235,7 @@ uint32_t EmitBallotLaneActiveBool(EmitterState& state, uint32_t active_ballot, u
|
|||||||
state.builder.AddFunction({OpBitwiseAnd, TypeU32(state), hit, mask, bit});
|
state.builder.AddFunction({OpBitwiseAnd, TypeU32(state), hit, mask, bit});
|
||||||
state.builder.AddFunction({OpINotEqual, TypeBool(state), active, hit, ConstantU32(state, 0)});
|
state.builder.AddFunction({OpINotEqual, TypeBool(state), active, hit, ConstantU32(state, 0)});
|
||||||
state.builder.AddFunction(
|
state.builder.AddFunction(
|
||||||
{OpULessThan, TypeBool(state), in_range, lane, ConstantU32(state, state.wave_size)});
|
{OpULessThan, TypeBool(state), in_range, lane, ConstantU32(state, state.program.wave_size)});
|
||||||
state.builder.AddFunction({OpLogicalAnd, TypeBool(state), ret, active, in_range});
|
state.builder.AddFunction({OpLogicalAnd, TypeBool(state), ret, active, in_range});
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -360,7 +360,6 @@ struct EmitterState {
|
|||||||
ShaderStageInputInfo input_info;
|
ShaderStageInputInfo input_info;
|
||||||
const IR::SpirvRequirements& requirements;
|
const IR::SpirvRequirements& requirements;
|
||||||
ShaderType stage = ShaderType::Unknown;
|
ShaderType stage = ShaderType::Unknown;
|
||||||
uint32_t wave_size = 64;
|
|
||||||
uint32_t lane_count = 1;
|
uint32_t lane_count = 1;
|
||||||
uint32_t lane_half = 0;
|
uint32_t lane_half = 0;
|
||||||
uint32_t storage_buffer_variable = 0;
|
uint32_t storage_buffer_variable = 0;
|
||||||
@@ -401,6 +400,7 @@ struct EmitterState {
|
|||||||
std::vector<InputBinding> inputs;
|
std::vector<InputBinding> inputs;
|
||||||
std::vector<OutputBinding> outputs;
|
std::vector<OutputBinding> outputs;
|
||||||
std::vector<uint32_t> interface_variables;
|
std::vector<uint32_t> interface_variables;
|
||||||
|
std::unordered_map<const IR::Block*, uint32_t> labels;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t TypeVoid(EmitterState& state);
|
uint32_t TypeVoid(EmitterState& state);
|
||||||
@@ -462,7 +462,6 @@ struct ValueEmitContext {
|
|||||||
EmitterState& state;
|
EmitterState& state;
|
||||||
const IR::Program& program;
|
const IR::Program& program;
|
||||||
std::unordered_map<const IR::Inst*, uint32_t> definitions;
|
std::unordered_map<const IR::Inst*, uint32_t> definitions;
|
||||||
std::unordered_map<const IR::Block*, uint32_t> labels;
|
|
||||||
const std::unordered_map<const IR::Inst*, uint32_t>* dispatcher_spills = nullptr;
|
const std::unordered_map<const IR::Inst*, uint32_t>* dispatcher_spills = nullptr;
|
||||||
std::unordered_map<const IR::Inst*, std::pair<uint32_t, uint32_t>> dispatcher_block_loads;
|
std::unordered_map<const IR::Inst*, std::pair<uint32_t, uint32_t>> dispatcher_block_loads;
|
||||||
const IR::Block* current_block = nullptr;
|
const IR::Block* current_block = nullptr;
|
||||||
@@ -496,8 +495,6 @@ struct F32Class {
|
|||||||
uint32_t zero = 0;
|
uint32_t zero = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t PixelParameterMappedLocation(const EmitterState& state, uint32_t attr);
|
|
||||||
|
|
||||||
uint32_t PixelParameterLocation(const EmitterState& state, uint32_t attr);
|
uint32_t PixelParameterLocation(const EmitterState& state, uint32_t attr);
|
||||||
|
|
||||||
bool PixelParameterIsFlat(const EmitterState& state, uint32_t attr);
|
bool PixelParameterIsFlat(const EmitterState& state, uint32_t attr);
|
||||||
@@ -512,9 +509,6 @@ uint32_t VertexParameterScalarType(EmitterState& state, VertexInputScalarKind ki
|
|||||||
|
|
||||||
uint32_t VertexParameterScalarPointerType(EmitterState& state, VertexInputScalarKind kind);
|
uint32_t VertexParameterScalarPointerType(EmitterState& state, VertexInputScalarKind kind);
|
||||||
|
|
||||||
uint32_t VertexParameterVectorOrScalarType(EmitterState& state, VertexInputScalarKind kind,
|
|
||||||
uint32_t components);
|
|
||||||
|
|
||||||
uint32_t VertexParameterInputPointerType(EmitterState& state, VertexInputScalarKind kind,
|
uint32_t VertexParameterInputPointerType(EmitterState& state, VertexInputScalarKind kind,
|
||||||
uint32_t components);
|
uint32_t components);
|
||||||
|
|
||||||
|
|||||||
@@ -360,34 +360,6 @@ uint32_t VertexParameterScalarPointerType(EmitterState& state, VertexInputScalar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t VertexParameterVectorOrScalarType(EmitterState& state, VertexInputScalarKind kind,
|
|
||||||
uint32_t components) {
|
|
||||||
switch (kind) {
|
|
||||||
case VertexInputScalarKind::Sint:
|
|
||||||
switch (components) {
|
|
||||||
case 1: return TypeI32(state);
|
|
||||||
case 2: return TypeI32Vector(state, 2);
|
|
||||||
case 3: return TypeI32Vector(state, 3);
|
|
||||||
default: return TypeI32Vector(state, 4);
|
|
||||||
}
|
|
||||||
case VertexInputScalarKind::Uint:
|
|
||||||
switch (components) {
|
|
||||||
case 1: return TypeU32(state);
|
|
||||||
case 2: return TypeU32Vector(state, 2);
|
|
||||||
case 3: return TypeU32Vector(state, 3);
|
|
||||||
default: return TypeU32Vector(state, 4);
|
|
||||||
}
|
|
||||||
case VertexInputScalarKind::Float:
|
|
||||||
default:
|
|
||||||
switch (components) {
|
|
||||||
case 1: return TypeF32(state);
|
|
||||||
case 2: return TypeF32Vector(state, 2);
|
|
||||||
case 3: return TypeF32Vector(state, 3);
|
|
||||||
default: return TypeF32Vector(state, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t VertexParameterInputPointerType(EmitterState& state, VertexInputScalarKind kind,
|
uint32_t VertexParameterInputPointerType(EmitterState& state, VertexInputScalarKind kind,
|
||||||
uint32_t components) {
|
uint32_t components) {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ void EmitStructuredInstruction(ValueEmitContext& ctx, StructuredFunctionState& s
|
|||||||
}
|
}
|
||||||
for (size_t index = 0; index < inst.NumArgs(); index++) {
|
for (size_t index = 0; index < inst.NumArgs(); index++) {
|
||||||
const auto* predecessor = inst.PhiBlock(index);
|
const auto* predecessor = inst.PhiBlock(index);
|
||||||
if (predecessor == nullptr || !ctx.labels.contains(predecessor)) {
|
if (predecessor == nullptr || !ctx.state.labels.contains(predecessor)) {
|
||||||
ctx.Fail(inst, "has a predecessor outside the structured function");
|
ctx.Fail(inst, "has a predecessor outside the structured function");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -579,7 +579,7 @@ const IR::ExportInfo& ValueEmitContext::Export(const IR::Inst& inst) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ValueEmitContext::Label(const IR::Block* block) const {
|
uint32_t ValueEmitContext::Label(const IR::Block* block) const {
|
||||||
return labels.at(block);
|
return state.labels.at(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] void ValueEmitContext::Fail(const char* reason) const {
|
[[noreturn]] void ValueEmitContext::Fail(const char* reason) const {
|
||||||
@@ -610,8 +610,7 @@ void EmitProgram(EmitterState& state, const IR::Program& program) {
|
|||||||
}
|
}
|
||||||
for (const auto* block: program.blocks) {
|
for (const auto* block: program.blocks) {
|
||||||
const auto label = state.builder.AllocateId();
|
const auto label = state.builder.AllocateId();
|
||||||
ctx.labels.emplace(block, label);
|
state.labels.emplace(block, label);
|
||||||
high.labels.emplace(block, label);
|
|
||||||
}
|
}
|
||||||
if (state.program.dispatcher_fallback) {
|
if (state.program.dispatcher_fallback) {
|
||||||
auto& dispatch = dispatcher.emplace();
|
auto& dispatch = dispatcher.emplace();
|
||||||
|
|||||||
Reference in New Issue
Block a user