mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-22 11:56:58 +02:00
Honor explicit gather LOD with shared image mip selection
Co-authored-by: YuhiAida <21134775+YuhiAida@users.noreply.github.com> Co-authored-by: BlackCAT <52720489+psnwd@users.noreply.github.com> Co-authored-by: shadowbeat070 <70843316+shadowbeat070@users.noreply.github.com> Co-authored-by: Senaxx <michelbeld@gmail.com> Co-authored-by: Mac <me@itsmemac.com> Co-authored-by: Ali Almohaya <AliAlmohaya@gmail.com>
This commit is contained in:
@@ -114,7 +114,7 @@ struct BufferResource {
|
||||
bool operator==(const BufferResource& other) const = default;
|
||||
};
|
||||
|
||||
enum class ImageMipMode { None, DynamicStorage };
|
||||
enum class ImageMipMode { None, Dynamic };
|
||||
|
||||
constexpr uint32_t ShaderImageIdentitySwizzle = 0x00000facu;
|
||||
|
||||
@@ -151,6 +151,7 @@ struct SamplerResource {
|
||||
bool force_point_filtering = false;
|
||||
bool depth_compare = false;
|
||||
bool integer_border = false;
|
||||
bool gather_lod = false;
|
||||
|
||||
bool operator==(const SamplerResource& other) const = default;
|
||||
};
|
||||
|
||||
@@ -297,7 +297,7 @@ VALUE_OPCODE(ImageQueryLod, U32x4, ImageResource, SamplerResource, ImageAddress)
|
||||
VALUE_OPCODE(ImageRead, U32x4, ImageResource, ImageAddress, U1)
|
||||
VALUE_OPCODE(ImageWrite, Void, ImageResource, ImageAddress, U32x4, U1)
|
||||
VALUE_OPCODE(ImageSampleRaw, U32x4, ImageResource, SamplerResource, ImageAddress)
|
||||
VALUE_OPCODE(ImageGatherRaw, U32x4, ImageResource, SamplerResource, ImageAddress)
|
||||
VALUE_OPCODE(ImageGatherRaw, U32x4, ImageResource, SamplerResource, ImageAddress, U32, U32, U32, U32)
|
||||
VALUE_OPCODE(ImageAtomicCompareSwap32, U32, ImageResource, ImageAddress, U32, U32, U1)
|
||||
VALUE_OPCODE(ImageAtomicSwap32, U32, ImageResource, ImageAddress, U32, U1)
|
||||
VALUE_OPCODE(ImageAtomicIAdd32, U32, ImageResource, ImageAddress, U32, U1)
|
||||
|
||||
@@ -126,7 +126,7 @@ void AllocateBindings(Program& program, uint32_t push_data_start_dword) {
|
||||
EXIT("shader binding layout failed: image %u has an unmapped binding class", i);
|
||||
}
|
||||
auto& resources = image_groups[group];
|
||||
const auto dynamic = program.info.images[i].mip_mode == ImageMipMode::DynamicStorage;
|
||||
const auto dynamic = program.info.images[i].mip_mode == ImageMipMode::Dynamic;
|
||||
const auto count = dynamic ? program.info.images[i].mip_count : 1u;
|
||||
if (count == 0u || (!dynamic && program.info.images[i].mip_count != 1u)) {
|
||||
EXIT("shader binding layout failed: image %u has invalid specialized mip count %u", i,
|
||||
|
||||
@@ -124,8 +124,8 @@ bool DescriptorIsCube(const DescriptorValue& descriptor) {
|
||||
Prospero::ImageType::kCube;
|
||||
}
|
||||
|
||||
uint32_t StorageMipCount(const ImageResource& image, const DescriptorValue& descriptor) {
|
||||
if (image.mip_mode != ImageMipMode::DynamicStorage || NullImageDescriptor(descriptor)) {
|
||||
uint32_t ImageMipCount(const ImageResource& image, const DescriptorValue& descriptor) {
|
||||
if (image.mip_mode != ImageMipMode::Dynamic || NullImageDescriptor(descriptor)) {
|
||||
return 1;
|
||||
}
|
||||
const auto base = (descriptor.dwords[3] >> 12u) & 0xfu;
|
||||
@@ -435,10 +435,10 @@ static bool BuildResourceSpecialization(const ResourcePlan& program, ResourceSna
|
||||
(base.atomic && base.resource_class != ImageResourceClass::Storage)) {
|
||||
return SpecializationFail(fmt::format("image resource {} has an invalid class", i));
|
||||
}
|
||||
image.mip_count = StorageMipCount(base, descriptor);
|
||||
image.mip_count = ImageMipCount(base, descriptor);
|
||||
if (image.mip_count == 0u) {
|
||||
return SpecializationFail(
|
||||
fmt::format("storage image descriptor {} has an invalid mip range", i));
|
||||
fmt::format("image descriptor {} has an invalid mip range", i));
|
||||
}
|
||||
if (NullImageDescriptor(descriptor)) {
|
||||
image.numeric_class = base.atomic ? Prospero::TextureNumericClass::Uint
|
||||
@@ -1077,6 +1077,16 @@ bool MaterializeResources(const ResourcePlan& program, const SrtRuntime& runtime
|
||||
if (!evaluate(program.info.samplers[i].source, snapshot.samplers[i])) {
|
||||
return false;
|
||||
}
|
||||
if (program.info.samplers[i].gather_lod) {
|
||||
const auto control = snapshot.samplers[i].dwords[2];
|
||||
const auto filter = (control >> 26u) & 3u;
|
||||
// MipNone always selects the base level. Explicit point gathers currently require
|
||||
// encoded-zero primary and secondary bias; linear primary-mip selection is unsupported.
|
||||
if (filter > 1u || (filter == 1u && (control & 0xfffffu) != 0u)) {
|
||||
return SpecializationFail(
|
||||
"explicit-LOD gather requires mip filtering None or Point with zero LOD biases");
|
||||
}
|
||||
}
|
||||
}
|
||||
snapshot.user_data.assign(runtime.user_data.begin(), runtime.user_data.end());
|
||||
return BuildResourceSpecialization(program, snapshot, specialization);
|
||||
|
||||
@@ -1727,9 +1727,11 @@ private:
|
||||
const auto resource_class = ImageOpcodeInfoOf(op).resource_class;
|
||||
const bool atomic64 = ImageOpcodeInfoOf(op).access == ImageAccess::Atomic &&
|
||||
memory.data_bits == 64u;
|
||||
const auto mip = resource_class == ImageResourceClass::Storage && memory.image_has_mip
|
||||
? ImageMipMode::DynamicStorage
|
||||
: ImageMipMode::None;
|
||||
const bool dynamic_mip =
|
||||
(resource_class == ImageResourceClass::Storage && memory.image_has_mip) ||
|
||||
(op == ValueOpcode::ImageGatherRaw &&
|
||||
(memory.image_sample_flags & Decoder::ImageSampleFlagLod) != 0u);
|
||||
const auto mip = dynamic_mip ? ImageMipMode::Dynamic : ImageMipMode::None;
|
||||
const bool depth = (memory.image_sample_flags & Decoder::ImageSampleFlagCompare) != 0;
|
||||
for (uint32_t i = 0; i < m_info.images.size(); i++) {
|
||||
auto& image = m_info.images[i];
|
||||
@@ -1939,6 +1941,9 @@ private:
|
||||
if (sampler == UINT32_MAX) {
|
||||
Fail(flags.pc, "sampler resource limit exceeded");
|
||||
}
|
||||
m_info.samplers[sampler].gather_lod |=
|
||||
op == ValueOpcode::ImageGatherRaw &&
|
||||
(memory.image_sample_flags & Decoder::ImageSampleFlagLod) != 0u;
|
||||
AddHandlePatch(sampler_handle, sampler, flags.pc);
|
||||
AddSampledPair(resource, sampler, flags.pc);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user