mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-24 04:46:56 +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,
|
static bool BuildResourceSpecialization(const ResourcePlan& program, ResourceSnapshot& snapshot,
|
||||||
ResourceSpecialization& specialization) {
|
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++) {
|
for (uint32_t i = 0; i < specialization.images.size(); i++) {
|
||||||
const auto& descriptor = snapshot.images[i];
|
const auto& descriptor = snapshot.images[i];
|
||||||
auto& image = specialization.images[i];
|
auto& image = specialization.images[i];
|
||||||
@@ -1029,11 +999,39 @@ bool MaterializeResources(const ResourcePlan& program, const SrtRuntime& runtime
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
snapshot.buffers.resize(program.info.buffers.size());
|
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) {
|
for (uint32_t i = 0; i < program.info.buffers.size(); ++i) {
|
||||||
if (!evaluate(program.info.buffers[i].source, snapshot.buffers[i],
|
if (!evaluate(program.info.buffers[i].source, snapshot.buffers[i],
|
||||||
program.info.buffers[i].written)) {
|
program.info.buffers[i].written)) {
|
||||||
return false;
|
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());
|
snapshot.images.resize(program.info.images.size());
|
||||||
specialization.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() ||
|
EXIT_IF(program.info.buffers.size() != specialization.buffers.size() ||
|
||||||
program.info.images.size() > specialization.images.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++) {
|
for (size_t index = 0; index < buffers.size(); index++) {
|
||||||
buffers[index].packed_stride = specialization.buffers[index].packed_stride;
|
buffers[index].packed_stride = specialization.buffers[index].packed_stride;
|
||||||
buffers[index].descriptor_format = specialization.buffers[index].descriptor_format;
|
buffers[index].descriptor_format = specialization.buffers[index].descriptor_format;
|
||||||
buffers[index].descriptor_swizzle = specialization.buffers[index].descriptor_swizzle;
|
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());
|
images.reserve(specialization.images.size());
|
||||||
for (uint32_t index = 0; index < specialization.images.size(); index++) {
|
for (uint32_t index = 0; index < specialization.images.size(); index++) {
|
||||||
const auto& source = specialization.images[index];
|
const auto& source = specialization.images[index];
|
||||||
if (index >= images.size()) {
|
if (index >= images.size()) {
|
||||||
EXIT_IF(source.indirect_root >= program.info.images.size());
|
EXIT_IF(source.indirect_root >= original_image_count);
|
||||||
images.push_back(program.info.images[source.indirect_root]);
|
images.push_back(images[source.indirect_root]);
|
||||||
}
|
}
|
||||||
auto& image = images[index];
|
auto& image = images[index];
|
||||||
image.numeric_class = source.numeric_class;
|
image.numeric_class = source.numeric_class;
|
||||||
@@ -1124,13 +1123,14 @@ void ApplyResourceSpecialization(Program& program, const ResourceSpecialization&
|
|||||||
|
|
||||||
SamplerPlan sampler_plan;
|
SamplerPlan sampler_plan;
|
||||||
EXIT_IF(!BuildSamplerPlan(program.info, images, sampler_plan));
|
EXIT_IF(!BuildSamplerPlan(program.info, images, sampler_plan));
|
||||||
auto samplers = program.info.samplers;
|
auto& samplers = program.info.samplers;
|
||||||
auto sampled_pairs = program.info.sampled_pairs;
|
auto& sampled_pairs = program.info.sampled_pairs;
|
||||||
|
const auto original_sampler_count = samplers.size();
|
||||||
samplers.reserve(sampler_plan.sampler_count);
|
samplers.reserve(sampler_plan.sampler_count);
|
||||||
for (uint32_t index = 0; index < sampler_plan.sampler_count; index++) {
|
for (uint32_t index = 0; index < sampler_plan.sampler_count; index++) {
|
||||||
const auto& binding = sampler_plan.bindings[index];
|
const auto& binding = sampler_plan.bindings[index];
|
||||||
if (index >= program.info.samplers.size()) {
|
if (index >= original_sampler_count) {
|
||||||
samplers.push_back(program.info.samplers[binding.source]);
|
samplers.push_back(samplers[binding.source]);
|
||||||
}
|
}
|
||||||
samplers[index].force_point_filtering = binding.type == SamplerClass::PointInteger;
|
samplers[index].force_point_filtering = binding.type == SamplerClass::PointInteger;
|
||||||
samplers[index].integer_border = binding.type != SamplerClass::Float;
|
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;
|
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);
|
const ImageRemap image_remap(specialization);
|
||||||
for (auto* block: program.blocks) {
|
for (auto* block: program.blocks) {
|
||||||
for (auto it = block->begin(); it != block->end(); ++it) {
|
for (auto it = block->begin(); it != block->end(); ++it) {
|
||||||
auto& inst = *it;
|
auto& inst = *it;
|
||||||
|
if (inst.GetOpcode() == ValueOpcode::GetImageResource) {
|
||||||
|
inst.SetFlags(image_remap[inst.Flags<uint32_t>()]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (BufferAccessOf(inst.GetOpcode()) == BufferAccess::Read) {
|
if (BufferAccessOf(inst.GetOpcode()) == BufferAccess::Read) {
|
||||||
const auto& memory = memory_info[inst.Flags<MemoryFlags>().index];
|
const auto& memory = memory_info[inst.Flags<MemoryFlags>().index];
|
||||||
if (memory.kind == ResourceKind::Buffer &&
|
if (memory.kind == ResourceKind::Buffer &&
|
||||||
@@ -1217,7 +1221,7 @@ void ApplyResourceSpecialization(Program& program, const ResourceSpecialization&
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (image_opcode.needs_sampler &&
|
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));
|
const auto type = static_cast<uint32_t>(ClassifySampler(image));
|
||||||
memory.sampler = sampler_plan.mapping[memory.sampler][type];
|
memory.sampler = sampler_plan.mapping[memory.sampler][type];
|
||||||
EXIT_IF(memory.sampler == UINT32_MAX);
|
EXIT_IF(memory.sampler == UINT32_MAX);
|
||||||
@@ -1226,13 +1230,6 @@ void ApplyResourceSpecialization(Program& program, const ResourceSpecialization&
|
|||||||
inst.GetOpcode() != ValueOpcode::ImageSampleRaw);
|
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) {
|
for (auto& memory: memory_info) {
|
||||||
if (memory.kind == ResourceKind::Image && !memory.planning_only) {
|
if (memory.kind == ResourceKind::Image && !memory.planning_only) {
|
||||||
memory.resource = image_remap[memory.resource];
|
memory.resource = image_remap[memory.resource];
|
||||||
@@ -1255,11 +1252,6 @@ void ApplyResourceSpecialization(Program& program, const ResourceSpecialization&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
image_remap.Apply(images);
|
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
|
} // namespace Libs::Graphics::ShaderRecompiler::IR
|
||||||
|
|||||||
Reference in New Issue
Block a user