refactor renderer

This commit is contained in:
nmzik
2026-07-27 02:24:50 +02:00
parent a720b28b7f
commit a20cf5d298
112 changed files with 18269 additions and 18368 deletions
@@ -726,6 +726,7 @@ struct ShaderInfo {
std::vector<StageInput> inputs;
std::vector<StageOutput> outputs;
int32_t vertex_offset_sgpr = -1;
bool has_bitwise_xor = false;
bool operator==(const ShaderInfo& other) const = default;
};
@@ -87,7 +87,7 @@ bool ValidateOptions(const Program& program, const ShaderInfoOptions& options, s
}
void CollectVertexInputs(const Program& program, const ShaderVertexInputInfo* vertex,
ShaderInfo& info) {
ShaderInfo& info) {
AddInput(info, StageInputKind::VertexIndex, 0, 1, "gl_VertexIndex");
AddInput(info, StageInputKind::InstanceIndex, 0, 1, "gl_InstanceIndex");
if (vertex == nullptr) {
@@ -130,7 +130,7 @@ void CollectPixelInputs(const ShaderPixelInputInfo* pixel, ShaderInfo& info) {
}
void CollectComputeInputs(const Program& program, const ShaderComputeInputInfo* compute,
ShaderInfo& info) {
ShaderInfo& info) {
if (compute != nullptr) {
if (compute->group_id[0] || compute->group_id[1] || compute->group_id[2]) {
AddInput(info, StageInputKind::WorkgroupId, 0, 3, "gl_WorkGroupID");
@@ -197,7 +197,7 @@ bool CollectShaderInfo(Program& program, const ShaderInfoOptions& options, std::
if (!program.resource_tracking_complete || program.shader_info_complete) {
if (error != nullptr) {
*error = !program.resource_tracking_complete ? "shader resources were not tracked"
: "shader info already collected";
: "shader info already collected";
}
return false;
}
@@ -208,6 +208,18 @@ bool CollectShaderInfo(Program& program, const ShaderInfoOptions& options, std::
auto next = program.info;
next.inputs.clear();
next.outputs.clear();
next.has_bitwise_xor =
std::any_of(program.blocks.begin(), program.blocks.end(), [](const auto& block) {
return std::any_of(block.instructions.begin(), block.instructions.end(),
[](const auto& inst) {
switch (inst.op) {
case Opcode::BitwiseXorU32:
case Opcode::BitwiseXor3U32:
case Opcode::XorAddU32: return true;
default: return false;
}
});
});
switch (program.stage) {
case ShaderType::Vertex: CollectVertexInputs(program, options.vertex, next); break;
case ShaderType::Pixel: CollectPixelInputs(options.pixel, next); break;
@@ -139,9 +139,8 @@ uint32_t EmitVsharpDwordLoad(EmitterState& state, uint32_t dword_index) {
const auto pointer = state.builder.AllocateId();
const auto value = state.builder.AllocateId();
state.builder.AddFunction({OpAccessChain, state.ptr_push_constant_uint, pointer,
state.push_constant_variable, ConstantU32(state, 0),
ConstantU32(state, dword_index / 4u),
ConstantU32(state, dword_index % 4u)});
state.push_constant_variable, ConstantU32(state, 0),
ConstantU32(state, dword_index)});
state.builder.AddFunction({OpLoad, state.uint_type, value, pointer});
return value;
}
@@ -149,8 +148,8 @@ uint32_t EmitVsharpDwordLoad(EmitterState& state, uint32_t dword_index) {
const auto pointer = state.builder.AllocateId();
const auto value = state.builder.AllocateId();
state.builder.AddFunction({OpAccessChain, state.ptr_storage_buffer_uint, pointer,
state.vsharp_storage_variable, ConstantU32(state, 0),
ConstantU32(state, dword_index)});
state.vsharp_storage_variable, ConstantU32(state, 0),
ConstantU32(state, dword_index)});
state.builder.AddFunction({OpLoad, state.uint_type, value, pointer});
return value;
}
@@ -192,8 +191,8 @@ void EmitRegisterVariables(EmitterState& state) {
{OpVariable, state.ptr_func_uint, state.dispatch_pc_variable, StorageClassFunction});
}
if (state.pixel_valid_mask_variable != 0) {
state.builder.AddFunction({OpVariable, state.ptr_func_uint,
state.pixel_valid_mask_variable, StorageClassFunction});
state.builder.AddFunction({OpVariable, state.ptr_func_uint, state.pixel_valid_mask_variable,
StorageClassFunction});
state.builder.AddFunction(
{OpStore, state.pixel_valid_mask_variable, ConstantU32(state, 1)});
}
@@ -226,9 +225,9 @@ void EmitComputeInputRegisters(EmitterState& state) {
if (!cs->group_id[i]) {
continue;
}
const auto pointer = PointerForRegister(
state,
{IR::RegisterFile::Scalar, static_cast<uint32_t>(cs->workgroup_register) + reg_offset});
const auto pointer =
PointerForRegister(state, {IR::RegisterFile::Scalar,
static_cast<uint32_t>(cs->workgroup_register) + reg_offset});
if (pointer != 0) {
state.builder.AddFunction(
{OpStore, pointer,
@@ -238,9 +237,9 @@ void EmitComputeInputRegisters(EmitterState& state) {
}
if (cs->tg_size_en) {
const auto pointer = PointerForRegister(
state,
{IR::RegisterFile::Scalar, static_cast<uint32_t>(cs->workgroup_register) + reg_offset});
const auto pointer =
PointerForRegister(state, {IR::RegisterFile::Scalar,
static_cast<uint32_t>(cs->workgroup_register) + reg_offset});
if (pointer != 0) {
const uint32_t wave_size = cs->wave_size != 0 ? cs->wave_size : 64u;
const uint32_t total_threads = std::max<uint32_t>(cs->threads_num[0], 1u) *
@@ -263,7 +262,7 @@ void EmitComputeInputRegisters(EmitterState& state) {
state.builder.AddFunction(
{OpIEqual, state.bool_type, is_first, wave_id, ConstantU32(state, 0)});
state.builder.AddFunction({OpSelect, state.uint_type, first_bit, is_first,
ConstantU32(state, 0x80000000u), ConstantU32(state, 0)});
ConstantU32(state, 0x80000000u), ConstantU32(state, 0)});
state.builder.AddFunction(
{OpBitwiseOr, state.uint_type, base, wave_bits, ConstantU32(state, waves)});
state.builder.AddFunction({OpBitwiseOr, state.uint_type, packed, base, first_bit});
@@ -360,7 +359,7 @@ void EmitVertexInputRegisters(EmitterState& state) {
const auto instance_index = PointerForRegister(state, {IR::RegisterFile::Vector, 8});
if (instance_index != 0) {
state.builder.AddFunction({OpStore, instance_index,
EmitInputScalarU32(state, IR::StageInputKind::InstanceIndex)});
EmitInputScalarU32(state, IR::StageInputKind::InstanceIndex)});
}
}
@@ -861,7 +860,7 @@ uint32_t DispatcherTargetValue(EmitterState& state, uint32_t block_id) {
void EmitDispatcherStoreTarget(EmitterState& state, uint32_t block_id) {
state.builder.AddFunction({OpStore, state.dispatch_pc_variable,
ConstantU32(state, DispatcherTargetValue(state, block_id))});
ConstantU32(state, DispatcherTargetValue(state, block_id))});
}
void EmitDispatcherExit(EmitterState& state);
@@ -912,7 +911,7 @@ void EmitDispatcherStoreSelectorTarget(EmitterState& state, const CFG::Terminato
for (uint32_t i = 0; i < term.indirect_selector_values.size(); i++) {
const auto match = state.builder.AllocateId();
state.builder.AddFunction({OpIEqual, state.bool_type, match, selector_value,
ConstantU32(state, term.indirect_selector_values[i])});
ConstantU32(state, term.indirect_selector_values[i])});
const auto next = state.builder.AllocateId();
state.builder.AddFunction(
{OpSelect, state.uint_type, next, match,
@@ -949,7 +948,7 @@ void EmitDispatcherStoreIndirectTarget(EmitterState& state, const CFG::Terminato
for (uint32_t i = 0; i < count; i++) {
const auto match = state.builder.AllocateId();
state.builder.AddFunction({OpIEqual, state.bool_type, match, pc_value,
ConstantU32(state, term.indirect_target_pcs[i])});
ConstantU32(state, term.indirect_target_pcs[i])});
const auto next = state.builder.AllocateId();
state.builder.AddFunction(
{OpSelect, state.uint_type, next, match,
@@ -1001,8 +1000,8 @@ void EmitDispatcherSwitch(EmitterState& state, const IR::Program& program) {
const auto done = state.builder.AllocateId();
state.builder.AddFunction(
{OpIEqual, state.bool_type, done, pc_value, ConstantU32(state, UINT32_MAX)});
state.builder.AddFunction({OpLoopMerge, state.dispatch_merge_label,
state.dispatch_continue_label, LoopControlNone});
state.builder.AddFunction(
{OpLoopMerge, state.dispatch_merge_label, state.dispatch_continue_label, LoopControlNone});
state.builder.AddFunction(
{OpBranchConditional, done, state.dispatch_merge_label, state.dispatch_select_label});
@@ -304,73 +304,72 @@ struct EmitterState {
Builder builder;
const IR::Program& program;
const IR::ResourceSnapshot& resources;
const ShaderVertexInputInfo* vertex_input_info = nullptr;
const ShaderPixelInputInfo* pixel_input_info = nullptr;
const ShaderComputeInputInfo* compute_input_info = nullptr;
ShaderType stage = ShaderType::Unknown;
uint32_t wave_size = 64;
bool exact_subgroup_operations = false;
bool per_invocation_masks = false;
uint32_t void_type = 0;
uint32_t bool_type = 0;
uint32_t uint_type = 0;
uint32_t uint_pair_type = 0;
uint32_t int_pair_type = 0;
uint32_t int_type = 0;
uint32_t float_type = 0;
uint32_t vec2_uint_type = 0;
uint32_t vec3_uint_type = 0;
uint32_t vec4_uint_type = 0;
uint32_t vec2_int_type = 0;
uint32_t vec3_int_type = 0;
uint32_t vec4_int_type = 0;
uint32_t vec2_float_type = 0;
uint32_t vec3_float_type = 0;
uint32_t vec4_float_type = 0;
uint32_t ptr_func_uint = 0;
uint32_t ptr_input_float = 0;
uint32_t ptr_input_bool = 0;
uint32_t ptr_input_int = 0;
uint32_t ptr_input_uint = 0;
uint32_t ptr_input_vec2_float = 0;
uint32_t ptr_input_vec3_float = 0;
uint32_t ptr_input_vec2_int = 0;
uint32_t ptr_input_vec3_int = 0;
uint32_t ptr_input_vec4_int = 0;
uint32_t ptr_input_vec2_uint = 0;
uint32_t ptr_input_vec3_uint = 0;
uint32_t ptr_input_vec4_uint = 0;
uint32_t ptr_input_vec4_float = 0;
uint32_t sample_mask_array_type = 0;
uint32_t ptr_output_int = 0;
uint32_t ptr_output_sample_mask_array = 0;
uint32_t ptr_output_float = 0;
uint32_t ptr_output_vec4_float = 0;
uint32_t per_vertex_type = 0;
uint32_t ptr_output_per_vertex = 0;
uint32_t storage_runtime_array_type = 0;
uint32_t storage_buffer_type = 0;
uint32_t ptr_storage_buffer = 0;
uint32_t ptr_storage_buffer_uint = 0;
uint32_t storage_buffer_array_type = 0;
uint32_t ptr_storage_buffer_array = 0;
uint32_t storage_buffer_variable = 0;
uint32_t address_memory_array_type = 0;
uint32_t ptr_address_memory_array = 0;
uint32_t address_memory_variable = 0;
uint32_t gds_variable = 0;
uint32_t push_constant_u32x4_array_type = 0;
uint32_t push_constant_rows_array_type = 0;
uint32_t push_constant_block_type = 0;
uint32_t ptr_push_constant_block = 0;
uint32_t ptr_push_constant_uint = 0;
uint32_t push_constant_variable = 0;
uint32_t vsharp_storage_variable = 0;
uint32_t flattened_srt_variable = 0;
uint32_t lds_array_type = 0;
uint32_t ptr_workgroup_array = 0;
uint32_t ptr_workgroup_uint = 0;
uint32_t lds_variable = 0;
const ShaderVertexInputInfo* vertex_input_info = nullptr;
const ShaderPixelInputInfo* pixel_input_info = nullptr;
const ShaderComputeInputInfo* compute_input_info = nullptr;
ShaderType stage = ShaderType::Unknown;
uint32_t wave_size = 64;
bool exact_subgroup_operations = false;
bool per_invocation_masks = false;
uint32_t void_type = 0;
uint32_t bool_type = 0;
uint32_t uint_type = 0;
uint32_t uint_pair_type = 0;
uint32_t int_pair_type = 0;
uint32_t int_type = 0;
uint32_t float_type = 0;
uint32_t vec2_uint_type = 0;
uint32_t vec3_uint_type = 0;
uint32_t vec4_uint_type = 0;
uint32_t vec2_int_type = 0;
uint32_t vec3_int_type = 0;
uint32_t vec4_int_type = 0;
uint32_t vec2_float_type = 0;
uint32_t vec3_float_type = 0;
uint32_t vec4_float_type = 0;
uint32_t ptr_func_uint = 0;
uint32_t ptr_input_float = 0;
uint32_t ptr_input_bool = 0;
uint32_t ptr_input_int = 0;
uint32_t ptr_input_uint = 0;
uint32_t ptr_input_vec2_float = 0;
uint32_t ptr_input_vec3_float = 0;
uint32_t ptr_input_vec2_int = 0;
uint32_t ptr_input_vec3_int = 0;
uint32_t ptr_input_vec4_int = 0;
uint32_t ptr_input_vec2_uint = 0;
uint32_t ptr_input_vec3_uint = 0;
uint32_t ptr_input_vec4_uint = 0;
uint32_t ptr_input_vec4_float = 0;
uint32_t sample_mask_array_type = 0;
uint32_t ptr_output_int = 0;
uint32_t ptr_output_sample_mask_array = 0;
uint32_t ptr_output_float = 0;
uint32_t ptr_output_vec4_float = 0;
uint32_t per_vertex_type = 0;
uint32_t ptr_output_per_vertex = 0;
uint32_t storage_runtime_array_type = 0;
uint32_t storage_buffer_type = 0;
uint32_t ptr_storage_buffer = 0;
uint32_t ptr_storage_buffer_uint = 0;
uint32_t storage_buffer_array_type = 0;
uint32_t ptr_storage_buffer_array = 0;
uint32_t storage_buffer_variable = 0;
uint32_t address_memory_array_type = 0;
uint32_t ptr_address_memory_array = 0;
uint32_t address_memory_variable = 0;
uint32_t gds_variable = 0;
uint32_t push_constant_array_type = 0;
uint32_t push_constant_block_type = 0;
uint32_t ptr_push_constant_block = 0;
uint32_t ptr_push_constant_uint = 0;
uint32_t push_constant_variable = 0;
uint32_t vsharp_storage_variable = 0;
uint32_t flattened_srt_variable = 0;
uint32_t lds_array_type = 0;
uint32_t ptr_workgroup_array = 0;
uint32_t ptr_workgroup_uint = 0;
uint32_t lds_variable = 0;
std::array<SampledImageDescriptors, 6> sampled_images;
uint32_t sampler_type = 0;
uint32_t sampler_array_type = 0;
@@ -237,9 +237,9 @@ uint32_t BuiltInForInput(IR::StageInputKind kind) {
void AddInputAnnotationsAndNames(EmitterState& state) {
if (state.subgroup_local_invocation_id_variable != 0) {
state.builder.AddName(state.subgroup_local_invocation_id_variable,
"gl_SubgroupInvocationID");
"gl_SubgroupInvocationID");
state.builder.AddAnnotation({OpDecorate, state.subgroup_local_invocation_id_variable,
DecorationBuiltIn, BuiltInSubgroupLocalInvocationId});
DecorationBuiltIn, BuiltInSubgroupLocalInvocationId});
if (state.stage == ShaderType::Pixel) {
state.builder.AddAnnotation(
{OpDecorate, state.subgroup_local_invocation_id_variable, DecorationFlat});
@@ -373,13 +373,10 @@ void AddVsharpAnnotationsAndNames(EmitterState& state) {
state.builder.AddName(state.push_constant_block_type, "BufferResource");
state.builder.AddName(state.push_constant_variable, "vsharp");
state.builder.AddAnnotation(
{OpDecorate, state.push_constant_u32x4_array_type, DecorationArrayStride, 4});
state.builder.AddAnnotation(
{OpDecorate, state.push_constant_rows_array_type, DecorationArrayStride, 16});
{OpDecorate, state.push_constant_array_type, DecorationArrayStride, 4});
state.builder.AddAnnotation({OpMemberDecorate, state.push_constant_block_type, 0,
DecorationOffset, bind.push_constant_offset});
state.builder.AddAnnotation(
{OpDecorate, state.push_constant_block_type, DecorationBlock});
DecorationOffset, bind.push_constant_offset});
state.builder.AddAnnotation({OpDecorate, state.push_constant_block_type, DecorationBlock});
}
if (state.vsharp_storage_variable != 0) {
const auto* storage = DescriptorBinding(state, IR::DescriptorBindingKind::UserData);
@@ -439,11 +436,10 @@ void EmitHeaderAndTypes(EmitterState& state) {
state.ptr_address_memory_array = state.builder.AllocateId();
}
if (state.push_constant_variable != 0) {
state.push_constant_u32x4_array_type = state.builder.AllocateId();
state.push_constant_rows_array_type = state.builder.AllocateId();
state.push_constant_block_type = state.builder.AllocateId();
state.ptr_push_constant_block = state.builder.AllocateId();
state.ptr_push_constant_uint = state.builder.AllocateId();
state.push_constant_array_type = state.builder.AllocateId();
state.push_constant_block_type = state.builder.AllocateId();
state.ptr_push_constant_block = state.builder.AllocateId();
state.ptr_push_constant_uint = state.builder.AllocateId();
}
state.lds_array_type = state.builder.AllocateId();
state.ptr_workgroup_array = state.builder.AllocateId();
@@ -517,7 +513,7 @@ void EmitHeaderAndTypes(EmitterState& state) {
state.builder.AddExtInstImport(state.glsl_std450, "GLSL.std.450");
state.builder.AddMemoryModel({AddressingModelLogical, MemoryModelGLSL450});
state.builder.AddEntryPoint(ExecutionModelForStage(state.stage), state.main_func, "main",
state.interface_variables);
state.interface_variables);
if (state.stage == ShaderType::Compute) {
uint32_t local_x = state.needs_compute_derivatives ? 2u : 1u;
uint32_t local_y = state.needs_compute_derivatives ? 2u : 1u;
@@ -563,8 +559,7 @@ void EmitHeaderAndTypes(EmitterState& state) {
state.builder.AddType({OpTypeVoid, state.void_type});
state.builder.AddType({OpTypeBool, state.bool_type});
state.builder.AddType({OpTypeInt, state.uint_type, 32, 0});
state.builder.AddType(
{OpTypeStruct, state.uint_pair_type, state.uint_type, state.uint_type});
state.builder.AddType({OpTypeStruct, state.uint_pair_type, state.uint_type, state.uint_type});
state.builder.AddType({OpTypeInt, state.int_type, 32, 1});
state.builder.AddType({OpTypeStruct, state.int_pair_type, state.int_type, state.int_type});
state.builder.AddType({OpTypeFloat, state.float_type, 32});
@@ -583,8 +578,7 @@ void EmitHeaderAndTypes(EmitterState& state) {
{OpTypePointer, state.ptr_input_float, StorageClassInput, state.float_type});
state.builder.AddType(
{OpTypePointer, state.ptr_input_bool, StorageClassInput, state.bool_type});
state.builder.AddType(
{OpTypePointer, state.ptr_input_int, StorageClassInput, state.int_type});
state.builder.AddType({OpTypePointer, state.ptr_input_int, StorageClassInput, state.int_type});
state.builder.AddType(
{OpTypePointer, state.ptr_input_uint, StorageClassInput, state.uint_type});
state.builder.AddType(
@@ -607,7 +601,7 @@ void EmitHeaderAndTypes(EmitterState& state) {
{OpTypePointer, state.ptr_input_vec4_float, StorageClassInput, state.vec4_float_type});
if (state.subgroup_local_invocation_id_variable != 0) {
state.builder.AddType({OpVariable, state.ptr_input_uint,
state.subgroup_local_invocation_id_variable, StorageClassInput});
state.subgroup_local_invocation_id_variable, StorageClassInput});
}
for (const auto& input: state.inputs) {
uint32_t ptr_type = state.ptr_input_uint;
@@ -643,15 +637,15 @@ void EmitHeaderAndTypes(EmitterState& state) {
if (state.per_vertex_variable != 0) {
state.builder.AddType({OpTypeStruct, state.per_vertex_type, state.vec4_float_type});
state.builder.AddType({OpTypePointer, state.ptr_output_per_vertex, StorageClassOutput,
state.per_vertex_type});
state.builder.AddType({OpVariable, state.ptr_output_per_vertex,
state.per_vertex_variable, StorageClassOutput});
state.per_vertex_type});
state.builder.AddType({OpVariable, state.ptr_output_per_vertex, state.per_vertex_variable,
StorageClassOutput});
}
for (const auto& binding: state.outputs) {
if (binding.kind == IR::StageOutputKind::Parameter ||
binding.kind == IR::StageOutputKind::Mrt) {
state.builder.AddType({OpVariable, state.ptr_output_vec4_float, binding.variable_id,
StorageClassOutput});
state.builder.AddType(
{OpVariable, state.ptr_output_vec4_float, binding.variable_id, StorageClassOutput});
}
}
if (state.depth_variable != 0) {
@@ -662,52 +656,48 @@ void EmitHeaderAndTypes(EmitterState& state) {
state.builder.AddType(
{OpTypeArray, state.sample_mask_array_type, state.int_type, ConstantU32(state, 1)});
state.builder.AddType({OpTypePointer, state.ptr_output_sample_mask_array,
StorageClassOutput, state.sample_mask_array_type});
StorageClassOutput, state.sample_mask_array_type});
state.builder.AddType({OpVariable, state.ptr_output_sample_mask_array,
state.sample_mask_variable, StorageClassOutput});
state.sample_mask_variable, StorageClassOutput});
}
state.builder.AddType(
{OpTypeRuntimeArray, state.storage_runtime_array_type, state.uint_type});
state.builder.AddType({OpTypeRuntimeArray, state.storage_runtime_array_type, state.uint_type});
state.builder.AddType(
{OpTypeStruct, state.storage_buffer_type, state.storage_runtime_array_type});
state.builder.AddType({OpTypePointer, state.ptr_storage_buffer, StorageClassStorageBuffer,
state.storage_buffer_type});
state.builder.AddType({OpTypePointer, state.ptr_storage_buffer_uint,
StorageClassStorageBuffer, state.uint_type});
state.storage_buffer_type});
state.builder.AddType(
{OpTypePointer, state.ptr_storage_buffer_uint, StorageClassStorageBuffer, state.uint_type});
if (state.storage_buffer_variable != 0) {
const auto count =
ConstantU32(state, DescriptorCount(state, IR::DescriptorBindingKind::Buffers));
state.builder.AddType(
{OpTypeArray, state.storage_buffer_array_type, state.storage_buffer_type, count});
state.builder.AddType({OpTypePointer, state.ptr_storage_buffer_array,
StorageClassStorageBuffer, state.storage_buffer_array_type});
StorageClassStorageBuffer, state.storage_buffer_array_type});
state.builder.AddType({OpVariable, state.ptr_storage_buffer_array,
state.storage_buffer_variable, StorageClassStorageBuffer});
state.storage_buffer_variable, StorageClassStorageBuffer});
}
if (state.gds_variable != 0) {
state.builder.AddType({OpVariable, state.ptr_storage_buffer, state.gds_variable,
StorageClassStorageBuffer});
state.builder.AddType(
{OpVariable, state.ptr_storage_buffer, state.gds_variable, StorageClassStorageBuffer});
}
if (state.push_constant_variable != 0) {
const auto row_width = ConstantU32(state, 4);
const auto row_count = ConstantU32(
state, std::max((state.program.bindings.push_constant_size + 15u) / 16u, 1u));
const auto dword_count =
ConstantU32(state, state.program.bindings.push_constant_size / sizeof(uint32_t));
state.builder.AddType(
{OpTypeArray, state.push_constant_u32x4_array_type, state.uint_type, row_width});
state.builder.AddType({OpTypeArray, state.push_constant_rows_array_type,
state.push_constant_u32x4_array_type, row_count});
{OpTypeArray, state.push_constant_array_type, state.uint_type, dword_count});
state.builder.AddType(
{OpTypeStruct, state.push_constant_block_type, state.push_constant_rows_array_type});
{OpTypeStruct, state.push_constant_block_type, state.push_constant_array_type});
state.builder.AddType({OpTypePointer, state.ptr_push_constant_block,
StorageClassPushConstant, state.push_constant_block_type});
StorageClassPushConstant, state.push_constant_block_type});
state.builder.AddType({OpTypePointer, state.ptr_push_constant_uint,
StorageClassPushConstant, state.uint_type});
StorageClassPushConstant, state.uint_type});
state.builder.AddType({OpVariable, state.ptr_push_constant_block,
state.push_constant_variable, StorageClassPushConstant});
state.push_constant_variable, StorageClassPushConstant});
}
if (state.vsharp_storage_variable != 0) {
state.builder.AddType({OpVariable, state.ptr_storage_buffer,
state.vsharp_storage_variable, StorageClassStorageBuffer});
state.builder.AddType({OpVariable, state.ptr_storage_buffer, state.vsharp_storage_variable,
StorageClassStorageBuffer});
}
if (state.address_memory_variable != 0) {
const auto count =
@@ -715,13 +705,13 @@ void EmitHeaderAndTypes(EmitterState& state) {
state.builder.AddType(
{OpTypeArray, state.address_memory_array_type, state.storage_buffer_type, count});
state.builder.AddType({OpTypePointer, state.ptr_address_memory_array,
StorageClassStorageBuffer, state.address_memory_array_type});
StorageClassStorageBuffer, state.address_memory_array_type});
state.builder.AddType({OpVariable, state.ptr_address_memory_array,
state.address_memory_variable, StorageClassStorageBuffer});
state.address_memory_variable, StorageClassStorageBuffer});
}
if (state.flattened_srt_variable != 0) {
state.builder.AddType({OpVariable, state.ptr_storage_buffer,
state.flattened_srt_variable, StorageClassStorageBuffer});
state.builder.AddType({OpVariable, state.ptr_storage_buffer, state.flattened_srt_variable,
StorageClassStorageBuffer});
}
if (state.stage == ShaderType::Compute || state.needs_function_lds) {
const auto storage_class =
@@ -733,8 +723,8 @@ void EmitHeaderAndTypes(EmitterState& state) {
state.builder.AddType(
{OpTypePointer, state.ptr_workgroup_uint, storage_class, state.uint_type});
if (state.stage == ShaderType::Compute) {
state.builder.AddType({OpVariable, state.ptr_workgroup_array, state.lds_variable,
StorageClassWorkgroup});
state.builder.AddType(
{OpVariable, state.ptr_workgroup_array, state.lds_variable, StorageClassWorkgroup});
}
}
for (uint32_t i = 0; i < state.sampled_images.size(); i++) {
@@ -744,7 +734,7 @@ void EmitHeaderAndTypes(EmitterState& state) {
const auto dimension = view == ImageViewKind::Dim3D ? Dim3D : Dim2D;
const auto arrayed = view == ImageViewKind::Dim2DArray ? 1u : 0u;
state.builder.AddType({OpTypeImage, image.image_type, component, dimension, 0, arrayed, 0,
1, ImageFormatUnknown});
1, ImageFormatUnknown});
state.builder.AddType({OpTypeSampledImage, image.sampled_image_type, image.image_type});
state.builder.AddType(
{OpTypePointer, image.pointer_type, StorageClassUniformConstant, image.image_type});
@@ -753,113 +743,110 @@ void EmitHeaderAndTypes(EmitterState& state) {
const auto count = ConstantU32(state, DescriptorCount(state, kind));
state.builder.AddType({OpTypeArray, image.array_type, image.image_type, count});
state.builder.AddType({OpTypePointer, image.array_pointer_type,
StorageClassUniformConstant, image.array_type});
StorageClassUniformConstant, image.array_type});
state.builder.AddType({OpVariable, image.array_pointer_type, image.variable,
StorageClassUniformConstant});
StorageClassUniformConstant});
}
}
state.builder.AddType({OpTypeSampler, state.sampler_type});
state.builder.AddType({OpTypePointer, state.ptr_uniform_sampler, StorageClassUniformConstant,
state.sampler_type});
state.sampler_type});
if (state.sampler_variable != 0) {
const auto count =
ConstantU32(state, DescriptorCount(state, IR::DescriptorBindingKind::Samplers));
state.builder.AddType(
{OpTypeArray, state.sampler_array_type, state.sampler_type, count});
state.builder.AddType({OpTypeArray, state.sampler_array_type, state.sampler_type, count});
state.builder.AddType({OpTypePointer, state.ptr_uniform_sampler_array,
StorageClassUniformConstant, state.sampler_array_type});
state.builder.AddType({OpVariable, state.ptr_uniform_sampler_array,
state.sampler_variable, StorageClassUniformConstant});
StorageClassUniformConstant, state.sampler_array_type});
state.builder.AddType({OpVariable, state.ptr_uniform_sampler_array, state.sampler_variable,
StorageClassUniformConstant});
}
state.builder.AddType({OpTypeImage, state.storage_image_type, state.float_type, Dim2D, 0, 0,
0, 2, ImageFormatUnknown});
state.builder.AddType({OpTypeImage, state.storage_image_type, state.float_type, Dim2D, 0, 0, 0,
2, ImageFormatUnknown});
state.builder.AddType({OpTypePointer, state.ptr_uniform_storage_image,
StorageClassUniformConstant, state.storage_image_type});
StorageClassUniformConstant, state.storage_image_type});
if (state.storage_image_variable != 0) {
const auto count =
ConstantU32(state, DescriptorCount(state, IR::DescriptorBindingKind::Storage2D));
state.builder.AddType(
{OpTypeArray, state.storage_image_array_type, state.storage_image_type, count});
state.builder.AddType({OpTypePointer, state.ptr_uniform_storage_image_array,
StorageClassUniformConstant, state.storage_image_array_type});
StorageClassUniformConstant, state.storage_image_array_type});
state.builder.AddType({OpVariable, state.ptr_uniform_storage_image_array,
state.storage_image_variable, StorageClassUniformConstant});
state.storage_image_variable, StorageClassUniformConstant});
}
state.builder.AddType({OpTypeImage, state.storage_image_2d_array_type, state.float_type,
Dim2D, 0, 1, 0, 2, ImageFormatUnknown});
state.builder.AddType({OpTypeImage, state.storage_image_2d_array_type, state.float_type, Dim2D,
0, 1, 0, 2, ImageFormatUnknown});
state.builder.AddType({OpTypePointer, state.ptr_uniform_storage_image_2d_array,
StorageClassUniformConstant, state.storage_image_2d_array_type});
StorageClassUniformConstant, state.storage_image_2d_array_type});
if (state.storage_image_2d_array_variable != 0) {
const auto count =
ConstantU32(state, DescriptorCount(state, IR::DescriptorBindingKind::Storage2DArray));
state.builder.AddType({OpTypeArray, state.storage_image_2d_array_array_type,
state.storage_image_2d_array_type, count});
state.storage_image_2d_array_type, count});
state.builder.AddType({OpTypePointer, state.ptr_uniform_storage_image_2d_array_array,
StorageClassUniformConstant,
state.storage_image_2d_array_array_type});
StorageClassUniformConstant,
state.storage_image_2d_array_array_type});
state.builder.AddType({OpVariable, state.ptr_uniform_storage_image_2d_array_array,
state.storage_image_2d_array_variable,
StorageClassUniformConstant});
state.storage_image_2d_array_variable, StorageClassUniformConstant});
}
state.builder.AddType({OpTypeImage, state.storage_image_3d_type, state.float_type, Dim3D, 0,
0, 0, 2, ImageFormatUnknown});
state.builder.AddType({OpTypeImage, state.storage_image_3d_type, state.float_type, Dim3D, 0, 0,
0, 2, ImageFormatUnknown});
state.builder.AddType({OpTypePointer, state.ptr_uniform_storage_image_3d,
StorageClassUniformConstant, state.storage_image_3d_type});
StorageClassUniformConstant, state.storage_image_3d_type});
if (state.storage_image_3d_variable != 0) {
const auto count =
ConstantU32(state, DescriptorCount(state, IR::DescriptorBindingKind::Storage3D));
state.builder.AddType(
{OpTypeArray, state.storage_image_3d_array_type, state.storage_image_3d_type, count});
state.builder.AddType({OpTypePointer, state.ptr_uniform_storage_image_3d_array,
StorageClassUniformConstant, state.storage_image_3d_array_type});
StorageClassUniformConstant, state.storage_image_3d_array_type});
state.builder.AddType({OpVariable, state.ptr_uniform_storage_image_3d_array,
state.storage_image_3d_variable, StorageClassUniformConstant});
state.storage_image_3d_variable, StorageClassUniformConstant});
}
state.builder.AddType({OpTypeImage, state.storage_image_uint_type, state.uint_type, Dim2D, 0,
0, 0, 2, ImageFormatR32ui});
state.builder.AddType({OpTypeImage, state.storage_image_uint_type, state.uint_type, Dim2D, 0, 0,
0, 2, ImageFormatR32ui});
state.builder.AddType({OpTypePointer, state.ptr_uniform_storage_image_uint,
StorageClassUniformConstant, state.storage_image_uint_type});
StorageClassUniformConstant, state.storage_image_uint_type});
if (state.storage_image_uint_variable != 0) {
const auto count =
ConstantU32(state, DescriptorCount(state, IR::DescriptorBindingKind::StorageUint2D));
state.builder.AddType({OpTypeArray, state.storage_image_uint_array_type,
state.storage_image_uint_type, count});
state.storage_image_uint_type, count});
state.builder.AddType({OpTypePointer, state.ptr_uniform_storage_image_uint_array,
StorageClassUniformConstant, state.storage_image_uint_array_type});
StorageClassUniformConstant, state.storage_image_uint_array_type});
state.builder.AddType({OpVariable, state.ptr_uniform_storage_image_uint_array,
state.storage_image_uint_variable, StorageClassUniformConstant});
state.storage_image_uint_variable, StorageClassUniformConstant});
}
state.builder.AddType({OpTypeImage, state.storage_image_uint_2d_array_type, state.uint_type,
Dim2D, 0, 1, 0, 2, ImageFormatR32ui});
Dim2D, 0, 1, 0, 2, ImageFormatR32ui});
state.builder.AddType({OpTypePointer, state.ptr_uniform_storage_image_uint_2d_array,
StorageClassUniformConstant, state.storage_image_uint_2d_array_type});
StorageClassUniformConstant, state.storage_image_uint_2d_array_type});
if (state.storage_image_uint_2d_array_variable != 0) {
const auto count = ConstantU32(
state, DescriptorCount(state, IR::DescriptorBindingKind::StorageUint2DArray));
state.builder.AddType({OpTypeArray, state.storage_image_uint_2d_array_array_type,
state.storage_image_uint_2d_array_type, count});
state.storage_image_uint_2d_array_type, count});
state.builder.AddType({OpTypePointer, state.ptr_uniform_storage_image_uint_2d_array_array,
StorageClassUniformConstant,
state.storage_image_uint_2d_array_array_type});
StorageClassUniformConstant,
state.storage_image_uint_2d_array_array_type});
state.builder.AddType({OpVariable, state.ptr_uniform_storage_image_uint_2d_array_array,
state.storage_image_uint_2d_array_variable,
StorageClassUniformConstant});
state.storage_image_uint_2d_array_variable,
StorageClassUniformConstant});
}
state.builder.AddType({OpTypeImage, state.storage_image_uint_3d_type, state.uint_type, Dim3D,
0, 0, 0, 2, ImageFormatR32ui});
state.builder.AddType({OpTypeImage, state.storage_image_uint_3d_type, state.uint_type, Dim3D, 0,
0, 0, 2, ImageFormatR32ui});
state.builder.AddType({OpTypePointer, state.ptr_uniform_storage_image_uint_3d,
StorageClassUniformConstant, state.storage_image_uint_3d_type});
StorageClassUniformConstant, state.storage_image_uint_3d_type});
if (state.storage_image_uint_3d_variable != 0) {
const auto count =
ConstantU32(state, DescriptorCount(state, IR::DescriptorBindingKind::StorageUint3D));
state.builder.AddType({OpTypeArray, state.storage_image_uint_3d_array_type,
state.storage_image_uint_3d_type, count});
state.storage_image_uint_3d_type, count});
state.builder.AddType({OpTypePointer, state.ptr_uniform_storage_image_uint_3d_array,
StorageClassUniformConstant,
state.storage_image_uint_3d_array_type});
StorageClassUniformConstant,
state.storage_image_uint_3d_array_type});
state.builder.AddType({OpVariable, state.ptr_uniform_storage_image_uint_3d_array,
state.storage_image_uint_3d_variable,
StorageClassUniformConstant});
state.storage_image_uint_3d_variable, StorageClassUniformConstant});
}
state.builder.AddType(
{OpTypePointer, state.ptr_image_uint, StorageClassImage, state.uint_type});
+15 -8
View File
@@ -12,6 +12,7 @@
#include "graphics/guest_gpu/gpu_defs.h"
#include "graphics/guest_gpu/graphicsRun.h"
#include "graphics/guest_gpu/hardwareContext.h"
#include "graphics/host_gpu/renderer/renderContext.h"
#include "graphics/shader/recompiler/ShaderDecoder.h"
#include "graphics/shader/recompiler/ShaderRecompiler.h"
#include "graphics/shader/shaderVertexMetadata.h"
@@ -825,6 +826,11 @@ static void ShaderGetStaticInputInfoPS(
vs_info.stage.program != nullptr && !vs_info.stage.program->bindings.descriptors.empty()
? 1
: 0;
ps_info.push_constant_offset =
vs_info.stage.program != nullptr
? vs_info.stage.program->bindings.push_constant_offset +
vs_info.stage.program->bindings.push_constant_size
: 0;
for (int i = 0; i < 8; i++) {
ps_info.target_output_mode[i] = sh.target_output_mode[i];
@@ -991,7 +997,7 @@ static void ShaderAppendNativeSpecialization(std::vector<uint32_t>&
ids.push_back(program.bindings.push_constant_size);
ids.push_back(static_cast<uint32_t>(program.bindings.user_data_registers.size()));
ids.insert(ids.end(), program.bindings.user_data_registers.begin(),
program.bindings.user_data_registers.end());
program.bindings.user_data_registers.end());
ids.push_back(static_cast<uint32_t>(program.bindings.descriptors.size()));
for (const auto& binding: program.bindings.descriptors) {
ids.push_back(static_cast<uint32_t>(binding.kind));
@@ -1284,9 +1290,9 @@ static void DumpShaderRecompilerSpirv(const char* type, uint64_t shader_hash,
static std::atomic_int id = 0;
const auto base_name = Config::GetShaderLogFolder() /
fmt::format("{:04d}_{:04d}_new_shader_{}_{:016x}",
GraphicsRunGetFrameNum(), id++, type, shader_hash);
const auto base_name =
Config::GetShaderLogFolder() /
fmt::format("{:04d}_new_shader_{}_{:016x}", id++, type, shader_hash);
Common::File::CreateDirectories(base_name.parent_path());
Common::File spv_file;
@@ -1335,9 +1341,9 @@ static void DumpShaderRecompilerOriginal(const char* type, uint64_t shader_hash,
static std::atomic_int id = 0;
const auto base_name = Config::GetShaderLogFolder() / "original" /
fmt::format("{:04d}_{:04d}_new_shader_{}_{:016x}",
GraphicsRunGetFrameNum(), id++, type, shader_hash);
const auto base_name =
Config::GetShaderLogFolder() / "original" /
fmt::format("{:04d}_new_shader_{}_{:016x}", id++, type, shader_hash);
Common::File::CreateDirectories(base_name.parent_path());
Common::File bin_file;
@@ -1437,7 +1443,7 @@ bool ShaderCompileSpirvPS(const HW::PixelShaderInfo& regs, const HW::ShaderRegis
options.user_data_count = regs.ps_regs.rsrc2.user_sgpr;
options.user_data = regs.ps_user_sgpr.value;
options.descriptor_set = input_info.descriptor_set;
options.push_constant_offset = 0;
options.push_constant_offset = input_info.push_constant_offset;
options.pixel_input_info = &input_info;
options.dump_ir = ShaderRecompilerTextDumpEnabled();
options.early_dump = options.dump_ir;
@@ -1591,6 +1597,7 @@ ShaderId ShaderGetIdPS(const HW::PixelShaderInfo& regs, const ShaderPixelInputIn
ret.crc32 = regs.ps_regs.chksum & 0xffffffffu;
ret.ids.push_back(input_info.descriptor_set);
ret.ids.push_back(input_info.push_constant_offset);
ret.ids.push_back(input_info.input_num);
ret.ids.push_back(input_info.ps_system_input_base);
ret.ids.push_back(static_cast<uint32_t>(input_info.ps_pos_x));
+1
View File
@@ -103,6 +103,7 @@ struct ShaderPixelInputInfo {
std::array<Prospero::ColorComponentMapping, 8> target_export_mapping = {};
uint32_t mrt_output_mask = 0;
uint32_t descriptor_set = 0;
uint32_t push_constant_offset = 0;
bool ps_pos_x = false;
bool ps_pos_y = false;
bool ps_pos_xy = false;