Use default texture if hasBinding is false.
Check the result of a `hasBinding` before doing a `getBinding`. If
`hasBinding` is false then return the default texture for that binding
type.
Bug: 441985246
Change-Id: Ib953c7416b581b12cd71cc9a3eb2aa20adf224c3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/259855
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/ir/transform/resource_binding.cc b/src/tint/lang/core/ir/transform/resource_binding.cc
index ee5265f..16f744b 100644
--- a/src/tint/lang/core/ir/transform/resource_binding.cc
+++ b/src/tint/lang/core/ir/transform/resource_binding.cc
@@ -85,6 +85,14 @@
auto alias_for_type =
helper->GenerateAliases(b, var, iter->second.default_binding_type_order);
+
+ std::unordered_map<ResourceType, uint32_t> resource_type_to_idx;
+ size_t def_size = iter->second.default_binding_type_order.size();
+ for (size_t i = 0; i < def_size; ++i) {
+ auto res_ty = static_cast<ResourceType>(iter->second.default_binding_type_order[i]);
+ resource_type_to_idx.insert({res_ty, uint32_t(i)});
+ }
+
auto* sb = InjectStorageBuffer(var, iter->second);
std::vector<core::ir::Value*> to_fix;
@@ -111,50 +119,22 @@
break;
}
case core::BuiltinFn::kHasBinding: {
+ auto* binding_ty = call->ExplicitTemplateParams()[0];
auto* idx = call->Args()[1];
-
if (idx->Type()->IsSignedIntegerScalar()) {
idx = b.Convert(ty.u32(), idx)->Result();
}
-
- auto* length =
- b.Access(ty.ptr<storage, u32, read>(), sb, 0_u);
- auto* len_check =
- b.LessThan(ty.bool_(), idx, b.Load(length));
-
- auto* has_check = b.If(len_check);
- has_check->SetResult(call->DetachResult());
-
- b.Append(has_check->True(), [&] {
- auto* type_val = b.Access(ty.ptr<storage, u32, read>(),
- sb, 1_u, idx);
-
- auto* v = b.Load(type_val);
- auto* eq = b.Equal(
- ty.bool_(), v,
- u32(static_cast<uint32_t>(
- core::type::TypeToResourceType(
- call->ExplicitTemplateParams()[0]))));
- b.ExitIf(has_check, eq);
- });
-
- b.Append(has_check->False(),
- [&] { b.ExitIf(has_check, b.Constant(false)); });
-
+ GenHasBinding(call->DetachResult(), binding_ty, idx, sb);
break;
}
case core::BuiltinFn::kGetBinding: {
auto* binding_ty = call->ExplicitTemplateParams()[0];
- auto alias = alias_for_type.Get(binding_ty);
- TINT_ASSERT(alias);
-
- // TODO(439627523): Check hasBinding matches for type
-
- // TODO(439627523): Fix pointer access
- auto* access =
- b.Access(ty.ptr(handle, binding_ty, read),
- (*alias)->Result(), call->Args()[1]);
- b.LoadWithResult(call->DetachResult(), access);
+ auto* idx = call->Args()[1];
+ if (idx->Type()->IsSignedIntegerScalar()) {
+ idx = b.Convert(ty.u32(), idx)->Result();
+ }
+ GenGetBinding(call->DetachResult(), binding_ty, idx, sb,
+ alias_for_type, resource_type_to_idx);
break;
}
default:
@@ -177,6 +157,67 @@
}
}
+ // Note, assumes it's called inside a builder append block.
+ void GenHasBinding(core::ir::InstructionResult* result,
+ const core::type::Type* type,
+ core::ir::Value* idx,
+ core::ir::Var* storage_buffer) {
+ auto* length = b.Access(ty.ptr<storage, u32, read>(), storage_buffer, 0_u);
+ auto* len_check = b.LessThan(ty.bool_(), idx, b.Load(length));
+
+ auto* has_check = b.If(len_check);
+ has_check->SetResult(result);
+
+ b.Append(has_check->True(), [&] {
+ auto* type_val = b.Access(ty.ptr<storage, u32, read>(), storage_buffer, 1_u, idx);
+
+ auto* v = b.Load(type_val);
+ auto* eq = b.Equal(ty.bool_(), v,
+ u32(static_cast<uint32_t>(core::type::TypeToResourceType(type))));
+ b.ExitIf(has_check, eq);
+ });
+
+ b.Append(has_check->False(), [&] { b.ExitIf(has_check, b.Constant(false)); });
+ }
+
+ // Note, assumes it's called inside a builder append block.
+ void GenGetBinding(core::ir::InstructionResult* result,
+ const core::type::Type* type,
+ core::ir::Value* idx,
+ core::ir::Var* storage_buffer,
+ const Hashmap<const core::type::Type*, core::ir::Var*, 4>& alias_for_type,
+ const std::unordered_map<ResourceType, uint32_t>& resource_type_to_idx) {
+ auto* has_result = b.InstructionResult(ty.bool_());
+ GenHasBinding(has_result, type, idx, storage_buffer);
+
+ auto* get_check = b.If(has_result);
+ auto* res = b.InstructionResult(ty.u32());
+ get_check->SetResult(res);
+
+ auto alias = alias_for_type.Get(type);
+ TINT_ASSERT(alias);
+
+ b.Append(get_check->True(), [&] { b.ExitIf(get_check, idx); });
+
+ b.Append(get_check->False(), [&] {
+ auto res_type = core::type::TypeToResourceType(type);
+ auto idx_iter = resource_type_to_idx.find(res_type);
+ TINT_ASSERT(idx_iter != resource_type_to_idx.end());
+
+ auto* len_access = b.Access(ty.ptr<storage, u32, read>(), storage_buffer, 0_u);
+ auto* num_elements = b.Load(len_access);
+
+ auto* r = b.Add(ty.u32(), u32(idx_iter->second), num_elements);
+
+ b.ExitIf(get_check, r);
+ });
+
+ // TODO(439627523): Fix pointer access
+ auto* ptr_ty = ty.ptr(handle, type, read);
+ auto* access = b.Access(ptr_ty, (*alias)->Result(), res);
+ b.LoadWithResult(result, access);
+ }
+
core::ir::Var* InjectStorageBuffer(core::ir::Var* var, const ResourceBindingInfo& info) {
core::ir::Var* sb = nullptr;
b.InsertBefore(var, [&] {
diff --git a/test/tint/extensions/dynamic_binding/access_as_constant.wgsl.expected.spvasm b/test/tint/extensions/dynamic_binding/access_as_constant.wgsl.expected.spvasm
index 9951326..708ad45 100644
--- a/test/tint/extensions/dynamic_binding/access_as_constant.wgsl.expected.spvasm
+++ b/test/tint/extensions/dynamic_binding/access_as_constant.wgsl.expected.spvasm
@@ -1,14 +1,14 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 55
; Schema: 0
OpCapability Shader
OpCapability RuntimeDescriptorArray
OpCapability Sampled1D
OpCapability ImageQuery
OpExtension "SPV_EXT_descriptor_indexing"
- %26 = OpExtInstImport "GLSL.std.450"
+ %44 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %fs "fs"
OpExecutionMode %fs OriginUpperLeft
@@ -38,24 +38,54 @@
%6 = OpVariable %_ptr_StorageBuffer_tint_resource_binding_buffer_tint_explicit_layout StorageBuffer
%void = OpTypeVoid
%13 = OpTypeFunction %void
-%_ptr_UniformConstant_4 = OpTypePointer UniformConstant %4
%int = OpTypeInt 32 1
%int_2 = OpConstant %int 2
+%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+ %uint_0 = OpConstant %uint 0
+ %bool = OpTypeBool
+ %false = OpConstantFalse %bool
+%_ptr_UniformConstant_4 = OpTypePointer UniformConstant %4
%uint_1 = OpConstant %uint 1
%int_0 = OpConstant %int 0
%v4float = OpTypeVector %float 4
%fs = OpFunction %void None %13
%14 = OpLabel
- %15 = OpAccessChain %_ptr_UniformConstant_4 %1 %int_2
- %19 = OpLoad %4 %15 None
- %20 = OpImageQueryLevels %uint %19
- %21 = OpISub %uint %20 %uint_1
- %23 = OpBitcast %uint %int_0
- %25 = OpExtInst %uint %26 UMin %23 %21
- %27 = OpImageQuerySizeLod %uint %19 %25
- %28 = OpISub %uint %27 %uint_1
- %29 = OpBitcast %uint %int_0
- %30 = OpExtInst %uint %26 UMin %29 %28
-%texture_load = OpImageFetch %v4float %19 %30 Lod %25
+ %15 = OpBitcast %uint %int_2
+ %18 = OpAccessChain %_ptr_StorageBuffer_uint %6 %uint_0
+ %21 = OpLoad %uint %18 None
+ %22 = OpULessThan %bool %15 %21
+ OpSelectionMerge %24 None
+ OpBranchConditional %22 %25 %26
+ %25 = OpLabel
+ %51 = OpAccessChain %_ptr_StorageBuffer_uint %6 %uint_1 %15
+ %52 = OpLoad %uint %51 None
+ %28 = OpIEqual %bool %52 %uint_1
+ OpBranch %24
+ %26 = OpLabel
+ OpBranch %24
+ %24 = OpLabel
+ %27 = OpPhi %bool %28 %25 %false %26
+ OpSelectionMerge %30 None
+ OpBranchConditional %27 %31 %32
+ %31 = OpLabel
+ OpBranch %30
+ %32 = OpLabel
+ %53 = OpAccessChain %_ptr_StorageBuffer_uint %6 %uint_0
+ %54 = OpLoad %uint %53 None
+ %34 = OpIAdd %uint %uint_0 %54
+ OpBranch %30
+ %30 = OpLabel
+ %33 = OpPhi %uint %15 %31 %34 %32
+ %35 = OpAccessChain %_ptr_UniformConstant_4 %1 %33
+ %37 = OpLoad %4 %35 None
+ %38 = OpImageQueryLevels %uint %37
+ %39 = OpISub %uint %38 %uint_1
+ %41 = OpBitcast %uint %int_0
+ %43 = OpExtInst %uint %44 UMin %41 %39
+ %45 = OpImageQuerySizeLod %uint %37 %43
+ %46 = OpISub %uint %45 %uint_1
+ %47 = OpBitcast %uint %int_0
+ %48 = OpExtInst %uint %44 UMin %47 %46
+%texture_load = OpImageFetch %v4float %37 %48 Lod %43
OpReturn
OpFunctionEnd
diff --git a/test/tint/extensions/dynamic_binding/access_as_uniform.wgsl.expected.spvasm b/test/tint/extensions/dynamic_binding/access_as_uniform.wgsl.expected.spvasm
index 6ac7b85..9efde4d 100644
--- a/test/tint/extensions/dynamic_binding/access_as_uniform.wgsl.expected.spvasm
+++ b/test/tint/extensions/dynamic_binding/access_as_uniform.wgsl.expected.spvasm
@@ -1,13 +1,13 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 64
; Schema: 0
OpCapability Shader
OpCapability RuntimeDescriptorArray
OpCapability ImageQuery
OpExtension "SPV_EXT_descriptor_indexing"
- %32 = OpExtInstImport "GLSL.std.450"
+ %48 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %fs "fs"
OpExecutionMode %fs OriginUpperLeft
@@ -49,29 +49,58 @@
%16 = OpTypeFunction %void
%_ptr_Uniform_uint = OpTypePointer Uniform %uint
%uint_0 = OpConstant %uint 0
+%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+ %bool = OpTypeBool
+ %false = OpConstantFalse %bool
%_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
%uint_1 = OpConstant %uint 1
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%v3uint = OpTypeVector %uint 3
- %36 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+ %52 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
%v3int = OpTypeVector %int 3
- %38 = OpConstantNull %v3int
+ %54 = OpConstantNull %v3int
%v4float = OpTypeVector %float 4
+ %uint_10 = OpConstant %uint 10
%fs = OpFunction %void None %16
%17 = OpLabel
%18 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0
%21 = OpLoad %uint %18 None
- %22 = OpAccessChain %_ptr_UniformConstant_8 %5 %21
- %24 = OpLoad %8 %22 None
- %25 = OpImageQueryLevels %uint %24
- %26 = OpISub %uint %25 %uint_1
- %28 = OpBitcast %uint %int_0
- %31 = OpExtInst %uint %32 UMin %28 %26
- %33 = OpImageQuerySizeLod %v3uint %24 %31
- %35 = OpISub %v3uint %33 %36
- %37 = OpBitcast %v3uint %38
- %40 = OpExtInst %v3uint %32 UMin %37 %35
-%texture_load = OpImageFetch %v4float %24 %40 Lod %31
+ %22 = OpAccessChain %_ptr_StorageBuffer_uint %10 %uint_0
+ %24 = OpLoad %uint %22 None
+ %25 = OpULessThan %bool %21 %24
+ OpSelectionMerge %27 None
+ OpBranchConditional %25 %28 %29
+ %28 = OpLabel
+ %59 = OpAccessChain %_ptr_StorageBuffer_uint %10 %uint_1 %21
+ %60 = OpLoad %uint %59 None
+ %31 = OpIEqual %bool %60 %uint_10
+ OpBranch %27
+ %29 = OpLabel
+ OpBranch %27
+ %27 = OpLabel
+ %30 = OpPhi %bool %31 %28 %false %29
+ OpSelectionMerge %33 None
+ OpBranchConditional %30 %34 %35
+ %34 = OpLabel
+ OpBranch %33
+ %35 = OpLabel
+ %62 = OpAccessChain %_ptr_StorageBuffer_uint %10 %uint_0
+ %63 = OpLoad %uint %62 None
+ %37 = OpIAdd %uint %uint_0 %63
+ OpBranch %33
+ %33 = OpLabel
+ %36 = OpPhi %uint %21 %34 %37 %35
+ %38 = OpAccessChain %_ptr_UniformConstant_8 %5 %36
+ %40 = OpLoad %8 %38 None
+ %41 = OpImageQueryLevels %uint %40
+ %42 = OpISub %uint %41 %uint_1
+ %44 = OpBitcast %uint %int_0
+ %47 = OpExtInst %uint %48 UMin %44 %42
+ %49 = OpImageQuerySizeLod %v3uint %40 %47
+ %51 = OpISub %v3uint %49 %52
+ %53 = OpBitcast %v3uint %54
+ %56 = OpExtInst %v3uint %48 UMin %53 %51
+%texture_load = OpImageFetch %v4float %40 %56 Lod %47
OpReturn
OpFunctionEnd
diff --git a/test/tint/extensions/dynamic_binding/access_multiple.wgsl.expected.spvasm b/test/tint/extensions/dynamic_binding/access_multiple.wgsl.expected.spvasm
index 48cc9ce..48cc9b2 100644
--- a/test/tint/extensions/dynamic_binding/access_multiple.wgsl.expected.spvasm
+++ b/test/tint/extensions/dynamic_binding/access_multiple.wgsl.expected.spvasm
@@ -1,14 +1,14 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 1
-; Bound: 76
+; Bound: 137
; Schema: 0
OpCapability Shader
OpCapability RuntimeDescriptorArray
OpCapability Sampled1D
OpCapability ImageQuery
OpExtension "SPV_EXT_descriptor_indexing"
- %34 = OpExtInstImport "GLSL.std.450"
+ %52 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %fs "fs"
OpExecutionMode %fs OriginUpperLeft
@@ -53,58 +53,143 @@
%16 = OpVariable %_ptr_StorageBuffer_tint_resource_binding_buffer_tint_explicit_layout StorageBuffer
%void = OpTypeVoid
%22 = OpTypeFunction %void
-%_ptr_UniformConstant_4 = OpTypePointer UniformConstant %4
%int_2 = OpConstant %int 2
+%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+ %uint_0 = OpConstant %uint 0
+ %bool = OpTypeBool
+ %false = OpConstantFalse %bool
+%_ptr_UniformConstant_4 = OpTypePointer UniformConstant %4
%uint_1 = OpConstant %uint 1
%int_0 = OpConstant %int 0
%v4float = OpTypeVector %float 4
-%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9
%int_1 = OpConstant %int 1
+%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9
%v2uint = OpTypeVector %uint 2
- %52 = OpConstantComposite %v2uint %uint_1 %uint_1
+ %84 = OpConstantComposite %v2uint %uint_1 %uint_1
%v2int = OpTypeVector %int 2
- %54 = OpConstantComposite %v2int %int_0 %int_1
+ %86 = OpConstantComposite %v2int %int_0 %int_1
%v4int = OpTypeVector %int 4
%_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
%v3uint = OpTypeVector %uint 3
- %69 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+ %115 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
%v3int = OpTypeVector %int 3
- %71 = OpConstantComposite %v3int %int_2 %int_1 %int_0
+ %117 = OpConstantComposite %v3int %int_2 %int_1 %int_0
%v4uint = OpTypeVector %uint 4
+ %uint_5 = OpConstant %uint 5
+ %uint_12 = OpConstant %uint 12
+ %uint_2 = OpConstant %uint 2
%fs = OpFunction %void None %22
%23 = OpLabel
- %24 = OpAccessChain %_ptr_UniformConstant_4 %1 %int_2
- %27 = OpLoad %4 %24 None
- %28 = OpImageQueryLevels %uint %27
- %29 = OpISub %uint %28 %uint_1
- %31 = OpBitcast %uint %int_0
- %33 = OpExtInst %uint %34 UMin %31 %29
- %35 = OpImageQuerySizeLod %uint %27 %33
- %36 = OpISub %uint %35 %uint_1
- %37 = OpBitcast %uint %int_0
- %38 = OpExtInst %uint %34 UMin %37 %36
- %t1d = OpImageFetch %v4float %27 %38 Lod %33
- %41 = OpAccessChain %_ptr_UniformConstant_9 %6 %int_1
- %44 = OpLoad %9 %41 None
- %45 = OpImageQueryLevels %uint %44
- %46 = OpISub %uint %45 %uint_1
- %47 = OpBitcast %uint %int_0
- %48 = OpExtInst %uint %34 UMin %47 %46
- %49 = OpImageQuerySizeLod %v2uint %44 %48
- %51 = OpISub %v2uint %49 %52
- %53 = OpBitcast %v2uint %54
- %56 = OpExtInst %v2uint %34 UMin %53 %51
- %t2d = OpImageFetch %v4int %44 %56 Lod %48
- %59 = OpAccessChain %_ptr_UniformConstant_14 %11 %int_1
- %61 = OpLoad %14 %59 None
- %62 = OpImageQueryLevels %uint %61
- %63 = OpISub %uint %62 %uint_1
- %64 = OpBitcast %uint %int_0
- %65 = OpExtInst %uint %34 UMin %64 %63
- %66 = OpImageQuerySizeLod %v3uint %61 %65
- %68 = OpISub %v3uint %66 %69
- %70 = OpBitcast %v3uint %71
- %73 = OpExtInst %v3uint %34 UMin %70 %68
- %tcube = OpImageFetch %v4uint %61 %73 Lod %65
+ %24 = OpBitcast %uint %int_2
+ %26 = OpAccessChain %_ptr_StorageBuffer_uint %16 %uint_0
+ %29 = OpLoad %uint %26 None
+ %30 = OpULessThan %bool %24 %29
+ OpSelectionMerge %32 None
+ OpBranchConditional %30 %33 %34
+ %33 = OpLabel
+ %122 = OpAccessChain %_ptr_StorageBuffer_uint %16 %uint_1 %24
+ %123 = OpLoad %uint %122 None
+ %36 = OpIEqual %bool %123 %uint_1
+ OpBranch %32
+ %34 = OpLabel
+ OpBranch %32
+ %32 = OpLabel
+ %35 = OpPhi %bool %36 %33 %false %34
+ OpSelectionMerge %38 None
+ OpBranchConditional %35 %39 %40
+ %39 = OpLabel
+ OpBranch %38
+ %40 = OpLabel
+ %124 = OpAccessChain %_ptr_StorageBuffer_uint %16 %uint_0
+ %125 = OpLoad %uint %124 None
+ %42 = OpIAdd %uint %uint_0 %125
+ OpBranch %38
+ %38 = OpLabel
+ %41 = OpPhi %uint %24 %39 %42 %40
+ %43 = OpAccessChain %_ptr_UniformConstant_4 %1 %41
+ %45 = OpLoad %4 %43 None
+ %46 = OpImageQueryLevels %uint %45
+ %47 = OpISub %uint %46 %uint_1
+ %49 = OpBitcast %uint %int_0
+ %51 = OpExtInst %uint %52 UMin %49 %47
+ %53 = OpImageQuerySizeLod %uint %45 %51
+ %54 = OpISub %uint %53 %uint_1
+ %55 = OpBitcast %uint %int_0
+ %56 = OpExtInst %uint %52 UMin %55 %54
+ %t1d = OpImageFetch %v4float %45 %56 Lod %51
+ %59 = OpBitcast %uint %int_1
+ %61 = OpAccessChain %_ptr_StorageBuffer_uint %16 %uint_0
+ %62 = OpLoad %uint %61 None
+ %63 = OpULessThan %bool %59 %62
+ OpSelectionMerge %64 None
+ OpBranchConditional %63 %65 %66
+ %65 = OpLabel
+ %126 = OpAccessChain %_ptr_StorageBuffer_uint %16 %uint_1 %59
+ %127 = OpLoad %uint %126 None
+ %68 = OpIEqual %bool %127 %uint_5
+ OpBranch %64
+ %66 = OpLabel
+ OpBranch %64
+ %64 = OpLabel
+ %67 = OpPhi %bool %68 %65 %false %66
+ OpSelectionMerge %69 None
+ OpBranchConditional %67 %70 %71
+ %70 = OpLabel
+ OpBranch %69
+ %71 = OpLabel
+ %129 = OpAccessChain %_ptr_StorageBuffer_uint %16 %uint_0
+ %130 = OpLoad %uint %129 None
+ %73 = OpIAdd %uint %uint_1 %130
+ OpBranch %69
+ %69 = OpLabel
+ %72 = OpPhi %uint %59 %70 %73 %71
+ %74 = OpAccessChain %_ptr_UniformConstant_9 %6 %72
+ %76 = OpLoad %9 %74 None
+ %77 = OpImageQueryLevels %uint %76
+ %78 = OpISub %uint %77 %uint_1
+ %79 = OpBitcast %uint %int_0
+ %80 = OpExtInst %uint %52 UMin %79 %78
+ %81 = OpImageQuerySizeLod %v2uint %76 %80
+ %83 = OpISub %v2uint %81 %84
+ %85 = OpBitcast %v2uint %86
+ %88 = OpExtInst %v2uint %52 UMin %85 %83
+ %t2d = OpImageFetch %v4int %76 %88 Lod %80
+ %91 = OpBitcast %uint %int_1
+ %92 = OpAccessChain %_ptr_StorageBuffer_uint %16 %uint_0
+ %93 = OpLoad %uint %92 None
+ %94 = OpULessThan %bool %91 %93
+ OpSelectionMerge %95 None
+ OpBranchConditional %94 %96 %97
+ %96 = OpLabel
+ %131 = OpAccessChain %_ptr_StorageBuffer_uint %16 %uint_1 %91
+ %132 = OpLoad %uint %131 None
+ %99 = OpIEqual %bool %132 %uint_12
+ OpBranch %95
+ %97 = OpLabel
+ OpBranch %95
+ %95 = OpLabel
+ %98 = OpPhi %bool %99 %96 %false %97
+ OpSelectionMerge %100 None
+ OpBranchConditional %98 %101 %102
+ %101 = OpLabel
+ OpBranch %100
+ %102 = OpLabel
+ %134 = OpAccessChain %_ptr_StorageBuffer_uint %16 %uint_0
+ %135 = OpLoad %uint %134 None
+ %104 = OpIAdd %uint %uint_2 %135
+ OpBranch %100
+ %100 = OpLabel
+ %103 = OpPhi %uint %91 %101 %104 %102
+ %105 = OpAccessChain %_ptr_UniformConstant_14 %11 %103
+ %107 = OpLoad %14 %105 None
+ %108 = OpImageQueryLevels %uint %107
+ %109 = OpISub %uint %108 %uint_1
+ %110 = OpBitcast %uint %int_0
+ %111 = OpExtInst %uint %52 UMin %110 %109
+ %112 = OpImageQuerySizeLod %v3uint %107 %111
+ %114 = OpISub %v3uint %112 %115
+ %116 = OpBitcast %v3uint %117
+ %119 = OpExtInst %v3uint %52 UMin %116 %114
+ %tcube = OpImageFetch %v4uint %107 %119 Lod %111
OpReturn
OpFunctionEnd