mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
Specialize shader resources in place and fuse buffer refresh work
This commit is contained in:
@@ -423,36 +423,6 @@ bool BuildSamplerPlan(const ShaderInfo& base, const Images& images, SamplerPlan&
|
||||
|
||||
static bool BuildResourceSpecialization(const ResourcePlan& program, ResourceSnapshot& snapshot,
|
||||
ResourceSpecialization& specialization) {
|
||||
specialization.buffers.clear();
|
||||
specialization.buffers.reserve(program.info.buffers.size());
|
||||
for (uint32_t i = 0; i < program.info.buffers.size(); i++) {
|
||||
auto& descriptor_value = snapshot.buffers[i];
|
||||
ShaderBufferResource descriptor;
|
||||
if (!DecodeBufferDescriptor(descriptor_value, descriptor)) {
|
||||
return SpecializationFail(fmt::format("buffer descriptor {} has invalid width", i));
|
||||
}
|
||||
if (descriptor.Type() != 0) {
|
||||
descriptor_value.dwords.fill(0);
|
||||
descriptor = {};
|
||||
}
|
||||
auto packed_stride = descriptor.PackedStride();
|
||||
const auto stride = packed_stride & 0x3fffu;
|
||||
const bool swizzle = stride != 0u && ((packed_stride >> 14u) & 1u) != 0u;
|
||||
if (stride == 0u) {
|
||||
packed_stride &= ~((1u << 14u) | (3u << 16u));
|
||||
} else if (!swizzle) {
|
||||
packed_stride &= ~(3u << 16u);
|
||||
}
|
||||
specialization.buffers.push_back({
|
||||
.packed_stride = packed_stride,
|
||||
.descriptor_format = program.info.buffers[i].formatted
|
||||
? descriptor.Format()
|
||||
: Prospero::BufferFormat::kInvalid,
|
||||
.descriptor_swizzle =
|
||||
program.info.buffers[i].formatted ? descriptor.DstSelXYZW() : DstSel(4, 5, 6, 7),
|
||||
.zero_stride_oob = descriptor.OutOfBounds() == 0u && stride == 0u,
|
||||
});
|
||||
}
|
||||
for (uint32_t i = 0; i < specialization.images.size(); i++) {
|
||||
const auto& descriptor = snapshot.images[i];
|
||||
auto& image = specialization.images[i];
|
||||
@@ -1029,11 +999,39 @@ bool MaterializeResources(const ResourcePlan& program, const SrtRuntime& runtime
|
||||
return true;
|
||||
};
|
||||
snapshot.buffers.resize(program.info.buffers.size());
|
||||
specialization.buffers.clear();
|
||||
specialization.buffers.reserve(program.info.buffers.size());
|
||||
for (uint32_t i = 0; i < program.info.buffers.size(); ++i) {
|
||||
if (!evaluate(program.info.buffers[i].source, snapshot.buffers[i],
|
||||
program.info.buffers[i].written)) {
|
||||
return false;
|
||||
}
|
||||
auto& descriptor_value = snapshot.buffers[i];
|
||||
ShaderBufferResource descriptor;
|
||||
if (!DecodeBufferDescriptor(descriptor_value, descriptor)) {
|
||||
return SpecializationFail(fmt::format("buffer descriptor {} has invalid width", i));
|
||||
}
|
||||
if (descriptor.Type() != 0) {
|
||||
descriptor_value.dwords.fill(0);
|
||||
descriptor = {};
|
||||
}
|
||||
auto packed_stride = descriptor.PackedStride();
|
||||
const auto stride = packed_stride & 0x3fffu;
|
||||
const bool swizzle = stride != 0u && ((packed_stride >> 14u) & 1u) != 0u;
|
||||
if (stride == 0u) {
|
||||
packed_stride &= ~((1u << 14u) | (3u << 16u));
|
||||
} else if (!swizzle) {
|
||||
packed_stride &= ~(3u << 16u);
|
||||
}
|
||||
specialization.buffers.push_back({
|
||||
.packed_stride = packed_stride,
|
||||
.descriptor_format = program.info.buffers[i].formatted
|
||||
? descriptor.Format()
|
||||
: Prospero::BufferFormat::kInvalid,
|
||||
.descriptor_swizzle =
|
||||
program.info.buffers[i].formatted ? descriptor.DstSelXYZW() : DstSel(4, 5, 6, 7),
|
||||
.zero_stride_oob = descriptor.OutOfBounds() == 0u && stride == 0u,
|
||||
});
|
||||
}
|
||||
snapshot.images.resize(program.info.images.size());
|
||||
specialization.images.resize(program.info.images.size());
|
||||
@@ -1088,19 +1086,20 @@ void ApplyResourceSpecialization(Program& program, const ResourceSpecialization&
|
||||
EXIT_IF(program.info.buffers.size() != specialization.buffers.size() ||
|
||||
program.info.images.size() > specialization.images.size());
|
||||
|
||||
auto buffers = program.info.buffers;
|
||||
auto& buffers = program.info.buffers;
|
||||
for (size_t index = 0; index < buffers.size(); index++) {
|
||||
buffers[index].packed_stride = specialization.buffers[index].packed_stride;
|
||||
buffers[index].descriptor_format = specialization.buffers[index].descriptor_format;
|
||||
buffers[index].descriptor_swizzle = specialization.buffers[index].descriptor_swizzle;
|
||||
}
|
||||
auto images = program.info.images;
|
||||
auto& images = program.info.images;
|
||||
const auto original_image_count = images.size();
|
||||
images.reserve(specialization.images.size());
|
||||
for (uint32_t index = 0; index < specialization.images.size(); index++) {
|
||||
const auto& source = specialization.images[index];
|
||||
if (index >= images.size()) {
|
||||
EXIT_IF(source.indirect_root >= program.info.images.size());
|
||||
images.push_back(program.info.images[source.indirect_root]);
|
||||
EXIT_IF(source.indirect_root >= original_image_count);
|
||||
images.push_back(images[source.indirect_root]);
|
||||
}
|
||||
auto& image = images[index];
|
||||
image.numeric_class = source.numeric_class;
|
||||
@@ -1124,13 +1123,14 @@ void ApplyResourceSpecialization(Program& program, const ResourceSpecialization&
|
||||
|
||||
SamplerPlan sampler_plan;
|
||||
EXIT_IF(!BuildSamplerPlan(program.info, images, sampler_plan));
|
||||
auto samplers = program.info.samplers;
|
||||
auto sampled_pairs = program.info.sampled_pairs;
|
||||
auto& samplers = program.info.samplers;
|
||||
auto& sampled_pairs = program.info.sampled_pairs;
|
||||
const auto original_sampler_count = samplers.size();
|
||||
samplers.reserve(sampler_plan.sampler_count);
|
||||
for (uint32_t index = 0; index < sampler_plan.sampler_count; index++) {
|
||||
const auto& binding = sampler_plan.bindings[index];
|
||||
if (index >= program.info.samplers.size()) {
|
||||
samplers.push_back(program.info.samplers[binding.source]);
|
||||
if (index >= original_sampler_count) {
|
||||
samplers.push_back(samplers[binding.source]);
|
||||
}
|
||||
samplers[index].force_point_filtering = binding.type == SamplerClass::PointInteger;
|
||||
samplers[index].integer_border = binding.type != SamplerClass::Float;
|
||||
@@ -1142,11 +1142,15 @@ void ApplyResourceSpecialization(Program& program, const ResourceSpecialization&
|
||||
samplers[pair.sampler].depth_compare |= images[pair.image].depth_compare;
|
||||
}
|
||||
|
||||
auto memory_info = program.memory_info;
|
||||
auto& memory_info = program.memory_info;
|
||||
const ImageRemap image_remap(specialization);
|
||||
for (auto* block: program.blocks) {
|
||||
for (auto it = block->begin(); it != block->end(); ++it) {
|
||||
auto& inst = *it;
|
||||
if (inst.GetOpcode() == ValueOpcode::GetImageResource) {
|
||||
inst.SetFlags(image_remap[inst.Flags<uint32_t>()]);
|
||||
continue;
|
||||
}
|
||||
if (BufferAccessOf(inst.GetOpcode()) == BufferAccess::Read) {
|
||||
const auto& memory = memory_info[inst.Flags<MemoryFlags>().index];
|
||||
if (memory.kind == ResourceKind::Buffer &&
|
||||
@@ -1217,7 +1221,7 @@ void ApplyResourceSpecialization(Program& program, const ResourceSpecialization&
|
||||
continue;
|
||||
}
|
||||
if (image_opcode.needs_sampler &&
|
||||
memory.sampler < program.info.samplers.size()) {
|
||||
memory.sampler < original_sampler_count) {
|
||||
const auto type = static_cast<uint32_t>(ClassifySampler(image));
|
||||
memory.sampler = sampler_plan.mapping[memory.sampler][type];
|
||||
EXIT_IF(memory.sampler == UINT32_MAX);
|
||||
@@ -1226,13 +1230,6 @@ void ApplyResourceSpecialization(Program& program, const ResourceSpecialization&
|
||||
inst.GetOpcode() != ValueOpcode::ImageSampleRaw);
|
||||
}
|
||||
}
|
||||
for (auto* block: program.blocks) {
|
||||
for (auto& inst: *block) {
|
||||
if (inst.GetOpcode() == ValueOpcode::GetImageResource) {
|
||||
inst.SetFlags(image_remap[inst.Flags<uint32_t>()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto& memory: memory_info) {
|
||||
if (memory.kind == ResourceKind::Image && !memory.planning_only) {
|
||||
memory.resource = image_remap[memory.resource];
|
||||
@@ -1255,11 +1252,6 @@ void ApplyResourceSpecialization(Program& program, const ResourceSpecialization&
|
||||
}
|
||||
}
|
||||
image_remap.Apply(images);
|
||||
program.info.buffers = std::move(buffers);
|
||||
program.info.images = std::move(images);
|
||||
program.info.samplers = std::move(samplers);
|
||||
program.info.sampled_pairs = std::move(sampled_pairs);
|
||||
program.memory_info = std::move(memory_info);
|
||||
}
|
||||
|
||||
} // namespace Libs::Graphics::ShaderRecompiler::IR
|
||||
|
||||
Reference in New Issue
Block a user