mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 03:16:54 +02:00
shader: decode packed UNorm image loads through shared conversion
Co-authored-by: fxpw <fxpw@outlook.com>
This commit is contained in:
@@ -220,6 +220,10 @@ uint32_t ResultVector(ValueEmitContext& ctx, uint32_t value,
|
||||
Prospero::TextureNumericClass numeric_class, bool dref,
|
||||
const IR::MemoryInfo& mem, bool gather = false) {
|
||||
auto value_class = numeric_class;
|
||||
const auto conversion = ctx.state.program.info.images[mem.resource].conversion_format;
|
||||
if (conversion != Prospero::BufferFormat::kInvalid) {
|
||||
value_class = Prospero::SampledTextureNumericClass(conversion);
|
||||
}
|
||||
if (dref) {
|
||||
value_class = Prospero::TextureNumericClass::Float;
|
||||
}
|
||||
@@ -425,6 +429,8 @@ uint32_t UnpackImageTexel(ValueEmitContext& ctx, const IR::MemoryInfo& mem, uint
|
||||
if (info.packed_bitfield) {
|
||||
components[component] =
|
||||
ExtractPackedImageComponent(ctx.state, info, packed, scalar_type, component);
|
||||
components[component] =
|
||||
NormalizeFormatComponent(ctx.state, info, component, components[component]);
|
||||
} else {
|
||||
components[component] = ctx.state.builder.AllocateId();
|
||||
ctx.state.builder.AddFunction(spv::OpCompositeExtract, scalar_type,
|
||||
@@ -443,8 +449,9 @@ uint32_t UnpackImageTexel(ValueEmitContext& ctx, const IR::MemoryInfo& mem, uint
|
||||
for (uint32_t component = 0; component < 4u; component++) {
|
||||
const auto selector = (swizzle >> (component * 3u)) & 7u;
|
||||
if (selector == 1u) {
|
||||
selected[component] = info.packed_bitfield ? ConstantU32(ctx.state, 1u)
|
||||
: ConstantF32Value(ctx.state, 1.0f);
|
||||
selected[component] = info.packed_bitfield
|
||||
? ConstantU32(ctx.state, Format::FormattedConstantBits(info, Format::FormattedSourceKind::One))
|
||||
: ConstantF32Value(ctx.state, 1.0f);
|
||||
} else if (selector >= 4u) {
|
||||
selected[component] = components[selector - 4u];
|
||||
} else {
|
||||
@@ -456,7 +463,8 @@ uint32_t UnpackImageTexel(ValueEmitContext& ctx, const IR::MemoryInfo& mem, uint
|
||||
ctx.state.builder.AddFunction(spv::OpCompositeConstruct,
|
||||
ImageVectorType(ctx.state, numeric_class, 4), result, selected[0],
|
||||
selected[1], selected[2], selected[3]);
|
||||
return result;
|
||||
return info.type == Format::ComponentType::Unorm
|
||||
? Unary(ctx.state, spv::OpBitcast, TypeF32Vector(ctx.state, 4), result) : result;
|
||||
}
|
||||
|
||||
uint32_t UnpackImageGather(ValueEmitContext& ctx, const IR::MemoryInfo& mem, uint32_t gathered) {
|
||||
@@ -840,7 +848,7 @@ void EmitImage(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
ctx.Define(inst, QueryDimensions(ctx, mem, *address));
|
||||
return;
|
||||
}
|
||||
if (image.resource_class == IR::ImageResourceClass::Sampled &&
|
||||
if (image_info.needs_sampler &&
|
||||
image.conversion_format == Prospero::BufferFormat::k11_11_10UNorm) {
|
||||
if (op != IR::ValueOpcode::ImageSampleRaw ||
|
||||
image.dimension != ImageDimension::Dim2D ||
|
||||
|
||||
@@ -716,7 +716,9 @@ static bool BuildResourceSpecialization(const ResourcePlan& program, ResourceSna
|
||||
if (image.indirect_root != ImageResource::NoIndirectImage) {
|
||||
return SpecializationFail("packed UNorm sampling requires a direct image");
|
||||
}
|
||||
if (!ValidatePackedUnormSampling(program, snapshot, i)) return false;
|
||||
if (std::ranges::any_of(program.info.sampled_pairs,
|
||||
[&](const auto& pair) { return pair.image == i; }) &&
|
||||
!ValidatePackedUnormSampling(program, snapshot, i)) return false;
|
||||
}
|
||||
if (storage) {
|
||||
if ((!raw_sint_storage && image.numeric_class == Prospero::TextureNumericClass::Sint) ||
|
||||
|
||||
@@ -34986,6 +34986,36 @@ TestCase ImageLoadPackedUintUnpacksAndSwizzles() {
|
||||
return test;
|
||||
}
|
||||
|
||||
template <bool d16, bool sparse> TestCase ImageLoadPackedUnorm() {
|
||||
TestCase test;
|
||||
test.opcodes = {ShaderOpcode::V_MOV_B32, ShaderOpcode::IMAGE_LOAD,
|
||||
ShaderOpcode::BUFFER_STORE_DWORD, ShaderOpcode::S_ENDPGM};
|
||||
test.name = d16 ? (sparse ? "ImageLoadPackedUnormD16Sparse" : "ImageLoadPackedUnormD16")
|
||||
: (sparse ? "ImageLoadPackedUnormSparse" : "ImageLoadPackedUnorm");
|
||||
AppendVMovU32(&test.code, 20, 2u);
|
||||
AppendVMovU32(&test.code, 21, 1u);
|
||||
test.code.push_back(EncodeMimg0(0x00u, sparse ? 0x5u : 0xfu));
|
||||
test.code.push_back(EncodeMimg1(0, 20, 0, 0, false, d16));
|
||||
constexpr u32 words = (sparse ? 2u : 4u) / (d16 ? 2u : 1u);
|
||||
for (u32 word = 0; word < words; ++word) AppendStoreVgpr(&test.code, word, word);
|
||||
AppendEnd(&test.code);
|
||||
test.sampled_image_rgba.assign(16, 0u);
|
||||
test.sampled_image_rgba[6] = (1024u << 11u) | (1023u << 22u);
|
||||
test.sampled_image_format = vk::Format::eR32Uint;
|
||||
test.sampled_image_dwords_per_pixel = 1;
|
||||
test.user_data = MakeSampledTextureData(Prospero::BufferFormat::k11_11_10UNorm);
|
||||
test.has_user_data = true;
|
||||
test.image_descriptor_swizzle = sparse ? DstSel(1, 4, 5, 0) : DstSel(6, 5, 4, 7);
|
||||
const u32 green = std::bit_cast<u32>(1024.0f * (1.0f / 2047.0f));
|
||||
test.expected = d16 ? std::vector<u32>{0x38013c00u, 0u}
|
||||
: std::vector<u32>{0x3f800000u, green, 0u, 0u};
|
||||
test.expected.resize(words);
|
||||
test.required_spirv = {"OpImageFetch %v4uint", "OpBitFieldUExtract", "OpConvertUToF"};
|
||||
if constexpr (d16) test.required_spirv.emplace_back("PackHalf2x16");
|
||||
test.forbidden_spirv = {"OpTypeSampler", "OpImageGather"};
|
||||
return test;
|
||||
}
|
||||
|
||||
TestCase ImageSamplePackedUintConvertsSampleAndGather() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
@@ -39429,6 +39459,10 @@ std::vector<TestCase> MakeCases() {
|
||||
AddCase(ImageLoadFmaskUsesNativeSampleMapping);
|
||||
AddCase(ImageLoadR32SintUsesSignedSampledImage);
|
||||
AddCase(ImageLoadPackedUintUnpacksAndSwizzles);
|
||||
AddCase(ImageLoadPackedUnorm<false, false>);
|
||||
AddCase(ImageLoadPackedUnorm<false, true>);
|
||||
AddCase(ImageLoadPackedUnorm<true, false>);
|
||||
AddCase(ImageLoadPackedUnorm<true, true>);
|
||||
AddCase(ImageSamplePackedUintConvertsSampleAndGather);
|
||||
AddCase(ImageSamplePackedUnormBilinear<false>);
|
||||
AddCase(ImageSamplePackedUnormBilinear<true>);
|
||||
@@ -45078,6 +45112,10 @@ int main(int argc, char **argv) {
|
||||
vulkan.CheckPackedTextureComponents();
|
||||
vulkan.CheckBgra16Readback();
|
||||
RunCase(&vulkan, ImageLoadPackedUintUnpacksAndSwizzles());
|
||||
RunCase(&vulkan, ImageLoadPackedUnorm<false, false>());
|
||||
RunCase(&vulkan, ImageLoadPackedUnorm<false, true>());
|
||||
RunCase(&vulkan, ImageLoadPackedUnorm<true, false>());
|
||||
RunCase(&vulkan, ImageLoadPackedUnorm<true, true>());
|
||||
RunCase(&vulkan, ImageSamplePackedUintConvertsSampleAndGather());
|
||||
RunCase(&vulkan, ImageSamplePackedUnormBilinear<false>());
|
||||
RunCase(&vulkan, ImageSamplePackedUnormBilinear<true>());
|
||||
|
||||
Reference in New Issue
Block a user