writer/hlsl: Fix level packing for textureLoad()

This was spectacularly broken. Caught by CTS.

Change-Id: Iebf9dd5934be8ef4ec4217d60d5691aee73f5ea3
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/56501
Auto-Submit: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2021-06-30 08:51:36 +00:00 committed by Tint LUCI CQ
parent b293f51f83
commit 51b9da45c8
23 changed files with 61 additions and 47 deletions

View File

@ -1663,7 +1663,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
if (!EmitExpression(out, texture)) if (!EmitExpression(out, texture))
return false; return false;
bool pack_mip_in_coords = false; bool pack_level_in_coords = false;
uint32_t hlsl_ret_width = 4u; uint32_t hlsl_ret_width = 4u;
switch (intrinsic->Type()) { switch (intrinsic->Type()) {
@ -1689,7 +1689,9 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
break; break;
case sem::IntrinsicType::kTextureLoad: case sem::IntrinsicType::kTextureLoad:
out << ".Load("; out << ".Load(";
pack_mip_in_coords = true; if (!texture_type->Is<sem::MultisampledTexture>()) {
pack_level_in_coords = true;
}
break; break;
case sem::IntrinsicType::kTextureStore: case sem::IntrinsicType::kTextureStore:
out << "["; out << "[";
@ -1723,11 +1725,20 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
return EmitExpression(out, packed); return EmitExpression(out, packed);
}; };
auto emit_vector_appended_with_level = [&](tint::ast::Expression* vector) {
if (auto* level = arg(Usage::kLevel)) {
auto* packed = AppendVector(&builder_, vector, level);
return EmitExpression(out, packed);
}
return emit_vector_appended_with_i32_zero(vector);
};
if (auto* array_index = arg(Usage::kArrayIndex)) { if (auto* array_index = arg(Usage::kArrayIndex)) {
// Array index needs to be appended to the coordinates. // Array index needs to be appended to the coordinates.
auto* packed = AppendVector(&builder_, param_coords, array_index); auto* packed = AppendVector(&builder_, param_coords, array_index);
if (pack_mip_in_coords) { if (pack_level_in_coords) {
if (!emit_vector_appended_with_i32_zero(packed)) { // Then mip level needs to be appended to the coordinates.
if (!emit_vector_appended_with_level(packed)) {
return false; return false;
} }
} else { } else {
@ -1735,9 +1746,9 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
return false; return false;
} }
} }
} else if (pack_mip_in_coords) { } else if (pack_level_in_coords) {
// Mip level needs to be appended to the coordinates, but is always zero. // Mip level needs to be appended to the coordinates.
if (!emit_vector_appended_with_i32_zero(param_coords)) { if (!emit_vector_appended_with_level(param_coords)) {
return false; return false;
} }
} else { } else {
@ -1748,6 +1759,9 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
for (auto usage : {Usage::kDepthRef, Usage::kBias, Usage::kLevel, Usage::kDdx, for (auto usage : {Usage::kDepthRef, Usage::kBias, Usage::kLevel, Usage::kDdx,
Usage::kDdy, Usage::kSampleIndex, Usage::kOffset}) { Usage::kDdy, Usage::kSampleIndex, Usage::kOffset}) {
if (usage == Usage::kLevel && pack_level_in_coords) {
continue; // mip level already packed in coordinates.
}
if (auto* e = arg(usage)) { if (auto* e = arg(usage)) {
out << ", "; out << ", ";
if (!EmitExpression(out, e)) { if (!EmitExpression(out, e)) {

View File

@ -292,39 +292,39 @@ ExpectedResult expected_texture_overload(
case ValidTextureOverload::kSampleCompareLevelDepthCubeArrayF32: case ValidTextureOverload::kSampleCompareLevelDepthCubeArrayF32:
return R"(tint_symbol.SampleCmpLevelZero(tint_symbol_1, float4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)"; return R"(tint_symbol.SampleCmpLevelZero(tint_symbol_1, float4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
case ValidTextureOverload::kLoad1dLevelF32: case ValidTextureOverload::kLoad1dLevelF32:
return R"(tint_symbol.Load(int2(1, 0), 3);)"; return R"(tint_symbol.Load(int2(1, 3));)";
case ValidTextureOverload::kLoad1dLevelU32: case ValidTextureOverload::kLoad1dLevelU32:
return R"(tint_symbol.Load(int2(1, 0), 3);)"; return R"(tint_symbol.Load(int2(1, 3));)";
case ValidTextureOverload::kLoad1dLevelI32: case ValidTextureOverload::kLoad1dLevelI32:
return R"(tint_symbol.Load(int2(1, 0), 3);)"; return R"(tint_symbol.Load(int2(1, 3));)";
case ValidTextureOverload::kLoad2dLevelF32: case ValidTextureOverload::kLoad2dLevelF32:
return R"(tint_symbol.Load(int3(1, 2, 0), 3);)"; return R"(tint_symbol.Load(int3(1, 2, 3));)";
case ValidTextureOverload::kLoad2dLevelU32: case ValidTextureOverload::kLoad2dLevelU32:
return R"(tint_symbol.Load(int3(1, 2, 0), 3);)"; return R"(tint_symbol.Load(int3(1, 2, 3));)";
case ValidTextureOverload::kLoad2dLevelI32: case ValidTextureOverload::kLoad2dLevelI32:
return R"(tint_symbol.Load(int3(1, 2, 0), 3);)"; return R"(tint_symbol.Load(int3(1, 2, 3));)";
case ValidTextureOverload::kLoad2dArrayLevelF32: case ValidTextureOverload::kLoad2dArrayLevelF32:
return R"(tint_symbol.Load(int4(1, 2, 3, 0), 4);)"; return R"(tint_symbol.Load(int4(1, 2, 3, 4));)";
case ValidTextureOverload::kLoad2dArrayLevelU32: case ValidTextureOverload::kLoad2dArrayLevelU32:
return R"(tint_symbol.Load(int4(1, 2, 3, 0), 4);)"; return R"(tint_symbol.Load(int4(1, 2, 3, 4));)";
case ValidTextureOverload::kLoad2dArrayLevelI32: case ValidTextureOverload::kLoad2dArrayLevelI32:
return R"(tint_symbol.Load(int4(1, 2, 3, 0), 4);)"; return R"(tint_symbol.Load(int4(1, 2, 3, 4));)";
case ValidTextureOverload::kLoad3dLevelF32: case ValidTextureOverload::kLoad3dLevelF32:
return R"(tint_symbol.Load(int4(1, 2, 3, 0), 4);)"; return R"(tint_symbol.Load(int4(1, 2, 3, 4));)";
case ValidTextureOverload::kLoad3dLevelU32: case ValidTextureOverload::kLoad3dLevelU32:
return R"(tint_symbol.Load(int4(1, 2, 3, 0), 4);)"; return R"(tint_symbol.Load(int4(1, 2, 3, 4));)";
case ValidTextureOverload::kLoad3dLevelI32: case ValidTextureOverload::kLoad3dLevelI32:
return R"(tint_symbol.Load(int4(1, 2, 3, 0), 4);)"; return R"(tint_symbol.Load(int4(1, 2, 3, 4));)";
case ValidTextureOverload::kLoadMultisampled2dF32: case ValidTextureOverload::kLoadMultisampled2dF32:
return R"(tint_symbol.Load(int3(1, 2, 0), 3);)"; return R"(tint_symbol.Load(int2(1, 2), 3);)";
case ValidTextureOverload::kLoadMultisampled2dU32: case ValidTextureOverload::kLoadMultisampled2dU32:
return R"(tint_symbol.Load(int3(1, 2, 0), 3);)"; return R"(tint_symbol.Load(int2(1, 2), 3);)";
case ValidTextureOverload::kLoadMultisampled2dI32: case ValidTextureOverload::kLoadMultisampled2dI32:
return R"(tint_symbol.Load(int3(1, 2, 0), 3);)"; return R"(tint_symbol.Load(int2(1, 2), 3);)";
case ValidTextureOverload::kLoadDepth2dLevelF32: case ValidTextureOverload::kLoadDepth2dLevelF32:
return R"(tint_symbol.Load(int3(1, 2, 0), 3).x;)"; return R"(tint_symbol.Load(int3(1, 2, 3)).x;)";
case ValidTextureOverload::kLoadDepth2dArrayLevelF32: case ValidTextureOverload::kLoadDepth2dArrayLevelF32:
return R"(tint_symbol.Load(int4(1, 2, 3, 0), 4).x;)"; return R"(tint_symbol.Load(int4(1, 2, 3, 4)).x;)";
case ValidTextureOverload::kLoadStorageRO1dRgba32float: case ValidTextureOverload::kLoadStorageRO1dRgba32float:
return R"(tint_symbol.Load(int2(1, 0));)"; return R"(tint_symbol.Load(int2(1, 0));)";
case ValidTextureOverload::kLoadStorageRO2dRgba8unorm: case ValidTextureOverload::kLoadStorageRO2dRgba8unorm:

View File

@ -14,7 +14,7 @@ void main(tint_symbol_1 tint_symbol) {
const uint3 GlobalInvocationID = tint_symbol.GlobalInvocationID; const uint3 GlobalInvocationID = tint_symbol.GlobalInvocationID;
uint flatIndex = ((((2u * 2u) * GlobalInvocationID.z) + (2u * GlobalInvocationID.y)) + GlobalInvocationID.x); uint flatIndex = ((((2u * 2u) * GlobalInvocationID.z) + (2u * GlobalInvocationID.y)) + GlobalInvocationID.x);
flatIndex = (flatIndex * 1u); flatIndex = (flatIndex * 1u);
float4 texel = myTexture.Load(int4(GlobalInvocationID.xy, 0, 0), 0); float4 texel = myTexture.Load(int4(GlobalInvocationID.xy, 0, 0));
{ {
uint i = 0u; uint i = 0u;
while (true) { while (true) {

View File

@ -9,6 +9,6 @@ struct tint_symbol_1 {
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void main(tint_symbol_1 tint_symbol) { void main(tint_symbol_1 tint_symbol) {
const uint3 GlobalInvocationId = tint_symbol.GlobalInvocationId; const uint3 GlobalInvocationId = tint_symbol.GlobalInvocationId;
result.Store((4u * ((GlobalInvocationId.y * width) + GlobalInvocationId.x)), asuint(tex.Load(int3(int(GlobalInvocationId.x), int(GlobalInvocationId.y), 0), 0).x)); result.Store((4u * ((GlobalInvocationId.y * width) + GlobalInvocationId.x)), asuint(tex.Load(int3(int(GlobalInvocationId.x), int(GlobalInvocationId.y), 0)).x));
return; return;
} }

View File

@ -46,7 +46,7 @@ void main(tint_symbol_2 tint_symbol_1) {
if ((tint_tmp_2)) { if ((tint_tmp_2)) {
bool tint_tmp_5 = success; bool tint_tmp_5 = success;
if (tint_tmp_5) { if (tint_tmp_5) {
tint_tmp_5 = all((tint_symbol.Load(int3(dstTexCoord, 0), 0) == nonCoveredColor)); tint_tmp_5 = all((tint_symbol.Load(int3(dstTexCoord, 0)) == nonCoveredColor));
} }
success = (tint_tmp_5); success = (tint_tmp_5);
} else { } else {
@ -59,8 +59,8 @@ void main(tint_symbol_2 tint_symbol_1) {
if ((uniforms[scalar_offset_8 / 4][scalar_offset_8 % 4] == 1u)) { if ((uniforms[scalar_offset_8 / 4][scalar_offset_8 % 4] == 1u)) {
srcTexCoord.y = ((uint(srcSize.y) - srcTexCoord.y) - 1u); srcTexCoord.y = ((uint(srcSize.y) - srcTexCoord.y) - 1u);
} }
const float4 srcColor = src.Load(int3(srcTexCoord, 0), 0); const float4 srcColor = src.Load(int3(srcTexCoord, 0));
const float4 dstColor = tint_symbol.Load(int3(dstTexCoord, 0), 0); const float4 dstColor = tint_symbol.Load(int3(dstTexCoord, 0));
const int scalar_offset_9 = (4u) / 4; const int scalar_offset_9 = (4u) / 4;
if ((uniforms[scalar_offset_9 / 4][scalar_offset_9 % 4] == 2u)) { if ((uniforms[scalar_offset_9 / 4][scalar_offset_9 % 4] == 2u)) {
bool tint_tmp_7 = success; bool tint_tmp_7 = success;

View File

@ -1,7 +1,7 @@
Texture2D arg_0 : register(t0, space1); Texture2D arg_0 : register(t0, space1);
void textureLoad_19cf87() { void textureLoad_19cf87() {
float res = arg_0.Load(int3(0, 0, 0), 1).x; float res = arg_0.Load(int3(0, 0, 1)).x;
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture1D<uint4> arg_0 : register(t0, space1); Texture1D<uint4> arg_0 : register(t0, space1);
void textureLoad_1b8588() { void textureLoad_1b8588() {
uint4 res = arg_0.Load(int2(1, 0), 1); uint4 res = arg_0.Load(int2(1, 1));
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture3D<float4> arg_0 : register(t0, space1); Texture3D<float4> arg_0 : register(t0, space1);
void textureLoad_1f2016() { void textureLoad_1f2016() {
float4 res = arg_0.Load(int4(0, 0, 0, 0), 1); float4 res = arg_0.Load(int4(0, 0, 0, 1));
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture2D<float4> arg_0 : register(t0, space1); Texture2D<float4> arg_0 : register(t0, space1);
void textureLoad_484344() { void textureLoad_484344() {
float4 res = arg_0.Load(int3(0, 0, 0), 1); float4 res = arg_0.Load(int3(0, 0, 1));
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture3D<int4> arg_0 : register(t0, space1); Texture3D<int4> arg_0 : register(t0, space1);
void textureLoad_4fd803() { void textureLoad_4fd803() {
int4 res = arg_0.Load(int4(0, 0, 0, 0), 1); int4 res = arg_0.Load(int4(0, 0, 0, 1));
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture1D<int4> arg_0 : register(t0, space1); Texture1D<int4> arg_0 : register(t0, space1);
void textureLoad_5a2f9d() { void textureLoad_5a2f9d() {
int4 res = arg_0.Load(int2(1, 0), 1); int4 res = arg_0.Load(int2(1, 1));
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture2D<uint4> arg_0 : register(t0, space1); Texture2D<uint4> arg_0 : register(t0, space1);
void textureLoad_6154d4() { void textureLoad_6154d4() {
uint4 res = arg_0.Load(int3(0, 0, 0), 1); uint4 res = arg_0.Load(int3(0, 0, 1));
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture2DArray<int4> arg_0 : register(t0, space1); Texture2DArray<int4> arg_0 : register(t0, space1);
void textureLoad_79e697() { void textureLoad_79e697() {
int4 res = arg_0.Load(int4(0, 0, 1, 0), 1); int4 res = arg_0.Load(int4(0, 0, 1, 1));
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture2DArray<uint4> arg_0 : register(t0, space1); Texture2DArray<uint4> arg_0 : register(t0, space1);
void textureLoad_7c90e5() { void textureLoad_7c90e5() {
uint4 res = arg_0.Load(int4(0, 0, 1, 0), 1); uint4 res = arg_0.Load(int4(0, 0, 1, 1));
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture1D<float4> arg_0 : register(t0, space1); Texture1D<float4> arg_0 : register(t0, space1);
void textureLoad_81c381() { void textureLoad_81c381() {
float4 res = arg_0.Load(int2(1, 0), 1); float4 res = arg_0.Load(int2(1, 1));
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture2DArray<float4> arg_0 : register(t0, space1); Texture2DArray<float4> arg_0 : register(t0, space1);
void textureLoad_87be85() { void textureLoad_87be85() {
float4 res = arg_0.Load(int4(0, 0, 1, 0), 1); float4 res = arg_0.Load(int4(0, 0, 1, 1));
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture2D<float4> arg_0 : register(t0, space1); Texture2D<float4> arg_0 : register(t0, space1);
void textureLoad_8acf41() { void textureLoad_8acf41() {
float4 res = arg_0.Load(int3(0, 0, 0), 0); float4 res = arg_0.Load(int3(0, 0, 0));
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture2DArray arg_0 : register(t0, space1); Texture2DArray arg_0 : register(t0, space1);
void textureLoad_9b2667() { void textureLoad_9b2667() {
float res = arg_0.Load(int4(0, 0, 1, 0), 1).x; float res = arg_0.Load(int4(0, 0, 1, 1)).x;
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture2DMS<float4> arg_0 : register(t0, space1); Texture2DMS<float4> arg_0 : register(t0, space1);
void textureLoad_a583c9() { void textureLoad_a583c9() {
float4 res = arg_0.Load(int3(0, 0, 0), 1); float4 res = arg_0.Load(int2(0, 0), 1);
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture3D<uint4> arg_0 : register(t0, space1); Texture3D<uint4> arg_0 : register(t0, space1);
void textureLoad_a9a9f5() { void textureLoad_a9a9f5() {
uint4 res = arg_0.Load(int4(0, 0, 0, 0), 1); uint4 res = arg_0.Load(int4(0, 0, 0, 1));
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture2D<int4> arg_0 : register(t0, space1); Texture2D<int4> arg_0 : register(t0, space1);
void textureLoad_c2a480() { void textureLoad_c2a480() {
int4 res = arg_0.Load(int3(0, 0, 0), 1); int4 res = arg_0.Load(int3(0, 0, 1));
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture2DMS<uint4> arg_0 : register(t0, space1); Texture2DMS<uint4> arg_0 : register(t0, space1);
void textureLoad_c378ee() { void textureLoad_c378ee() {
uint4 res = arg_0.Load(int3(0, 0, 0), 1); uint4 res = arg_0.Load(int2(0, 0), 1);
} }
struct tint_symbol { struct tint_symbol {

View File

@ -1,7 +1,7 @@
Texture2DMS<int4> arg_0 : register(t0, space1); Texture2DMS<int4> arg_0 : register(t0, space1);
void textureLoad_e3d2cc() { void textureLoad_e3d2cc() {
int4 res = arg_0.Load(int3(0, 0, 0), 1); int4 res = arg_0.Load(int2(0, 0), 1);
} }
struct tint_symbol { struct tint_symbol {