mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 02:47:02 +02:00
shader: track buffer liveness and offsets by resource count
Co-authored-by: fxpw <fxpw@outlook.com>
This commit is contained in:
@@ -18,7 +18,7 @@ namespace {
|
||||
}
|
||||
|
||||
void ValidateNativeProgram(const IR::Program& program, bool lds_storage) {
|
||||
uint64_t live_buffers = 0;
|
||||
std::vector<bool> live_buffers(program.info.buffers.size());
|
||||
bool uses_lds = false;
|
||||
bool uses_gds = false;
|
||||
const auto uses_mapping = [](const auto& resource) {
|
||||
@@ -85,12 +85,12 @@ void ValidateNativeProgram(const IR::Program& program, bool lds_storage) {
|
||||
if (memory.resource >= program.info.buffers.size()) {
|
||||
Fail(program, "typed shader contains an invalid buffer resource");
|
||||
}
|
||||
live_buffers |= uint64_t{1} << memory.resource;
|
||||
live_buffers[memory.resource] = true;
|
||||
for (const auto child: program.info.buffers[memory.resource].indirect_resources) {
|
||||
if (child >= program.info.buffers.size()) {
|
||||
Fail(program, "typed shader contains an invalid indirect buffer resource");
|
||||
}
|
||||
live_buffers |= uint64_t{1} << child;
|
||||
live_buffers[child] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -149,8 +149,9 @@ void ValidateNativeProgram(const IR::Program& program, bool lds_storage) {
|
||||
std::array<uint32_t, static_cast<size_t>(Kind::Count)> expected {};
|
||||
auto& buffer_count = expected[static_cast<size_t>(Kind::Buffers)];
|
||||
for (uint32_t index = 0; index < program.info.buffers.size(); ++index) {
|
||||
const auto slot = (live_buffers & (uint64_t{1} << index)) != 0 ? buffer_count++ : UINT32_MAX;
|
||||
if (program.info.buffers[index].descriptor_index != slot) {
|
||||
const auto slot = live_buffers[index] ? buffer_count++ : UINT32_MAX;
|
||||
if (program.info.buffers[index].live != live_buffers[index] ||
|
||||
program.info.buffers[index].descriptor_index != slot) {
|
||||
Fail(program, "native buffer descriptor index does not match shader topology");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ struct EmitterState {
|
||||
uint32_t lane_count = 1;
|
||||
uint32_t lane_half = 0;
|
||||
std::array<BufferDefinition, 4> storage_buffers {};
|
||||
std::array<uint32_t, IR::ShaderInfo::MaxBuffers> memory_byte_offsets {};
|
||||
std::vector<uint32_t> memory_byte_offsets;
|
||||
uint32_t bda_pagetable_variable = 0;
|
||||
uint32_t fault_buffer_variable = 0;
|
||||
uint32_t bda_pointer_function = 0;
|
||||
|
||||
@@ -129,14 +129,15 @@ bool UsesSharedIndirectBufferAccess(const EmitterState& state, uint32_t resource
|
||||
}
|
||||
|
||||
void EmitMemoryOffsets(EmitterState& state) {
|
||||
std::array<bool, IR::ShaderInfo::MaxBuffers> dynamic_offsets {};
|
||||
const auto count = state.program.bindings.descriptor_counts[static_cast<size_t>(IR::DescriptorBindingKind::Buffers)];
|
||||
state.memory_byte_offsets.resize(count);
|
||||
std::vector<bool> dynamic_offsets(count);
|
||||
for (uint32_t resource = 0; resource < state.program.info.buffers.size(); ++resource) {
|
||||
if (!UsesSharedIndirectBufferAccess(state, resource)) continue;
|
||||
for (const auto candidate: state.program.info.buffers[resource].indirect_resources) {
|
||||
dynamic_offsets[state.program.info.buffers[candidate].descriptor_index] = true;
|
||||
}
|
||||
}
|
||||
const auto count = state.program.bindings.descriptor_counts[static_cast<size_t>(IR::DescriptorBindingKind::Buffers)];
|
||||
for (uint32_t i = 0; i < count; i += 4u) {
|
||||
const auto lanes = std::min(4u, count - i);
|
||||
if (std::all_of(dynamic_offsets.begin() + i, dynamic_offsets.begin() + i + lanes,
|
||||
|
||||
@@ -212,9 +212,8 @@ void DefineDescriptors(EmitterState& state) {
|
||||
auto& bindings = state.program.bindings;
|
||||
auto& counts = bindings.descriptor_counts;
|
||||
auto& buffer_count = counts[static_cast<size_t>(Kind::Buffers)];
|
||||
for (uint32_t index = 0; index < info.buffers.size(); ++index) {
|
||||
info.buffers[index].descriptor_index = (info.live_buffers & (uint64_t{1} << index)) != 0
|
||||
? buffer_count++ : UINT32_MAX;
|
||||
for (auto& buffer: info.buffers) {
|
||||
buffer.descriptor_index = buffer.live ? buffer_count++ : UINT32_MAX;
|
||||
}
|
||||
std::array<const IR::ImageResource*, IR::ImageBindingCount> image_types {};
|
||||
for (auto& image: info.images) {
|
||||
|
||||
@@ -129,6 +129,7 @@ struct BufferResource {
|
||||
bool atomic = false;
|
||||
bool formatted = false;
|
||||
bool scalar = false;
|
||||
bool live = false;
|
||||
uint32_t indirect_root = NoIndirectBuffer;
|
||||
uint32_t indirect_mapping_offset = 0;
|
||||
uint32_t indirect_search_iterations = 0;
|
||||
@@ -493,7 +494,6 @@ struct ShaderInfo {
|
||||
std::vector<StageInput> inputs;
|
||||
std::vector<StageOutput> outputs;
|
||||
std::vector<uint32_t> user_data_registers;
|
||||
uint64_t live_buffers = 0;
|
||||
std::array<uint8_t, 32> vertex_fetch_components {};
|
||||
int32_t vertex_offset_sgpr = -1;
|
||||
int32_t instance_offset_sgpr = -1;
|
||||
|
||||
@@ -311,12 +311,12 @@ void Visit(Program& program, ShaderStageInputInfo input_info, InputUsage& inputs
|
||||
if (memory.resource >= info.buffers.size() || memory.resource >= ShaderInfo::MaxBuffers) {
|
||||
return Fail("buffer operation has invalid resource metadata");
|
||||
}
|
||||
info.live_buffers |= uint64_t{1} << memory.resource;
|
||||
info.buffers[memory.resource].live = true;
|
||||
for (const auto child: info.buffers[memory.resource].indirect_resources) {
|
||||
if (child >= info.buffers.size()) {
|
||||
return Fail("indirect buffer operation has invalid resource metadata");
|
||||
}
|
||||
info.live_buffers |= uint64_t{1} << child;
|
||||
info.buffers[child].live = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -572,7 +572,7 @@ void CollectShaderInfo(Program& program, ShaderStageInputInfo input_info) {
|
||||
info.inputs.clear();
|
||||
info.outputs.clear();
|
||||
info.user_data_registers.clear();
|
||||
info.live_buffers = 0;
|
||||
for (auto& buffer: info.buffers) buffer.live = false;
|
||||
info.has_bitwise_xor = info.uses_lds = info.uses_gds = info.uses_flattened_srt =
|
||||
info.uses_dispatch_threads = info.uses_swizzle = false;
|
||||
info.bvh = info.subgroup_ballot = info.subgroup_barrier = info.subgroup_shuffle = info.subgroup_arithmetic =
|
||||
|
||||
Reference in New Issue
Block a user