gpu: enable native R8 SNORM texture sampling

This commit is contained in:
nmzik 2026-10-11 00:00:23 +02:00
parent b7b335ac63
commit 7e4e142aae
2 changed files with 34 additions and 20 deletions

View File

@ -21,7 +21,7 @@ struct FormatInfo {
constexpr FormatInfo kFormatInfo[] = {
{BufferFormat::k8UNorm, 1, 0, 1, true, false},
{BufferFormat::k8UScaled, 1, 0, 0, true, false},
{BufferFormat::k8SNorm, 1, 0, 1, false, false},
{BufferFormat::k8SNorm, 1, 0, 1, true, false},
{BufferFormat::k8UInt, 1, 0, 1, true, true},
{BufferFormat::k16UNorm, 2, 0, 2, true, false},
{BufferFormat::k16SNorm, 2, 0, 2, true, false},

View File

@ -34170,10 +34170,11 @@ TestCase ImageSamplePackedUintConvertsSampleAndGather() {
return test;
}
template <bool rg> TestCase ImageSampleUScaled8() {
template <bool rg, bool snorm = false> TestCase ImageSamplePacked8() {
using O = ShaderOpcode;
TestCase test;
test.name = rg ? "ImageSampleRG8UScaled" : "ImageSampleR8UScaled";
test.name = snorm ? "ImageSampleR8SNorm"
: rg ? "ImageSampleRG8UScaled" : "ImageSampleR8UScaled";
AppendVMovLiteral(&test.code, 20, std::bit_cast<u32>(0.375f));
AppendVMovLiteral(&test.code, 21, std::bit_cast<u32>(0.375f));
test.code.push_back(EncodeMimg0(0x20, 0xf));
@ -34186,26 +34187,37 @@ template <bool rg> TestCase ImageSampleUScaled8() {
AppendStoreVgpr(&test.code, component, component);
}
AppendEnd(&test.code);
// R varies horizontally; G varies vertically in the opposite direction.
// Bilinear samples must retain fractions despite host UNorm filter precision.
test.image_width = test.image_height = 2;
test.sampled_image_rgba = rg ? std::vector<u32>{0xffffff00u, 0x00ff0000u}
: std::vector<u32>{0xff00ff00u};
test.sampled_image_format = rg ? vk::Format::eR8G8Unorm : vk::Format::eR8Unorm;
test.sampled_image_rgba =
snorm ? std::vector<u32>{0x7fc08180u}
: rg ? std::vector<u32>{0xffffff00u, 0x00ff0000u}
: std::vector<u32>{0xff00ff00u};
test.sampled_image_format =
snorm ? vk::Format::eR8Snorm
: rg ? vk::Format::eR8G8Unorm : vk::Format::eR8Unorm;
test.sampled_image_dwords_per_pixel = 1;
test.sampler_filter = vk::Filter::eLinear;
test.expected_float_tolerance = 0.01f;
test.user_data = MakeSampledTextureData(rg ? Prospero::BufferFormat::k8_8UScaled
: Prospero::BufferFormat::k8UScaled);
test.sampler_filter = snorm ? vk::Filter::eNearest : vk::Filter::eLinear;
test.expected_float_tolerance = snorm ? 0.00002f : 0.01f;
test.user_data = MakeSampledTextureData(
snorm ? Prospero::BufferFormat::k8SNorm
: rg ? Prospero::BufferFormat::k8_8UScaled
: Prospero::BufferFormat::k8UScaled);
test.user_data[1] |= 1u << 30u;
test.user_data[2] = 1u << 14u;
test.user_data[50] = 12u * sizeof(u32);
test.user_data[51] = 3u << 28u;
test.has_user_data = true;
test.image_descriptor_swizzle = DstSel(rg ? 5 : 4, 4, 0, 1);
for (float value : {rg ? 191.25f : 63.75f, 63.75f, 0.0f, 1.0f,
0.0f, rg ? 0.0f : 255.0f, 255.0f, rg ? 255.0f : 0.0f,
1.0f, 1.0f, 1.0f, 1.0f}) {
test.image_descriptor_swizzle = snorm ? DstSel(4, 5, 6, 7)
: DstSel(rg ? 5 : 4, 4, 0, 1);
constexpr float midpoint = -64.0f / 127.0f;
const std::array<float, 12> expected = snorm
// -128 and -127 both clamp to -1; the interior signed value normalizes by 127.
? std::array<float, 12>{-1, 0, 0, 1, midpoint, 1, -1, -1, 1, 1, 1, 1}
// R varies horizontally; G varies vertically in the opposite direction.
: std::array<float, 12>{rg ? 191.25f : 63.75f, 63.75f, 0.0f, 1.0f,
0.0f, rg ? 0.0f : 255.0f, 255.0f, rg ? 255.0f : 0.0f,
1.0f, 1.0f, 1.0f, 1.0f};
for (float value : expected) {
test.expected.push_back(std::bit_cast<u32>(value));
}
test.opcodes = {O::V_MOV_B32, O::IMAGE_SAMPLE, O::IMAGE_GATHER4_LZ,
@ -37565,8 +37577,9 @@ std::vector<TestCase> MakeCases() {
AddCase(ImageLoadR32SintUsesSignedSampledImage);
AddCase(ImageLoadPackedUintUnpacksAndSwizzles);
AddCase(ImageSamplePackedUintConvertsSampleAndGather);
AddCase(ImageSampleUScaled8<false>);
AddCase(ImageSampleUScaled8<true>);
AddCase(ImageSamplePacked8<false>);
AddCase(ImageSamplePacked8<true>);
AddCase(ImageSamplePacked8<false, true>);
AddCase(ImageLoadR128IgnoresAdjacentMaskSgprs);
AddCase(ImageLoad1DUsesScalarCoordinate);
AddCase(ImageGather2DInstructionWith1DDescriptor);
@ -43136,8 +43149,9 @@ int main(int argc, char **argv) {
}
if (argc == 2 && std::strcmp(argv[1], "--scaled-texture-only") == 0) {
VulkanHarness vulkan;
RunCase(&vulkan, ImageSampleUScaled8<false>());
RunCase(&vulkan, ImageSampleUScaled8<true>());
RunCase(&vulkan, ImageSamplePacked8<false>());
RunCase(&vulkan, ImageSamplePacked8<true>());
RunCase(&vulkan, ImageSamplePacked8<false, true>());
return 0;
}
if (argc == 2 && std::strcmp(argv[1], "--packed-texture-only") == 0) {