mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
implement dynamic
This commit is contained in:
@@ -237,8 +237,14 @@ bool ValidateNativeProgram(const IR::Program& program, std::string* error) {
|
||||
if (!ImageBinding(program.info.images[i], kind)) {
|
||||
return Fail(error, "native shader plan has an invalid image class");
|
||||
}
|
||||
const auto bindings = program.info.images[i].NumBindings();
|
||||
if (bindings == 0 || bindings > IR::ImageResource::MaxMipLevels) {
|
||||
return Fail(error, "native shader plan has an invalid image descriptor count");
|
||||
}
|
||||
present[static_cast<size_t>(kind)] = true;
|
||||
expected[static_cast<size_t>(kind)].push_back(i);
|
||||
for (uint32_t binding = 0; binding < bindings; binding++) {
|
||||
expected[static_cast<size_t>(kind)].push_back(i);
|
||||
}
|
||||
}
|
||||
if (!program.info.samplers.empty()) {
|
||||
Expect(Kind::Samplers, Dense(program.info.samplers.size()));
|
||||
@@ -316,6 +322,11 @@ bool ValidateNativeProgram(const IR::Program& program, std::string* error) {
|
||||
inst.memory.image_dimension)) {
|
||||
return Fail(error, "image instruction has an invalid dense resource");
|
||||
}
|
||||
if (inst.op == IR::Opcode::ImageStore &&
|
||||
((program.info.images[inst.memory.resource].mip_mode ==
|
||||
IR::ImageMipMode::DynamicStorage) != inst.memory.image_has_mip)) {
|
||||
return Fail(error, "storage image mip mode does not match the instruction");
|
||||
}
|
||||
const bool address =
|
||||
inst.op == IR::Opcode::SLoadDword || memory == IR::ResourceKind::Flat ||
|
||||
memory == IR::ResourceKind::Global || memory == IR::ResourceKind::Scratch;
|
||||
|
||||
@@ -560,12 +560,21 @@ uint32_t DescriptorElementPointer(EmitterState& state, uint32_t result_ptr_type,
|
||||
uint32_t variable_id, uint32_t array_index,
|
||||
IR::DescriptorBindingKind kind, uint32_t resource,
|
||||
const char* variable_name) {
|
||||
return DescriptorElementPointerId(state, result_ptr_type, variable_id,
|
||||
ConstantU32(state, array_index), kind, resource,
|
||||
variable_name);
|
||||
}
|
||||
|
||||
uint32_t DescriptorElementPointerId(EmitterState& state, uint32_t result_ptr_type,
|
||||
uint32_t variable_id, uint32_t array_index_id,
|
||||
IR::DescriptorBindingKind kind, uint32_t resource,
|
||||
const char* variable_name) {
|
||||
if (variable_id == 0) {
|
||||
ExitDescriptorBindingFailure(state, kind, resource, variable_name);
|
||||
}
|
||||
const auto pointer = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{OpAccessChain, result_ptr_type, pointer, variable_id, ConstantU32(state, array_index)});
|
||||
{OpAccessChain, result_ptr_type, pointer, variable_id, array_index_id});
|
||||
return pointer;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,13 +33,13 @@ uint32_t ConstantImageGatherHorizontalOffsets(EmitterState& state, ImageViewKind
|
||||
}
|
||||
|
||||
uint32_t LoadStorageImageDescriptorAtIndex(EmitterState& state, uint32_t resource,
|
||||
uint32_t array_index, bool uint_image,
|
||||
uint32_t array_index_id, bool uint_image,
|
||||
ImageViewKind view) {
|
||||
const auto kind = StorageBindingKind(uint_image, view);
|
||||
const auto& descriptors = state.storage_images[StorageImageIndex(uint_image, view)];
|
||||
const auto pointer =
|
||||
DescriptorElementPointer(state, descriptors.pointer_type, descriptors.variable, array_index,
|
||||
kind, resource, "storage image descriptor array was not emitted");
|
||||
const auto pointer = DescriptorElementPointerId(
|
||||
state, descriptors.pointer_type, descriptors.variable, array_index_id, kind, resource,
|
||||
"storage image descriptor array was not emitted");
|
||||
const auto image = state.builder.AllocateId();
|
||||
state.builder.AddFunction({OpLoad, descriptors.image_type, image, pointer});
|
||||
return image;
|
||||
@@ -168,12 +168,38 @@ void EmitImageStore(EmitterState& state, const IR::Instruction& inst) {
|
||||
const auto view = StorageImageViewKind(state, inst.memory, uint_image, inst.pc);
|
||||
const auto binding =
|
||||
ResourceForDescriptor(state, StorageBindingKind(uint_image, view), inst.memory.resource);
|
||||
const auto image = LoadStorageImageDescriptorAtIndex(state, inst.memory.resource,
|
||||
binding.array_index, uint_image, view);
|
||||
const auto emit_write = [&](uint32_t descriptor_index, bool non_uniform) {
|
||||
if (non_uniform) {
|
||||
state.builder.AddAnnotation({OpDecorate, descriptor_index, DecorationNonUniform});
|
||||
}
|
||||
const auto image = LoadStorageImageDescriptorAtIndex(state, inst.memory.resource,
|
||||
descriptor_index, uint_image, view);
|
||||
if (non_uniform) {
|
||||
state.builder.AddAnnotation({OpDecorate, image, DecorationNonUniform});
|
||||
}
|
||||
state.builder.AddFunction({OpImageWrite, image, EmitImageCoordU32(state, inst, view),
|
||||
uint_image ? EmitImageStoreTexelU32(state, inst)
|
||||
: EmitImageStoreTexelF32(state, inst)});
|
||||
};
|
||||
if (!inst.memory.image_has_mip) {
|
||||
emit_write(ConstantU32(state, binding.array_index), false);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& resource = state.program.info.images[inst.memory.resource];
|
||||
const auto mip = EmitImageMipLodU32(state, inst, inst.src[1], view);
|
||||
const auto in_range = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{OpImageWrite, image, EmitImageCoordU32(state, inst, view),
|
||||
uint_image ? EmitImageStoreTexelU32(state, inst) : EmitImageStoreTexelF32(state, inst)});
|
||||
{OpULessThan, state.bool_type, in_range, mip, ConstantU32(state, resource.mip_levels)});
|
||||
EmitIfCondition(state, in_range, [&] {
|
||||
auto descriptor_index = mip;
|
||||
if (binding.array_index != 0) {
|
||||
descriptor_index = state.builder.AllocateId();
|
||||
state.builder.AddFunction({OpIAdd, state.uint_type, descriptor_index,
|
||||
ConstantU32(state, binding.array_index), mip});
|
||||
}
|
||||
emit_write(descriptor_index, true);
|
||||
});
|
||||
}
|
||||
|
||||
void EmitImageSampleResult(EmitterState& state, const IR::Instruction& inst, uint32_t sample,
|
||||
|
||||
@@ -23,38 +23,40 @@
|
||||
namespace Libs::Graphics::ShaderRecompiler::Spirv::Emitter {
|
||||
|
||||
enum : uint32_t {
|
||||
ExecutionModelVertex = 0,
|
||||
ExecutionModelFragment = 4,
|
||||
ExecutionModelGLCompute = 5,
|
||||
ExecutionModeOriginUpperLeft = 7,
|
||||
ExecutionModeEarlyFragmentTests = 9,
|
||||
ExecutionModeDepthReplacing = 12,
|
||||
ExecutionModeLocalSize = 17,
|
||||
ExecutionModeDerivativeGroupQuadsKHR = 5289,
|
||||
AddressingModelLogical = 0,
|
||||
MemoryModelGLSL450 = 1,
|
||||
CapabilityShader = 1,
|
||||
CapabilityImageGatherExtended = 25,
|
||||
CapabilitySampled1D = 43,
|
||||
CapabilityImage1D = 44,
|
||||
CapabilityImageQuery = 50,
|
||||
CapabilityStorageImageReadWithoutFormat = 55,
|
||||
CapabilityStorageImageWriteWithoutFormat = 56,
|
||||
CapabilityGroupNonUniform = 61,
|
||||
CapabilityGroupNonUniformBallot = 64,
|
||||
CapabilityGroupNonUniformShuffle = 65,
|
||||
CapabilityComputeDerivativeGroupQuadsKHR = 5288,
|
||||
StorageClassUniformConstant = 0,
|
||||
StorageClassInput = 1,
|
||||
StorageClassOutput = 3,
|
||||
StorageClassWorkgroup = 4,
|
||||
StorageClassFunction = 7,
|
||||
StorageClassPushConstant = 9,
|
||||
StorageClassImage = 11,
|
||||
StorageClassStorageBuffer = 12,
|
||||
FunctionControlNone = 0,
|
||||
SelectionControlNone = 0,
|
||||
LoopControlNone = 0,
|
||||
ExecutionModelVertex = 0,
|
||||
ExecutionModelFragment = 4,
|
||||
ExecutionModelGLCompute = 5,
|
||||
ExecutionModeOriginUpperLeft = 7,
|
||||
ExecutionModeEarlyFragmentTests = 9,
|
||||
ExecutionModeDepthReplacing = 12,
|
||||
ExecutionModeLocalSize = 17,
|
||||
ExecutionModeDerivativeGroupQuadsKHR = 5289,
|
||||
AddressingModelLogical = 0,
|
||||
MemoryModelGLSL450 = 1,
|
||||
CapabilityShader = 1,
|
||||
CapabilityImageGatherExtended = 25,
|
||||
CapabilitySampled1D = 43,
|
||||
CapabilityImage1D = 44,
|
||||
CapabilityImageQuery = 50,
|
||||
CapabilityStorageImageReadWithoutFormat = 55,
|
||||
CapabilityStorageImageWriteWithoutFormat = 56,
|
||||
CapabilityGroupNonUniform = 61,
|
||||
CapabilityGroupNonUniformBallot = 64,
|
||||
CapabilityGroupNonUniformShuffle = 65,
|
||||
CapabilityShaderNonUniform = 5301,
|
||||
CapabilityStorageImageArrayNonUniformIndexing = 5309,
|
||||
CapabilityComputeDerivativeGroupQuadsKHR = 5288,
|
||||
StorageClassUniformConstant = 0,
|
||||
StorageClassInput = 1,
|
||||
StorageClassOutput = 3,
|
||||
StorageClassWorkgroup = 4,
|
||||
StorageClassFunction = 7,
|
||||
StorageClassPushConstant = 9,
|
||||
StorageClassImage = 11,
|
||||
StorageClassStorageBuffer = 12,
|
||||
FunctionControlNone = 0,
|
||||
SelectionControlNone = 0,
|
||||
LoopControlNone = 0,
|
||||
};
|
||||
|
||||
enum : uint32_t {
|
||||
@@ -67,6 +69,7 @@ enum : uint32_t {
|
||||
DecorationBinding = 33,
|
||||
DecorationDescriptorSet = 34,
|
||||
DecorationOffset = 35,
|
||||
DecorationNonUniform = 5300,
|
||||
};
|
||||
|
||||
enum : uint32_t {
|
||||
@@ -679,6 +682,10 @@ uint32_t DescriptorElementPointer(EmitterState& state, uint32_t result_ptr_type,
|
||||
uint32_t variable_id, uint32_t array_index,
|
||||
IR::DescriptorBindingKind kind, uint32_t resource,
|
||||
const char* variable_name);
|
||||
uint32_t DescriptorElementPointerId(EmitterState& state, uint32_t result_ptr_type,
|
||||
uint32_t variable_id, uint32_t array_index_id,
|
||||
IR::DescriptorBindingKind kind, uint32_t resource,
|
||||
const char* variable_name);
|
||||
|
||||
ImageViewKind SampledImageViewKind(const EmitterState& state, const IR::MemoryInfo& mem,
|
||||
uint32_t use_pc);
|
||||
|
||||
@@ -484,6 +484,13 @@ void EmitHeaderAndTypes(EmitterState& state) {
|
||||
if (state.needs_image_gather_extended) {
|
||||
state.builder.AddCapability({CapabilityImageGatherExtended});
|
||||
}
|
||||
if (std::any_of(
|
||||
state.program.info.images.begin(), state.program.info.images.end(),
|
||||
[](const auto& image) { return image.mip_mode == IR::ImageMipMode::DynamicStorage; })) {
|
||||
state.builder.AddCapability({CapabilityShaderNonUniform});
|
||||
state.builder.AddCapability({CapabilityStorageImageArrayNonUniformIndexing});
|
||||
state.builder.AddExtension("SPV_EXT_descriptor_indexing");
|
||||
}
|
||||
if (std::any_of(state.storage_images.begin(),
|
||||
state.storage_images.begin() + StorageImageViewKindCount,
|
||||
[](const auto& image) { return image.variable != 0; })) {
|
||||
|
||||
Reference in New Issue
Block a user