shader: select the primary mip for linear explicit-LOD gathers

This commit is contained in:
nmzik
2026-10-18 20:50:03 +02:00
parent 8b51370ca1
commit ac3711ce7c
4 changed files with 41 additions and 23 deletions
+15 -10
View File
@@ -5177,19 +5177,24 @@ void TestGatherLodSamplerValidation() {
Libs::Graphics::Prospero::BufferFormat::k32Float) << 20u;
user_data[3] = Libs::Graphics::DstSel(4, 5, 6, 7) |
(static_cast<uint32_t>(Libs::Graphics::Prospero::ImageType::kColor2D) << 28u);
user_data[9] = 0xfff000u;
constexpr std::array sampler_controls{
0u, 0x4001u, 1u << 26u, (1u << 26u) | 256u,
(1u << 26u) | (1u << 14u), 2u << 26u, 3u << 26u};
(1u << 26u) | (1u << 14u), 2u << 26u, (2u << 26u) | 256u,
(2u << 26u) | (1u << 14u), 0x0a500000u, 0x1a500000u, 3u << 26u};
for (const auto control : sampler_controls) {
user_data[10] = control;
ResourceSnapshot snapshot;
ResourceSpecialization specialization;
const bool supported = !explicit_lod || (control >> 26u) == 0 ||
control == (1u << 26u);
Check(MaterializeResources(plan, {.user_data = user_data}, snapshot,
specialization) == supported,
"explicit gather accepted an unsupported sampler or rejected a valid one");
for (const uint32_t perf_mip : {0u, 1u}) {
user_data[9] = 0xfff000u | (perf_mip << 24u);
user_data[10] = control;
ResourceSnapshot snapshot;
ResourceSpecialization specialization;
const auto filter = (control >> 26u) & 3u;
const bool supported = !explicit_lod || filter == 0 ||
(filter <= 2 && (control & 0xfffffu) == 0 &&
(filter != 2 || perf_mip == 0));
Check(MaterializeResources(plan, {.user_data = user_data}, snapshot,
specialization) == supported,
"explicit gather accepted an unsupported sampler or rejected a valid one");
}
}
}
}
+12 -5
View File
@@ -37524,11 +37524,12 @@ template <u32 mode> TestCase ImageGatherLodPerLane() {
"ImageGatherLodSamplerBounds", "ImageGatherLodTextureMinimum",
"ImageGatherLodMipNone", "ImageGatherLodPointPostclampMaximum",
"ImageGatherLodPointPreclampMaximum", "ImageGatherLodPointPostclampMinimum",
"ImageGatherLodPointPreclampMinimum"};
"ImageGatherLodPointPreclampMinimum", "ImageGatherLodLinearPrimary",
"ImageGatherLodLinearIgnoresPreclamp"};
constexpr std::array lods = mode < 5
? std::array{-1.0f, 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 9.0f}
: std::array{-1.0f, 0.0f, 0.25f, 0.75f, 1.25f, 1.75f, 2.75f, 9.0f};
constexpr std::array<std::array<u32, 8>, 9> selected_mips{{
constexpr std::array<std::array<u32, 8>, 11> selected_mips{{
{0, 0, 1, 2, 3, 4, 4, 4},
{1, 1, 2, 3, 4, 4, 4, 4},
{2, 2, 2, 3, 3, 3, 3, 3},
@@ -37538,9 +37539,11 @@ template <u32 mode> TestCase ImageGatherLodPerLane() {
{0, 0, 0, 1, 1, 1, 1, 1},
{2, 2, 2, 2, 2, 2, 3, 4},
{1, 1, 1, 1, 1, 2, 3, 4},
{0, 0, 0, 0, 1, 1, 2, 4},
{0, 0, 0, 0, 1, 1, 2, 4},
}};
constexpr u32 lanes = lods.size();
constexpr u32 sampler_min = mode == 2 ? 256 : mode >= 7 ? 448 : 0;
constexpr u32 sampler_min = mode == 2 ? 256 : mode == 7 || mode == 8 ? 448 : 0;
constexpr u32 sampler_max = mode == 2 ? 512 : mode == 3 ? 256
: mode == 5 || mode == 6 ? 448 : 1024;
TestCase test;
@@ -37585,8 +37588,8 @@ template <u32 mode> TestCase ImageGatherLodPerLane() {
test.user_data[9] = sampler_min | (sampler_max << 12u);
// Point preclamp selects whether the half-level rounding adjustment precedes
// or follows the clamps. The streaming T# minimum follows the sampler bounds.
test.user_data[10] = mode == 4 ? 0x4001u : (1u << 26u);
if constexpr (mode == 6 || mode == 8) {
test.user_data[10] = mode == 4 ? 0x4001u : mode >= 9 ? 0x0a500000u : (1u << 26u);
if constexpr (mode == 6 || mode == 8 || mode == 10) {
test.user_data[10] |= 1u << 28u;
}
test.user_data[18] = lanes * sizeof(u32);
@@ -42828,6 +42831,8 @@ std::vector<TestCase> MakeCases() {
AddCase(ImageGatherLodPerLane<6>);
AddCase(ImageGatherLodPerLane<7>);
AddCase(ImageGatherLodPerLane<8>);
AddCase(ImageGatherLodPerLane<9>);
AddCase(ImageGatherLodPerLane<10>);
AddCase(ImageD16GatherPacksHalfPairs);
AddCase(ImageSampleA16SamplerCoordsOnGpu);
AddCase(ImageSampleOpcodeAliasUsesNormalCoords);
@@ -48658,6 +48663,8 @@ int main(int argc, char **argv) {
RunCase(&vulkan, ImageGatherLodPerLane<6>());
RunCase(&vulkan, ImageGatherLodPerLane<7>());
RunCase(&vulkan, ImageGatherLodPerLane<8>());
RunCase(&vulkan, ImageGatherLodPerLane<9>());
RunCase(&vulkan, ImageGatherLodPerLane<10>());
RunCase(&vulkan, ImageStoreSingleMipBounds<0>());
RunCase(&vulkan, ImageStoreSingleMipBounds<1>());
RunCase(&vulkan, ImageStoreSingleMipBounds<2>());