test(agc): pin R10_G11_B11 float image edge values
Store: negative, -0, NaN (quiet and low-payload), +-Inf, overflow to the largest finite value, truncation and small-float denormals. Load: Inf, denormal and largest finite codes. Values measured on gfx1035. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
ede33d56e2
commit
61fbade375
|
|
@ -253,6 +253,22 @@ void CheckStore(AgcDriver::VulkanDevice& device, std::uint8_t* texels, std::span
|
|||
|
||||
constexpr std::array<float, 11> FloatValues{0.0f, 1.0f, 0.5f, 2.0f, 0.25f, 3.0f, 1.5f, 10.0f, 0.75f, 6.5f, 0.125f};
|
||||
|
||||
constexpr std::array<std::array<std::uint32_t, 4>, 7> FloatStoreEdges{{
|
||||
{0xbf800000u, 0x80000000u, 0x7fc00000u, 0xfc000000u},
|
||||
{0x7f800000u, 0x7149f2cau, 0x477fff00u, 0xf7feffe0u},
|
||||
{0x3f830000u, 0x3f818000u, 0x35800000u, 0x002f01e0u},
|
||||
{0x00000001u, 0xff800000u, 0xffc00000u, 0xfc000000u},
|
||||
{0x477c0000u, 0x4788b800u, 0x33000000u, 0x001effdfu},
|
||||
{0x36400000u, 0x477e0000u, 0x3dcccccdu, 0x5cdefc01u},
|
||||
{0x7f800001u, 0x7f810000u, 0x7fa00000u, 0xfa1f07e1u},
|
||||
}};
|
||||
|
||||
constexpr std::array<std::array<std::uint32_t, 4>, 3> FloatLoadEdges{{
|
||||
{0x3e0u | (0x7c0u << 10u) | (0x03fu << 21u), 0x7f800000u, 0x7f800000u, 0x387c0000u},
|
||||
{0x001u | (0x041u << 10u) | (0x7bfu << 21u), 0x36000000u, 0x38820000u, 0x477e0000u},
|
||||
{0x3dfu | (0x001u << 10u), 0x477c0000u, 0x35800000u, 0x00000000u},
|
||||
}};
|
||||
|
||||
std::uint32_t SmallFloat(float value, std::uint32_t mantissaBits) {
|
||||
if (value == 0.0f) return 0u;
|
||||
const auto bits = std::bit_cast<std::uint32_t>(value);
|
||||
|
|
@ -266,15 +282,18 @@ std::uint32_t FloatTexel(std::uint32_t index) {
|
|||
|
||||
void CheckFloatLoad(AgcDriver::VulkanDevice& device, std::uint8_t* texels) {
|
||||
for (std::uint32_t index = 0; index < LoadWidth; ++index) {
|
||||
const auto texel = FloatTexel(index);
|
||||
const auto texel = index < FloatLoadEdges.size() ? FloatLoadEdges[index][0] : FloatTexel(index);
|
||||
std::memcpy(texels + index * 4u, &texel, 4u);
|
||||
}
|
||||
Run(device, LoadXyzw, TextureDescriptor(texels, FloatFormat, SwizzleXYZ1, LoadWidth), {}, LoadGroups);
|
||||
for (std::uint32_t index = 0; index < LoadWidth; ++index) {
|
||||
const std::array<float, 4> expected{FloatValues[index % 11u], FloatValues[(index + 4u) % 11u], FloatValues[(index + 8u) % 11u], 1.0f};
|
||||
std::array<std::uint32_t, 4> expected{std::bit_cast<std::uint32_t>(FloatValues[index % 11u]), std::bit_cast<std::uint32_t>(FloatValues[(index + 4u) % 11u]), std::bit_cast<std::uint32_t>(FloatValues[(index + 8u) % 11u]), std::bit_cast<std::uint32_t>(1.0f)};
|
||||
if (index < FloatLoadEdges.size()) {
|
||||
expected = {FloatLoadEdges[index][1], FloatLoadEdges[index][2], FloatLoadEdges[index][3], std::bit_cast<std::uint32_t>(1.0f)};
|
||||
}
|
||||
for (std::uint32_t component = 0; component < 4u; ++component) {
|
||||
const auto actual = Output[index * 4u + component];
|
||||
Require(actual == std::bit_cast<std::uint32_t>(expected[component]), "image_load of R10_G11_B11_FLOAT: texel " + std::to_string(index) + " component " + std::to_string(component) + " is " + Hex(actual) + ", expected " + Hex(std::bit_cast<std::uint32_t>(expected[component])));
|
||||
Require(actual == expected[component], "image_load of R10_G11_B11_FLOAT: texel " + std::to_string(index) + " component " + std::to_string(component) + " is " + Hex(actual) + ", expected " + Hex(expected[component]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -286,6 +305,11 @@ void CheckFloatStore(AgcDriver::VulkanDevice& device, std::uint8_t* texels) {
|
|||
Input[tid * 4u + 0u] = std::bit_cast<std::uint32_t>(FloatValues[tid % 11u]);
|
||||
Input[tid * 4u + 1u] = std::bit_cast<std::uint32_t>(FloatValues[(tid + 4u) % 11u]);
|
||||
Input[tid * 4u + 2u] = std::bit_cast<std::uint32_t>(FloatValues[(tid + 8u) % 11u]);
|
||||
if (tid < FloatStoreEdges.size()) {
|
||||
for (std::uint32_t component = 0; component < 3u; ++component) {
|
||||
Input[tid * 4u + component] = FloatStoreEdges[tid][component];
|
||||
}
|
||||
}
|
||||
}
|
||||
Run(device, StoreXyz, TextureDescriptor(texels, FloatFormat, SwizzleXYZ1, Threads), BufferDescriptor(Input.data(), static_cast<std::uint32_t>(Input.size() * 4u)), 1);
|
||||
AgcDriver::Graphics::StorageTexture::FlushPending(reinterpret_cast<std::uintptr_t>(texels), Threads * 4u, nullptr, "test");
|
||||
|
|
@ -293,7 +317,8 @@ void CheckFloatStore(AgcDriver::VulkanDevice& device, std::uint8_t* texels) {
|
|||
for (std::uint32_t tid = 0; tid < Threads; ++tid) {
|
||||
std::uint32_t actual = 0;
|
||||
std::memcpy(&actual, texels + tid * 4u, 4u);
|
||||
Require(actual == FloatTexel(tid), "image_store of R10_G11_B11_FLOAT: texel " + std::to_string(tid) + " is " + Hex(actual) + ", expected " + Hex(FloatTexel(tid)));
|
||||
const auto expected = tid < FloatStoreEdges.size() ? FloatStoreEdges[tid][3] : FloatTexel(tid);
|
||||
Require(actual == expected, "image_store of R10_G11_B11_FLOAT: texel " + std::to_string(tid) + " is " + Hex(actual) + ", expected " + Hex(expected));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue