dEQP-VK.spirv_assembly.instruction.compute.physical_pointers.complex_types_compute.opcopyobject_float_single_buffer_first_input
dEQP-VK.spirv_assembly.instruction.compute.physical_pointers.complex_types_compute.opptraccesschain_float_single_buffer_first_input
dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_1.modfstruct
+dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_1.frexpstruct
dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_2.modfstruct
+dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_2.frexpstruct
dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_3.modfstruct
+dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_3.frexpstruct
dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_4.modfstruct
+dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_4.frexpstruct
dEQP-VK.spirv_assembly.instruction.compute.spirv_ids_abuse.sparse_ids
dEQP-VK.spirv_assembly.instruction.compute.spirv_ids_abuse.lots_ids
dEQP-VK.spirv_assembly.instruction.compute.signed_int_compare.uint_sgreaterthanequal
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.modfstruct_tese
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.modfstruct_geom
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.modfstruct_frag
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.frexpstruct_vert
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.frexpstruct_tesc
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.frexpstruct_tese
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.frexpstruct_geom
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.frexpstruct_frag
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.modfstruct_vert
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.modfstruct_tesc
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.modfstruct_tese
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.modfstruct_geom
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.modfstruct_frag
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.frexpstruct_vert
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.frexpstruct_tesc
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.frexpstruct_tese
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.frexpstruct_geom
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.frexpstruct_frag
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.modfstruct_vert
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.modfstruct_tesc
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.modfstruct_tese
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.modfstruct_geom
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.modfstruct_frag
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.frexpstruct_vert
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.frexpstruct_tesc
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.frexpstruct_tese
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.frexpstruct_geom
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.frexpstruct_frag
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.modfstruct_vert
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.modfstruct_tesc
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.modfstruct_tese
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.modfstruct_geom
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.modfstruct_frag
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.frexpstruct_vert
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.frexpstruct_tesc
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.frexpstruct_tese
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.frexpstruct_geom
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.frexpstruct_frag
dEQP-VK.spirv_assembly.instruction.graphics.spirv_ids_abuse.sparse_ids_vert
dEQP-VK.spirv_assembly.instruction.graphics.spirv_ids_abuse.sparse_ids_tessc
dEQP-VK.spirv_assembly.instruction.graphics.spirv_ids_abuse.sparse_ids_tesse
dEQP-VK.spirv_assembly.instruction.compute.float16.arithmetic_4.opdot
dEQP-VK.spirv_assembly.instruction.compute.float16.arithmetic_4.opvectortimesscalar
dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_1.modfstruct
+dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_1.frexpstruct
dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_2.modfstruct
+dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_2.frexpstruct
dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_3.modfstruct
+dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_3.frexpstruct
dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_4.modfstruct
+dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_4.frexpstruct
dEQP-VK.spirv_assembly.instruction.compute.bool.mixed_bitsize.b32b32b32b16
dEQP-VK.spirv_assembly.instruction.compute.bool.mixed_bitsize.b32b32b32b8
dEQP-VK.spirv_assembly.instruction.compute.bool.mixed_bitsize.b32b32b16b32
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.modfstruct_tese
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.modfstruct_geom
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.modfstruct_frag
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.frexpstruct_vert
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.frexpstruct_tesc
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.frexpstruct_tese
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.frexpstruct_geom
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.frexpstruct_frag
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.modfstruct_vert
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.modfstruct_tesc
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.modfstruct_tese
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.modfstruct_geom
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.modfstruct_frag
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.frexpstruct_vert
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.frexpstruct_tesc
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.frexpstruct_tese
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.frexpstruct_geom
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.frexpstruct_frag
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.modfstruct_vert
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.modfstruct_tesc
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.modfstruct_tese
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.modfstruct_geom
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.modfstruct_frag
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.frexpstruct_vert
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.frexpstruct_tesc
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.frexpstruct_tese
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.frexpstruct_geom
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.frexpstruct_frag
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.modfstruct_vert
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.modfstruct_tesc
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.modfstruct_tese
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.modfstruct_geom
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.modfstruct_frag
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.frexpstruct_vert
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.frexpstruct_tesc
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.frexpstruct_tese
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.frexpstruct_geom
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.frexpstruct_frag
dEQP-VK.spirv_assembly.instruction.graphics.spirv_ids_abuse.sparse_ids_vert
dEQP-VK.spirv_assembly.instruction.graphics.spirv_ids_abuse.sparse_ids_tessc
dEQP-VK.spirv_assembly.instruction.graphics.spirv_ids_abuse.sparse_ids_tesse
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A compute shader test for FrexpStruct.
+
+# SHADER compute comp_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296 / 1;
+# const uint half_ndp = ndp / 2;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uint in_values[half_ndp];
+# };
+#
+# layout(set = 0, binding = 1) buffer block1 {
+# float frexp_out[ndp];
+# };
+#
+# layout(set = 0, binding = 2) buffer block2 {
+# float frexpStruct_out[ndp];
+# };
+#
+# struct frexpStructType
+# {
+# float x;
+# int exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (float orig)
+# {
+# float x;
+# int exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# for (uint ndx = 0; ndx < ndp; ndx += 2)
+# {
+# uint in_uint = in_values[ndx/2];
+# float in_float = uintBitsToFloat(in_uint);
+# float x;
+# int exp;
+#
+# x = frexp(in_float, exp);
+# frexpStructType res = frexpStruct(in_float);
+#
+# frexp_out[ndx] = intBitsToFloat(exp);
+# frexp_out[ndx+1] = x;
+# frexpStruct_out[ndx] = intBitsToFloat(res.exp);
+# frexpStruct_out[ndx+1] = res.x;
+# }
+#
+# return;
+# }
+# END
+
+SHADER compute comp_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpDecorate %_arr_uint_uint_648 ArrayStride 4
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %_arr_float_uint_1296 ArrayStride 4
+ OpMemberDecorate %block1 0 Offset 0
+ OpDecorate %block1 BufferBlock
+ OpDecorate %__0 DescriptorSet 0
+ OpDecorate %__0 Binding 1
+ OpDecorate %_arr_float_uint_1296_0 ArrayStride 4
+ OpMemberDecorate %block2 0 Offset 0
+ OpDecorate %block2 BufferBlock
+ OpDecorate %__1 DescriptorSet 0
+ OpDecorate %__1 Binding 2
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+ %int = OpTypeInt 32 1
+%frexpStructType = OpTypeStruct %float %int
+ %10 = OpTypeFunction %frexpStructType %_ptr_Function_float
+%_ptr_Function_int = OpTypePointer Function %int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %uint_0 = OpConstant %uint 0
+ %uint_1296 = OpConstant %uint 1296
+ %bool = OpTypeBool
+ %uint_648 = OpConstant %uint 648
+%_arr_uint_uint_648 = OpTypeArray %uint %uint_648
+ %block0 = OpTypeStruct %_arr_uint_uint_648
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %int_0 = OpConstant %int 0
+ %uint_2 = OpConstant %uint 2
+%_ptr_Uniform_uint = OpTypePointer Uniform %uint
+%_arr_float_uint_1296 = OpTypeArray %float %uint_1296
+ %block1 = OpTypeStruct %_arr_float_uint_1296
+%_ptr_Uniform_block1 = OpTypePointer Uniform %block1
+ %__0 = OpVariable %_ptr_Uniform_block1 Uniform
+%_ptr_Uniform_float = OpTypePointer Uniform %float
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1296_0 = OpTypeArray %float %uint_1296
+ %block2 = OpTypeStruct %_arr_float_uint_1296_0
+%_ptr_Uniform_block2 = OpTypePointer Uniform %block2
+ %__1 = OpVariable %_ptr_Uniform_block2 Uniform
+ %int_1 = OpConstant %int 1
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %ndx = OpVariable %_ptr_Function_uint Function
+ %in_uint = OpVariable %_ptr_Function_uint Function
+ %in_float = OpVariable %_ptr_Function_float Function
+ %x_0 = OpVariable %_ptr_Function_float Function
+ %exp_0 = OpVariable %_ptr_Function_int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ OpStore %ndx %uint_0
+ OpBranch %31
+ %31 = OpLabel
+ OpLoopMerge %33 %34 None
+ OpBranch %35
+ %35 = OpLabel
+ %36 = OpLoad %uint %ndx
+ %39 = OpULessThan %bool %36 %uint_1296
+ OpBranchConditional %39 %32 %33
+ %32 = OpLabel
+ %47 = OpLoad %uint %ndx
+ %49 = OpUDiv %uint %47 %uint_2
+ %51 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 %49
+ %52 = OpLoad %uint %51
+ OpStore %in_uint %52
+ %54 = OpLoad %uint %in_uint
+ %55 = OpBitcast %float %54
+ OpStore %in_float %55
+ %57 = OpLoad %float %in_float
+ %59 = OpExtInst %float %1 Frexp %57 %exp_0
+ OpStore %x_0 %59
+ %62 = OpLoad %float %in_float
+ %63 = OpExtInst %frexpStructType %1 FrexpStruct %62
+ OpStore %res_0 %63
+ %68 = OpLoad %uint %ndx
+ %69 = OpLoad %int %exp_0
+ %70 = OpBitcast %float %69
+ %72 = OpAccessChain %_ptr_Uniform_float %__0 %int_0 %68
+ OpStore %72 %70
+ %73 = OpLoad %uint %ndx
+ %75 = OpIAdd %uint %73 %uint_1
+ %76 = OpLoad %float %x_0
+ %77 = OpAccessChain %_ptr_Uniform_float %__0 %int_0 %75
+ OpStore %77 %76
+ %82 = OpLoad %uint %ndx
+ %84 = OpAccessChain %_ptr_Function_int %res_0 %int_1
+ %85 = OpLoad %int %84
+ %86 = OpBitcast %float %85
+ %87 = OpAccessChain %_ptr_Uniform_float %__1 %int_0 %82
+ OpStore %87 %86
+ %88 = OpLoad %uint %ndx
+ %89 = OpIAdd %uint %88 %uint_1
+ %90 = OpAccessChain %_ptr_Function_float %res_0 %int_0
+ %91 = OpLoad %float %90
+ %92 = OpAccessChain %_ptr_Uniform_float %__1 %int_0 %89
+ OpStore %92 %91
+ OpBranch %34
+ %34 = OpLabel
+ %93 = OpLoad %uint %ndx
+ %94 = OpIAdd %uint %93 %uint_2
+ OpStore %ndx %94
+ OpBranch %31
+ %33 = OpLabel
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+
+BUFFER buf_frexp DATA_TYPE float SIZE 1296 FILL 0.0
+BUFFER buf_frexpStruct DATA_TYPE float SIZE 1296 FILL 1.0
+
+PIPELINE compute test_pipeline
+ ATTACH comp_shader
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER buf_frexp AS storage DESCRIPTOR_SET 0 BINDING 1
+ BIND BUFFER buf_frexpStruct AS storage DESCRIPTOR_SET 0 BINDING 2
+END
+
+RUN test_pipeline 1 1 1
+
+EXPECT buf_frexp EQ_BUFFER buf_frexpStruct
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A fragment shader test for FrexpStruct.
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out uint ndx_out;
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# ndx_out = xcoord + ycoord * ndpSqrt;
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %ndx_out %_
+ OpDecorate %position Location 0
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+ %float_1 = OpConstant %float 1
+ %uint_1 = OpConstant %uint 1
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %ndx_out = OpVariable %_ptr_Output_uint Output
+ %uint_36 = OpConstant %uint 36
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_1_02777779 = OpConstant %float 1.02777779
+ %float_18 = OpConstant %float 18
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %17 = OpLoad %float %16
+ %21 = OpFAdd %float %17 %float_1_02777779
+ %24 = OpFMul %float %21 %float_18
+ %25 = OpFSub %float %24 %float_1
+ %26 = OpConvertFToU %uint %25
+ %29 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %30 = OpLoad %float %29
+ %32 = OpFAdd %float %30 %float_1_02777779
+ %34 = OpFMul %float %32 %float_18
+ %35 = OpFSub %float %34 %float_1
+ %36 = OpConvertFToU %uint %35
+ %42 = OpIMul %uint %36 %uint_36
+ %43 = OpIAdd %uint %26 %42
+ OpStore %ndx_out %43
+ %51 = OpLoad %v2float %position
+ %53 = OpCompositeExtract %float %51 0
+ %54 = OpCompositeExtract %float %51 1
+ %55 = OpCompositeConstruct %v4float %53 %54 %float_0 %float_1
+ %57 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %57 %55
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const vec4 clear_value = vec4(0.0, 0.0, 0.0, 1.0);
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uint in_values[ndp];
+# };
+#
+# layout (location = 0) flat in uint ndx_in;
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+# struct frexpStructType
+# {
+# float x;
+# int exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (float orig)
+# {
+# float x;
+# int exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# uint in_uint = in_values[ndx_in];
+# float in_float = uintBitsToFloat(in_uint);
+# float x;
+# int exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out = clear_value;
+# frexp_exp_out = clear_value;
+# frexpStruct_x_out = clear_value;
+# frexpStruct_exp_out = clear_value;
+# frexp_x_out.r = x;
+# frexp_exp_out.r = intBitsToFloat(exp);
+# frexpStruct_x_out.r = res.x;
+# frexpStruct_exp_out.r = intBitsToFloat(res.exp);
+#
+# return;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %ndx_in %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %_arr_uint_uint_1296 ArrayStride 4
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+ %int = OpTypeInt 32 1
+%frexpStructType = OpTypeStruct %float %int
+ %10 = OpTypeFunction %frexpStructType %_ptr_Function_float
+%_ptr_Function_int = OpTypePointer Function %int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_uint_uint_1296 = OpTypeArray %uint %uint_1296
+ %block0 = OpTypeStruct %_arr_uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %int_0 = OpConstant %int 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+ %ndx_in = OpVariable %_ptr_Input_uint Input
+%_ptr_Uniform_uint = OpTypePointer Uniform %uint
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %58 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+ %uint_0 = OpConstant %uint 0
+%_ptr_Output_float = OpTypePointer Output %float
+ %int_1 = OpConstant %int 1
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %in_uint = OpVariable %_ptr_Function_uint Function
+ %in_float = OpVariable %_ptr_Function_float Function
+ %x_0 = OpVariable %_ptr_Function_float Function
+ %exp_0 = OpVariable %_ptr_Function_int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ %38 = OpLoad %uint %ndx_in
+ %40 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 %38
+ %41 = OpLoad %uint %40
+ OpStore %in_uint %41
+ %43 = OpLoad %uint %in_uint
+ %44 = OpBitcast %float %43
+ OpStore %in_float %44
+ %46 = OpLoad %float %in_float
+ %48 = OpExtInst %float %1 Frexp %46 %exp_0
+ OpStore %x_0 %48
+ %51 = OpLoad %float %in_float
+ %52 = OpExtInst %frexpStructType %1 FrexpStruct %51
+ OpStore %res_0 %52
+ OpStore %frexp_x_out %58
+ OpStore %frexp_exp_out %58
+ OpStore %frexpStruct_x_out %58
+ OpStore %frexpStruct_exp_out %58
+ %62 = OpLoad %float %x_0
+ %65 = OpAccessChain %_ptr_Output_float %frexp_x_out %uint_0
+ OpStore %65 %62
+ %66 = OpLoad %int %exp_0
+ %67 = OpBitcast %float %66
+ %68 = OpAccessChain %_ptr_Output_float %frexp_exp_out %uint_0
+ OpStore %68 %67
+ %69 = OpAccessChain %_ptr_Function_float %res_0 %int_0
+ %70 = OpLoad %float %69
+ %71 = OpAccessChain %_ptr_Output_float %frexpStruct_x_out %uint_0
+ OpStore %71 %70
+ %73 = OpAccessChain %_ptr_Function_int %res_0 %int_1
+ %74 = OpLoad %int %73
+ %75 = OpBitcast %float %74
+ %76 = OpAccessChain %_ptr_Output_float %frexpStruct_exp_out %uint_0
+ OpStore %76 %75
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+RUN test_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A geometry shader test for FrexpStruct.
+
+DEVICE_FEATURE geometryShader
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out uint ndx_out;
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# ndx_out = xcoord + ycoord * ndpSqrt;
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %ndx_out %_
+ OpDecorate %position Location 0
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+ %float_1 = OpConstant %float 1
+ %uint_1 = OpConstant %uint 1
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %ndx_out = OpVariable %_ptr_Output_uint Output
+ %uint_36 = OpConstant %uint 36
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_1_02777779 = OpConstant %float 1.02777779
+ %float_18 = OpConstant %float 18
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %17 = OpLoad %float %16
+ %21 = OpFAdd %float %17 %float_1_02777779
+ %24 = OpFMul %float %21 %float_18
+ %25 = OpFSub %float %24 %float_1
+ %26 = OpConvertFToU %uint %25
+ %29 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %30 = OpLoad %float %29
+ %32 = OpFAdd %float %30 %float_1_02777779
+ %34 = OpFMul %float %32 %float_18
+ %35 = OpFSub %float %34 %float_1
+ %36 = OpConvertFToU %uint %35
+ %42 = OpIMul %uint %36 %uint_36
+ %43 = OpIAdd %uint %26 %42
+ OpStore %ndx_out %43
+ %51 = OpLoad %v2float %position
+ %53 = OpCompositeExtract %float %51 0
+ %54 = OpCompositeExtract %float %51 1
+ %55 = OpCompositeConstruct %v4float %53 %54 %float_0 %float_1
+ %57 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %57 %55
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER geometry geom_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uint in_values[ndp];
+# };
+#
+# layout (triangles) in;
+# layout (triangle_strip, max_vertices = 3) out;
+#
+# layout (location = 0) flat in uint ndx_in[];
+# layout (location = 0) flat out float frexp_x_out;
+# layout (location = 1) flat out float frexp_exp_out;
+# layout (location = 2) flat out float frexpStruct_x_out;
+# layout (location = 3) flat out float frexpStruct_exp_out;
+#
+# struct frexpStructType
+# {
+# float x;
+# int exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (float orig)
+# {
+# float x;
+# int exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# for (int vertex = 0; vertex < 3; vertex++)
+# {
+# uint in_uint = in_values[ndx_in[vertex]];
+# float in_float = uintBitsToFloat(in_uint);
+# float x;
+# int exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out = x;
+# frexp_exp_out = intBitsToFloat(exp);
+# frexpStruct_x_out = res.x;
+# frexpStruct_exp_out = intBitsToFloat(res.exp);
+#
+# gl_Position = gl_in[vertex].gl_Position;
+# EmitVertex();
+# }
+#
+# EndPrimitive();
+# }
+# END
+
+SHADER geometry geom_shader SPIRV-ASM
+ OpCapability Geometry
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Geometry %main "main" %ndx_in %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %__0 %gl_in
+ OpExecutionMode %main Triangles
+ OpExecutionMode %main Invocations 1
+ OpExecutionMode %main OutputTriangleStrip
+ OpExecutionMode %main OutputVertices 3
+ OpDecorate %_arr_uint_uint_1296 ArrayStride 4
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+ %int = OpTypeInt 32 1
+%frexpStructType = OpTypeStruct %float %int
+ %10 = OpTypeFunction %frexpStructType %_ptr_Function_float
+%_ptr_Function_int = OpTypePointer Function %int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %int_0 = OpConstant %int 0
+ %int_3 = OpConstant %int 3
+ %bool = OpTypeBool
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_uint_uint_1296 = OpTypeArray %uint %uint_1296
+ %block0 = OpTypeStruct %_arr_uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %uint_3 = OpConstant %uint 3
+%_arr_uint_uint_3 = OpTypeArray %uint %uint_3
+%_ptr_Input__arr_uint_uint_3 = OpTypePointer Input %_arr_uint_uint_3
+ %ndx_in = OpVariable %_ptr_Input__arr_uint_uint_3 Input
+%_ptr_Input_uint = OpTypePointer Input %uint
+%_ptr_Uniform_uint = OpTypePointer Uniform %uint
+%_ptr_Output_float = OpTypePointer Output %float
+%frexp_x_out = OpVariable %_ptr_Output_float Output
+%frexp_exp_out = OpVariable %_ptr_Output_float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_float Output
+ %int_1 = OpConstant %int 1
+ %v4float = OpTypeVector %float 4
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %__0 = OpVariable %_ptr_Output_gl_PerVertex Output
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_arr_gl_PerVertex_0_uint_3 = OpTypeArray %gl_PerVertex_0 %uint_3
+%_ptr_Input__arr_gl_PerVertex_0_uint_3 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_3
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_3 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %vertex = OpVariable %_ptr_Function_int Function
+ %in_uint = OpVariable %_ptr_Function_uint Function
+ %in_float = OpVariable %_ptr_Function_float Function
+ %x_0 = OpVariable %_ptr_Function_float Function
+ %exp_0 = OpVariable %_ptr_Function_int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ OpStore %vertex %int_0
+ OpBranch %29
+ %29 = OpLabel
+ OpLoopMerge %31 %32 None
+ OpBranch %33
+ %33 = OpLabel
+ %34 = OpLoad %int %vertex
+ %37 = OpSLessThan %bool %34 %int_3
+ OpBranchConditional %37 %30 %31
+ %30 = OpLabel
+ %50 = OpLoad %int %vertex
+ %52 = OpAccessChain %_ptr_Input_uint %ndx_in %50
+ %53 = OpLoad %uint %52
+ %55 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 %53
+ %56 = OpLoad %uint %55
+ OpStore %in_uint %56
+ %58 = OpLoad %uint %in_uint
+ %59 = OpBitcast %float %58
+ OpStore %in_float %59
+ %61 = OpLoad %float %in_float
+ %63 = OpExtInst %float %1 Frexp %61 %exp_0
+ OpStore %x_0 %63
+ %66 = OpLoad %float %in_float
+ %67 = OpExtInst %frexpStructType %1 FrexpStruct %66
+ OpStore %res_0 %67
+ %70 = OpLoad %float %x_0
+ OpStore %frexp_x_out %70
+ %72 = OpLoad %int %exp_0
+ %73 = OpBitcast %float %72
+ OpStore %frexp_exp_out %73
+ %75 = OpAccessChain %_ptr_Function_float %res_0 %int_0
+ %76 = OpLoad %float %75
+ OpStore %frexpStruct_x_out %76
+ %79 = OpAccessChain %_ptr_Function_int %res_0 %int_1
+ %80 = OpLoad %int %79
+ %81 = OpBitcast %float %80
+ OpStore %frexpStruct_exp_out %81
+ %92 = OpLoad %int %vertex
+ %94 = OpAccessChain %_ptr_Input_v4float %gl_in %92 %int_0
+ %95 = OpLoad %v4float %94
+ %97 = OpAccessChain %_ptr_Output_v4float %__0 %int_0
+ OpStore %97 %95
+ OpEmitVertex
+ OpBranch %32
+ %32 = OpLabel
+ %98 = OpLoad %int %vertex
+ %99 = OpIAdd %int %98 %int_1
+ OpStore %vertex %99
+ OpBranch %29
+ %31 = OpLabel
+ OpEndPrimitive
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (location = 0) flat in float frexp_x_in;
+# layout (location = 1) flat in float frexp_exp_in;
+# layout (location = 2) flat in float frexpStruct_x_in;
+# layout (location = 3) flat in float frexpStruct_exp_in;
+#
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+# const vec4 clear_value = vec4(0.0, 0.0, 0.0, 1.0);
+#
+# void main ()
+# {
+# frexp_x_out = clear_value;
+# frexp_exp_out = clear_value;
+# frexpStruct_x_out = clear_value;
+# frexpStruct_exp_out = clear_value;
+# frexp_x_out.r = frexp_x_in;
+# frexp_exp_out.r = frexp_exp_in;
+# frexpStruct_x_out.r = frexpStruct_x_in;
+# frexpStruct_exp_out.r = frexpStruct_exp_in;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %frexp_x_in %frexp_exp_in %frexpStruct_x_in %frexpStruct_exp_in
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+%_ptr_Input_float = OpTypePointer Input %float
+ %frexp_x_in = OpVariable %_ptr_Input_float Input
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+%_ptr_Output_float = OpTypePointer Output %float
+%frexp_exp_in = OpVariable %_ptr_Input_float Input
+%frexpStruct_x_in = OpVariable %_ptr_Input_float Input
+%frexpStruct_exp_in = OpVariable %_ptr_Input_float Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpStore %frexp_x_out %12
+ OpStore %frexp_exp_out %12
+ OpStore %frexpStruct_x_out %12
+ OpStore %frexpStruct_exp_out %12
+ %18 = OpLoad %float %frexp_x_in
+ %22 = OpAccessChain %_ptr_Output_float %frexp_x_out %uint_0
+ OpStore %22 %18
+ %24 = OpLoad %float %frexp_exp_in
+ %25 = OpAccessChain %_ptr_Output_float %frexp_exp_out %uint_0
+ OpStore %25 %24
+ %27 = OpLoad %float %frexpStruct_x_in
+ %28 = OpAccessChain %_ptr_Output_float %frexpStruct_x_out %uint_0
+ OpStore %28 %27
+ %30 = OpLoad %float %frexpStruct_exp_in
+ %31 = OpAccessChain %_ptr_Output_float %frexpStruct_exp_out %uint_0
+ OpStore %31 %30
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH geom_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+RUN test_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A tessellation control shader test for FrexpStruct.
+
+DEVICE_FEATURE tessellationShader
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out uint ndx_out;
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# ndx_out = xcoord + ycoord * ndpSqrt;
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %ndx_out %_
+ OpDecorate %position Location 0
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+ %float_1 = OpConstant %float 1
+ %uint_1 = OpConstant %uint 1
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %ndx_out = OpVariable %_ptr_Output_uint Output
+ %uint_36 = OpConstant %uint 36
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_1_02777779 = OpConstant %float 1.02777779
+ %float_18 = OpConstant %float 18
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %17 = OpLoad %float %16
+ %21 = OpFAdd %float %17 %float_1_02777779
+ %24 = OpFMul %float %21 %float_18
+ %25 = OpFSub %float %24 %float_1
+ %26 = OpConvertFToU %uint %25
+ %29 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %30 = OpLoad %float %29
+ %32 = OpFAdd %float %30 %float_1_02777779
+ %34 = OpFMul %float %32 %float_18
+ %35 = OpFSub %float %34 %float_1
+ %36 = OpConvertFToU %uint %35
+ %42 = OpIMul %uint %36 %uint_36
+ %43 = OpIAdd %uint %26 %42
+ OpStore %ndx_out %43
+ %51 = OpLoad %v2float %position
+ %53 = OpCompositeExtract %float %51 0
+ %54 = OpCompositeExtract %float %51 1
+ %55 = OpCompositeConstruct %v4float %53 %54 %float_0 %float_1
+ %57 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %57 %55
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER tessellation_control tesc_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+#
+# layout (vertices = 3) out;
+#
+# layout (location = 0) flat in uint ndx_in[];
+# layout (location = 0) flat out float frexp_x_out[];
+# layout (location = 1) flat out float frexp_exp_out[];
+# layout (location = 2) flat out float frexpStruct_x_out[];
+# layout (location = 3) flat out float frexpStruct_exp_out[];
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uint in_values[ndp];
+# };
+#
+# struct frexpStructType
+# {
+# float x;
+# int exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (float orig)
+# {
+# float x;
+# int exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# uint in_uint = in_values[ndx_in[gl_InvocationID]];
+# float in_float = uintBitsToFloat(in_uint);
+# float x;
+# int exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out[gl_InvocationID] = x;
+# frexp_exp_out[gl_InvocationID] = intBitsToFloat(exp);
+# frexpStruct_x_out[gl_InvocationID] = res.x;
+# frexpStruct_exp_out[gl_InvocationID] = intBitsToFloat(res.exp);
+#
+# gl_TessLevelInner[0] = 1.0;
+# gl_TessLevelInner[1] = 1.0;
+# gl_TessLevelOuter[0] = 1.0;
+# gl_TessLevelOuter[1] = 1.0;
+# gl_TessLevelOuter[2] = 1.0;
+# gl_TessLevelOuter[3] = 1.0;
+# gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
+# }
+# END
+
+SHADER tessellation_control tesc_shader SPIRV-ASM
+ OpCapability Tessellation
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationControl %main "main" %ndx_in %gl_InvocationID %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %gl_TessLevelInner %gl_TessLevelOuter %gl_out %gl_in
+ OpExecutionMode %main OutputVertices 3
+ OpDecorate %_arr_uint_uint_1296 ArrayStride 4
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ OpDecorate %gl_InvocationID BuiltIn InvocationId
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %gl_TessLevelInner Patch
+ OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner
+ OpDecorate %gl_TessLevelOuter Patch
+ OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+ %int = OpTypeInt 32 1
+%frexpStructType = OpTypeStruct %float %int
+ %10 = OpTypeFunction %frexpStructType %_ptr_Function_float
+%_ptr_Function_int = OpTypePointer Function %int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_uint_uint_1296 = OpTypeArray %uint %uint_1296
+ %block0 = OpTypeStruct %_arr_uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %int_0 = OpConstant %int 0
+ %uint_32 = OpConstant %uint 32
+%_arr_uint_uint_32 = OpTypeArray %uint %uint_32
+%_ptr_Input__arr_uint_uint_32 = OpTypePointer Input %_arr_uint_uint_32
+ %ndx_in = OpVariable %_ptr_Input__arr_uint_uint_32 Input
+%_ptr_Input_int = OpTypePointer Input %int
+%gl_InvocationID = OpVariable %_ptr_Input_int Input
+%_ptr_Input_uint = OpTypePointer Input %uint
+%_ptr_Uniform_uint = OpTypePointer Uniform %uint
+ %uint_3 = OpConstant %uint 3
+%_arr_float_uint_3 = OpTypeArray %float %uint_3
+%_ptr_Output__arr_float_uint_3 = OpTypePointer Output %_arr_float_uint_3
+%frexp_x_out = OpVariable %_ptr_Output__arr_float_uint_3 Output
+%_ptr_Output_float = OpTypePointer Output %float
+%frexp_exp_out = OpVariable %_ptr_Output__arr_float_uint_3 Output
+%frexpStruct_x_out = OpVariable %_ptr_Output__arr_float_uint_3 Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output__arr_float_uint_3 Output
+ %int_1 = OpConstant %int 1
+ %uint_2 = OpConstant %uint 2
+%_arr_float_uint_2 = OpTypeArray %float %uint_2
+%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2
+%gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output
+ %float_1 = OpConstant %float 1
+ %uint_4 = OpConstant %uint 4
+%_arr_float_uint_4 = OpTypeArray %float %uint_4
+%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4
+%gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output
+ %int_2 = OpConstant %int 2
+ %int_3 = OpConstant %int 3
+ %v4float = OpTypeVector %float 4
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_arr_gl_PerVertex_uint_3 = OpTypeArray %gl_PerVertex %uint_3
+%_ptr_Output__arr_gl_PerVertex_uint_3 = OpTypePointer Output %_arr_gl_PerVertex_uint_3
+ %gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_uint_3 Output
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_arr_gl_PerVertex_0_uint_32 = OpTypeArray %gl_PerVertex_0 %uint_32
+%_ptr_Input__arr_gl_PerVertex_0_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_32
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %in_uint = OpVariable %_ptr_Function_uint Function
+ %in_float = OpVariable %_ptr_Function_float Function
+ %x_0 = OpVariable %_ptr_Function_float Function
+ %exp_0 = OpVariable %_ptr_Function_int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ %42 = OpLoad %int %gl_InvocationID
+ %44 = OpAccessChain %_ptr_Input_uint %ndx_in %42
+ %45 = OpLoad %uint %44
+ %47 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 %45
+ %48 = OpLoad %uint %47
+ OpStore %in_uint %48
+ %50 = OpLoad %uint %in_uint
+ %51 = OpBitcast %float %50
+ OpStore %in_float %51
+ %53 = OpLoad %float %in_float
+ %55 = OpExtInst %float %1 Frexp %53 %exp_0
+ OpStore %x_0 %55
+ %58 = OpLoad %float %in_float
+ %59 = OpExtInst %frexpStructType %1 FrexpStruct %58
+ OpStore %res_0 %59
+ %64 = OpLoad %int %gl_InvocationID
+ %65 = OpLoad %float %x_0
+ %67 = OpAccessChain %_ptr_Output_float %frexp_x_out %64
+ OpStore %67 %65
+ %69 = OpLoad %int %gl_InvocationID
+ %70 = OpLoad %int %exp_0
+ %71 = OpBitcast %float %70
+ %72 = OpAccessChain %_ptr_Output_float %frexp_exp_out %69
+ OpStore %72 %71
+ %74 = OpLoad %int %gl_InvocationID
+ %75 = OpAccessChain %_ptr_Function_float %res_0 %int_0
+ %76 = OpLoad %float %75
+ %77 = OpAccessChain %_ptr_Output_float %frexpStruct_x_out %74
+ OpStore %77 %76
+ %79 = OpLoad %int %gl_InvocationID
+ %81 = OpAccessChain %_ptr_Function_int %res_0 %int_1
+ %82 = OpLoad %int %81
+ %83 = OpBitcast %float %82
+ %84 = OpAccessChain %_ptr_Output_float %frexpStruct_exp_out %79
+ OpStore %84 %83
+ %90 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0
+ OpStore %90 %float_1
+ %91 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_1
+ OpStore %91 %float_1
+ %96 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0
+ OpStore %96 %float_1
+ %97 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1
+ OpStore %97 %float_1
+ %99 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2
+ OpStore %99 %float_1
+ %101 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_3
+ OpStore %101 %float_1
+ %109 = OpLoad %int %gl_InvocationID
+ %114 = OpLoad %int %gl_InvocationID
+ %116 = OpAccessChain %_ptr_Input_v4float %gl_in %114 %int_0
+ %117 = OpLoad %v4float %116
+ %119 = OpAccessChain %_ptr_Output_v4float %gl_out %109 %int_0
+ OpStore %119 %117
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER tessellation_evaluation tese_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (triangles) in;
+#
+# layout (location = 0) flat in float frexp_x_in[];
+# layout (location = 1) flat in float frexp_exp_in[];
+# layout (location = 2) flat in float frexpStruct_x_in[];
+# layout (location = 3) flat in float frexpStruct_exp_in[];
+#
+# layout (location = 0) flat out float frexp_x_out;
+# layout (location = 1) flat out float frexp_exp_out;
+# layout (location = 2) flat out float frexpStruct_x_out;
+# layout (location = 3) flat out float frexpStruct_exp_out;
+#
+# void main ()
+# {
+# gl_Position = gl_TessCoord.x * gl_in[0].gl_Position +
+# gl_TessCoord.y * gl_in[1].gl_Position +
+# gl_TessCoord.z * gl_in[2].gl_Position;
+#
+# frexp_x_out = frexp_x_in[0];
+# frexp_exp_out = frexp_exp_in[0];
+# frexpStruct_x_out = frexpStruct_x_in[0];
+# frexpStruct_exp_out = frexpStruct_exp_in[0];
+# }
+# END
+
+SHADER tessellation_evaluation tese_shader SPIRV-ASM
+ OpCapability Tessellation
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationEvaluation %main "main" %_ %gl_TessCoord %gl_in %frexp_x_out %frexp_x_in %frexp_exp_out %frexp_exp_in %frexpStruct_x_out %frexpStruct_x_in %frexpStruct_exp_out %frexpStruct_exp_in
+ OpExecutionMode %main Triangles
+ OpExecutionMode %main SpacingEqual
+ OpExecutionMode %main VertexOrderCcw
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpDecorate %gl_TessCoord BuiltIn TessCoord
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+ %uint = OpTypeInt 32 0
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %v3float = OpTypeVector %float 3
+%_ptr_Input_v3float = OpTypePointer Input %v3float
+%gl_TessCoord = OpVariable %_ptr_Input_v3float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+ %uint_32 = OpConstant %uint 32
+%_arr_gl_PerVertex_0_uint_32 = OpTypeArray %gl_PerVertex_0 %uint_32
+%_ptr_Input__arr_gl_PerVertex_0_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_32
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %int_1 = OpConstant %int 1
+ %uint_2 = OpConstant %uint 2
+ %int_2 = OpConstant %int 2
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%_ptr_Output_float = OpTypePointer Output %float
+%frexp_x_out = OpVariable %_ptr_Output_float Output
+%_arr_float_uint_32 = OpTypeArray %float %uint_32
+%_ptr_Input__arr_float_uint_32 = OpTypePointer Input %_arr_float_uint_32
+ %frexp_x_in = OpVariable %_ptr_Input__arr_float_uint_32 Input
+%frexp_exp_out = OpVariable %_ptr_Output_float Output
+%frexp_exp_in = OpVariable %_ptr_Input__arr_float_uint_32 Input
+%frexpStruct_x_out = OpVariable %_ptr_Output_float Output
+%frexpStruct_x_in = OpVariable %_ptr_Input__arr_float_uint_32 Input
+%frexpStruct_exp_out = OpVariable %_ptr_Output_float Output
+%frexpStruct_exp_in = OpVariable %_ptr_Input__arr_float_uint_32 Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %21 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_0
+ %22 = OpLoad %float %21
+ %29 = OpAccessChain %_ptr_Input_v4float %gl_in %int_0 %int_0
+ %30 = OpLoad %v4float %29
+ %31 = OpVectorTimesScalar %v4float %30 %22
+ %32 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_1
+ %33 = OpLoad %float %32
+ %35 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0
+ %36 = OpLoad %v4float %35
+ %37 = OpVectorTimesScalar %v4float %36 %33
+ %38 = OpFAdd %v4float %31 %37
+ %40 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_2
+ %41 = OpLoad %float %40
+ %43 = OpAccessChain %_ptr_Input_v4float %gl_in %int_2 %int_0
+ %44 = OpLoad %v4float %43
+ %45 = OpVectorTimesScalar %v4float %44 %41
+ %46 = OpFAdd %v4float %38 %45
+ %48 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %48 %46
+ %54 = OpAccessChain %_ptr_Input_float %frexp_x_in %int_0
+ %55 = OpLoad %float %54
+ OpStore %frexp_x_out %55
+ %58 = OpAccessChain %_ptr_Input_float %frexp_exp_in %int_0
+ %59 = OpLoad %float %58
+ OpStore %frexp_exp_out %59
+ %62 = OpAccessChain %_ptr_Input_float %frexpStruct_x_in %int_0
+ %63 = OpLoad %float %62
+ OpStore %frexpStruct_x_out %63
+ %66 = OpAccessChain %_ptr_Input_float %frexpStruct_exp_in %int_0
+ %67 = OpLoad %float %66
+ OpStore %frexpStruct_exp_out %67
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (location = 0) flat in float frexp_x_in;
+# layout (location = 1) flat in float frexp_exp_in;
+# layout (location = 2) flat in float frexpStruct_x_in;
+# layout (location = 3) flat in float frexpStruct_exp_in;
+#
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+# const vec4 clear_value = vec4(0.0, 0.0, 0.0, 1.0);
+#
+# void main ()
+# {
+# frexp_x_out = clear_value;
+# frexp_exp_out = clear_value;
+# frexpStruct_x_out = clear_value;
+# frexpStruct_exp_out = clear_value;
+# frexp_x_out.r = frexp_x_in;
+# frexp_exp_out.r = frexp_exp_in;
+# frexpStruct_x_out.r = frexpStruct_x_in;
+# frexpStruct_exp_out.r = frexpStruct_exp_in;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %frexp_x_in %frexp_exp_in %frexpStruct_x_in %frexpStruct_exp_in
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+%_ptr_Input_float = OpTypePointer Input %float
+ %frexp_x_in = OpVariable %_ptr_Input_float Input
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+%_ptr_Output_float = OpTypePointer Output %float
+%frexp_exp_in = OpVariable %_ptr_Input_float Input
+%frexpStruct_x_in = OpVariable %_ptr_Input_float Input
+%frexpStruct_exp_in = OpVariable %_ptr_Input_float Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpStore %frexp_x_out %12
+ OpStore %frexp_exp_out %12
+ OpStore %frexpStruct_x_out %12
+ OpStore %frexpStruct_exp_out %12
+ %18 = OpLoad %float %frexp_x_in
+ %22 = OpAccessChain %_ptr_Output_float %frexp_x_out %uint_0
+ OpStore %22 %18
+ %24 = OpLoad %float %frexp_exp_in
+ %25 = OpAccessChain %_ptr_Output_float %frexp_exp_out %uint_0
+ OpStore %25 %24
+ %27 = OpLoad %float %frexpStruct_x_in
+ %28 = OpAccessChain %_ptr_Output_float %frexpStruct_x_out %uint_0
+ OpStore %28 %27
+ %30 = OpLoad %float %frexpStruct_exp_in
+ %31 = OpAccessChain %_ptr_Output_float %frexpStruct_exp_out %uint_0
+ OpStore %31 %30
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH tesc_shader
+ ATTACH tese_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+#RUN test_pipeline DRAW_GRID POS 0 0 SIZE 144 144 CELLS 144 144
+RUN test_pipeline DRAW_ARRAY AS PATCH_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A tessellation evaluation shader test for FrexpStruct.
+
+DEVICE_FEATURE tessellationShader
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out uint ndx_out;
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# ndx_out = xcoord + ycoord * ndpSqrt;
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %ndx_out %_
+ OpDecorate %position Location 0
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+ %float_1 = OpConstant %float 1
+ %uint_1 = OpConstant %uint 1
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %ndx_out = OpVariable %_ptr_Output_uint Output
+ %uint_36 = OpConstant %uint 36
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_1_02777779 = OpConstant %float 1.02777779
+ %float_18 = OpConstant %float 18
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %17 = OpLoad %float %16
+ %21 = OpFAdd %float %17 %float_1_02777779
+ %24 = OpFMul %float %21 %float_18
+ %25 = OpFSub %float %24 %float_1
+ %26 = OpConvertFToU %uint %25
+ %29 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %30 = OpLoad %float %29
+ %32 = OpFAdd %float %30 %float_1_02777779
+ %34 = OpFMul %float %32 %float_18
+ %35 = OpFSub %float %34 %float_1
+ %36 = OpConvertFToU %uint %35
+ %42 = OpIMul %uint %36 %uint_36
+ %43 = OpIAdd %uint %26 %42
+ OpStore %ndx_out %43
+ %51 = OpLoad %v2float %position
+ %53 = OpCompositeExtract %float %51 0
+ %54 = OpCompositeExtract %float %51 1
+ %55 = OpCompositeConstruct %v4float %53 %54 %float_0 %float_1
+ %57 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %57 %55
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER tessellation_control tesc_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (vertices = 3) out;
+#
+# layout (location = 0) flat in uint ndx_in[];
+# layout (location = 0) flat out uint ndx_out[];
+#
+# void main ()
+# {
+# gl_TessLevelInner[0] = 1.0;
+# gl_TessLevelInner[1] = 1.0;
+# gl_TessLevelOuter[0] = 1.0;
+# gl_TessLevelOuter[1] = 1.0;
+# gl_TessLevelOuter[2] = 1.0;
+# gl_TessLevelOuter[3] = 1.0;
+#
+# gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
+# ndx_out[gl_InvocationID] = ndx_in[gl_InvocationID];
+# }
+# END
+
+SHADER tessellation_control tesc_shader SPIRV-ASM
+ OpCapability Tessellation
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationControl %main "main" %gl_TessLevelInner %gl_TessLevelOuter %gl_out %gl_InvocationID %gl_in %ndx_out %ndx_in
+ OpExecutionMode %main OutputVertices 3
+ OpDecorate %gl_TessLevelInner Patch
+ OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner
+ OpDecorate %gl_TessLevelOuter Patch
+ OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpDecorate %gl_InvocationID BuiltIn InvocationId
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_2 = OpConstant %uint 2
+%_arr_float_uint_2 = OpTypeArray %float %uint_2
+%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2
+%gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_1 = OpConstant %float 1
+%_ptr_Output_float = OpTypePointer Output %float
+ %int_1 = OpConstant %int 1
+ %uint_4 = OpConstant %uint 4
+%_arr_float_uint_4 = OpTypeArray %float %uint_4
+%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4
+%gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output
+ %int_2 = OpConstant %int 2
+ %int_3 = OpConstant %int 3
+ %v4float = OpTypeVector %float 4
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+ %uint_3 = OpConstant %uint 3
+%_arr_gl_PerVertex_uint_3 = OpTypeArray %gl_PerVertex %uint_3
+%_ptr_Output__arr_gl_PerVertex_uint_3 = OpTypePointer Output %_arr_gl_PerVertex_uint_3
+ %gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_uint_3 Output
+%_ptr_Input_int = OpTypePointer Input %int
+%gl_InvocationID = OpVariable %_ptr_Input_int Input
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+ %uint_32 = OpConstant %uint 32
+%_arr_gl_PerVertex_0_uint_32 = OpTypeArray %gl_PerVertex_0 %uint_32
+%_ptr_Input__arr_gl_PerVertex_0_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_32
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%_arr_uint_uint_3 = OpTypeArray %uint %uint_3
+%_ptr_Output__arr_uint_uint_3 = OpTypePointer Output %_arr_uint_uint_3
+ %ndx_out = OpVariable %_ptr_Output__arr_uint_uint_3 Output
+%_arr_uint_uint_32 = OpTypeArray %uint %uint_32
+%_ptr_Input__arr_uint_uint_32 = OpTypePointer Input %_arr_uint_uint_32
+ %ndx_in = OpVariable %_ptr_Input__arr_uint_uint_32 Input
+%_ptr_Input_uint = OpTypePointer Input %uint
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0
+ OpStore %16 %float_1
+ %18 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_1
+ OpStore %18 %float_1
+ %23 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0
+ OpStore %23 %float_1
+ %24 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1
+ OpStore %24 %float_1
+ %26 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2
+ OpStore %26 %float_1
+ %28 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_3
+ OpStore %28 %float_1
+ %39 = OpLoad %int %gl_InvocationID
+ %47 = OpAccessChain %_ptr_Input_v4float %gl_in %39 %int_0
+ %48 = OpLoad %v4float %47
+ %50 = OpAccessChain %_ptr_Output_v4float %gl_out %39 %int_0
+ OpStore %50 %48
+ %60 = OpAccessChain %_ptr_Input_uint %ndx_in %39
+ %61 = OpLoad %uint %60
+ %63 = OpAccessChain %_ptr_Output_uint %ndx_out %39
+ OpStore %63 %61
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER tessellation_evaluation tese_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+#
+# layout (triangles) in;
+#
+# layout (location = 0) flat in uint ndx_in[];
+# layout (location = 0) flat out float frexp_x_out;
+# layout (location = 1) flat out float frexp_exp_out;
+# layout (location = 2) flat out float frexpStruct_x_out;
+# layout (location = 3) flat out float frexpStruct_exp_out;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uint in_values[ndp];
+# };
+#
+# struct frexpStructType
+# {
+# float x;
+# int exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (float orig)
+# {
+# float x;
+# int exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# gl_Position = gl_TessCoord.x * gl_in[0].gl_Position +
+# gl_TessCoord.y * gl_in[1].gl_Position +
+# gl_TessCoord.z * gl_in[2].gl_Position;
+#
+# uint in_uint = in_values[ndx_in[0]];
+# float in_float = uintBitsToFloat(in_uint);
+# float x;
+# int exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out = x;
+# frexp_exp_out = intBitsToFloat(exp);
+# frexpStruct_x_out = res.x;
+# frexpStruct_exp_out = intBitsToFloat(res.exp);
+# }
+# END
+
+SHADER tessellation_evaluation tese_shader SPIRV-ASM
+ OpCapability Tessellation
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationEvaluation %main "main" %_ %gl_TessCoord %gl_in %ndx_in %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out
+ OpExecutionMode %main Triangles
+ OpExecutionMode %main SpacingEqual
+ OpExecutionMode %main VertexOrderCcw
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpDecorate %gl_TessCoord BuiltIn TessCoord
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ OpDecorate %_arr_uint_uint_1296 ArrayStride 4
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %__0 DescriptorSet 0
+ OpDecorate %__0 Binding 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+ %int = OpTypeInt 32 1
+%frexpStructType = OpTypeStruct %float %int
+ %10 = OpTypeFunction %frexpStructType %_ptr_Function_float
+%_ptr_Function_int = OpTypePointer Function %int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %v4float = OpTypeVector %float 4
+ %uint = OpTypeInt 32 0
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int_0 = OpConstant %int 0
+ %v3float = OpTypeVector %float 3
+%_ptr_Input_v3float = OpTypePointer Input %v3float
+%gl_TessCoord = OpVariable %_ptr_Input_v3float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+ %uint_32 = OpConstant %uint 32
+%_arr_gl_PerVertex_0_uint_32 = OpTypeArray %gl_PerVertex_0 %uint_32
+%_ptr_Input__arr_gl_PerVertex_0_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_32
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %int_1 = OpConstant %int 1
+ %uint_2 = OpConstant %uint 2
+ %int_2 = OpConstant %int 2
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_uint_uint_1296 = OpTypeArray %uint %uint_1296
+ %block0 = OpTypeStruct %_arr_uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %__0 = OpVariable %_ptr_Uniform_block0 Uniform
+%_arr_uint_uint_32 = OpTypeArray %uint %uint_32
+%_ptr_Input__arr_uint_uint_32 = OpTypePointer Input %_arr_uint_uint_32
+ %ndx_in = OpVariable %_ptr_Input__arr_uint_uint_32 Input
+%_ptr_Input_uint = OpTypePointer Input %uint
+%_ptr_Uniform_uint = OpTypePointer Uniform %uint
+%_ptr_Output_float = OpTypePointer Output %float
+%frexp_x_out = OpVariable %_ptr_Output_float Output
+%frexp_exp_out = OpVariable %_ptr_Output_float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_float Output
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %in_uint = OpVariable %_ptr_Function_uint Function
+ %in_float = OpVariable %_ptr_Function_float Function
+ %x_0 = OpVariable %_ptr_Function_float Function
+ %exp_0 = OpVariable %_ptr_Function_int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ %40 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_0
+ %41 = OpLoad %float %40
+ %48 = OpAccessChain %_ptr_Input_v4float %gl_in %int_0 %int_0
+ %49 = OpLoad %v4float %48
+ %50 = OpVectorTimesScalar %v4float %49 %41
+ %51 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_1
+ %52 = OpLoad %float %51
+ %54 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0
+ %55 = OpLoad %v4float %54
+ %56 = OpVectorTimesScalar %v4float %55 %52
+ %57 = OpFAdd %v4float %50 %56
+ %59 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_2
+ %60 = OpLoad %float %59
+ %62 = OpAccessChain %_ptr_Input_v4float %gl_in %int_2 %int_0
+ %63 = OpLoad %v4float %62
+ %64 = OpVectorTimesScalar %v4float %63 %60
+ %65 = OpFAdd %v4float %57 %64
+ %67 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %67 %65
+ %79 = OpAccessChain %_ptr_Input_uint %ndx_in %int_0
+ %80 = OpLoad %uint %79
+ %82 = OpAccessChain %_ptr_Uniform_uint %__0 %int_0 %80
+ %83 = OpLoad %uint %82
+ OpStore %in_uint %83
+ %85 = OpLoad %uint %in_uint
+ %86 = OpBitcast %float %85
+ OpStore %in_float %86
+ %88 = OpLoad %float %in_float
+ %90 = OpExtInst %float %1 Frexp %88 %exp_0
+ OpStore %x_0 %90
+ %93 = OpLoad %float %in_float
+ %94 = OpExtInst %frexpStructType %1 FrexpStruct %93
+ OpStore %res_0 %94
+ %97 = OpLoad %float %x_0
+ OpStore %frexp_x_out %97
+ %99 = OpLoad %int %exp_0
+ %100 = OpBitcast %float %99
+ OpStore %frexp_exp_out %100
+ %102 = OpAccessChain %_ptr_Function_float %res_0 %int_0
+ %103 = OpLoad %float %102
+ OpStore %frexpStruct_x_out %103
+ %105 = OpAccessChain %_ptr_Function_int %res_0 %int_1
+ %106 = OpLoad %int %105
+ %107 = OpBitcast %float %106
+ OpStore %frexpStruct_exp_out %107
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (location = 0) flat in float frexp_x_in;
+# layout (location = 1) flat in float frexp_exp_in;
+# layout (location = 2) flat in float frexpStruct_x_in;
+# layout (location = 3) flat in float frexpStruct_exp_in;
+#
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+# const vec4 clear_value = vec4(0.0, 0.0, 0.0, 1.0);
+#
+# void main ()
+# {
+# frexp_x_out = clear_value;
+# frexp_exp_out = clear_value;
+# frexpStruct_x_out = clear_value;
+# frexpStruct_exp_out = clear_value;
+# frexp_x_out.r = frexp_x_in;
+# frexp_exp_out.r = frexp_exp_in;
+# frexpStruct_x_out.r = frexpStruct_x_in;
+# frexpStruct_exp_out.r = frexpStruct_exp_in;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %frexp_x_in %frexp_exp_in %frexpStruct_x_in %frexpStruct_exp_in
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+%_ptr_Input_float = OpTypePointer Input %float
+ %frexp_x_in = OpVariable %_ptr_Input_float Input
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+%_ptr_Output_float = OpTypePointer Output %float
+%frexp_exp_in = OpVariable %_ptr_Input_float Input
+%frexpStruct_x_in = OpVariable %_ptr_Input_float Input
+%frexpStruct_exp_in = OpVariable %_ptr_Input_float Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpStore %frexp_x_out %12
+ OpStore %frexp_exp_out %12
+ OpStore %frexpStruct_x_out %12
+ OpStore %frexpStruct_exp_out %12
+ %18 = OpLoad %float %frexp_x_in
+ %22 = OpAccessChain %_ptr_Output_float %frexp_x_out %uint_0
+ OpStore %22 %18
+ %24 = OpLoad %float %frexp_exp_in
+ %25 = OpAccessChain %_ptr_Output_float %frexp_exp_out %uint_0
+ OpStore %25 %24
+ %27 = OpLoad %float %frexpStruct_x_in
+ %28 = OpAccessChain %_ptr_Output_float %frexpStruct_x_out %uint_0
+ OpStore %28 %27
+ %30 = OpLoad %float %frexpStruct_exp_in
+ %31 = OpAccessChain %_ptr_Output_float %frexpStruct_exp_out %uint_0
+ OpStore %31 %30
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH tesc_shader
+ ATTACH tese_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+#RUN test_pipeline DRAW_GRID POS 0 0 SIZE 144 144 CELLS 144 144
+RUN test_pipeline DRAW_ARRAY AS PATCH_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A vertex shader test for FrexpStruct.
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out float frexp_x_out;
+# layout (location = 1) flat out float frexp_exp_out;
+# layout (location = 2) flat out float frexpStruct_x_out;
+# layout (location = 3) flat out float frexpStruct_exp_out;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uint in_values[ndp];
+# };
+#
+# struct frexpStructType
+# {
+# float x;
+# int exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (float orig)
+# {
+# float x;
+# int exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# uint ndx = xcoord + ycoord * ndpSqrt;
+#
+# uint in_uint = in_values[ndx];
+# float in_float = uintBitsToFloat(in_uint);
+# float x;
+# int exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out = x;
+# frexp_exp_out = intBitsToFloat(exp);
+# frexpStruct_x_out = res.x;
+# frexpStruct_exp_out = intBitsToFloat(res.exp);
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %__0
+ OpDecorate %position Location 0
+ OpDecorate %_arr_uint_uint_1296 ArrayStride 4
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+ %int = OpTypeInt 32 1
+%frexpStructType = OpTypeStruct %float %int
+ %10 = OpTypeFunction %frexpStructType %_ptr_Function_float
+%_ptr_Function_int = OpTypePointer Function %int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %float_36 = OpConstant %float 36
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+%float_0_027777778 = OpConstant %float 0.027777778
+ %float_1 = OpConstant %float 1
+ %float_2 = OpConstant %float 2
+ %uint_1 = OpConstant %uint 1
+ %uint_36 = OpConstant %uint 36
+ %uint_1296 = OpConstant %uint 1296
+%_arr_uint_uint_1296 = OpTypeArray %uint %uint_1296
+ %block0 = OpTypeStruct %_arr_uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %int_0 = OpConstant %int 0
+%_ptr_Uniform_uint = OpTypePointer Uniform %uint
+%_ptr_Output_float = OpTypePointer Output %float
+%frexp_x_out = OpVariable %_ptr_Output_float Output
+%frexp_exp_out = OpVariable %_ptr_Output_float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_float Output
+ %int_1 = OpConstant %int 1
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %__0 = OpVariable %_ptr_Output_gl_PerVertex Output
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %xcoord = OpVariable %_ptr_Function_uint Function
+ %ycoord = OpVariable %_ptr_Function_uint Function
+ %ndx = OpVariable %_ptr_Function_uint Function
+ %in_uint = OpVariable %_ptr_Function_uint Function
+ %in_float = OpVariable %_ptr_Function_float Function
+ %x_0 = OpVariable %_ptr_Function_float Function
+ %exp_0 = OpVariable %_ptr_Function_int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ %36 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %37 = OpLoad %float %36
+ %39 = OpFAdd %float %37 %float_0_027777778
+ %41 = OpFAdd %float %39 %float_1
+ %43 = OpFDiv %float %41 %float_2
+ %44 = OpFMul %float %float_36 %43
+ %45 = OpFSub %float %44 %float_1
+ %46 = OpConvertFToU %uint %45
+ OpStore %xcoord %46
+ %49 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %50 = OpLoad %float %49
+ %51 = OpFAdd %float %50 %float_0_027777778
+ %52 = OpFAdd %float %51 %float_1
+ %53 = OpFDiv %float %52 %float_2
+ %54 = OpFMul %float %float_36 %53
+ %55 = OpFSub %float %54 %float_1
+ %56 = OpConvertFToU %uint %55
+ OpStore %ycoord %56
+ %58 = OpLoad %uint %xcoord
+ %59 = OpLoad %uint %ycoord
+ %61 = OpIMul %uint %59 %uint_36
+ %62 = OpIAdd %uint %58 %61
+ OpStore %ndx %62
+ %70 = OpLoad %uint %ndx
+ %72 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 %70
+ %73 = OpLoad %uint %72
+ OpStore %in_uint %73
+ %75 = OpLoad %uint %in_uint
+ %76 = OpBitcast %float %75
+ OpStore %in_float %76
+ %78 = OpLoad %float %in_float
+ %80 = OpExtInst %float %1 Frexp %78 %exp_0
+ OpStore %x_0 %80
+ %83 = OpLoad %float %in_float
+ %84 = OpExtInst %frexpStructType %1 FrexpStruct %83
+ OpStore %res_0 %84
+ %87 = OpLoad %float %x_0
+ OpStore %frexp_x_out %87
+ %89 = OpLoad %int %exp_0
+ %90 = OpBitcast %float %89
+ OpStore %frexp_exp_out %90
+ %92 = OpAccessChain %_ptr_Function_float %res_0 %int_0
+ %93 = OpLoad %float %92
+ OpStore %frexpStruct_x_out %93
+ %96 = OpAccessChain %_ptr_Function_int %res_0 %int_1
+ %97 = OpLoad %int %96
+ %98 = OpBitcast %float %97
+ OpStore %frexpStruct_exp_out %98
+ %104 = OpLoad %v2float %position
+ %106 = OpCompositeExtract %float %104 0
+ %107 = OpCompositeExtract %float %104 1
+ %108 = OpCompositeConstruct %v4float %106 %107 %float_0 %float_1
+ %110 = OpAccessChain %_ptr_Output_v4float %__0 %int_0
+ OpStore %110 %108
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (location = 0) flat in float frexp_x_in;
+# layout (location = 1) flat in float frexp_exp_in;
+# layout (location = 2) flat in float frexpStruct_x_in;
+# layout (location = 3) flat in float frexpStruct_exp_in;
+#
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+# const vec4 clear_value = vec4(0.0, 0.0, 0.0, 1.0);
+#
+# void main ()
+# {
+# frexp_x_out = clear_value;
+# frexp_exp_out = clear_value;
+# frexpStruct_x_out = clear_value;
+# frexpStruct_exp_out = clear_value;
+# frexp_x_out.r = frexp_x_in;
+# frexp_exp_out.r = frexp_exp_in;
+# frexpStruct_x_out.r = frexpStruct_x_in;
+# frexpStruct_exp_out.r = frexpStruct_exp_in;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %frexp_x_in %frexp_exp_in %frexpStruct_x_in %frexpStruct_exp_in
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+%_ptr_Input_float = OpTypePointer Input %float
+ %frexp_x_in = OpVariable %_ptr_Input_float Input
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+%_ptr_Output_float = OpTypePointer Output %float
+%frexp_exp_in = OpVariable %_ptr_Input_float Input
+%frexpStruct_x_in = OpVariable %_ptr_Input_float Input
+%frexpStruct_exp_in = OpVariable %_ptr_Input_float Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpStore %frexp_x_out %12
+ OpStore %frexp_exp_out %12
+ OpStore %frexpStruct_x_out %12
+ OpStore %frexpStruct_exp_out %12
+ %18 = OpLoad %float %frexp_x_in
+ %22 = OpAccessChain %_ptr_Output_float %frexp_x_out %uint_0
+ OpStore %22 %18
+ %24 = OpLoad %float %frexp_exp_in
+ %25 = OpAccessChain %_ptr_Output_float %frexp_exp_out %uint_0
+ OpStore %25 %24
+ %27 = OpLoad %float %frexpStruct_x_in
+ %28 = OpAccessChain %_ptr_Output_float %frexpStruct_x_out %uint_0
+ OpStore %28 %27
+ %30 = OpLoad %float %frexpStruct_exp_in
+ %31 = OpAccessChain %_ptr_Output_float %frexpStruct_exp_out %uint_0
+ OpStore %31 %30
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+RUN test_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A compute shader test for FrexpStruct.
+
+# SHADER compute comp_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296 / 2;
+# const uint half_ndp = ndp / 2;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec2 in_values[half_ndp];
+# };
+#
+# layout(set = 0, binding = 1) buffer block1 {
+# vec2 frexp_out[ndp];
+# };
+#
+# layout(set = 0, binding = 2) buffer block2 {
+# vec2 frexpStruct_out[ndp];
+# };
+#
+# struct frexpStructType
+# {
+# vec2 x;
+# ivec2 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec2 orig)
+# {
+# vec2 x;
+# ivec2 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# for (uint ndx = 0; ndx < ndp; ndx += 2)
+# {
+# uvec2 in_uint = in_values[ndx/2];
+# vec2 in_float = uintBitsToFloat(in_uint);
+# vec2 x;
+# ivec2 exp;
+#
+# x = frexp(in_float, exp);
+# frexpStructType res = frexpStruct(in_float);
+#
+# frexp_out[ndx] = intBitsToFloat(exp);
+# frexp_out[ndx+1] = x;
+# frexpStruct_out[ndx] = intBitsToFloat(res.exp);
+# frexpStruct_out[ndx+1] = res.x;
+# }
+#
+# return;
+# }
+# END
+
+SHADER compute comp_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpDecorate %_arr_v2uint_uint_324 ArrayStride 8
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %_arr_v2float_uint_648 ArrayStride 8
+ OpMemberDecorate %block1 0 Offset 0
+ OpDecorate %block1 BufferBlock
+ OpDecorate %__0 DescriptorSet 0
+ OpDecorate %__0 Binding 1
+ OpDecorate %_arr_v2float_uint_648_0 ArrayStride 8
+ OpMemberDecorate %block2 0 Offset 0
+ OpDecorate %block2 BufferBlock
+ OpDecorate %__1 DescriptorSet 0
+ OpDecorate %__1 Binding 2
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+ %int = OpTypeInt 32 1
+ %v2int = OpTypeVector %int 2
+%frexpStructType = OpTypeStruct %v2float %v2int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v2float
+%_ptr_Function_v2int = OpTypePointer Function %v2int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %uint_0 = OpConstant %uint 0
+ %uint_648 = OpConstant %uint 648
+ %bool = OpTypeBool
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %uint_324 = OpConstant %uint 324
+%_arr_v2uint_uint_324 = OpTypeArray %v2uint %uint_324
+ %block0 = OpTypeStruct %_arr_v2uint_uint_324
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %int_0 = OpConstant %int 0
+ %uint_2 = OpConstant %uint 2
+%_ptr_Uniform_v2uint = OpTypePointer Uniform %v2uint
+%_arr_v2float_uint_648 = OpTypeArray %v2float %uint_648
+ %block1 = OpTypeStruct %_arr_v2float_uint_648
+%_ptr_Uniform_block1 = OpTypePointer Uniform %block1
+ %__0 = OpVariable %_ptr_Uniform_block1 Uniform
+%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
+ %uint_1 = OpConstant %uint 1
+%_arr_v2float_uint_648_0 = OpTypeArray %v2float %uint_648
+ %block2 = OpTypeStruct %_arr_v2float_uint_648_0
+%_ptr_Uniform_block2 = OpTypePointer Uniform %block2
+ %__1 = OpVariable %_ptr_Uniform_block2 Uniform
+ %int_1 = OpConstant %int 1
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %ndx = OpVariable %_ptr_Function_uint Function
+ %in_uint = OpVariable %_ptr_Function_v2uint Function
+ %in_float = OpVariable %_ptr_Function_v2float Function
+ %x_0 = OpVariable %_ptr_Function_v2float Function
+ %exp_0 = OpVariable %_ptr_Function_v2int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ OpStore %ndx %uint_0
+ OpBranch %33
+ %33 = OpLabel
+ OpLoopMerge %35 %36 None
+ OpBranch %37
+ %37 = OpLabel
+ %38 = OpLoad %uint %ndx
+ %41 = OpULessThan %bool %38 %uint_648
+ OpBranchConditional %41 %34 %35
+ %34 = OpLabel
+ %51 = OpLoad %uint %ndx
+ %53 = OpUDiv %uint %51 %uint_2
+ %55 = OpAccessChain %_ptr_Uniform_v2uint %_ %int_0 %53
+ %56 = OpLoad %v2uint %55
+ OpStore %in_uint %56
+ %58 = OpLoad %v2uint %in_uint
+ %59 = OpBitcast %v2float %58
+ OpStore %in_float %59
+ %61 = OpLoad %v2float %in_float
+ %63 = OpExtInst %v2float %1 Frexp %61 %exp_0
+ OpStore %x_0 %63
+ %66 = OpLoad %v2float %in_float
+ %67 = OpExtInst %frexpStructType %1 FrexpStruct %66
+ OpStore %res_0 %67
+ %72 = OpLoad %uint %ndx
+ %73 = OpLoad %v2int %exp_0
+ %74 = OpBitcast %v2float %73
+ %76 = OpAccessChain %_ptr_Uniform_v2float %__0 %int_0 %72
+ OpStore %76 %74
+ %77 = OpLoad %uint %ndx
+ %79 = OpIAdd %uint %77 %uint_1
+ %80 = OpLoad %v2float %x_0
+ %81 = OpAccessChain %_ptr_Uniform_v2float %__0 %int_0 %79
+ OpStore %81 %80
+ %86 = OpLoad %uint %ndx
+ %88 = OpAccessChain %_ptr_Function_v2int %res_0 %int_1
+ %89 = OpLoad %v2int %88
+ %90 = OpBitcast %v2float %89
+ %91 = OpAccessChain %_ptr_Uniform_v2float %__1 %int_0 %86
+ OpStore %91 %90
+ %92 = OpLoad %uint %ndx
+ %93 = OpIAdd %uint %92 %uint_1
+ %94 = OpAccessChain %_ptr_Function_v2float %res_0 %int_0
+ %95 = OpLoad %v2float %94
+ %96 = OpAccessChain %_ptr_Uniform_v2float %__1 %int_0 %93
+ OpStore %96 %95
+ OpBranch %36
+ %36 = OpLabel
+ %97 = OpLoad %uint %ndx
+ %98 = OpIAdd %uint %97 %uint_2
+ OpStore %ndx %98
+ OpBranch %33
+ %35 = OpLabel
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+
+BUFFER buf_frexp DATA_TYPE vec2<float> SIZE 648 FILL 0.0
+BUFFER buf_frexpStruct DATA_TYPE vec2<float> SIZE 648 FILL 1.0
+
+PIPELINE compute test_pipeline
+ ATTACH comp_shader
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER buf_frexp AS storage DESCRIPTOR_SET 0 BINDING 1
+ BIND BUFFER buf_frexpStruct AS storage DESCRIPTOR_SET 0 BINDING 2
+END
+
+RUN test_pipeline 1 1 1
+
+EXPECT buf_frexp EQ_BUFFER buf_frexpStruct
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A fragment shader test for FrexpStruct.
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out uint ndx_out;
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# ndx_out = xcoord + ycoord * ndpSqrt;
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %ndx_out %_
+ OpDecorate %position Location 0
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+ %float_1 = OpConstant %float 1
+ %uint_1 = OpConstant %uint 1
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %ndx_out = OpVariable %_ptr_Output_uint Output
+ %uint_36 = OpConstant %uint 36
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_1_02777779 = OpConstant %float 1.02777779
+ %float_18 = OpConstant %float 18
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %17 = OpLoad %float %16
+ %21 = OpFAdd %float %17 %float_1_02777779
+ %24 = OpFMul %float %21 %float_18
+ %25 = OpFSub %float %24 %float_1
+ %26 = OpConvertFToU %uint %25
+ %29 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %30 = OpLoad %float %29
+ %32 = OpFAdd %float %30 %float_1_02777779
+ %34 = OpFMul %float %32 %float_18
+ %35 = OpFSub %float %34 %float_1
+ %36 = OpConvertFToU %uint %35
+ %42 = OpIMul %uint %36 %uint_36
+ %43 = OpIAdd %uint %26 %42
+ OpStore %ndx_out %43
+ %51 = OpLoad %v2float %position
+ %53 = OpCompositeExtract %float %51 0
+ %54 = OpCompositeExtract %float %51 1
+ %55 = OpCompositeConstruct %v4float %53 %54 %float_0 %float_1
+ %57 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %57 %55
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const vec4 clear_value = vec4(0.0, 0.0, 0.0, 1.0);
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec2 in_values[ndp];
+# };
+#
+# layout (location = 0) flat in uint ndx_in;
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+# struct frexpStructType
+# {
+# vec2 x;
+# ivec2 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec2 orig)
+# {
+# vec2 x;
+# ivec2 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# uvec2 in_uint = in_values[ndx_in];
+# vec2 in_float = uintBitsToFloat(in_uint);
+# vec2 x;
+# ivec2 exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out = clear_value;
+# frexp_exp_out = clear_value;
+# frexpStruct_x_out = clear_value;
+# frexpStruct_exp_out = clear_value;
+# frexp_x_out.rg = x;
+# frexp_exp_out.rg = intBitsToFloat(exp);
+# frexpStruct_x_out.rg = res.x;
+# frexpStruct_exp_out.rg = intBitsToFloat(res.exp);
+#
+# return;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %ndx_in %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %_arr_v2uint_uint_1296 ArrayStride 8
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+ %int = OpTypeInt 32 1
+ %v2int = OpTypeVector %int 2
+%frexpStructType = OpTypeStruct %v2float %v2int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v2float
+%_ptr_Function_v2int = OpTypePointer Function %v2int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_v2uint_uint_1296 = OpTypeArray %v2uint %uint_1296
+ %block0 = OpTypeStruct %_arr_v2uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %int_0 = OpConstant %int 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+ %ndx_in = OpVariable %_ptr_Input_uint Input
+%_ptr_Uniform_v2uint = OpTypePointer Uniform %v2uint
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %61 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+ %int_1 = OpConstant %int 1
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %in_uint = OpVariable %_ptr_Function_v2uint Function
+ %in_float = OpVariable %_ptr_Function_v2float Function
+ %x_0 = OpVariable %_ptr_Function_v2float Function
+ %exp_0 = OpVariable %_ptr_Function_v2int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ %41 = OpLoad %uint %ndx_in
+ %43 = OpAccessChain %_ptr_Uniform_v2uint %_ %int_0 %41
+ %44 = OpLoad %v2uint %43
+ OpStore %in_uint %44
+ %46 = OpLoad %v2uint %in_uint
+ %47 = OpBitcast %v2float %46
+ OpStore %in_float %47
+ %49 = OpLoad %v2float %in_float
+ %51 = OpExtInst %v2float %1 Frexp %49 %exp_0
+ OpStore %x_0 %51
+ %54 = OpLoad %v2float %in_float
+ %55 = OpExtInst %frexpStructType %1 FrexpStruct %54
+ OpStore %res_0 %55
+ OpStore %frexp_x_out %61
+ OpStore %frexp_exp_out %61
+ OpStore %frexpStruct_x_out %61
+ OpStore %frexpStruct_exp_out %61
+ %65 = OpLoad %v2float %x_0
+ %66 = OpLoad %v4float %frexp_x_out
+ %67 = OpVectorShuffle %v4float %66 %65 4 5 2 3
+ OpStore %frexp_x_out %67
+ %68 = OpLoad %v2int %exp_0
+ %69 = OpBitcast %v2float %68
+ %70 = OpLoad %v4float %frexp_exp_out
+ %71 = OpVectorShuffle %v4float %70 %69 4 5 2 3
+ OpStore %frexp_exp_out %71
+ %72 = OpAccessChain %_ptr_Function_v2float %res_0 %int_0
+ %73 = OpLoad %v2float %72
+ %74 = OpLoad %v4float %frexpStruct_x_out
+ %75 = OpVectorShuffle %v4float %74 %73 4 5 2 3
+ OpStore %frexpStruct_x_out %75
+ %77 = OpAccessChain %_ptr_Function_v2int %res_0 %int_1
+ %78 = OpLoad %v2int %77
+ %79 = OpBitcast %v2float %78
+ %80 = OpLoad %v4float %frexpStruct_exp_out
+ %81 = OpVectorShuffle %v4float %80 %79 4 5 2 3
+ OpStore %frexpStruct_exp_out %81
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+RUN test_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A geometry shader test for FrexpStruct.
+
+DEVICE_FEATURE geometryShader
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out uint ndx_out;
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# ndx_out = xcoord + ycoord * ndpSqrt;
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %ndx_out %_
+ OpDecorate %position Location 0
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+ %float_1 = OpConstant %float 1
+ %uint_1 = OpConstant %uint 1
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %ndx_out = OpVariable %_ptr_Output_uint Output
+ %uint_36 = OpConstant %uint 36
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_1_02777779 = OpConstant %float 1.02777779
+ %float_18 = OpConstant %float 18
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %17 = OpLoad %float %16
+ %21 = OpFAdd %float %17 %float_1_02777779
+ %24 = OpFMul %float %21 %float_18
+ %25 = OpFSub %float %24 %float_1
+ %26 = OpConvertFToU %uint %25
+ %29 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %30 = OpLoad %float %29
+ %32 = OpFAdd %float %30 %float_1_02777779
+ %34 = OpFMul %float %32 %float_18
+ %35 = OpFSub %float %34 %float_1
+ %36 = OpConvertFToU %uint %35
+ %42 = OpIMul %uint %36 %uint_36
+ %43 = OpIAdd %uint %26 %42
+ OpStore %ndx_out %43
+ %51 = OpLoad %v2float %position
+ %53 = OpCompositeExtract %float %51 0
+ %54 = OpCompositeExtract %float %51 1
+ %55 = OpCompositeConstruct %v4float %53 %54 %float_0 %float_1
+ %57 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %57 %55
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER geometry geom_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec2 in_values[ndp];
+# };
+#
+# layout (triangles) in;
+# layout (triangle_strip, max_vertices = 3) out;
+#
+# layout (location = 0) flat in uint ndx_in[];
+# layout (location = 0) flat out vec2 frexp_x_out;
+# layout (location = 1) flat out vec2 frexp_exp_out;
+# layout (location = 2) flat out vec2 frexpStruct_x_out;
+# layout (location = 3) flat out vec2 frexpStruct_exp_out;
+#
+# struct frexpStructType
+# {
+# vec2 x;
+# ivec2 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec2 orig)
+# {
+# vec2 x;
+# ivec2 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# for (int vertex = 0; vertex < 3; vertex++)
+# {
+# uvec2 in_uint = in_values[ndx_in[vertex]];
+# vec2 in_float = uintBitsToFloat(in_uint);
+# vec2 x;
+# ivec2 exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out = x;
+# frexp_exp_out = intBitsToFloat(exp);
+# frexpStruct_x_out = res.x;
+# frexpStruct_exp_out = intBitsToFloat(res.exp);
+#
+# gl_Position = gl_in[vertex].gl_Position;
+# EmitVertex();
+# }
+#
+# EndPrimitive();
+# }
+# END
+
+SHADER geometry geom_shader SPIRV-ASM
+ OpCapability Geometry
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Geometry %main "main" %ndx_in %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %__0 %gl_in
+ OpExecutionMode %main Triangles
+ OpExecutionMode %main Invocations 1
+ OpExecutionMode %main OutputTriangleStrip
+ OpExecutionMode %main OutputVertices 3
+ OpDecorate %_arr_v2uint_uint_1296 ArrayStride 8
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+ %int = OpTypeInt 32 1
+ %v2int = OpTypeVector %int 2
+%frexpStructType = OpTypeStruct %v2float %v2int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v2float
+%_ptr_Function_v2int = OpTypePointer Function %v2int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+%_ptr_Function_int = OpTypePointer Function %int
+ %int_0 = OpConstant %int 0
+ %int_3 = OpConstant %int 3
+ %bool = OpTypeBool
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_v2uint_uint_1296 = OpTypeArray %v2uint %uint_1296
+ %block0 = OpTypeStruct %_arr_v2uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %uint_3 = OpConstant %uint 3
+%_arr_uint_uint_3 = OpTypeArray %uint %uint_3
+%_ptr_Input__arr_uint_uint_3 = OpTypePointer Input %_arr_uint_uint_3
+ %ndx_in = OpVariable %_ptr_Input__arr_uint_uint_3 Input
+%_ptr_Input_uint = OpTypePointer Input %uint
+%_ptr_Uniform_v2uint = OpTypePointer Uniform %v2uint
+%_ptr_Output_v2float = OpTypePointer Output %v2float
+%frexp_x_out = OpVariable %_ptr_Output_v2float Output
+%frexp_exp_out = OpVariable %_ptr_Output_v2float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v2float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v2float Output
+ %int_1 = OpConstant %int 1
+ %v4float = OpTypeVector %float 4
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %__0 = OpVariable %_ptr_Output_gl_PerVertex Output
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_arr_gl_PerVertex_0_uint_3 = OpTypeArray %gl_PerVertex_0 %uint_3
+%_ptr_Input__arr_gl_PerVertex_0_uint_3 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_3
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_3 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %vertex = OpVariable %_ptr_Function_int Function
+ %in_uint = OpVariable %_ptr_Function_v2uint Function
+ %in_float = OpVariable %_ptr_Function_v2float Function
+ %x_0 = OpVariable %_ptr_Function_v2float Function
+ %exp_0 = OpVariable %_ptr_Function_v2int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ OpStore %vertex %int_0
+ OpBranch %32
+ %32 = OpLabel
+ OpLoopMerge %34 %35 None
+ OpBranch %36
+ %36 = OpLabel
+ %37 = OpLoad %int %vertex
+ %40 = OpSLessThan %bool %37 %int_3
+ OpBranchConditional %40 %33 %34
+ %33 = OpLabel
+ %54 = OpLoad %int %vertex
+ %56 = OpAccessChain %_ptr_Input_uint %ndx_in %54
+ %57 = OpLoad %uint %56
+ %59 = OpAccessChain %_ptr_Uniform_v2uint %_ %int_0 %57
+ %60 = OpLoad %v2uint %59
+ OpStore %in_uint %60
+ %62 = OpLoad %v2uint %in_uint
+ %63 = OpBitcast %v2float %62
+ OpStore %in_float %63
+ %65 = OpLoad %v2float %in_float
+ %67 = OpExtInst %v2float %1 Frexp %65 %exp_0
+ OpStore %x_0 %67
+ %70 = OpLoad %v2float %in_float
+ %71 = OpExtInst %frexpStructType %1 FrexpStruct %70
+ OpStore %res_0 %71
+ %74 = OpLoad %v2float %x_0
+ OpStore %frexp_x_out %74
+ %76 = OpLoad %v2int %exp_0
+ %77 = OpBitcast %v2float %76
+ OpStore %frexp_exp_out %77
+ %79 = OpAccessChain %_ptr_Function_v2float %res_0 %int_0
+ %80 = OpLoad %v2float %79
+ OpStore %frexpStruct_x_out %80
+ %83 = OpAccessChain %_ptr_Function_v2int %res_0 %int_1
+ %84 = OpLoad %v2int %83
+ %85 = OpBitcast %v2float %84
+ OpStore %frexpStruct_exp_out %85
+ %96 = OpLoad %int %vertex
+ %98 = OpAccessChain %_ptr_Input_v4float %gl_in %96 %int_0
+ %99 = OpLoad %v4float %98
+ %101 = OpAccessChain %_ptr_Output_v4float %__0 %int_0
+ OpStore %101 %99
+ OpEmitVertex
+ OpBranch %35
+ %35 = OpLabel
+ %102 = OpLoad %int %vertex
+ %103 = OpIAdd %int %102 %int_1
+ OpStore %vertex %103
+ OpBranch %32
+ %34 = OpLabel
+ OpEndPrimitive
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (location = 0) flat in vec2 frexp_x_in;
+# layout (location = 1) flat in vec2 frexp_exp_in;
+# layout (location = 2) flat in vec2 frexpStruct_x_in;
+# layout (location = 3) flat in vec2 frexpStruct_exp_in;
+#
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+# const vec4 clear_value = vec4(0.0, 0.0, 0.0, 1.0);
+#
+# void main ()
+# {
+# frexp_x_out = clear_value;
+# frexp_exp_out = clear_value;
+# frexpStruct_x_out = clear_value;
+# frexpStruct_exp_out = clear_value;
+# frexp_x_out.rg = frexp_x_in;
+# frexp_exp_out.rg = frexp_exp_in;
+# frexpStruct_x_out.rg = frexpStruct_x_in;
+# frexpStruct_exp_out.rg = frexpStruct_exp_in;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %frexp_x_in %frexp_exp_in %frexpStruct_x_in %frexpStruct_exp_in
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %frexp_x_in = OpVariable %_ptr_Input_v2float Input
+%frexp_exp_in = OpVariable %_ptr_Input_v2float Input
+%frexpStruct_x_in = OpVariable %_ptr_Input_v2float Input
+%frexpStruct_exp_in = OpVariable %_ptr_Input_v2float Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpStore %frexp_x_out %12
+ OpStore %frexp_exp_out %12
+ OpStore %frexpStruct_x_out %12
+ OpStore %frexpStruct_exp_out %12
+ %19 = OpLoad %v2float %frexp_x_in
+ %20 = OpLoad %v4float %frexp_x_out
+ %21 = OpVectorShuffle %v4float %20 %19 4 5 2 3
+ OpStore %frexp_x_out %21
+ %23 = OpLoad %v2float %frexp_exp_in
+ %24 = OpLoad %v4float %frexp_exp_out
+ %25 = OpVectorShuffle %v4float %24 %23 4 5 2 3
+ OpStore %frexp_exp_out %25
+ %27 = OpLoad %v2float %frexpStruct_x_in
+ %28 = OpLoad %v4float %frexpStruct_x_out
+ %29 = OpVectorShuffle %v4float %28 %27 4 5 2 3
+ OpStore %frexpStruct_x_out %29
+ %31 = OpLoad %v2float %frexpStruct_exp_in
+ %32 = OpLoad %v4float %frexpStruct_exp_out
+ %33 = OpVectorShuffle %v4float %32 %31 4 5 2 3
+ OpStore %frexpStruct_exp_out %33
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH geom_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+RUN test_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A tessellation control shader test for FrexpStruct.
+
+DEVICE_FEATURE tessellationShader
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out uint ndx_out;
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# ndx_out = xcoord + ycoord * ndpSqrt;
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %ndx_out %_
+ OpDecorate %position Location 0
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+ %float_1 = OpConstant %float 1
+ %uint_1 = OpConstant %uint 1
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %ndx_out = OpVariable %_ptr_Output_uint Output
+ %uint_36 = OpConstant %uint 36
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_1_02777779 = OpConstant %float 1.02777779
+ %float_18 = OpConstant %float 18
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %17 = OpLoad %float %16
+ %21 = OpFAdd %float %17 %float_1_02777779
+ %24 = OpFMul %float %21 %float_18
+ %25 = OpFSub %float %24 %float_1
+ %26 = OpConvertFToU %uint %25
+ %29 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %30 = OpLoad %float %29
+ %32 = OpFAdd %float %30 %float_1_02777779
+ %34 = OpFMul %float %32 %float_18
+ %35 = OpFSub %float %34 %float_1
+ %36 = OpConvertFToU %uint %35
+ %42 = OpIMul %uint %36 %uint_36
+ %43 = OpIAdd %uint %26 %42
+ OpStore %ndx_out %43
+ %51 = OpLoad %v2float %position
+ %53 = OpCompositeExtract %float %51 0
+ %54 = OpCompositeExtract %float %51 1
+ %55 = OpCompositeConstruct %v4float %53 %54 %float_0 %float_1
+ %57 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %57 %55
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER tessellation_control tesc_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+#
+# layout (vertices = 3) out;
+#
+# layout (location = 0) flat in uint ndx_in[];
+# layout (location = 0) flat out vec2 frexp_x_out[];
+# layout (location = 1) flat out vec2 frexp_exp_out[];
+# layout (location = 2) flat out vec2 frexpStruct_x_out[];
+# layout (location = 3) flat out vec2 frexpStruct_exp_out[];
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec2 in_values[ndp];
+# };
+#
+# struct frexpStructType
+# {
+# vec2 x;
+# ivec2 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec2 orig)
+# {
+# vec2 x;
+# ivec2 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# uvec2 in_uint = in_values[ndx_in[gl_InvocationID]];
+# vec2 in_float = uintBitsToFloat(in_uint);
+# vec2 x;
+# ivec2 exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out[gl_InvocationID] = x;
+# frexp_exp_out[gl_InvocationID] = intBitsToFloat(exp);
+# frexpStruct_x_out[gl_InvocationID] = res.x;
+# frexpStruct_exp_out[gl_InvocationID] = intBitsToFloat(res.exp);
+#
+# gl_TessLevelInner[0] = 1.0;
+# gl_TessLevelInner[1] = 1.0;
+# gl_TessLevelOuter[0] = 1.0;
+# gl_TessLevelOuter[1] = 1.0;
+# gl_TessLevelOuter[2] = 1.0;
+# gl_TessLevelOuter[3] = 1.0;
+# gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
+# }
+# END
+
+SHADER tessellation_control tesc_shader SPIRV-ASM
+ OpCapability Tessellation
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationControl %main "main" %ndx_in %gl_InvocationID %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %gl_TessLevelInner %gl_TessLevelOuter %gl_out %gl_in
+ OpExecutionMode %main OutputVertices 3
+ OpDecorate %_arr_v2uint_uint_1296 ArrayStride 8
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ OpDecorate %gl_InvocationID BuiltIn InvocationId
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %gl_TessLevelInner Patch
+ OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner
+ OpDecorate %gl_TessLevelOuter Patch
+ OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+ %int = OpTypeInt 32 1
+ %v2int = OpTypeVector %int 2
+%frexpStructType = OpTypeStruct %v2float %v2int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v2float
+%_ptr_Function_v2int = OpTypePointer Function %v2int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_v2uint_uint_1296 = OpTypeArray %v2uint %uint_1296
+ %block0 = OpTypeStruct %_arr_v2uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %int_0 = OpConstant %int 0
+ %uint_32 = OpConstant %uint 32
+%_arr_uint_uint_32 = OpTypeArray %uint %uint_32
+%_ptr_Input__arr_uint_uint_32 = OpTypePointer Input %_arr_uint_uint_32
+ %ndx_in = OpVariable %_ptr_Input__arr_uint_uint_32 Input
+%_ptr_Input_int = OpTypePointer Input %int
+%gl_InvocationID = OpVariable %_ptr_Input_int Input
+%_ptr_Input_uint = OpTypePointer Input %uint
+%_ptr_Uniform_v2uint = OpTypePointer Uniform %v2uint
+ %uint_3 = OpConstant %uint 3
+%_arr_v2float_uint_3 = OpTypeArray %v2float %uint_3
+%_ptr_Output__arr_v2float_uint_3 = OpTypePointer Output %_arr_v2float_uint_3
+%frexp_x_out = OpVariable %_ptr_Output__arr_v2float_uint_3 Output
+%_ptr_Output_v2float = OpTypePointer Output %v2float
+%frexp_exp_out = OpVariable %_ptr_Output__arr_v2float_uint_3 Output
+%frexpStruct_x_out = OpVariable %_ptr_Output__arr_v2float_uint_3 Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output__arr_v2float_uint_3 Output
+ %int_1 = OpConstant %int 1
+ %uint_2 = OpConstant %uint 2
+%_arr_float_uint_2 = OpTypeArray %float %uint_2
+%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2
+%gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output
+ %float_1 = OpConstant %float 1
+%_ptr_Output_float = OpTypePointer Output %float
+ %uint_4 = OpConstant %uint 4
+%_arr_float_uint_4 = OpTypeArray %float %uint_4
+%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4
+%gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output
+ %int_2 = OpConstant %int 2
+ %int_3 = OpConstant %int 3
+ %v4float = OpTypeVector %float 4
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_arr_gl_PerVertex_uint_3 = OpTypeArray %gl_PerVertex %uint_3
+%_ptr_Output__arr_gl_PerVertex_uint_3 = OpTypePointer Output %_arr_gl_PerVertex_uint_3
+ %gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_uint_3 Output
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_arr_gl_PerVertex_0_uint_32 = OpTypeArray %gl_PerVertex_0 %uint_32
+%_ptr_Input__arr_gl_PerVertex_0_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_32
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %in_uint = OpVariable %_ptr_Function_v2uint Function
+ %in_float = OpVariable %_ptr_Function_v2float Function
+ %x_0 = OpVariable %_ptr_Function_v2float Function
+ %exp_0 = OpVariable %_ptr_Function_v2int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ %45 = OpLoad %int %gl_InvocationID
+ %47 = OpAccessChain %_ptr_Input_uint %ndx_in %45
+ %48 = OpLoad %uint %47
+ %50 = OpAccessChain %_ptr_Uniform_v2uint %_ %int_0 %48
+ %51 = OpLoad %v2uint %50
+ OpStore %in_uint %51
+ %53 = OpLoad %v2uint %in_uint
+ %54 = OpBitcast %v2float %53
+ OpStore %in_float %54
+ %56 = OpLoad %v2float %in_float
+ %58 = OpExtInst %v2float %1 Frexp %56 %exp_0
+ OpStore %x_0 %58
+ %61 = OpLoad %v2float %in_float
+ %62 = OpExtInst %frexpStructType %1 FrexpStruct %61
+ OpStore %res_0 %62
+ %67 = OpLoad %int %gl_InvocationID
+ %68 = OpLoad %v2float %x_0
+ %70 = OpAccessChain %_ptr_Output_v2float %frexp_x_out %67
+ OpStore %70 %68
+ %72 = OpLoad %int %gl_InvocationID
+ %73 = OpLoad %v2int %exp_0
+ %74 = OpBitcast %v2float %73
+ %75 = OpAccessChain %_ptr_Output_v2float %frexp_exp_out %72
+ OpStore %75 %74
+ %77 = OpLoad %int %gl_InvocationID
+ %78 = OpAccessChain %_ptr_Function_v2float %res_0 %int_0
+ %79 = OpLoad %v2float %78
+ %80 = OpAccessChain %_ptr_Output_v2float %frexpStruct_x_out %77
+ OpStore %80 %79
+ %82 = OpLoad %int %gl_InvocationID
+ %84 = OpAccessChain %_ptr_Function_v2int %res_0 %int_1
+ %85 = OpLoad %v2int %84
+ %86 = OpBitcast %v2float %85
+ %87 = OpAccessChain %_ptr_Output_v2float %frexpStruct_exp_out %82
+ OpStore %87 %86
+ %94 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0
+ OpStore %94 %float_1
+ %95 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_1
+ OpStore %95 %float_1
+ %100 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0
+ OpStore %100 %float_1
+ %101 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1
+ OpStore %101 %float_1
+ %103 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2
+ OpStore %103 %float_1
+ %105 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_3
+ OpStore %105 %float_1
+ %113 = OpLoad %int %gl_InvocationID
+ %118 = OpLoad %int %gl_InvocationID
+ %120 = OpAccessChain %_ptr_Input_v4float %gl_in %118 %int_0
+ %121 = OpLoad %v4float %120
+ %123 = OpAccessChain %_ptr_Output_v4float %gl_out %113 %int_0
+ OpStore %123 %121
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER tessellation_evaluation tese_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (triangles) in;
+#
+# layout (location = 0) flat in vec2 frexp_x_in[];
+# layout (location = 1) flat in vec2 frexp_exp_in[];
+# layout (location = 2) flat in vec2 frexpStruct_x_in[];
+# layout (location = 3) flat in vec2 frexpStruct_exp_in[];
+#
+# layout (location = 0) flat out vec2 frexp_x_out;
+# layout (location = 1) flat out vec2 frexp_exp_out;
+# layout (location = 2) flat out vec2 frexpStruct_x_out;
+# layout (location = 3) flat out vec2 frexpStruct_exp_out;
+#
+# void main ()
+# {
+# gl_Position = gl_TessCoord.x * gl_in[0].gl_Position +
+# gl_TessCoord.y * gl_in[1].gl_Position +
+# gl_TessCoord.z * gl_in[2].gl_Position;
+#
+# frexp_x_out = frexp_x_in[0];
+# frexp_exp_out = frexp_exp_in[0];
+# frexpStruct_x_out = frexpStruct_x_in[0];
+# frexpStruct_exp_out = frexpStruct_exp_in[0];
+# }
+# END
+
+SHADER tessellation_evaluation tese_shader SPIRV-ASM
+ OpCapability Tessellation
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationEvaluation %main "main" %_ %gl_TessCoord %gl_in %frexp_x_out %frexp_x_in %frexp_exp_out %frexp_exp_in %frexpStruct_x_out %frexpStruct_x_in %frexpStruct_exp_out %frexpStruct_exp_in
+ OpExecutionMode %main Triangles
+ OpExecutionMode %main SpacingEqual
+ OpExecutionMode %main VertexOrderCcw
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpDecorate %gl_TessCoord BuiltIn TessCoord
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+ %uint = OpTypeInt 32 0
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %v3float = OpTypeVector %float 3
+%_ptr_Input_v3float = OpTypePointer Input %v3float
+%gl_TessCoord = OpVariable %_ptr_Input_v3float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+ %uint_32 = OpConstant %uint 32
+%_arr_gl_PerVertex_0_uint_32 = OpTypeArray %gl_PerVertex_0 %uint_32
+%_ptr_Input__arr_gl_PerVertex_0_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_32
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %int_1 = OpConstant %int 1
+ %uint_2 = OpConstant %uint 2
+ %int_2 = OpConstant %int 2
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %v2float = OpTypeVector %float 2
+%_ptr_Output_v2float = OpTypePointer Output %v2float
+%frexp_x_out = OpVariable %_ptr_Output_v2float Output
+%_arr_v2float_uint_32 = OpTypeArray %v2float %uint_32
+%_ptr_Input__arr_v2float_uint_32 = OpTypePointer Input %_arr_v2float_uint_32
+ %frexp_x_in = OpVariable %_ptr_Input__arr_v2float_uint_32 Input
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+%frexp_exp_out = OpVariable %_ptr_Output_v2float Output
+%frexp_exp_in = OpVariable %_ptr_Input__arr_v2float_uint_32 Input
+%frexpStruct_x_out = OpVariable %_ptr_Output_v2float Output
+%frexpStruct_x_in = OpVariable %_ptr_Input__arr_v2float_uint_32 Input
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v2float Output
+%frexpStruct_exp_in = OpVariable %_ptr_Input__arr_v2float_uint_32 Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %21 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_0
+ %22 = OpLoad %float %21
+ %29 = OpAccessChain %_ptr_Input_v4float %gl_in %int_0 %int_0
+ %30 = OpLoad %v4float %29
+ %31 = OpVectorTimesScalar %v4float %30 %22
+ %32 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_1
+ %33 = OpLoad %float %32
+ %35 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0
+ %36 = OpLoad %v4float %35
+ %37 = OpVectorTimesScalar %v4float %36 %33
+ %38 = OpFAdd %v4float %31 %37
+ %40 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_2
+ %41 = OpLoad %float %40
+ %43 = OpAccessChain %_ptr_Input_v4float %gl_in %int_2 %int_0
+ %44 = OpLoad %v4float %43
+ %45 = OpVectorTimesScalar %v4float %44 %41
+ %46 = OpFAdd %v4float %38 %45
+ %48 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %48 %46
+ %56 = OpAccessChain %_ptr_Input_v2float %frexp_x_in %int_0
+ %57 = OpLoad %v2float %56
+ OpStore %frexp_x_out %57
+ %60 = OpAccessChain %_ptr_Input_v2float %frexp_exp_in %int_0
+ %61 = OpLoad %v2float %60
+ OpStore %frexp_exp_out %61
+ %64 = OpAccessChain %_ptr_Input_v2float %frexpStruct_x_in %int_0
+ %65 = OpLoad %v2float %64
+ OpStore %frexpStruct_x_out %65
+ %68 = OpAccessChain %_ptr_Input_v2float %frexpStruct_exp_in %int_0
+ %69 = OpLoad %v2float %68
+ OpStore %frexpStruct_exp_out %69
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (location = 0) flat in vec2 frexp_x_in;
+# layout (location = 1) flat in vec2 frexp_exp_in;
+# layout (location = 2) flat in vec2 frexpStruct_x_in;
+# layout (location = 3) flat in vec2 frexpStruct_exp_in;
+#
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+# const vec4 clear_value = vec4(0.0, 0.0, 0.0, 1.0);
+#
+# void main ()
+# {
+# frexp_x_out = clear_value;
+# frexp_exp_out = clear_value;
+# frexpStruct_x_out = clear_value;
+# frexpStruct_exp_out = clear_value;
+# frexp_x_out.rg = frexp_x_in;
+# frexp_exp_out.rg = frexp_exp_in;
+# frexpStruct_x_out.rg = frexpStruct_x_in;
+# frexpStruct_exp_out.rg = frexpStruct_exp_in;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %frexp_x_in %frexp_exp_in %frexpStruct_x_in %frexpStruct_exp_in
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %frexp_x_in = OpVariable %_ptr_Input_v2float Input
+%frexp_exp_in = OpVariable %_ptr_Input_v2float Input
+%frexpStruct_x_in = OpVariable %_ptr_Input_v2float Input
+%frexpStruct_exp_in = OpVariable %_ptr_Input_v2float Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpStore %frexp_x_out %12
+ OpStore %frexp_exp_out %12
+ OpStore %frexpStruct_x_out %12
+ OpStore %frexpStruct_exp_out %12
+ %19 = OpLoad %v2float %frexp_x_in
+ %20 = OpLoad %v4float %frexp_x_out
+ %21 = OpVectorShuffle %v4float %20 %19 4 5 2 3
+ OpStore %frexp_x_out %21
+ %23 = OpLoad %v2float %frexp_exp_in
+ %24 = OpLoad %v4float %frexp_exp_out
+ %25 = OpVectorShuffle %v4float %24 %23 4 5 2 3
+ OpStore %frexp_exp_out %25
+ %27 = OpLoad %v2float %frexpStruct_x_in
+ %28 = OpLoad %v4float %frexpStruct_x_out
+ %29 = OpVectorShuffle %v4float %28 %27 4 5 2 3
+ OpStore %frexpStruct_x_out %29
+ %31 = OpLoad %v2float %frexpStruct_exp_in
+ %32 = OpLoad %v4float %frexpStruct_exp_out
+ %33 = OpVectorShuffle %v4float %32 %31 4 5 2 3
+ OpStore %frexpStruct_exp_out %33
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH tesc_shader
+ ATTACH tese_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+#RUN test_pipeline DRAW_GRID POS 0 0 SIZE 144 144 CELLS 144 144
+RUN test_pipeline DRAW_ARRAY AS PATCH_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A tessellation evaluation shader test for FrexpStruct.
+
+DEVICE_FEATURE tessellationShader
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out uint ndx_out;
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# ndx_out = xcoord + ycoord * ndpSqrt;
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %ndx_out %_
+ OpDecorate %position Location 0
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+ %float_1 = OpConstant %float 1
+ %uint_1 = OpConstant %uint 1
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %ndx_out = OpVariable %_ptr_Output_uint Output
+ %uint_36 = OpConstant %uint 36
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_1_02777779 = OpConstant %float 1.02777779
+ %float_18 = OpConstant %float 18
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %17 = OpLoad %float %16
+ %21 = OpFAdd %float %17 %float_1_02777779
+ %24 = OpFMul %float %21 %float_18
+ %25 = OpFSub %float %24 %float_1
+ %26 = OpConvertFToU %uint %25
+ %29 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %30 = OpLoad %float %29
+ %32 = OpFAdd %float %30 %float_1_02777779
+ %34 = OpFMul %float %32 %float_18
+ %35 = OpFSub %float %34 %float_1
+ %36 = OpConvertFToU %uint %35
+ %42 = OpIMul %uint %36 %uint_36
+ %43 = OpIAdd %uint %26 %42
+ OpStore %ndx_out %43
+ %51 = OpLoad %v2float %position
+ %53 = OpCompositeExtract %float %51 0
+ %54 = OpCompositeExtract %float %51 1
+ %55 = OpCompositeConstruct %v4float %53 %54 %float_0 %float_1
+ %57 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %57 %55
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER tessellation_control tesc_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (vertices = 3) out;
+#
+# layout (location = 0) flat in uint ndx_in[];
+# layout (location = 0) flat out uint ndx_out[];
+#
+# void main ()
+# {
+# gl_TessLevelInner[0] = 1.0;
+# gl_TessLevelInner[1] = 1.0;
+# gl_TessLevelOuter[0] = 1.0;
+# gl_TessLevelOuter[1] = 1.0;
+# gl_TessLevelOuter[2] = 1.0;
+# gl_TessLevelOuter[3] = 1.0;
+#
+# gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
+# ndx_out[gl_InvocationID] = ndx_in[gl_InvocationID];
+# }
+# END
+
+SHADER tessellation_control tesc_shader SPIRV-ASM
+ OpCapability Tessellation
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationControl %main "main" %gl_TessLevelInner %gl_TessLevelOuter %gl_out %gl_InvocationID %gl_in %ndx_out %ndx_in
+ OpExecutionMode %main OutputVertices 3
+ OpDecorate %gl_TessLevelInner Patch
+ OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner
+ OpDecorate %gl_TessLevelOuter Patch
+ OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpDecorate %gl_InvocationID BuiltIn InvocationId
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_2 = OpConstant %uint 2
+%_arr_float_uint_2 = OpTypeArray %float %uint_2
+%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2
+%gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_1 = OpConstant %float 1
+%_ptr_Output_float = OpTypePointer Output %float
+ %int_1 = OpConstant %int 1
+ %uint_4 = OpConstant %uint 4
+%_arr_float_uint_4 = OpTypeArray %float %uint_4
+%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4
+%gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output
+ %int_2 = OpConstant %int 2
+ %int_3 = OpConstant %int 3
+ %v4float = OpTypeVector %float 4
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+ %uint_3 = OpConstant %uint 3
+%_arr_gl_PerVertex_uint_3 = OpTypeArray %gl_PerVertex %uint_3
+%_ptr_Output__arr_gl_PerVertex_uint_3 = OpTypePointer Output %_arr_gl_PerVertex_uint_3
+ %gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_uint_3 Output
+%_ptr_Input_int = OpTypePointer Input %int
+%gl_InvocationID = OpVariable %_ptr_Input_int Input
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+ %uint_32 = OpConstant %uint 32
+%_arr_gl_PerVertex_0_uint_32 = OpTypeArray %gl_PerVertex_0 %uint_32
+%_ptr_Input__arr_gl_PerVertex_0_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_32
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%_arr_uint_uint_3 = OpTypeArray %uint %uint_3
+%_ptr_Output__arr_uint_uint_3 = OpTypePointer Output %_arr_uint_uint_3
+ %ndx_out = OpVariable %_ptr_Output__arr_uint_uint_3 Output
+%_arr_uint_uint_32 = OpTypeArray %uint %uint_32
+%_ptr_Input__arr_uint_uint_32 = OpTypePointer Input %_arr_uint_uint_32
+ %ndx_in = OpVariable %_ptr_Input__arr_uint_uint_32 Input
+%_ptr_Input_uint = OpTypePointer Input %uint
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0
+ OpStore %16 %float_1
+ %18 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_1
+ OpStore %18 %float_1
+ %23 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0
+ OpStore %23 %float_1
+ %24 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1
+ OpStore %24 %float_1
+ %26 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2
+ OpStore %26 %float_1
+ %28 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_3
+ OpStore %28 %float_1
+ %39 = OpLoad %int %gl_InvocationID
+ %47 = OpAccessChain %_ptr_Input_v4float %gl_in %39 %int_0
+ %48 = OpLoad %v4float %47
+ %50 = OpAccessChain %_ptr_Output_v4float %gl_out %39 %int_0
+ OpStore %50 %48
+ %60 = OpAccessChain %_ptr_Input_uint %ndx_in %39
+ %61 = OpLoad %uint %60
+ %63 = OpAccessChain %_ptr_Output_uint %ndx_out %39
+ OpStore %63 %61
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER tessellation_evaluation tese_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+#
+# layout (triangles) in;
+#
+# layout (location = 0) flat in uint ndx_in[];
+# layout (location = 0) flat out vec2 frexp_x_out;
+# layout (location = 1) flat out vec2 frexp_exp_out;
+# layout (location = 2) flat out vec2 frexpStruct_x_out;
+# layout (location = 3) flat out vec2 frexpStruct_exp_out;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec2 in_values[ndp];
+# };
+#
+# struct frexpStructType
+# {
+# vec2 x;
+# ivec2 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec2 orig)
+# {
+# vec2 x;
+# ivec2 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# gl_Position = gl_TessCoord.x * gl_in[0].gl_Position +
+# gl_TessCoord.y * gl_in[1].gl_Position +
+# gl_TessCoord.z * gl_in[2].gl_Position;
+#
+# uvec2 in_uint = in_values[ndx_in[0]];
+# vec2 in_float = uintBitsToFloat(in_uint);
+# vec2 x;
+# ivec2 exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out = x;
+# frexp_exp_out = intBitsToFloat(exp);
+# frexpStruct_x_out = res.x;
+# frexpStruct_exp_out = intBitsToFloat(res.exp);
+# }
+# END
+
+SHADER tessellation_evaluation tese_shader SPIRV-ASM
+ OpCapability Tessellation
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationEvaluation %main "main" %_ %gl_TessCoord %gl_in %ndx_in %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out
+ OpExecutionMode %main Triangles
+ OpExecutionMode %main SpacingEqual
+ OpExecutionMode %main VertexOrderCcw
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpDecorate %gl_TessCoord BuiltIn TessCoord
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ OpDecorate %_arr_v2uint_uint_1296 ArrayStride 8
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %__0 DescriptorSet 0
+ OpDecorate %__0 Binding 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+ %int = OpTypeInt 32 1
+ %v2int = OpTypeVector %int 2
+%frexpStructType = OpTypeStruct %v2float %v2int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v2float
+%_ptr_Function_v2int = OpTypePointer Function %v2int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %v4float = OpTypeVector %float 4
+ %uint = OpTypeInt 32 0
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int_0 = OpConstant %int 0
+ %v3float = OpTypeVector %float 3
+%_ptr_Input_v3float = OpTypePointer Input %v3float
+%gl_TessCoord = OpVariable %_ptr_Input_v3float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+ %uint_32 = OpConstant %uint 32
+%_arr_gl_PerVertex_0_uint_32 = OpTypeArray %gl_PerVertex_0 %uint_32
+%_ptr_Input__arr_gl_PerVertex_0_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_32
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %int_1 = OpConstant %int 1
+ %uint_2 = OpConstant %uint 2
+ %int_2 = OpConstant %int 2
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_v2uint_uint_1296 = OpTypeArray %v2uint %uint_1296
+ %block0 = OpTypeStruct %_arr_v2uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %__0 = OpVariable %_ptr_Uniform_block0 Uniform
+%_arr_uint_uint_32 = OpTypeArray %uint %uint_32
+%_ptr_Input__arr_uint_uint_32 = OpTypePointer Input %_arr_uint_uint_32
+ %ndx_in = OpVariable %_ptr_Input__arr_uint_uint_32 Input
+%_ptr_Input_uint = OpTypePointer Input %uint
+%_ptr_Uniform_v2uint = OpTypePointer Uniform %v2uint
+%_ptr_Output_v2float = OpTypePointer Output %v2float
+%frexp_x_out = OpVariable %_ptr_Output_v2float Output
+%frexp_exp_out = OpVariable %_ptr_Output_v2float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v2float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v2float Output
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %in_uint = OpVariable %_ptr_Function_v2uint Function
+ %in_float = OpVariable %_ptr_Function_v2float Function
+ %x_0 = OpVariable %_ptr_Function_v2float Function
+ %exp_0 = OpVariable %_ptr_Function_v2int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ %42 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_0
+ %43 = OpLoad %float %42
+ %50 = OpAccessChain %_ptr_Input_v4float %gl_in %int_0 %int_0
+ %51 = OpLoad %v4float %50
+ %52 = OpVectorTimesScalar %v4float %51 %43
+ %53 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_1
+ %54 = OpLoad %float %53
+ %56 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0
+ %57 = OpLoad %v4float %56
+ %58 = OpVectorTimesScalar %v4float %57 %54
+ %59 = OpFAdd %v4float %52 %58
+ %61 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_2
+ %62 = OpLoad %float %61
+ %64 = OpAccessChain %_ptr_Input_v4float %gl_in %int_2 %int_0
+ %65 = OpLoad %v4float %64
+ %66 = OpVectorTimesScalar %v4float %65 %62
+ %67 = OpFAdd %v4float %59 %66
+ %69 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %69 %67
+ %82 = OpAccessChain %_ptr_Input_uint %ndx_in %int_0
+ %83 = OpLoad %uint %82
+ %85 = OpAccessChain %_ptr_Uniform_v2uint %__0 %int_0 %83
+ %86 = OpLoad %v2uint %85
+ OpStore %in_uint %86
+ %88 = OpLoad %v2uint %in_uint
+ %89 = OpBitcast %v2float %88
+ OpStore %in_float %89
+ %91 = OpLoad %v2float %in_float
+ %93 = OpExtInst %v2float %1 Frexp %91 %exp_0
+ OpStore %x_0 %93
+ %96 = OpLoad %v2float %in_float
+ %97 = OpExtInst %frexpStructType %1 FrexpStruct %96
+ OpStore %res_0 %97
+ %100 = OpLoad %v2float %x_0
+ OpStore %frexp_x_out %100
+ %102 = OpLoad %v2int %exp_0
+ %103 = OpBitcast %v2float %102
+ OpStore %frexp_exp_out %103
+ %105 = OpAccessChain %_ptr_Function_v2float %res_0 %int_0
+ %106 = OpLoad %v2float %105
+ OpStore %frexpStruct_x_out %106
+ %108 = OpAccessChain %_ptr_Function_v2int %res_0 %int_1
+ %109 = OpLoad %v2int %108
+ %110 = OpBitcast %v2float %109
+ OpStore %frexpStruct_exp_out %110
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (location = 0) flat in vec2 frexp_x_in;
+# layout (location = 1) flat in vec2 frexp_exp_in;
+# layout (location = 2) flat in vec2 frexpStruct_x_in;
+# layout (location = 3) flat in vec2 frexpStruct_exp_in;
+#
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+# const vec4 clear_value = vec4(0.0, 0.0, 0.0, 1.0);
+#
+# void main ()
+# {
+# frexp_x_out = clear_value;
+# frexp_exp_out = clear_value;
+# frexpStruct_x_out = clear_value;
+# frexpStruct_exp_out = clear_value;
+# frexp_x_out.rg = frexp_x_in;
+# frexp_exp_out.rg = frexp_exp_in;
+# frexpStruct_x_out.rg = frexpStruct_x_in;
+# frexpStruct_exp_out.rg = frexpStruct_exp_in;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %frexp_x_in %frexp_exp_in %frexpStruct_x_in %frexpStruct_exp_in
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %frexp_x_in = OpVariable %_ptr_Input_v2float Input
+%frexp_exp_in = OpVariable %_ptr_Input_v2float Input
+%frexpStruct_x_in = OpVariable %_ptr_Input_v2float Input
+%frexpStruct_exp_in = OpVariable %_ptr_Input_v2float Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpStore %frexp_x_out %12
+ OpStore %frexp_exp_out %12
+ OpStore %frexpStruct_x_out %12
+ OpStore %frexpStruct_exp_out %12
+ %19 = OpLoad %v2float %frexp_x_in
+ %20 = OpLoad %v4float %frexp_x_out
+ %21 = OpVectorShuffle %v4float %20 %19 4 5 2 3
+ OpStore %frexp_x_out %21
+ %23 = OpLoad %v2float %frexp_exp_in
+ %24 = OpLoad %v4float %frexp_exp_out
+ %25 = OpVectorShuffle %v4float %24 %23 4 5 2 3
+ OpStore %frexp_exp_out %25
+ %27 = OpLoad %v2float %frexpStruct_x_in
+ %28 = OpLoad %v4float %frexpStruct_x_out
+ %29 = OpVectorShuffle %v4float %28 %27 4 5 2 3
+ OpStore %frexpStruct_x_out %29
+ %31 = OpLoad %v2float %frexpStruct_exp_in
+ %32 = OpLoad %v4float %frexpStruct_exp_out
+ %33 = OpVectorShuffle %v4float %32 %31 4 5 2 3
+ OpStore %frexpStruct_exp_out %33
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH tesc_shader
+ ATTACH tese_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+#RUN test_pipeline DRAW_GRID POS 0 0 SIZE 144 144 CELLS 144 144
+RUN test_pipeline DRAW_ARRAY AS PATCH_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A vertex shader test for FrexpStruct.
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out vec2 frexp_x_out;
+# layout (location = 1) flat out vec2 frexp_exp_out;
+# layout (location = 2) flat out vec2 frexpStruct_x_out;
+# layout (location = 3) flat out vec2 frexpStruct_exp_out;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec2 in_values[ndp];
+# };
+#
+# struct frexpStructType
+# {
+# vec2 x;
+# ivec2 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec2 orig)
+# {
+# vec2 x;
+# ivec2 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# uint ndx = xcoord + ycoord * ndpSqrt;
+#
+# uvec2 in_uint = in_values[ndx];
+# vec2 in_float = uintBitsToFloat(in_uint);
+# vec2 x;
+# ivec2 exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out = x;
+# frexp_exp_out = intBitsToFloat(exp);
+# frexpStruct_x_out = res.x;
+# frexpStruct_exp_out = intBitsToFloat(res.exp);
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %__0
+ OpDecorate %position Location 0
+ OpDecorate %_arr_v2uint_uint_1296 ArrayStride 8
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+ %int = OpTypeInt 32 1
+ %v2int = OpTypeVector %int 2
+%frexpStructType = OpTypeStruct %v2float %v2int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v2float
+%_ptr_Function_v2int = OpTypePointer Function %v2int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %float_36 = OpConstant %float 36
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+%float_0_027777778 = OpConstant %float 0.027777778
+ %float_1 = OpConstant %float 1
+ %float_2 = OpConstant %float 2
+ %uint_1 = OpConstant %uint 1
+ %uint_36 = OpConstant %uint 36
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_v2uint_uint_1296 = OpTypeArray %v2uint %uint_1296
+ %block0 = OpTypeStruct %_arr_v2uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %int_0 = OpConstant %int 0
+%_ptr_Uniform_v2uint = OpTypePointer Uniform %v2uint
+%_ptr_Output_v2float = OpTypePointer Output %v2float
+%frexp_x_out = OpVariable %_ptr_Output_v2float Output
+%frexp_exp_out = OpVariable %_ptr_Output_v2float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v2float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v2float Output
+ %int_1 = OpConstant %int 1
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %__0 = OpVariable %_ptr_Output_gl_PerVertex Output
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %xcoord = OpVariable %_ptr_Function_uint Function
+ %ycoord = OpVariable %_ptr_Function_uint Function
+ %ndx = OpVariable %_ptr_Function_uint Function
+ %in_uint = OpVariable %_ptr_Function_v2uint Function
+ %in_float = OpVariable %_ptr_Function_v2float Function
+ %x_0 = OpVariable %_ptr_Function_v2float Function
+ %exp_0 = OpVariable %_ptr_Function_v2int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ %37 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %38 = OpLoad %float %37
+ %40 = OpFAdd %float %38 %float_0_027777778
+ %42 = OpFAdd %float %40 %float_1
+ %44 = OpFDiv %float %42 %float_2
+ %45 = OpFMul %float %float_36 %44
+ %46 = OpFSub %float %45 %float_1
+ %47 = OpConvertFToU %uint %46
+ OpStore %xcoord %47
+ %50 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %51 = OpLoad %float %50
+ %52 = OpFAdd %float %51 %float_0_027777778
+ %53 = OpFAdd %float %52 %float_1
+ %54 = OpFDiv %float %53 %float_2
+ %55 = OpFMul %float %float_36 %54
+ %56 = OpFSub %float %55 %float_1
+ %57 = OpConvertFToU %uint %56
+ OpStore %ycoord %57
+ %59 = OpLoad %uint %xcoord
+ %60 = OpLoad %uint %ycoord
+ %62 = OpIMul %uint %60 %uint_36
+ %63 = OpIAdd %uint %59 %62
+ OpStore %ndx %63
+ %73 = OpLoad %uint %ndx
+ %75 = OpAccessChain %_ptr_Uniform_v2uint %_ %int_0 %73
+ %76 = OpLoad %v2uint %75
+ OpStore %in_uint %76
+ %78 = OpLoad %v2uint %in_uint
+ %79 = OpBitcast %v2float %78
+ OpStore %in_float %79
+ %81 = OpLoad %v2float %in_float
+ %83 = OpExtInst %v2float %1 Frexp %81 %exp_0
+ OpStore %x_0 %83
+ %86 = OpLoad %v2float %in_float
+ %87 = OpExtInst %frexpStructType %1 FrexpStruct %86
+ OpStore %res_0 %87
+ %90 = OpLoad %v2float %x_0
+ OpStore %frexp_x_out %90
+ %92 = OpLoad %v2int %exp_0
+ %93 = OpBitcast %v2float %92
+ OpStore %frexp_exp_out %93
+ %95 = OpAccessChain %_ptr_Function_v2float %res_0 %int_0
+ %96 = OpLoad %v2float %95
+ OpStore %frexpStruct_x_out %96
+ %99 = OpAccessChain %_ptr_Function_v2int %res_0 %int_1
+ %100 = OpLoad %v2int %99
+ %101 = OpBitcast %v2float %100
+ OpStore %frexpStruct_exp_out %101
+ %107 = OpLoad %v2float %position
+ %109 = OpCompositeExtract %float %107 0
+ %110 = OpCompositeExtract %float %107 1
+ %111 = OpCompositeConstruct %v4float %109 %110 %float_0 %float_1
+ %113 = OpAccessChain %_ptr_Output_v4float %__0 %int_0
+ OpStore %113 %111
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (location = 0) flat in vec2 frexp_x_in;
+# layout (location = 1) flat in vec2 frexp_exp_in;
+# layout (location = 2) flat in vec2 frexpStruct_x_in;
+# layout (location = 3) flat in vec2 frexpStruct_exp_in;
+#
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+# const vec4 clear_value = vec4(0.0, 0.0, 0.0, 1.0);
+#
+# void main ()
+# {
+# frexp_x_out = clear_value;
+# frexp_exp_out = clear_value;
+# frexpStruct_x_out = clear_value;
+# frexpStruct_exp_out = clear_value;
+# frexp_x_out.rg = frexp_x_in;
+# frexp_exp_out.rg = frexp_exp_in;
+# frexpStruct_x_out.rg = frexpStruct_x_in;
+# frexpStruct_exp_out.rg = frexpStruct_exp_in;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %frexp_x_in %frexp_exp_in %frexpStruct_x_in %frexpStruct_exp_in
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %frexp_x_in = OpVariable %_ptr_Input_v2float Input
+%frexp_exp_in = OpVariable %_ptr_Input_v2float Input
+%frexpStruct_x_in = OpVariable %_ptr_Input_v2float Input
+%frexpStruct_exp_in = OpVariable %_ptr_Input_v2float Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpStore %frexp_x_out %12
+ OpStore %frexp_exp_out %12
+ OpStore %frexpStruct_x_out %12
+ OpStore %frexpStruct_exp_out %12
+ %19 = OpLoad %v2float %frexp_x_in
+ %20 = OpLoad %v4float %frexp_x_out
+ %21 = OpVectorShuffle %v4float %20 %19 4 5 2 3
+ OpStore %frexp_x_out %21
+ %23 = OpLoad %v2float %frexp_exp_in
+ %24 = OpLoad %v4float %frexp_exp_out
+ %25 = OpVectorShuffle %v4float %24 %23 4 5 2 3
+ OpStore %frexp_exp_out %25
+ %27 = OpLoad %v2float %frexpStruct_x_in
+ %28 = OpLoad %v4float %frexpStruct_x_out
+ %29 = OpVectorShuffle %v4float %28 %27 4 5 2 3
+ OpStore %frexpStruct_x_out %29
+ %31 = OpLoad %v2float %frexpStruct_exp_in
+ %32 = OpLoad %v4float %frexpStruct_exp_out
+ %33 = OpVectorShuffle %v4float %32 %31 4 5 2 3
+ OpStore %frexpStruct_exp_out %33
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+RUN test_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A compute shader test for FrexpStruct.
+
+# SHADER compute comp_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296 / 3;
+# const uint half_ndp = ndp / 2;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec3 in_values[half_ndp];
+# };
+#
+# layout(set = 0, binding = 1) buffer block1 {
+# vec3 frexp_out[ndp];
+# };
+#
+# layout(set = 0, binding = 2) buffer block2 {
+# vec3 frexpStruct_out[ndp];
+# };
+#
+# struct frexpStructType
+# {
+# vec3 x;
+# ivec3 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec3 orig)
+# {
+# vec3 x;
+# ivec3 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# for (uint ndx = 0; ndx < ndp; ndx += 2)
+# {
+# uvec3 in_uint = in_values[ndx/2];
+# vec3 in_float = uintBitsToFloat(in_uint);
+# vec3 x;
+# ivec3 exp;
+#
+# x = frexp(in_float, exp);
+# frexpStructType res = frexpStruct(in_float);
+#
+# frexp_out[ndx] = intBitsToFloat(exp);
+# frexp_out[ndx+1] = x;
+# frexpStruct_out[ndx] = intBitsToFloat(res.exp);
+# frexpStruct_out[ndx+1] = res.x;
+# }
+#
+# return;
+# }
+# END
+
+SHADER compute comp_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpDecorate %_arr_v3uint_uint_216 ArrayStride 16
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %_arr_v3float_uint_432 ArrayStride 16
+ OpMemberDecorate %block1 0 Offset 0
+ OpDecorate %block1 BufferBlock
+ OpDecorate %__0 DescriptorSet 0
+ OpDecorate %__0 Binding 1
+ OpDecorate %_arr_v3float_uint_432_0 ArrayStride 16
+ OpMemberDecorate %block2 0 Offset 0
+ OpDecorate %block2 BufferBlock
+ OpDecorate %__1 DescriptorSet 0
+ OpDecorate %__1 Binding 2
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v3float = OpTypeVector %float 3
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+ %int = OpTypeInt 32 1
+ %v3int = OpTypeVector %int 3
+%frexpStructType = OpTypeStruct %v3float %v3int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v3float
+%_ptr_Function_v3int = OpTypePointer Function %v3int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %uint_0 = OpConstant %uint 0
+ %uint_432 = OpConstant %uint 432
+ %bool = OpTypeBool
+ %v3uint = OpTypeVector %uint 3
+%_ptr_Function_v3uint = OpTypePointer Function %v3uint
+ %uint_216 = OpConstant %uint 216
+%_arr_v3uint_uint_216 = OpTypeArray %v3uint %uint_216
+ %block0 = OpTypeStruct %_arr_v3uint_uint_216
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %int_0 = OpConstant %int 0
+ %uint_2 = OpConstant %uint 2
+%_ptr_Uniform_v3uint = OpTypePointer Uniform %v3uint
+%_arr_v3float_uint_432 = OpTypeArray %v3float %uint_432
+ %block1 = OpTypeStruct %_arr_v3float_uint_432
+%_ptr_Uniform_block1 = OpTypePointer Uniform %block1
+ %__0 = OpVariable %_ptr_Uniform_block1 Uniform
+%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
+ %uint_1 = OpConstant %uint 1
+%_arr_v3float_uint_432_0 = OpTypeArray %v3float %uint_432
+ %block2 = OpTypeStruct %_arr_v3float_uint_432_0
+%_ptr_Uniform_block2 = OpTypePointer Uniform %block2
+ %__1 = OpVariable %_ptr_Uniform_block2 Uniform
+ %int_1 = OpConstant %int 1
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %ndx = OpVariable %_ptr_Function_uint Function
+ %in_uint = OpVariable %_ptr_Function_v3uint Function
+ %in_float = OpVariable %_ptr_Function_v3float Function
+ %x_0 = OpVariable %_ptr_Function_v3float Function
+ %exp_0 = OpVariable %_ptr_Function_v3int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ OpStore %ndx %uint_0
+ OpBranch %33
+ %33 = OpLabel
+ OpLoopMerge %35 %36 None
+ OpBranch %37
+ %37 = OpLabel
+ %38 = OpLoad %uint %ndx
+ %41 = OpULessThan %bool %38 %uint_432
+ OpBranchConditional %41 %34 %35
+ %34 = OpLabel
+ %51 = OpLoad %uint %ndx
+ %53 = OpUDiv %uint %51 %uint_2
+ %55 = OpAccessChain %_ptr_Uniform_v3uint %_ %int_0 %53
+ %56 = OpLoad %v3uint %55
+ OpStore %in_uint %56
+ %58 = OpLoad %v3uint %in_uint
+ %59 = OpBitcast %v3float %58
+ OpStore %in_float %59
+ %61 = OpLoad %v3float %in_float
+ %63 = OpExtInst %v3float %1 Frexp %61 %exp_0
+ OpStore %x_0 %63
+ %66 = OpLoad %v3float %in_float
+ %67 = OpExtInst %frexpStructType %1 FrexpStruct %66
+ OpStore %res_0 %67
+ %72 = OpLoad %uint %ndx
+ %73 = OpLoad %v3int %exp_0
+ %74 = OpBitcast %v3float %73
+ %76 = OpAccessChain %_ptr_Uniform_v3float %__0 %int_0 %72
+ OpStore %76 %74
+ %77 = OpLoad %uint %ndx
+ %79 = OpIAdd %uint %77 %uint_1
+ %80 = OpLoad %v3float %x_0
+ %81 = OpAccessChain %_ptr_Uniform_v3float %__0 %int_0 %79
+ OpStore %81 %80
+ %86 = OpLoad %uint %ndx
+ %88 = OpAccessChain %_ptr_Function_v3int %res_0 %int_1
+ %89 = OpLoad %v3int %88
+ %90 = OpBitcast %v3float %89
+ %91 = OpAccessChain %_ptr_Uniform_v3float %__1 %int_0 %86
+ OpStore %91 %90
+ %92 = OpLoad %uint %ndx
+ %93 = OpIAdd %uint %92 %uint_1
+ %94 = OpAccessChain %_ptr_Function_v3float %res_0 %int_0
+ %95 = OpLoad %v3float %94
+ %96 = OpAccessChain %_ptr_Uniform_v3float %__1 %int_0 %93
+ OpStore %96 %95
+ OpBranch %36
+ %36 = OpLabel
+ %97 = OpLoad %uint %ndx
+ %98 = OpIAdd %uint %97 %uint_2
+ OpStore %ndx %98
+ OpBranch %33
+ %35 = OpLabel
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+
+BUFFER buf_frexp DATA_TYPE vec3<float> SIZE 432 FILL 0.0
+BUFFER buf_frexpStruct DATA_TYPE vec3<float> SIZE 432 FILL 1.0
+
+PIPELINE compute test_pipeline
+ ATTACH comp_shader
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER buf_frexp AS storage DESCRIPTOR_SET 0 BINDING 1
+ BIND BUFFER buf_frexpStruct AS storage DESCRIPTOR_SET 0 BINDING 2
+END
+
+RUN test_pipeline 1 1 1
+
+EXPECT buf_frexp EQ_BUFFER buf_frexpStruct
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A fragment shader test for FrexpStruct.
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out uint ndx_out;
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# ndx_out = xcoord + ycoord * ndpSqrt;
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %ndx_out %_
+ OpDecorate %position Location 0
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+ %float_1 = OpConstant %float 1
+ %uint_1 = OpConstant %uint 1
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %ndx_out = OpVariable %_ptr_Output_uint Output
+ %uint_36 = OpConstant %uint 36
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_1_02777779 = OpConstant %float 1.02777779
+ %float_18 = OpConstant %float 18
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %17 = OpLoad %float %16
+ %21 = OpFAdd %float %17 %float_1_02777779
+ %24 = OpFMul %float %21 %float_18
+ %25 = OpFSub %float %24 %float_1
+ %26 = OpConvertFToU %uint %25
+ %29 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %30 = OpLoad %float %29
+ %32 = OpFAdd %float %30 %float_1_02777779
+ %34 = OpFMul %float %32 %float_18
+ %35 = OpFSub %float %34 %float_1
+ %36 = OpConvertFToU %uint %35
+ %42 = OpIMul %uint %36 %uint_36
+ %43 = OpIAdd %uint %26 %42
+ OpStore %ndx_out %43
+ %51 = OpLoad %v2float %position
+ %53 = OpCompositeExtract %float %51 0
+ %54 = OpCompositeExtract %float %51 1
+ %55 = OpCompositeConstruct %v4float %53 %54 %float_0 %float_1
+ %57 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %57 %55
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const vec4 clear_value = vec4(0.0, 0.0, 0.0, 1.0);
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec3 in_values[ndp];
+# };
+#
+# layout (location = 0) flat in uint ndx_in;
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+# struct frexpStructType
+# {
+# vec3 x;
+# ivec3 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec3 orig)
+# {
+# vec3 x;
+# ivec3 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# uvec3 in_uint = in_values[ndx_in];
+# vec3 in_float = uintBitsToFloat(in_uint);
+# vec3 x;
+# ivec3 exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out = clear_value;
+# frexp_exp_out = clear_value;
+# frexpStruct_x_out = clear_value;
+# frexpStruct_exp_out = clear_value;
+# frexp_x_out.rgb = x;
+# frexp_exp_out.rgb = intBitsToFloat(exp);
+# frexpStruct_x_out.rgb = res.x;
+# frexpStruct_exp_out.rgb = intBitsToFloat(res.exp);
+#
+# return;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %ndx_in %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %_arr_v3uint_uint_1296 ArrayStride 16
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v3float = OpTypeVector %float 3
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+ %int = OpTypeInt 32 1
+ %v3int = OpTypeVector %int 3
+%frexpStructType = OpTypeStruct %v3float %v3int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v3float
+%_ptr_Function_v3int = OpTypePointer Function %v3int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+ %v3uint = OpTypeVector %uint 3
+%_ptr_Function_v3uint = OpTypePointer Function %v3uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_v3uint_uint_1296 = OpTypeArray %v3uint %uint_1296
+ %block0 = OpTypeStruct %_arr_v3uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %int_0 = OpConstant %int 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+ %ndx_in = OpVariable %_ptr_Input_uint Input
+%_ptr_Uniform_v3uint = OpTypePointer Uniform %v3uint
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %61 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+ %int_1 = OpConstant %int 1
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %in_uint = OpVariable %_ptr_Function_v3uint Function
+ %in_float = OpVariable %_ptr_Function_v3float Function
+ %x_0 = OpVariable %_ptr_Function_v3float Function
+ %exp_0 = OpVariable %_ptr_Function_v3int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ %41 = OpLoad %uint %ndx_in
+ %43 = OpAccessChain %_ptr_Uniform_v3uint %_ %int_0 %41
+ %44 = OpLoad %v3uint %43
+ OpStore %in_uint %44
+ %46 = OpLoad %v3uint %in_uint
+ %47 = OpBitcast %v3float %46
+ OpStore %in_float %47
+ %49 = OpLoad %v3float %in_float
+ %51 = OpExtInst %v3float %1 Frexp %49 %exp_0
+ OpStore %x_0 %51
+ %54 = OpLoad %v3float %in_float
+ %55 = OpExtInst %frexpStructType %1 FrexpStruct %54
+ OpStore %res_0 %55
+ OpStore %frexp_x_out %61
+ OpStore %frexp_exp_out %61
+ OpStore %frexpStruct_x_out %61
+ OpStore %frexpStruct_exp_out %61
+ %65 = OpLoad %v3float %x_0
+ %66 = OpLoad %v4float %frexp_x_out
+ %67 = OpVectorShuffle %v4float %66 %65 4 5 6 3
+ OpStore %frexp_x_out %67
+ %68 = OpLoad %v3int %exp_0
+ %69 = OpBitcast %v3float %68
+ %70 = OpLoad %v4float %frexp_exp_out
+ %71 = OpVectorShuffle %v4float %70 %69 4 5 6 3
+ OpStore %frexp_exp_out %71
+ %72 = OpAccessChain %_ptr_Function_v3float %res_0 %int_0
+ %73 = OpLoad %v3float %72
+ %74 = OpLoad %v4float %frexpStruct_x_out
+ %75 = OpVectorShuffle %v4float %74 %73 4 5 6 3
+ OpStore %frexpStruct_x_out %75
+ %77 = OpAccessChain %_ptr_Function_v3int %res_0 %int_1
+ %78 = OpLoad %v3int %77
+ %79 = OpBitcast %v3float %78
+ %80 = OpLoad %v4float %frexpStruct_exp_out
+ %81 = OpVectorShuffle %v4float %80 %79 4 5 6 3
+ OpStore %frexpStruct_exp_out %81
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+RUN test_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A geometry shader test for FrexpStruct.
+
+DEVICE_FEATURE geometryShader
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out uint ndx_out;
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# ndx_out = xcoord + ycoord * ndpSqrt;
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %ndx_out %_
+ OpDecorate %position Location 0
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+ %float_1 = OpConstant %float 1
+ %uint_1 = OpConstant %uint 1
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %ndx_out = OpVariable %_ptr_Output_uint Output
+ %uint_36 = OpConstant %uint 36
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_1_02777779 = OpConstant %float 1.02777779
+ %float_18 = OpConstant %float 18
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %17 = OpLoad %float %16
+ %21 = OpFAdd %float %17 %float_1_02777779
+ %24 = OpFMul %float %21 %float_18
+ %25 = OpFSub %float %24 %float_1
+ %26 = OpConvertFToU %uint %25
+ %29 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %30 = OpLoad %float %29
+ %32 = OpFAdd %float %30 %float_1_02777779
+ %34 = OpFMul %float %32 %float_18
+ %35 = OpFSub %float %34 %float_1
+ %36 = OpConvertFToU %uint %35
+ %42 = OpIMul %uint %36 %uint_36
+ %43 = OpIAdd %uint %26 %42
+ OpStore %ndx_out %43
+ %51 = OpLoad %v2float %position
+ %53 = OpCompositeExtract %float %51 0
+ %54 = OpCompositeExtract %float %51 1
+ %55 = OpCompositeConstruct %v4float %53 %54 %float_0 %float_1
+ %57 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %57 %55
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER geometry geom_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec3 in_values[ndp];
+# };
+#
+# layout (triangles) in;
+# layout (triangle_strip, max_vertices = 3) out;
+#
+# layout (location = 0) flat in uint ndx_in[];
+# layout (location = 0) flat out vec3 frexp_x_out;
+# layout (location = 1) flat out vec3 frexp_exp_out;
+# layout (location = 2) flat out vec3 frexpStruct_x_out;
+# layout (location = 3) flat out vec3 frexpStruct_exp_out;
+#
+# struct frexpStructType
+# {
+# vec3 x;
+# ivec3 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec3 orig)
+# {
+# vec3 x;
+# ivec3 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# for (int vertex = 0; vertex < 3; vertex++)
+# {
+# uvec3 in_uint = in_values[ndx_in[vertex]];
+# vec3 in_float = uintBitsToFloat(in_uint);
+# vec3 x;
+# ivec3 exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out = x;
+# frexp_exp_out = intBitsToFloat(exp);
+# frexpStruct_x_out = res.x;
+# frexpStruct_exp_out = intBitsToFloat(res.exp);
+#
+# gl_Position = gl_in[vertex].gl_Position;
+# EmitVertex();
+# }
+#
+# EndPrimitive();
+# }
+# END
+
+SHADER geometry geom_shader SPIRV-ASM
+ OpCapability Geometry
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Geometry %main "main" %ndx_in %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %__0 %gl_in
+ OpExecutionMode %main Triangles
+ OpExecutionMode %main Invocations 1
+ OpExecutionMode %main OutputTriangleStrip
+ OpExecutionMode %main OutputVertices 3
+ OpDecorate %_arr_v3uint_uint_1296 ArrayStride 16
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v3float = OpTypeVector %float 3
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+ %int = OpTypeInt 32 1
+ %v3int = OpTypeVector %int 3
+%frexpStructType = OpTypeStruct %v3float %v3int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v3float
+%_ptr_Function_v3int = OpTypePointer Function %v3int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+%_ptr_Function_int = OpTypePointer Function %int
+ %int_0 = OpConstant %int 0
+ %int_3 = OpConstant %int 3
+ %bool = OpTypeBool
+ %uint = OpTypeInt 32 0
+ %v3uint = OpTypeVector %uint 3
+%_ptr_Function_v3uint = OpTypePointer Function %v3uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_v3uint_uint_1296 = OpTypeArray %v3uint %uint_1296
+ %block0 = OpTypeStruct %_arr_v3uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %uint_3 = OpConstant %uint 3
+%_arr_uint_uint_3 = OpTypeArray %uint %uint_3
+%_ptr_Input__arr_uint_uint_3 = OpTypePointer Input %_arr_uint_uint_3
+ %ndx_in = OpVariable %_ptr_Input__arr_uint_uint_3 Input
+%_ptr_Input_uint = OpTypePointer Input %uint
+%_ptr_Uniform_v3uint = OpTypePointer Uniform %v3uint
+%_ptr_Output_v3float = OpTypePointer Output %v3float
+%frexp_x_out = OpVariable %_ptr_Output_v3float Output
+%frexp_exp_out = OpVariable %_ptr_Output_v3float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v3float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v3float Output
+ %int_1 = OpConstant %int 1
+ %v4float = OpTypeVector %float 4
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %__0 = OpVariable %_ptr_Output_gl_PerVertex Output
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_arr_gl_PerVertex_0_uint_3 = OpTypeArray %gl_PerVertex_0 %uint_3
+%_ptr_Input__arr_gl_PerVertex_0_uint_3 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_3
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_3 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %vertex = OpVariable %_ptr_Function_int Function
+ %in_uint = OpVariable %_ptr_Function_v3uint Function
+ %in_float = OpVariable %_ptr_Function_v3float Function
+ %x_0 = OpVariable %_ptr_Function_v3float Function
+ %exp_0 = OpVariable %_ptr_Function_v3int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ OpStore %vertex %int_0
+ OpBranch %32
+ %32 = OpLabel
+ OpLoopMerge %34 %35 None
+ OpBranch %36
+ %36 = OpLabel
+ %37 = OpLoad %int %vertex
+ %40 = OpSLessThan %bool %37 %int_3
+ OpBranchConditional %40 %33 %34
+ %33 = OpLabel
+ %54 = OpLoad %int %vertex
+ %56 = OpAccessChain %_ptr_Input_uint %ndx_in %54
+ %57 = OpLoad %uint %56
+ %59 = OpAccessChain %_ptr_Uniform_v3uint %_ %int_0 %57
+ %60 = OpLoad %v3uint %59
+ OpStore %in_uint %60
+ %62 = OpLoad %v3uint %in_uint
+ %63 = OpBitcast %v3float %62
+ OpStore %in_float %63
+ %65 = OpLoad %v3float %in_float
+ %67 = OpExtInst %v3float %1 Frexp %65 %exp_0
+ OpStore %x_0 %67
+ %70 = OpLoad %v3float %in_float
+ %71 = OpExtInst %frexpStructType %1 FrexpStruct %70
+ OpStore %res_0 %71
+ %74 = OpLoad %v3float %x_0
+ OpStore %frexp_x_out %74
+ %76 = OpLoad %v3int %exp_0
+ %77 = OpBitcast %v3float %76
+ OpStore %frexp_exp_out %77
+ %79 = OpAccessChain %_ptr_Function_v3float %res_0 %int_0
+ %80 = OpLoad %v3float %79
+ OpStore %frexpStruct_x_out %80
+ %83 = OpAccessChain %_ptr_Function_v3int %res_0 %int_1
+ %84 = OpLoad %v3int %83
+ %85 = OpBitcast %v3float %84
+ OpStore %frexpStruct_exp_out %85
+ %96 = OpLoad %int %vertex
+ %98 = OpAccessChain %_ptr_Input_v4float %gl_in %96 %int_0
+ %99 = OpLoad %v4float %98
+ %101 = OpAccessChain %_ptr_Output_v4float %__0 %int_0
+ OpStore %101 %99
+ OpEmitVertex
+ OpBranch %35
+ %35 = OpLabel
+ %102 = OpLoad %int %vertex
+ %103 = OpIAdd %int %102 %int_1
+ OpStore %vertex %103
+ OpBranch %32
+ %34 = OpLabel
+ OpEndPrimitive
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (location = 0) flat in vec3 frexp_x_in;
+# layout (location = 1) flat in vec3 frexp_exp_in;
+# layout (location = 2) flat in vec3 frexpStruct_x_in;
+# layout (location = 3) flat in vec3 frexpStruct_exp_in;
+#
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+# const vec4 clear_value = vec4(0.0, 0.0, 0.0, 1.0);
+#
+# void main ()
+# {
+# frexp_x_out = clear_value;
+# frexp_exp_out = clear_value;
+# frexpStruct_x_out = clear_value;
+# frexpStruct_exp_out = clear_value;
+# frexp_x_out.rgb = frexp_x_in;
+# frexp_exp_out.rgb = frexp_exp_in;
+# frexpStruct_x_out.rgb = frexpStruct_x_in;
+# frexpStruct_exp_out.rgb = frexpStruct_exp_in;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %frexp_x_in %frexp_exp_in %frexpStruct_x_in %frexpStruct_exp_in
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+ %v3float = OpTypeVector %float 3
+%_ptr_Input_v3float = OpTypePointer Input %v3float
+ %frexp_x_in = OpVariable %_ptr_Input_v3float Input
+%frexp_exp_in = OpVariable %_ptr_Input_v3float Input
+%frexpStruct_x_in = OpVariable %_ptr_Input_v3float Input
+%frexpStruct_exp_in = OpVariable %_ptr_Input_v3float Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpStore %frexp_x_out %12
+ OpStore %frexp_exp_out %12
+ OpStore %frexpStruct_x_out %12
+ OpStore %frexpStruct_exp_out %12
+ %19 = OpLoad %v3float %frexp_x_in
+ %20 = OpLoad %v4float %frexp_x_out
+ %21 = OpVectorShuffle %v4float %20 %19 4 5 6 3
+ OpStore %frexp_x_out %21
+ %23 = OpLoad %v3float %frexp_exp_in
+ %24 = OpLoad %v4float %frexp_exp_out
+ %25 = OpVectorShuffle %v4float %24 %23 4 5 6 3
+ OpStore %frexp_exp_out %25
+ %27 = OpLoad %v3float %frexpStruct_x_in
+ %28 = OpLoad %v4float %frexpStruct_x_out
+ %29 = OpVectorShuffle %v4float %28 %27 4 5 6 3
+ OpStore %frexpStruct_x_out %29
+ %31 = OpLoad %v3float %frexpStruct_exp_in
+ %32 = OpLoad %v4float %frexpStruct_exp_out
+ %33 = OpVectorShuffle %v4float %32 %31 4 5 6 3
+ OpStore %frexpStruct_exp_out %33
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH geom_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+RUN test_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A tessellation control shader test for FrexpStruct.
+
+DEVICE_FEATURE tessellationShader
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out uint ndx_out;
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# ndx_out = xcoord + ycoord * ndpSqrt;
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %ndx_out %_
+ OpDecorate %position Location 0
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+ %float_1 = OpConstant %float 1
+ %uint_1 = OpConstant %uint 1
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %ndx_out = OpVariable %_ptr_Output_uint Output
+ %uint_36 = OpConstant %uint 36
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_1_02777779 = OpConstant %float 1.02777779
+ %float_18 = OpConstant %float 18
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %17 = OpLoad %float %16
+ %21 = OpFAdd %float %17 %float_1_02777779
+ %24 = OpFMul %float %21 %float_18
+ %25 = OpFSub %float %24 %float_1
+ %26 = OpConvertFToU %uint %25
+ %29 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %30 = OpLoad %float %29
+ %32 = OpFAdd %float %30 %float_1_02777779
+ %34 = OpFMul %float %32 %float_18
+ %35 = OpFSub %float %34 %float_1
+ %36 = OpConvertFToU %uint %35
+ %42 = OpIMul %uint %36 %uint_36
+ %43 = OpIAdd %uint %26 %42
+ OpStore %ndx_out %43
+ %51 = OpLoad %v2float %position
+ %53 = OpCompositeExtract %float %51 0
+ %54 = OpCompositeExtract %float %51 1
+ %55 = OpCompositeConstruct %v4float %53 %54 %float_0 %float_1
+ %57 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %57 %55
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER tessellation_control tesc_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+#
+# layout (vertices = 3) out;
+#
+# layout (location = 0) flat in uint ndx_in[];
+# layout (location = 0) flat out vec3 frexp_x_out[];
+# layout (location = 1) flat out vec3 frexp_exp_out[];
+# layout (location = 2) flat out vec3 frexpStruct_x_out[];
+# layout (location = 3) flat out vec3 frexpStruct_exp_out[];
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec3 in_values[ndp];
+# };
+#
+# struct frexpStructType
+# {
+# vec3 x;
+# ivec3 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec3 orig)
+# {
+# vec3 x;
+# ivec3 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# uvec3 in_uint = in_values[ndx_in[gl_InvocationID]];
+# vec3 in_float = uintBitsToFloat(in_uint);
+# vec3 x;
+# ivec3 exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out[gl_InvocationID] = x;
+# frexp_exp_out[gl_InvocationID] = intBitsToFloat(exp);
+# frexpStruct_x_out[gl_InvocationID] = res.x;
+# frexpStruct_exp_out[gl_InvocationID] = intBitsToFloat(res.exp);
+#
+# gl_TessLevelInner[0] = 1.0;
+# gl_TessLevelInner[1] = 1.0;
+# gl_TessLevelOuter[0] = 1.0;
+# gl_TessLevelOuter[1] = 1.0;
+# gl_TessLevelOuter[2] = 1.0;
+# gl_TessLevelOuter[3] = 1.0;
+# gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
+# }
+# END
+
+SHADER tessellation_control tesc_shader SPIRV-ASM
+ OpCapability Tessellation
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationControl %main "main" %ndx_in %gl_InvocationID %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %gl_TessLevelInner %gl_TessLevelOuter %gl_out %gl_in
+ OpExecutionMode %main OutputVertices 3
+ OpDecorate %_arr_v3uint_uint_1296 ArrayStride 16
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ OpDecorate %gl_InvocationID BuiltIn InvocationId
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %gl_TessLevelInner Patch
+ OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner
+ OpDecorate %gl_TessLevelOuter Patch
+ OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v3float = OpTypeVector %float 3
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+ %int = OpTypeInt 32 1
+ %v3int = OpTypeVector %int 3
+%frexpStructType = OpTypeStruct %v3float %v3int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v3float
+%_ptr_Function_v3int = OpTypePointer Function %v3int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+ %v3uint = OpTypeVector %uint 3
+%_ptr_Function_v3uint = OpTypePointer Function %v3uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_v3uint_uint_1296 = OpTypeArray %v3uint %uint_1296
+ %block0 = OpTypeStruct %_arr_v3uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %int_0 = OpConstant %int 0
+ %uint_32 = OpConstant %uint 32
+%_arr_uint_uint_32 = OpTypeArray %uint %uint_32
+%_ptr_Input__arr_uint_uint_32 = OpTypePointer Input %_arr_uint_uint_32
+ %ndx_in = OpVariable %_ptr_Input__arr_uint_uint_32 Input
+%_ptr_Input_int = OpTypePointer Input %int
+%gl_InvocationID = OpVariable %_ptr_Input_int Input
+%_ptr_Input_uint = OpTypePointer Input %uint
+%_ptr_Uniform_v3uint = OpTypePointer Uniform %v3uint
+ %uint_3 = OpConstant %uint 3
+%_arr_v3float_uint_3 = OpTypeArray %v3float %uint_3
+%_ptr_Output__arr_v3float_uint_3 = OpTypePointer Output %_arr_v3float_uint_3
+%frexp_x_out = OpVariable %_ptr_Output__arr_v3float_uint_3 Output
+%_ptr_Output_v3float = OpTypePointer Output %v3float
+%frexp_exp_out = OpVariable %_ptr_Output__arr_v3float_uint_3 Output
+%frexpStruct_x_out = OpVariable %_ptr_Output__arr_v3float_uint_3 Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output__arr_v3float_uint_3 Output
+ %int_1 = OpConstant %int 1
+ %uint_2 = OpConstant %uint 2
+%_arr_float_uint_2 = OpTypeArray %float %uint_2
+%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2
+%gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output
+ %float_1 = OpConstant %float 1
+%_ptr_Output_float = OpTypePointer Output %float
+ %uint_4 = OpConstant %uint 4
+%_arr_float_uint_4 = OpTypeArray %float %uint_4
+%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4
+%gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output
+ %int_2 = OpConstant %int 2
+ %int_3 = OpConstant %int 3
+ %v4float = OpTypeVector %float 4
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_arr_gl_PerVertex_uint_3 = OpTypeArray %gl_PerVertex %uint_3
+%_ptr_Output__arr_gl_PerVertex_uint_3 = OpTypePointer Output %_arr_gl_PerVertex_uint_3
+ %gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_uint_3 Output
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_arr_gl_PerVertex_0_uint_32 = OpTypeArray %gl_PerVertex_0 %uint_32
+%_ptr_Input__arr_gl_PerVertex_0_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_32
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %in_uint = OpVariable %_ptr_Function_v3uint Function
+ %in_float = OpVariable %_ptr_Function_v3float Function
+ %x_0 = OpVariable %_ptr_Function_v3float Function
+ %exp_0 = OpVariable %_ptr_Function_v3int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ %45 = OpLoad %int %gl_InvocationID
+ %47 = OpAccessChain %_ptr_Input_uint %ndx_in %45
+ %48 = OpLoad %uint %47
+ %50 = OpAccessChain %_ptr_Uniform_v3uint %_ %int_0 %48
+ %51 = OpLoad %v3uint %50
+ OpStore %in_uint %51
+ %53 = OpLoad %v3uint %in_uint
+ %54 = OpBitcast %v3float %53
+ OpStore %in_float %54
+ %56 = OpLoad %v3float %in_float
+ %58 = OpExtInst %v3float %1 Frexp %56 %exp_0
+ OpStore %x_0 %58
+ %61 = OpLoad %v3float %in_float
+ %62 = OpExtInst %frexpStructType %1 FrexpStruct %61
+ OpStore %res_0 %62
+ %67 = OpLoad %int %gl_InvocationID
+ %68 = OpLoad %v3float %x_0
+ %70 = OpAccessChain %_ptr_Output_v3float %frexp_x_out %67
+ OpStore %70 %68
+ %72 = OpLoad %int %gl_InvocationID
+ %73 = OpLoad %v3int %exp_0
+ %74 = OpBitcast %v3float %73
+ %75 = OpAccessChain %_ptr_Output_v3float %frexp_exp_out %72
+ OpStore %75 %74
+ %77 = OpLoad %int %gl_InvocationID
+ %78 = OpAccessChain %_ptr_Function_v3float %res_0 %int_0
+ %79 = OpLoad %v3float %78
+ %80 = OpAccessChain %_ptr_Output_v3float %frexpStruct_x_out %77
+ OpStore %80 %79
+ %82 = OpLoad %int %gl_InvocationID
+ %84 = OpAccessChain %_ptr_Function_v3int %res_0 %int_1
+ %85 = OpLoad %v3int %84
+ %86 = OpBitcast %v3float %85
+ %87 = OpAccessChain %_ptr_Output_v3float %frexpStruct_exp_out %82
+ OpStore %87 %86
+ %94 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0
+ OpStore %94 %float_1
+ %95 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_1
+ OpStore %95 %float_1
+ %100 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0
+ OpStore %100 %float_1
+ %101 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1
+ OpStore %101 %float_1
+ %103 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2
+ OpStore %103 %float_1
+ %105 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_3
+ OpStore %105 %float_1
+ %113 = OpLoad %int %gl_InvocationID
+ %118 = OpLoad %int %gl_InvocationID
+ %120 = OpAccessChain %_ptr_Input_v4float %gl_in %118 %int_0
+ %121 = OpLoad %v4float %120
+ %123 = OpAccessChain %_ptr_Output_v4float %gl_out %113 %int_0
+ OpStore %123 %121
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER tessellation_evaluation tese_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (triangles) in;
+#
+# layout (location = 0) flat in vec3 frexp_x_in[];
+# layout (location = 1) flat in vec3 frexp_exp_in[];
+# layout (location = 2) flat in vec3 frexpStruct_x_in[];
+# layout (location = 3) flat in vec3 frexpStruct_exp_in[];
+#
+# layout (location = 0) flat out vec3 frexp_x_out;
+# layout (location = 1) flat out vec3 frexp_exp_out;
+# layout (location = 2) flat out vec3 frexpStruct_x_out;
+# layout (location = 3) flat out vec3 frexpStruct_exp_out;
+#
+# void main ()
+# {
+# gl_Position = gl_TessCoord.x * gl_in[0].gl_Position +
+# gl_TessCoord.y * gl_in[1].gl_Position +
+# gl_TessCoord.z * gl_in[2].gl_Position;
+#
+# frexp_x_out = frexp_x_in[0];
+# frexp_exp_out = frexp_exp_in[0];
+# frexpStruct_x_out = frexpStruct_x_in[0];
+# frexpStruct_exp_out = frexpStruct_exp_in[0];
+# }
+# END
+
+SHADER tessellation_evaluation tese_shader SPIRV-ASM
+ OpCapability Tessellation
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationEvaluation %main "main" %_ %gl_TessCoord %gl_in %frexp_x_out %frexp_x_in %frexp_exp_out %frexp_exp_in %frexpStruct_x_out %frexpStruct_x_in %frexpStruct_exp_out %frexpStruct_exp_in
+ OpExecutionMode %main Triangles
+ OpExecutionMode %main SpacingEqual
+ OpExecutionMode %main VertexOrderCcw
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpDecorate %gl_TessCoord BuiltIn TessCoord
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+ %uint = OpTypeInt 32 0
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %v3float = OpTypeVector %float 3
+%_ptr_Input_v3float = OpTypePointer Input %v3float
+%gl_TessCoord = OpVariable %_ptr_Input_v3float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+ %uint_32 = OpConstant %uint 32
+%_arr_gl_PerVertex_0_uint_32 = OpTypeArray %gl_PerVertex_0 %uint_32
+%_ptr_Input__arr_gl_PerVertex_0_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_32
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %int_1 = OpConstant %int 1
+ %uint_2 = OpConstant %uint 2
+ %int_2 = OpConstant %int 2
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%_ptr_Output_v3float = OpTypePointer Output %v3float
+%frexp_x_out = OpVariable %_ptr_Output_v3float Output
+%_arr_v3float_uint_32 = OpTypeArray %v3float %uint_32
+%_ptr_Input__arr_v3float_uint_32 = OpTypePointer Input %_arr_v3float_uint_32
+ %frexp_x_in = OpVariable %_ptr_Input__arr_v3float_uint_32 Input
+%frexp_exp_out = OpVariable %_ptr_Output_v3float Output
+%frexp_exp_in = OpVariable %_ptr_Input__arr_v3float_uint_32 Input
+%frexpStruct_x_out = OpVariable %_ptr_Output_v3float Output
+%frexpStruct_x_in = OpVariable %_ptr_Input__arr_v3float_uint_32 Input
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v3float Output
+%frexpStruct_exp_in = OpVariable %_ptr_Input__arr_v3float_uint_32 Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %21 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_0
+ %22 = OpLoad %float %21
+ %29 = OpAccessChain %_ptr_Input_v4float %gl_in %int_0 %int_0
+ %30 = OpLoad %v4float %29
+ %31 = OpVectorTimesScalar %v4float %30 %22
+ %32 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_1
+ %33 = OpLoad %float %32
+ %35 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0
+ %36 = OpLoad %v4float %35
+ %37 = OpVectorTimesScalar %v4float %36 %33
+ %38 = OpFAdd %v4float %31 %37
+ %40 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_2
+ %41 = OpLoad %float %40
+ %43 = OpAccessChain %_ptr_Input_v4float %gl_in %int_2 %int_0
+ %44 = OpLoad %v4float %43
+ %45 = OpVectorTimesScalar %v4float %44 %41
+ %46 = OpFAdd %v4float %38 %45
+ %48 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %48 %46
+ %54 = OpAccessChain %_ptr_Input_v3float %frexp_x_in %int_0
+ %55 = OpLoad %v3float %54
+ OpStore %frexp_x_out %55
+ %58 = OpAccessChain %_ptr_Input_v3float %frexp_exp_in %int_0
+ %59 = OpLoad %v3float %58
+ OpStore %frexp_exp_out %59
+ %62 = OpAccessChain %_ptr_Input_v3float %frexpStruct_x_in %int_0
+ %63 = OpLoad %v3float %62
+ OpStore %frexpStruct_x_out %63
+ %66 = OpAccessChain %_ptr_Input_v3float %frexpStruct_exp_in %int_0
+ %67 = OpLoad %v3float %66
+ OpStore %frexpStruct_exp_out %67
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (location = 0) flat in vec3 frexp_x_in;
+# layout (location = 1) flat in vec3 frexp_exp_in;
+# layout (location = 2) flat in vec3 frexpStruct_x_in;
+# layout (location = 3) flat in vec3 frexpStruct_exp_in;
+#
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+# const vec4 clear_value = vec4(0.0, 0.0, 0.0, 1.0);
+#
+# void main ()
+# {
+# frexp_x_out = clear_value;
+# frexp_exp_out = clear_value;
+# frexpStruct_x_out = clear_value;
+# frexpStruct_exp_out = clear_value;
+# frexp_x_out.rgb = frexp_x_in;
+# frexp_exp_out.rgb = frexp_exp_in;
+# frexpStruct_x_out.rgb = frexpStruct_x_in;
+# frexpStruct_exp_out.rgb = frexpStruct_exp_in;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %frexp_x_in %frexp_exp_in %frexpStruct_x_in %frexpStruct_exp_in
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+ %v3float = OpTypeVector %float 3
+%_ptr_Input_v3float = OpTypePointer Input %v3float
+ %frexp_x_in = OpVariable %_ptr_Input_v3float Input
+%frexp_exp_in = OpVariable %_ptr_Input_v3float Input
+%frexpStruct_x_in = OpVariable %_ptr_Input_v3float Input
+%frexpStruct_exp_in = OpVariable %_ptr_Input_v3float Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpStore %frexp_x_out %12
+ OpStore %frexp_exp_out %12
+ OpStore %frexpStruct_x_out %12
+ OpStore %frexpStruct_exp_out %12
+ %19 = OpLoad %v3float %frexp_x_in
+ %20 = OpLoad %v4float %frexp_x_out
+ %21 = OpVectorShuffle %v4float %20 %19 4 5 6 3
+ OpStore %frexp_x_out %21
+ %23 = OpLoad %v3float %frexp_exp_in
+ %24 = OpLoad %v4float %frexp_exp_out
+ %25 = OpVectorShuffle %v4float %24 %23 4 5 6 3
+ OpStore %frexp_exp_out %25
+ %27 = OpLoad %v3float %frexpStruct_x_in
+ %28 = OpLoad %v4float %frexpStruct_x_out
+ %29 = OpVectorShuffle %v4float %28 %27 4 5 6 3
+ OpStore %frexpStruct_x_out %29
+ %31 = OpLoad %v3float %frexpStruct_exp_in
+ %32 = OpLoad %v4float %frexpStruct_exp_out
+ %33 = OpVectorShuffle %v4float %32 %31 4 5 6 3
+ OpStore %frexpStruct_exp_out %33
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH tesc_shader
+ ATTACH tese_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+#RUN test_pipeline DRAW_GRID POS 0 0 SIZE 144 144 CELLS 144 144
+RUN test_pipeline DRAW_ARRAY AS PATCH_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A tessellation evaluation shader test for FrexpStruct.
+
+DEVICE_FEATURE tessellationShader
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out uint ndx_out;
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# ndx_out = xcoord + ycoord * ndpSqrt;
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %ndx_out %_
+ OpDecorate %position Location 0
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+ %float_1 = OpConstant %float 1
+ %uint_1 = OpConstant %uint 1
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %ndx_out = OpVariable %_ptr_Output_uint Output
+ %uint_36 = OpConstant %uint 36
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_1_02777779 = OpConstant %float 1.02777779
+ %float_18 = OpConstant %float 18
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %17 = OpLoad %float %16
+ %21 = OpFAdd %float %17 %float_1_02777779
+ %24 = OpFMul %float %21 %float_18
+ %25 = OpFSub %float %24 %float_1
+ %26 = OpConvertFToU %uint %25
+ %29 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %30 = OpLoad %float %29
+ %32 = OpFAdd %float %30 %float_1_02777779
+ %34 = OpFMul %float %32 %float_18
+ %35 = OpFSub %float %34 %float_1
+ %36 = OpConvertFToU %uint %35
+ %42 = OpIMul %uint %36 %uint_36
+ %43 = OpIAdd %uint %26 %42
+ OpStore %ndx_out %43
+ %51 = OpLoad %v2float %position
+ %53 = OpCompositeExtract %float %51 0
+ %54 = OpCompositeExtract %float %51 1
+ %55 = OpCompositeConstruct %v4float %53 %54 %float_0 %float_1
+ %57 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %57 %55
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER tessellation_control tesc_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (vertices = 3) out;
+#
+# layout (location = 0) flat in uint ndx_in[];
+# layout (location = 0) flat out uint ndx_out[];
+#
+# void main ()
+# {
+# gl_TessLevelInner[0] = 1.0;
+# gl_TessLevelInner[1] = 1.0;
+# gl_TessLevelOuter[0] = 1.0;
+# gl_TessLevelOuter[1] = 1.0;
+# gl_TessLevelOuter[2] = 1.0;
+# gl_TessLevelOuter[3] = 1.0;
+#
+# gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
+# ndx_out[gl_InvocationID] = ndx_in[gl_InvocationID];
+# }
+# END
+
+SHADER tessellation_control tesc_shader SPIRV-ASM
+ OpCapability Tessellation
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationControl %main "main" %gl_TessLevelInner %gl_TessLevelOuter %gl_out %gl_InvocationID %gl_in %ndx_out %ndx_in
+ OpExecutionMode %main OutputVertices 3
+ OpDecorate %gl_TessLevelInner Patch
+ OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner
+ OpDecorate %gl_TessLevelOuter Patch
+ OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpDecorate %gl_InvocationID BuiltIn InvocationId
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_2 = OpConstant %uint 2
+%_arr_float_uint_2 = OpTypeArray %float %uint_2
+%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2
+%gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_1 = OpConstant %float 1
+%_ptr_Output_float = OpTypePointer Output %float
+ %int_1 = OpConstant %int 1
+ %uint_4 = OpConstant %uint 4
+%_arr_float_uint_4 = OpTypeArray %float %uint_4
+%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4
+%gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output
+ %int_2 = OpConstant %int 2
+ %int_3 = OpConstant %int 3
+ %v4float = OpTypeVector %float 4
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+ %uint_3 = OpConstant %uint 3
+%_arr_gl_PerVertex_uint_3 = OpTypeArray %gl_PerVertex %uint_3
+%_ptr_Output__arr_gl_PerVertex_uint_3 = OpTypePointer Output %_arr_gl_PerVertex_uint_3
+ %gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_uint_3 Output
+%_ptr_Input_int = OpTypePointer Input %int
+%gl_InvocationID = OpVariable %_ptr_Input_int Input
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+ %uint_32 = OpConstant %uint 32
+%_arr_gl_PerVertex_0_uint_32 = OpTypeArray %gl_PerVertex_0 %uint_32
+%_ptr_Input__arr_gl_PerVertex_0_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_32
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%_arr_uint_uint_3 = OpTypeArray %uint %uint_3
+%_ptr_Output__arr_uint_uint_3 = OpTypePointer Output %_arr_uint_uint_3
+ %ndx_out = OpVariable %_ptr_Output__arr_uint_uint_3 Output
+%_arr_uint_uint_32 = OpTypeArray %uint %uint_32
+%_ptr_Input__arr_uint_uint_32 = OpTypePointer Input %_arr_uint_uint_32
+ %ndx_in = OpVariable %_ptr_Input__arr_uint_uint_32 Input
+%_ptr_Input_uint = OpTypePointer Input %uint
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0
+ OpStore %16 %float_1
+ %18 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_1
+ OpStore %18 %float_1
+ %23 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0
+ OpStore %23 %float_1
+ %24 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1
+ OpStore %24 %float_1
+ %26 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2
+ OpStore %26 %float_1
+ %28 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_3
+ OpStore %28 %float_1
+ %39 = OpLoad %int %gl_InvocationID
+ %47 = OpAccessChain %_ptr_Input_v4float %gl_in %39 %int_0
+ %48 = OpLoad %v4float %47
+ %50 = OpAccessChain %_ptr_Output_v4float %gl_out %39 %int_0
+ OpStore %50 %48
+ %60 = OpAccessChain %_ptr_Input_uint %ndx_in %39
+ %61 = OpLoad %uint %60
+ %63 = OpAccessChain %_ptr_Output_uint %ndx_out %39
+ OpStore %63 %61
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER tessellation_evaluation tese_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+#
+# layout (triangles) in;
+#
+# layout (location = 0) flat in uint ndx_in[];
+# layout (location = 0) flat out vec3 frexp_x_out;
+# layout (location = 1) flat out vec3 frexp_exp_out;
+# layout (location = 2) flat out vec3 frexpStruct_x_out;
+# layout (location = 3) flat out vec3 frexpStruct_exp_out;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec3 in_values[ndp];
+# };
+#
+# struct frexpStructType
+# {
+# vec3 x;
+# ivec3 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec3 orig)
+# {
+# vec3 x;
+# ivec3 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# gl_Position = gl_TessCoord.x * gl_in[0].gl_Position +
+# gl_TessCoord.y * gl_in[1].gl_Position +
+# gl_TessCoord.z * gl_in[2].gl_Position;
+#
+# uvec3 in_uint = in_values[ndx_in[0]];
+# vec3 in_float = uintBitsToFloat(in_uint);
+# vec3 x;
+# ivec3 exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out = x;
+# frexp_exp_out = intBitsToFloat(exp);
+# frexpStruct_x_out = res.x;
+# frexpStruct_exp_out = intBitsToFloat(res.exp);
+# }
+# END
+
+SHADER tessellation_evaluation tese_shader SPIRV-ASM
+ OpCapability Tessellation
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationEvaluation %main "main" %_ %gl_TessCoord %gl_in %ndx_in %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out
+ OpExecutionMode %main Triangles
+ OpExecutionMode %main SpacingEqual
+ OpExecutionMode %main VertexOrderCcw
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpDecorate %gl_TessCoord BuiltIn TessCoord
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ OpDecorate %_arr_v3uint_uint_1296 ArrayStride 16
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %__0 DescriptorSet 0
+ OpDecorate %__0 Binding 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v3float = OpTypeVector %float 3
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+ %int = OpTypeInt 32 1
+ %v3int = OpTypeVector %int 3
+%frexpStructType = OpTypeStruct %v3float %v3int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v3float
+%_ptr_Function_v3int = OpTypePointer Function %v3int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %v4float = OpTypeVector %float 4
+ %uint = OpTypeInt 32 0
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int_0 = OpConstant %int 0
+%_ptr_Input_v3float = OpTypePointer Input %v3float
+%gl_TessCoord = OpVariable %_ptr_Input_v3float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+ %uint_32 = OpConstant %uint 32
+%_arr_gl_PerVertex_0_uint_32 = OpTypeArray %gl_PerVertex_0 %uint_32
+%_ptr_Input__arr_gl_PerVertex_0_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_32
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %int_1 = OpConstant %int 1
+ %uint_2 = OpConstant %uint 2
+ %int_2 = OpConstant %int 2
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %v3uint = OpTypeVector %uint 3
+%_ptr_Function_v3uint = OpTypePointer Function %v3uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_v3uint_uint_1296 = OpTypeArray %v3uint %uint_1296
+ %block0 = OpTypeStruct %_arr_v3uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %__0 = OpVariable %_ptr_Uniform_block0 Uniform
+%_arr_uint_uint_32 = OpTypeArray %uint %uint_32
+%_ptr_Input__arr_uint_uint_32 = OpTypePointer Input %_arr_uint_uint_32
+ %ndx_in = OpVariable %_ptr_Input__arr_uint_uint_32 Input
+%_ptr_Input_uint = OpTypePointer Input %uint
+%_ptr_Uniform_v3uint = OpTypePointer Uniform %v3uint
+%_ptr_Output_v3float = OpTypePointer Output %v3float
+%frexp_x_out = OpVariable %_ptr_Output_v3float Output
+%frexp_exp_out = OpVariable %_ptr_Output_v3float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v3float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v3float Output
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %in_uint = OpVariable %_ptr_Function_v3uint Function
+ %in_float = OpVariable %_ptr_Function_v3float Function
+ %x_0 = OpVariable %_ptr_Function_v3float Function
+ %exp_0 = OpVariable %_ptr_Function_v3int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ %41 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_0
+ %42 = OpLoad %float %41
+ %49 = OpAccessChain %_ptr_Input_v4float %gl_in %int_0 %int_0
+ %50 = OpLoad %v4float %49
+ %51 = OpVectorTimesScalar %v4float %50 %42
+ %52 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_1
+ %53 = OpLoad %float %52
+ %55 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0
+ %56 = OpLoad %v4float %55
+ %57 = OpVectorTimesScalar %v4float %56 %53
+ %58 = OpFAdd %v4float %51 %57
+ %60 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_2
+ %61 = OpLoad %float %60
+ %63 = OpAccessChain %_ptr_Input_v4float %gl_in %int_2 %int_0
+ %64 = OpLoad %v4float %63
+ %65 = OpVectorTimesScalar %v4float %64 %61
+ %66 = OpFAdd %v4float %58 %65
+ %68 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %68 %66
+ %81 = OpAccessChain %_ptr_Input_uint %ndx_in %int_0
+ %82 = OpLoad %uint %81
+ %84 = OpAccessChain %_ptr_Uniform_v3uint %__0 %int_0 %82
+ %85 = OpLoad %v3uint %84
+ OpStore %in_uint %85
+ %87 = OpLoad %v3uint %in_uint
+ %88 = OpBitcast %v3float %87
+ OpStore %in_float %88
+ %90 = OpLoad %v3float %in_float
+ %92 = OpExtInst %v3float %1 Frexp %90 %exp_0
+ OpStore %x_0 %92
+ %95 = OpLoad %v3float %in_float
+ %96 = OpExtInst %frexpStructType %1 FrexpStruct %95
+ OpStore %res_0 %96
+ %99 = OpLoad %v3float %x_0
+ OpStore %frexp_x_out %99
+ %101 = OpLoad %v3int %exp_0
+ %102 = OpBitcast %v3float %101
+ OpStore %frexp_exp_out %102
+ %104 = OpAccessChain %_ptr_Function_v3float %res_0 %int_0
+ %105 = OpLoad %v3float %104
+ OpStore %frexpStruct_x_out %105
+ %107 = OpAccessChain %_ptr_Function_v3int %res_0 %int_1
+ %108 = OpLoad %v3int %107
+ %109 = OpBitcast %v3float %108
+ OpStore %frexpStruct_exp_out %109
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (location = 0) flat in vec3 frexp_x_in;
+# layout (location = 1) flat in vec3 frexp_exp_in;
+# layout (location = 2) flat in vec3 frexpStruct_x_in;
+# layout (location = 3) flat in vec3 frexpStruct_exp_in;
+#
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+# const vec4 clear_value = vec4(0.0, 0.0, 0.0, 1.0);
+#
+# void main ()
+# {
+# frexp_x_out = clear_value;
+# frexp_exp_out = clear_value;
+# frexpStruct_x_out = clear_value;
+# frexpStruct_exp_out = clear_value;
+# frexp_x_out.rgb = frexp_x_in;
+# frexp_exp_out.rgb = frexp_exp_in;
+# frexpStruct_x_out.rgb = frexpStruct_x_in;
+# frexpStruct_exp_out.rgb = frexpStruct_exp_in;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %frexp_x_in %frexp_exp_in %frexpStruct_x_in %frexpStruct_exp_in
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+ %v3float = OpTypeVector %float 3
+%_ptr_Input_v3float = OpTypePointer Input %v3float
+ %frexp_x_in = OpVariable %_ptr_Input_v3float Input
+%frexp_exp_in = OpVariable %_ptr_Input_v3float Input
+%frexpStruct_x_in = OpVariable %_ptr_Input_v3float Input
+%frexpStruct_exp_in = OpVariable %_ptr_Input_v3float Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpStore %frexp_x_out %12
+ OpStore %frexp_exp_out %12
+ OpStore %frexpStruct_x_out %12
+ OpStore %frexpStruct_exp_out %12
+ %19 = OpLoad %v3float %frexp_x_in
+ %20 = OpLoad %v4float %frexp_x_out
+ %21 = OpVectorShuffle %v4float %20 %19 4 5 6 3
+ OpStore %frexp_x_out %21
+ %23 = OpLoad %v3float %frexp_exp_in
+ %24 = OpLoad %v4float %frexp_exp_out
+ %25 = OpVectorShuffle %v4float %24 %23 4 5 6 3
+ OpStore %frexp_exp_out %25
+ %27 = OpLoad %v3float %frexpStruct_x_in
+ %28 = OpLoad %v4float %frexpStruct_x_out
+ %29 = OpVectorShuffle %v4float %28 %27 4 5 6 3
+ OpStore %frexpStruct_x_out %29
+ %31 = OpLoad %v3float %frexpStruct_exp_in
+ %32 = OpLoad %v4float %frexpStruct_exp_out
+ %33 = OpVectorShuffle %v4float %32 %31 4 5 6 3
+ OpStore %frexpStruct_exp_out %33
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH tesc_shader
+ ATTACH tese_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+#RUN test_pipeline DRAW_GRID POS 0 0 SIZE 144 144 CELLS 144 144
+RUN test_pipeline DRAW_ARRAY AS PATCH_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A vertex shader test for FrexpStruct.
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out vec3 frexp_x_out;
+# layout (location = 1) flat out vec3 frexp_exp_out;
+# layout (location = 2) flat out vec3 frexpStruct_x_out;
+# layout (location = 3) flat out vec3 frexpStruct_exp_out;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec3 in_values[ndp];
+# };
+#
+# struct frexpStructType
+# {
+# vec3 x;
+# ivec3 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec3 orig)
+# {
+# vec3 x;
+# ivec3 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# uint ndx = xcoord + ycoord * ndpSqrt;
+#
+# uvec3 in_uint = in_values[ndx];
+# vec3 in_float = uintBitsToFloat(in_uint);
+# vec3 x;
+# ivec3 exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out = x;
+# frexp_exp_out = intBitsToFloat(exp);
+# frexpStruct_x_out = res.x;
+# frexpStruct_exp_out = intBitsToFloat(res.exp);
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %__0
+ OpDecorate %position Location 0
+ OpDecorate %_arr_v3uint_uint_1296 ArrayStride 16
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v3float = OpTypeVector %float 3
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+ %int = OpTypeInt 32 1
+ %v3int = OpTypeVector %int 3
+%frexpStructType = OpTypeStruct %v3float %v3int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v3float
+%_ptr_Function_v3int = OpTypePointer Function %v3int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %float_36 = OpConstant %float 36
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+%float_0_027777778 = OpConstant %float 0.027777778
+ %float_1 = OpConstant %float 1
+ %float_2 = OpConstant %float 2
+ %uint_1 = OpConstant %uint 1
+ %uint_36 = OpConstant %uint 36
+ %v3uint = OpTypeVector %uint 3
+%_ptr_Function_v3uint = OpTypePointer Function %v3uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_v3uint_uint_1296 = OpTypeArray %v3uint %uint_1296
+ %block0 = OpTypeStruct %_arr_v3uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %int_0 = OpConstant %int 0
+%_ptr_Uniform_v3uint = OpTypePointer Uniform %v3uint
+%_ptr_Output_v3float = OpTypePointer Output %v3float
+%frexp_x_out = OpVariable %_ptr_Output_v3float Output
+%frexp_exp_out = OpVariable %_ptr_Output_v3float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v3float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v3float Output
+ %int_1 = OpConstant %int 1
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %__0 = OpVariable %_ptr_Output_gl_PerVertex Output
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %xcoord = OpVariable %_ptr_Function_uint Function
+ %ycoord = OpVariable %_ptr_Function_uint Function
+ %ndx = OpVariable %_ptr_Function_uint Function
+ %in_uint = OpVariable %_ptr_Function_v3uint Function
+ %in_float = OpVariable %_ptr_Function_v3float Function
+ %x_0 = OpVariable %_ptr_Function_v3float Function
+ %exp_0 = OpVariable %_ptr_Function_v3int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ %38 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %39 = OpLoad %float %38
+ %41 = OpFAdd %float %39 %float_0_027777778
+ %43 = OpFAdd %float %41 %float_1
+ %45 = OpFDiv %float %43 %float_2
+ %46 = OpFMul %float %float_36 %45
+ %47 = OpFSub %float %46 %float_1
+ %48 = OpConvertFToU %uint %47
+ OpStore %xcoord %48
+ %51 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %52 = OpLoad %float %51
+ %53 = OpFAdd %float %52 %float_0_027777778
+ %54 = OpFAdd %float %53 %float_1
+ %55 = OpFDiv %float %54 %float_2
+ %56 = OpFMul %float %float_36 %55
+ %57 = OpFSub %float %56 %float_1
+ %58 = OpConvertFToU %uint %57
+ OpStore %ycoord %58
+ %60 = OpLoad %uint %xcoord
+ %61 = OpLoad %uint %ycoord
+ %63 = OpIMul %uint %61 %uint_36
+ %64 = OpIAdd %uint %60 %63
+ OpStore %ndx %64
+ %74 = OpLoad %uint %ndx
+ %76 = OpAccessChain %_ptr_Uniform_v3uint %_ %int_0 %74
+ %77 = OpLoad %v3uint %76
+ OpStore %in_uint %77
+ %79 = OpLoad %v3uint %in_uint
+ %80 = OpBitcast %v3float %79
+ OpStore %in_float %80
+ %82 = OpLoad %v3float %in_float
+ %84 = OpExtInst %v3float %1 Frexp %82 %exp_0
+ OpStore %x_0 %84
+ %87 = OpLoad %v3float %in_float
+ %88 = OpExtInst %frexpStructType %1 FrexpStruct %87
+ OpStore %res_0 %88
+ %91 = OpLoad %v3float %x_0
+ OpStore %frexp_x_out %91
+ %93 = OpLoad %v3int %exp_0
+ %94 = OpBitcast %v3float %93
+ OpStore %frexp_exp_out %94
+ %96 = OpAccessChain %_ptr_Function_v3float %res_0 %int_0
+ %97 = OpLoad %v3float %96
+ OpStore %frexpStruct_x_out %97
+ %100 = OpAccessChain %_ptr_Function_v3int %res_0 %int_1
+ %101 = OpLoad %v3int %100
+ %102 = OpBitcast %v3float %101
+ OpStore %frexpStruct_exp_out %102
+ %108 = OpLoad %v2float %position
+ %110 = OpCompositeExtract %float %108 0
+ %111 = OpCompositeExtract %float %108 1
+ %112 = OpCompositeConstruct %v4float %110 %111 %float_0 %float_1
+ %114 = OpAccessChain %_ptr_Output_v4float %__0 %int_0
+ OpStore %114 %112
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (location = 0) flat in vec3 frexp_x_in;
+# layout (location = 1) flat in vec3 frexp_exp_in;
+# layout (location = 2) flat in vec3 frexpStruct_x_in;
+# layout (location = 3) flat in vec3 frexpStruct_exp_in;
+#
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+# const vec4 clear_value = vec4(0.0, 0.0, 0.0, 1.0);
+#
+# void main ()
+# {
+# frexp_x_out = clear_value;
+# frexp_exp_out = clear_value;
+# frexpStruct_x_out = clear_value;
+# frexpStruct_exp_out = clear_value;
+# frexp_x_out.rgb = frexp_x_in;
+# frexp_exp_out.rgb = frexp_exp_in;
+# frexpStruct_x_out.rgb = frexpStruct_x_in;
+# frexpStruct_exp_out.rgb = frexpStruct_exp_in;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %frexp_x_in %frexp_exp_in %frexpStruct_x_in %frexpStruct_exp_in
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+ %v3float = OpTypeVector %float 3
+%_ptr_Input_v3float = OpTypePointer Input %v3float
+ %frexp_x_in = OpVariable %_ptr_Input_v3float Input
+%frexp_exp_in = OpVariable %_ptr_Input_v3float Input
+%frexpStruct_x_in = OpVariable %_ptr_Input_v3float Input
+%frexpStruct_exp_in = OpVariable %_ptr_Input_v3float Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpStore %frexp_x_out %12
+ OpStore %frexp_exp_out %12
+ OpStore %frexpStruct_x_out %12
+ OpStore %frexpStruct_exp_out %12
+ %19 = OpLoad %v3float %frexp_x_in
+ %20 = OpLoad %v4float %frexp_x_out
+ %21 = OpVectorShuffle %v4float %20 %19 4 5 6 3
+ OpStore %frexp_x_out %21
+ %23 = OpLoad %v3float %frexp_exp_in
+ %24 = OpLoad %v4float %frexp_exp_out
+ %25 = OpVectorShuffle %v4float %24 %23 4 5 6 3
+ OpStore %frexp_exp_out %25
+ %27 = OpLoad %v3float %frexpStruct_x_in
+ %28 = OpLoad %v4float %frexpStruct_x_out
+ %29 = OpVectorShuffle %v4float %28 %27 4 5 6 3
+ OpStore %frexpStruct_x_out %29
+ %31 = OpLoad %v3float %frexpStruct_exp_in
+ %32 = OpLoad %v4float %frexpStruct_exp_out
+ %33 = OpVectorShuffle %v4float %32 %31 4 5 6 3
+ OpStore %frexpStruct_exp_out %33
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+RUN test_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A compute shader test for FrexpStruct.
+
+# SHADER compute comp_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296 / 4;
+# const uint half_ndp = ndp / 2;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec4 in_values[half_ndp];
+# };
+#
+# layout(set = 0, binding = 1) buffer block1 {
+# vec4 frexp_out[ndp];
+# };
+#
+# layout(set = 0, binding = 2) buffer block2 {
+# vec4 frexpStruct_out[ndp];
+# };
+#
+# struct frexpStructType
+# {
+# vec4 x;
+# ivec4 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec4 orig)
+# {
+# vec4 x;
+# ivec4 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# for (uint ndx = 0; ndx < ndp; ndx += 2)
+# {
+# uvec4 in_uint = in_values[ndx/2];
+# vec4 in_float = uintBitsToFloat(in_uint);
+# vec4 x;
+# ivec4 exp;
+#
+# x = frexp(in_float, exp);
+# frexpStructType res = frexpStruct(in_float);
+#
+# frexp_out[ndx] = intBitsToFloat(exp);
+# frexp_out[ndx+1] = x;
+# frexpStruct_out[ndx] = intBitsToFloat(res.exp);
+# frexpStruct_out[ndx+1] = res.x;
+# }
+#
+# return;
+# }
+# END
+
+SHADER compute comp_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpDecorate %_arr_v4uint_uint_162 ArrayStride 16
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %_arr_v4float_uint_324 ArrayStride 16
+ OpMemberDecorate %block1 0 Offset 0
+ OpDecorate %block1 BufferBlock
+ OpDecorate %__0 DescriptorSet 0
+ OpDecorate %__0 Binding 1
+ OpDecorate %_arr_v4float_uint_324_0 ArrayStride 16
+ OpMemberDecorate %block2 0 Offset 0
+ OpDecorate %block2 BufferBlock
+ OpDecorate %__1 DescriptorSet 0
+ OpDecorate %__1 Binding 2
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+ %int = OpTypeInt 32 1
+ %v4int = OpTypeVector %int 4
+%frexpStructType = OpTypeStruct %v4float %v4int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v4float
+%_ptr_Function_v4int = OpTypePointer Function %v4int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %uint_0 = OpConstant %uint 0
+ %uint_324 = OpConstant %uint 324
+ %bool = OpTypeBool
+ %v4uint = OpTypeVector %uint 4
+%_ptr_Function_v4uint = OpTypePointer Function %v4uint
+ %uint_162 = OpConstant %uint 162
+%_arr_v4uint_uint_162 = OpTypeArray %v4uint %uint_162
+ %block0 = OpTypeStruct %_arr_v4uint_uint_162
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %int_0 = OpConstant %int 0
+ %uint_2 = OpConstant %uint 2
+%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint
+%_arr_v4float_uint_324 = OpTypeArray %v4float %uint_324
+ %block1 = OpTypeStruct %_arr_v4float_uint_324
+%_ptr_Uniform_block1 = OpTypePointer Uniform %block1
+ %__0 = OpVariable %_ptr_Uniform_block1 Uniform
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+ %uint_1 = OpConstant %uint 1
+%_arr_v4float_uint_324_0 = OpTypeArray %v4float %uint_324
+ %block2 = OpTypeStruct %_arr_v4float_uint_324_0
+%_ptr_Uniform_block2 = OpTypePointer Uniform %block2
+ %__1 = OpVariable %_ptr_Uniform_block2 Uniform
+ %int_1 = OpConstant %int 1
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %ndx = OpVariable %_ptr_Function_uint Function
+ %in_uint = OpVariable %_ptr_Function_v4uint Function
+ %in_float = OpVariable %_ptr_Function_v4float Function
+ %x_0 = OpVariable %_ptr_Function_v4float Function
+ %exp_0 = OpVariable %_ptr_Function_v4int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ OpStore %ndx %uint_0
+ OpBranch %33
+ %33 = OpLabel
+ OpLoopMerge %35 %36 None
+ OpBranch %37
+ %37 = OpLabel
+ %38 = OpLoad %uint %ndx
+ %41 = OpULessThan %bool %38 %uint_324
+ OpBranchConditional %41 %34 %35
+ %34 = OpLabel
+ %51 = OpLoad %uint %ndx
+ %53 = OpUDiv %uint %51 %uint_2
+ %55 = OpAccessChain %_ptr_Uniform_v4uint %_ %int_0 %53
+ %56 = OpLoad %v4uint %55
+ OpStore %in_uint %56
+ %58 = OpLoad %v4uint %in_uint
+ %59 = OpBitcast %v4float %58
+ OpStore %in_float %59
+ %61 = OpLoad %v4float %in_float
+ %63 = OpExtInst %v4float %1 Frexp %61 %exp_0
+ OpStore %x_0 %63
+ %66 = OpLoad %v4float %in_float
+ %67 = OpExtInst %frexpStructType %1 FrexpStruct %66
+ OpStore %res_0 %67
+ %72 = OpLoad %uint %ndx
+ %73 = OpLoad %v4int %exp_0
+ %74 = OpBitcast %v4float %73
+ %76 = OpAccessChain %_ptr_Uniform_v4float %__0 %int_0 %72
+ OpStore %76 %74
+ %77 = OpLoad %uint %ndx
+ %79 = OpIAdd %uint %77 %uint_1
+ %80 = OpLoad %v4float %x_0
+ %81 = OpAccessChain %_ptr_Uniform_v4float %__0 %int_0 %79
+ OpStore %81 %80
+ %86 = OpLoad %uint %ndx
+ %88 = OpAccessChain %_ptr_Function_v4int %res_0 %int_1
+ %89 = OpLoad %v4int %88
+ %90 = OpBitcast %v4float %89
+ %91 = OpAccessChain %_ptr_Uniform_v4float %__1 %int_0 %86
+ OpStore %91 %90
+ %92 = OpLoad %uint %ndx
+ %93 = OpIAdd %uint %92 %uint_1
+ %94 = OpAccessChain %_ptr_Function_v4float %res_0 %int_0
+ %95 = OpLoad %v4float %94
+ %96 = OpAccessChain %_ptr_Uniform_v4float %__1 %int_0 %93
+ OpStore %96 %95
+ OpBranch %36
+ %36 = OpLabel
+ %97 = OpLoad %uint %ndx
+ %98 = OpIAdd %uint %97 %uint_2
+ OpStore %ndx %98
+ OpBranch %33
+ %35 = OpLabel
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+
+BUFFER buf_frexp DATA_TYPE vec4<float> SIZE 324 FILL 0.0
+BUFFER buf_frexpStruct DATA_TYPE vec4<float> SIZE 324 FILL 1.0
+
+PIPELINE compute test_pipeline
+ ATTACH comp_shader
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER buf_frexp AS storage DESCRIPTOR_SET 0 BINDING 1
+ BIND BUFFER buf_frexpStruct AS storage DESCRIPTOR_SET 0 BINDING 2
+END
+
+RUN test_pipeline 1 1 1
+
+EXPECT buf_frexp EQ_BUFFER buf_frexpStruct
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A fragment shader test for FrexpStruct.
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out uint ndx_out;
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# ndx_out = xcoord + ycoord * ndpSqrt;
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %ndx_out %_
+ OpDecorate %position Location 0
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+ %float_1 = OpConstant %float 1
+ %uint_1 = OpConstant %uint 1
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %ndx_out = OpVariable %_ptr_Output_uint Output
+ %uint_36 = OpConstant %uint 36
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_1_02777779 = OpConstant %float 1.02777779
+ %float_18 = OpConstant %float 18
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %17 = OpLoad %float %16
+ %21 = OpFAdd %float %17 %float_1_02777779
+ %24 = OpFMul %float %21 %float_18
+ %25 = OpFSub %float %24 %float_1
+ %26 = OpConvertFToU %uint %25
+ %29 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %30 = OpLoad %float %29
+ %32 = OpFAdd %float %30 %float_1_02777779
+ %34 = OpFMul %float %32 %float_18
+ %35 = OpFSub %float %34 %float_1
+ %36 = OpConvertFToU %uint %35
+ %42 = OpIMul %uint %36 %uint_36
+ %43 = OpIAdd %uint %26 %42
+ OpStore %ndx_out %43
+ %51 = OpLoad %v2float %position
+ %53 = OpCompositeExtract %float %51 0
+ %54 = OpCompositeExtract %float %51 1
+ %55 = OpCompositeConstruct %v4float %53 %54 %float_0 %float_1
+ %57 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %57 %55
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec4 in_values[ndp];
+# };
+#
+# layout (location = 0) flat in uint ndx_in;
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+# struct frexpStructType
+# {
+# vec4 x;
+# ivec4 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec4 orig)
+# {
+# vec4 x;
+# ivec4 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# uvec4 in_uint = in_values[ndx_in];
+# vec4 in_float = uintBitsToFloat(in_uint);
+# vec4 x;
+# ivec4 exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out.rgba = x;
+# frexp_exp_out.rgba = intBitsToFloat(exp);
+# frexpStruct_x_out.rgba = res.x;
+# frexpStruct_exp_out.rgba = intBitsToFloat(res.exp);
+#
+# return;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %ndx_in %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %_arr_v4uint_uint_1296 ArrayStride 16
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+ %int = OpTypeInt 32 1
+ %v4int = OpTypeVector %int 4
+%frexpStructType = OpTypeStruct %v4float %v4int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v4float
+%_ptr_Function_v4int = OpTypePointer Function %v4int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+ %v4uint = OpTypeVector %uint 4
+%_ptr_Function_v4uint = OpTypePointer Function %v4uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_v4uint_uint_1296 = OpTypeArray %v4uint %uint_1296
+ %block0 = OpTypeStruct %_arr_v4uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %int_0 = OpConstant %int 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+ %ndx_in = OpVariable %_ptr_Input_uint Input
+%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+ %int_1 = OpConstant %int 1
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %in_uint = OpVariable %_ptr_Function_v4uint Function
+ %in_float = OpVariable %_ptr_Function_v4float Function
+ %x_0 = OpVariable %_ptr_Function_v4float Function
+ %exp_0 = OpVariable %_ptr_Function_v4int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ %41 = OpLoad %uint %ndx_in
+ %43 = OpAccessChain %_ptr_Uniform_v4uint %_ %int_0 %41
+ %44 = OpLoad %v4uint %43
+ OpStore %in_uint %44
+ %46 = OpLoad %v4uint %in_uint
+ %47 = OpBitcast %v4float %46
+ OpStore %in_float %47
+ %49 = OpLoad %v4float %in_float
+ %51 = OpExtInst %v4float %1 Frexp %49 %exp_0
+ OpStore %x_0 %51
+ %54 = OpLoad %v4float %in_float
+ %55 = OpExtInst %frexpStructType %1 FrexpStruct %54
+ OpStore %res_0 %55
+ %58 = OpLoad %v4float %x_0
+ OpStore %frexp_x_out %58
+ %60 = OpLoad %v4int %exp_0
+ %61 = OpBitcast %v4float %60
+ OpStore %frexp_exp_out %61
+ %63 = OpAccessChain %_ptr_Function_v4float %res_0 %int_0
+ %64 = OpLoad %v4float %63
+ OpStore %frexpStruct_x_out %64
+ %67 = OpAccessChain %_ptr_Function_v4int %res_0 %int_1
+ %68 = OpLoad %v4int %67
+ %69 = OpBitcast %v4float %68
+ OpStore %frexpStruct_exp_out %69
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+RUN test_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A geometry shader test for FrexpStruct.
+
+DEVICE_FEATURE geometryShader
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out uint ndx_out;
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# ndx_out = xcoord + ycoord * ndpSqrt;
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %ndx_out %_
+ OpDecorate %position Location 0
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+ %float_1 = OpConstant %float 1
+ %uint_1 = OpConstant %uint 1
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %ndx_out = OpVariable %_ptr_Output_uint Output
+ %uint_36 = OpConstant %uint 36
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_1_02777779 = OpConstant %float 1.02777779
+ %float_18 = OpConstant %float 18
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %17 = OpLoad %float %16
+ %21 = OpFAdd %float %17 %float_1_02777779
+ %24 = OpFMul %float %21 %float_18
+ %25 = OpFSub %float %24 %float_1
+ %26 = OpConvertFToU %uint %25
+ %29 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %30 = OpLoad %float %29
+ %32 = OpFAdd %float %30 %float_1_02777779
+ %34 = OpFMul %float %32 %float_18
+ %35 = OpFSub %float %34 %float_1
+ %36 = OpConvertFToU %uint %35
+ %42 = OpIMul %uint %36 %uint_36
+ %43 = OpIAdd %uint %26 %42
+ OpStore %ndx_out %43
+ %51 = OpLoad %v2float %position
+ %53 = OpCompositeExtract %float %51 0
+ %54 = OpCompositeExtract %float %51 1
+ %55 = OpCompositeConstruct %v4float %53 %54 %float_0 %float_1
+ %57 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %57 %55
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER geometry geom_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec4 in_values[ndp];
+# };
+#
+# layout (triangles) in;
+# layout (triangle_strip, max_vertices = 3) out;
+#
+# layout (location = 0) flat in uint ndx_in[];
+# layout (location = 0) flat out vec4 frexp_x_out;
+# layout (location = 1) flat out vec4 frexp_exp_out;
+# layout (location = 2) flat out vec4 frexpStruct_x_out;
+# layout (location = 3) flat out vec4 frexpStruct_exp_out;
+#
+# struct frexpStructType
+# {
+# vec4 x;
+# ivec4 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec4 orig)
+# {
+# vec4 x;
+# ivec4 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# for (int vertex = 0; vertex < 3; vertex++)
+# {
+# uvec4 in_uint = in_values[ndx_in[vertex]];
+# vec4 in_float = uintBitsToFloat(in_uint);
+# vec4 x;
+# ivec4 exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out = x;
+# frexp_exp_out = intBitsToFloat(exp);
+# frexpStruct_x_out = res.x;
+# frexpStruct_exp_out = intBitsToFloat(res.exp);
+#
+# gl_Position = gl_in[vertex].gl_Position;
+# EmitVertex();
+# }
+#
+# EndPrimitive();
+# }
+# END
+
+SHADER geometry geom_shader SPIRV-ASM
+ OpCapability Geometry
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Geometry %main "main" %ndx_in %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %__0 %gl_in
+ OpExecutionMode %main Triangles
+ OpExecutionMode %main Invocations 1
+ OpExecutionMode %main OutputTriangleStrip
+ OpExecutionMode %main OutputVertices 3
+ OpDecorate %_arr_v4uint_uint_1296 ArrayStride 16
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+ %int = OpTypeInt 32 1
+ %v4int = OpTypeVector %int 4
+%frexpStructType = OpTypeStruct %v4float %v4int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v4float
+%_ptr_Function_v4int = OpTypePointer Function %v4int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+%_ptr_Function_int = OpTypePointer Function %int
+ %int_0 = OpConstant %int 0
+ %int_3 = OpConstant %int 3
+ %bool = OpTypeBool
+ %uint = OpTypeInt 32 0
+ %v4uint = OpTypeVector %uint 4
+%_ptr_Function_v4uint = OpTypePointer Function %v4uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_v4uint_uint_1296 = OpTypeArray %v4uint %uint_1296
+ %block0 = OpTypeStruct %_arr_v4uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %uint_3 = OpConstant %uint 3
+%_arr_uint_uint_3 = OpTypeArray %uint %uint_3
+%_ptr_Input__arr_uint_uint_3 = OpTypePointer Input %_arr_uint_uint_3
+ %ndx_in = OpVariable %_ptr_Input__arr_uint_uint_3 Input
+%_ptr_Input_uint = OpTypePointer Input %uint
+%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+ %int_1 = OpConstant %int 1
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %__0 = OpVariable %_ptr_Output_gl_PerVertex Output
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_arr_gl_PerVertex_0_uint_3 = OpTypeArray %gl_PerVertex_0 %uint_3
+%_ptr_Input__arr_gl_PerVertex_0_uint_3 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_3
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_3 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %vertex = OpVariable %_ptr_Function_int Function
+ %in_uint = OpVariable %_ptr_Function_v4uint Function
+ %in_float = OpVariable %_ptr_Function_v4float Function
+ %x_0 = OpVariable %_ptr_Function_v4float Function
+ %exp_0 = OpVariable %_ptr_Function_v4int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ OpStore %vertex %int_0
+ OpBranch %32
+ %32 = OpLabel
+ OpLoopMerge %34 %35 None
+ OpBranch %36
+ %36 = OpLabel
+ %37 = OpLoad %int %vertex
+ %40 = OpSLessThan %bool %37 %int_3
+ OpBranchConditional %40 %33 %34
+ %33 = OpLabel
+ %54 = OpLoad %int %vertex
+ %56 = OpAccessChain %_ptr_Input_uint %ndx_in %54
+ %57 = OpLoad %uint %56
+ %59 = OpAccessChain %_ptr_Uniform_v4uint %_ %int_0 %57
+ %60 = OpLoad %v4uint %59
+ OpStore %in_uint %60
+ %62 = OpLoad %v4uint %in_uint
+ %63 = OpBitcast %v4float %62
+ OpStore %in_float %63
+ %65 = OpLoad %v4float %in_float
+ %67 = OpExtInst %v4float %1 Frexp %65 %exp_0
+ OpStore %x_0 %67
+ %70 = OpLoad %v4float %in_float
+ %71 = OpExtInst %frexpStructType %1 FrexpStruct %70
+ OpStore %res_0 %71
+ %74 = OpLoad %v4float %x_0
+ OpStore %frexp_x_out %74
+ %76 = OpLoad %v4int %exp_0
+ %77 = OpBitcast %v4float %76
+ OpStore %frexp_exp_out %77
+ %79 = OpAccessChain %_ptr_Function_v4float %res_0 %int_0
+ %80 = OpLoad %v4float %79
+ OpStore %frexpStruct_x_out %80
+ %83 = OpAccessChain %_ptr_Function_v4int %res_0 %int_1
+ %84 = OpLoad %v4int %83
+ %85 = OpBitcast %v4float %84
+ OpStore %frexpStruct_exp_out %85
+ %95 = OpLoad %int %vertex
+ %97 = OpAccessChain %_ptr_Input_v4float %gl_in %95 %int_0
+ %98 = OpLoad %v4float %97
+ %99 = OpAccessChain %_ptr_Output_v4float %__0 %int_0
+ OpStore %99 %98
+ OpEmitVertex
+ OpBranch %35
+ %35 = OpLabel
+ %100 = OpLoad %int %vertex
+ %101 = OpIAdd %int %100 %int_1
+ OpStore %vertex %101
+ OpBranch %32
+ %34 = OpLabel
+ OpEndPrimitive
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (location = 0) flat in vec4 frexp_x_in;
+# layout (location = 1) flat in vec4 frexp_exp_in;
+# layout (location = 2) flat in vec4 frexpStruct_x_in;
+# layout (location = 3) flat in vec4 frexpStruct_exp_in;
+#
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+#
+# void main ()
+# {
+# frexp_x_out.rgba = frexp_x_in;
+# frexp_exp_out.rgba = frexp_exp_in;
+# frexpStruct_x_out.rgba = frexpStruct_x_in;
+# frexpStruct_exp_out.rgba = frexpStruct_exp_in;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %frexp_x_out %frexp_x_in %frexp_exp_out %frexp_exp_in %frexpStruct_x_out %frexpStruct_x_in %frexpStruct_exp_out %frexpStruct_exp_in
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %frexp_x_in = OpVariable %_ptr_Input_v4float Input
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexp_exp_in = OpVariable %_ptr_Input_v4float Input
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_in = OpVariable %_ptr_Input_v4float Input
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_in = OpVariable %_ptr_Input_v4float Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %12 = OpLoad %v4float %frexp_x_in
+ OpStore %frexp_x_out %12
+ %15 = OpLoad %v4float %frexp_exp_in
+ OpStore %frexp_exp_out %15
+ %18 = OpLoad %v4float %frexpStruct_x_in
+ OpStore %frexpStruct_x_out %18
+ %21 = OpLoad %v4float %frexpStruct_exp_in
+ OpStore %frexpStruct_exp_out %21
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH geom_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+RUN test_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A tessellation control shader test for FrexpStruct.
+
+DEVICE_FEATURE tessellationShader
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out uint ndx_out;
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# ndx_out = xcoord + ycoord * ndpSqrt;
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %ndx_out %_
+ OpDecorate %position Location 0
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+ %float_1 = OpConstant %float 1
+ %uint_1 = OpConstant %uint 1
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %ndx_out = OpVariable %_ptr_Output_uint Output
+ %uint_36 = OpConstant %uint 36
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_1_02777779 = OpConstant %float 1.02777779
+ %float_18 = OpConstant %float 18
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %17 = OpLoad %float %16
+ %21 = OpFAdd %float %17 %float_1_02777779
+ %24 = OpFMul %float %21 %float_18
+ %25 = OpFSub %float %24 %float_1
+ %26 = OpConvertFToU %uint %25
+ %29 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %30 = OpLoad %float %29
+ %32 = OpFAdd %float %30 %float_1_02777779
+ %34 = OpFMul %float %32 %float_18
+ %35 = OpFSub %float %34 %float_1
+ %36 = OpConvertFToU %uint %35
+ %42 = OpIMul %uint %36 %uint_36
+ %43 = OpIAdd %uint %26 %42
+ OpStore %ndx_out %43
+ %51 = OpLoad %v2float %position
+ %53 = OpCompositeExtract %float %51 0
+ %54 = OpCompositeExtract %float %51 1
+ %55 = OpCompositeConstruct %v4float %53 %54 %float_0 %float_1
+ %57 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %57 %55
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER tessellation_control tesc_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+#
+# layout (vertices = 3) out;
+#
+# layout (location = 0) flat in uint ndx_in[];
+# layout (location = 0) flat out vec4 frexp_x_out[];
+# layout (location = 1) flat out vec4 frexp_exp_out[];
+# layout (location = 2) flat out vec4 frexpStruct_x_out[];
+# layout (location = 3) flat out vec4 frexpStruct_exp_out[];
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec4 in_values[ndp];
+# };
+#
+# struct frexpStructType
+# {
+# vec4 x;
+# ivec4 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec4 orig)
+# {
+# vec4 x;
+# ivec4 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# uvec4 in_uint = in_values[ndx_in[gl_InvocationID]];
+# vec4 in_float = uintBitsToFloat(in_uint);
+# vec4 x;
+# ivec4 exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out[gl_InvocationID] = x;
+# frexp_exp_out[gl_InvocationID] = intBitsToFloat(exp);
+# frexpStruct_x_out[gl_InvocationID] = res.x;
+# frexpStruct_exp_out[gl_InvocationID] = intBitsToFloat(res.exp);
+#
+# gl_TessLevelInner[0] = 1.0;
+# gl_TessLevelInner[1] = 1.0;
+# gl_TessLevelOuter[0] = 1.0;
+# gl_TessLevelOuter[1] = 1.0;
+# gl_TessLevelOuter[2] = 1.0;
+# gl_TessLevelOuter[3] = 1.0;
+# gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
+# }
+# END
+
+SHADER tessellation_control tesc_shader SPIRV-ASM
+ OpCapability Tessellation
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationControl %main "main" %ndx_in %gl_InvocationID %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %gl_TessLevelInner %gl_TessLevelOuter %gl_out %gl_in
+ OpExecutionMode %main OutputVertices 3
+ OpDecorate %_arr_v4uint_uint_1296 ArrayStride 16
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ OpDecorate %gl_InvocationID BuiltIn InvocationId
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %gl_TessLevelInner Patch
+ OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner
+ OpDecorate %gl_TessLevelOuter Patch
+ OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+ %int = OpTypeInt 32 1
+ %v4int = OpTypeVector %int 4
+%frexpStructType = OpTypeStruct %v4float %v4int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v4float
+%_ptr_Function_v4int = OpTypePointer Function %v4int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+ %v4uint = OpTypeVector %uint 4
+%_ptr_Function_v4uint = OpTypePointer Function %v4uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_v4uint_uint_1296 = OpTypeArray %v4uint %uint_1296
+ %block0 = OpTypeStruct %_arr_v4uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %int_0 = OpConstant %int 0
+ %uint_32 = OpConstant %uint 32
+%_arr_uint_uint_32 = OpTypeArray %uint %uint_32
+%_ptr_Input__arr_uint_uint_32 = OpTypePointer Input %_arr_uint_uint_32
+ %ndx_in = OpVariable %_ptr_Input__arr_uint_uint_32 Input
+%_ptr_Input_int = OpTypePointer Input %int
+%gl_InvocationID = OpVariable %_ptr_Input_int Input
+%_ptr_Input_uint = OpTypePointer Input %uint
+%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint
+ %uint_3 = OpConstant %uint 3
+%_arr_v4float_uint_3 = OpTypeArray %v4float %uint_3
+%_ptr_Output__arr_v4float_uint_3 = OpTypePointer Output %_arr_v4float_uint_3
+%frexp_x_out = OpVariable %_ptr_Output__arr_v4float_uint_3 Output
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_exp_out = OpVariable %_ptr_Output__arr_v4float_uint_3 Output
+%frexpStruct_x_out = OpVariable %_ptr_Output__arr_v4float_uint_3 Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output__arr_v4float_uint_3 Output
+ %int_1 = OpConstant %int 1
+ %uint_2 = OpConstant %uint 2
+%_arr_float_uint_2 = OpTypeArray %float %uint_2
+%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2
+%gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output
+ %float_1 = OpConstant %float 1
+%_ptr_Output_float = OpTypePointer Output %float
+ %uint_4 = OpConstant %uint 4
+%_arr_float_uint_4 = OpTypeArray %float %uint_4
+%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4
+%gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output
+ %int_2 = OpConstant %int 2
+ %int_3 = OpConstant %int 3
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_arr_gl_PerVertex_uint_3 = OpTypeArray %gl_PerVertex %uint_3
+%_ptr_Output__arr_gl_PerVertex_uint_3 = OpTypePointer Output %_arr_gl_PerVertex_uint_3
+ %gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_uint_3 Output
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_arr_gl_PerVertex_0_uint_32 = OpTypeArray %gl_PerVertex_0 %uint_32
+%_ptr_Input__arr_gl_PerVertex_0_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_32
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %in_uint = OpVariable %_ptr_Function_v4uint Function
+ %in_float = OpVariable %_ptr_Function_v4float Function
+ %x_0 = OpVariable %_ptr_Function_v4float Function
+ %exp_0 = OpVariable %_ptr_Function_v4int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ %45 = OpLoad %int %gl_InvocationID
+ %47 = OpAccessChain %_ptr_Input_uint %ndx_in %45
+ %48 = OpLoad %uint %47
+ %50 = OpAccessChain %_ptr_Uniform_v4uint %_ %int_0 %48
+ %51 = OpLoad %v4uint %50
+ OpStore %in_uint %51
+ %53 = OpLoad %v4uint %in_uint
+ %54 = OpBitcast %v4float %53
+ OpStore %in_float %54
+ %56 = OpLoad %v4float %in_float
+ %58 = OpExtInst %v4float %1 Frexp %56 %exp_0
+ OpStore %x_0 %58
+ %61 = OpLoad %v4float %in_float
+ %62 = OpExtInst %frexpStructType %1 FrexpStruct %61
+ OpStore %res_0 %62
+ %67 = OpLoad %int %gl_InvocationID
+ %68 = OpLoad %v4float %x_0
+ %70 = OpAccessChain %_ptr_Output_v4float %frexp_x_out %67
+ OpStore %70 %68
+ %72 = OpLoad %int %gl_InvocationID
+ %73 = OpLoad %v4int %exp_0
+ %74 = OpBitcast %v4float %73
+ %75 = OpAccessChain %_ptr_Output_v4float %frexp_exp_out %72
+ OpStore %75 %74
+ %77 = OpLoad %int %gl_InvocationID
+ %78 = OpAccessChain %_ptr_Function_v4float %res_0 %int_0
+ %79 = OpLoad %v4float %78
+ %80 = OpAccessChain %_ptr_Output_v4float %frexpStruct_x_out %77
+ OpStore %80 %79
+ %82 = OpLoad %int %gl_InvocationID
+ %84 = OpAccessChain %_ptr_Function_v4int %res_0 %int_1
+ %85 = OpLoad %v4int %84
+ %86 = OpBitcast %v4float %85
+ %87 = OpAccessChain %_ptr_Output_v4float %frexpStruct_exp_out %82
+ OpStore %87 %86
+ %94 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0
+ OpStore %94 %float_1
+ %95 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_1
+ OpStore %95 %float_1
+ %100 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0
+ OpStore %100 %float_1
+ %101 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1
+ OpStore %101 %float_1
+ %103 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2
+ OpStore %103 %float_1
+ %105 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_3
+ OpStore %105 %float_1
+ %112 = OpLoad %int %gl_InvocationID
+ %117 = OpLoad %int %gl_InvocationID
+ %119 = OpAccessChain %_ptr_Input_v4float %gl_in %117 %int_0
+ %120 = OpLoad %v4float %119
+ %121 = OpAccessChain %_ptr_Output_v4float %gl_out %112 %int_0
+ OpStore %121 %120
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER tessellation_evaluation tese_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (triangles) in;
+#
+# layout (location = 0) flat in vec4 frexp_x_in[];
+# layout (location = 1) flat in vec4 frexp_exp_in[];
+# layout (location = 2) flat in vec4 frexpStruct_x_in[];
+# layout (location = 3) flat in vec4 frexpStruct_exp_in[];
+#
+# layout (location = 0) flat out vec4 frexp_x_out;
+# layout (location = 1) flat out vec4 frexp_exp_out;
+# layout (location = 2) flat out vec4 frexpStruct_x_out;
+# layout (location = 3) flat out vec4 frexpStruct_exp_out;
+#
+# void main ()
+# {
+# gl_Position = gl_TessCoord.x * gl_in[0].gl_Position +
+# gl_TessCoord.y * gl_in[1].gl_Position +
+# gl_TessCoord.z * gl_in[2].gl_Position;
+#
+# frexp_x_out = frexp_x_in[0];
+# frexp_exp_out = frexp_exp_in[0];
+# frexpStruct_x_out = frexpStruct_x_in[0];
+# frexpStruct_exp_out = frexpStruct_exp_in[0];
+# }
+# END
+
+SHADER tessellation_evaluation tese_shader SPIRV-ASM
+ OpCapability Tessellation
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationEvaluation %main "main" %_ %gl_TessCoord %gl_in %frexp_x_out %frexp_x_in %frexp_exp_out %frexp_exp_in %frexpStruct_x_out %frexpStruct_x_in %frexpStruct_exp_out %frexpStruct_exp_in
+ OpExecutionMode %main Triangles
+ OpExecutionMode %main SpacingEqual
+ OpExecutionMode %main VertexOrderCcw
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpDecorate %gl_TessCoord BuiltIn TessCoord
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+ %uint = OpTypeInt 32 0
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %v3float = OpTypeVector %float 3
+%_ptr_Input_v3float = OpTypePointer Input %v3float
+%gl_TessCoord = OpVariable %_ptr_Input_v3float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+ %uint_32 = OpConstant %uint 32
+%_arr_gl_PerVertex_0_uint_32 = OpTypeArray %gl_PerVertex_0 %uint_32
+%_ptr_Input__arr_gl_PerVertex_0_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_32
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %int_1 = OpConstant %int 1
+ %uint_2 = OpConstant %uint 2
+ %int_2 = OpConstant %int 2
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+%_arr_v4float_uint_32 = OpTypeArray %v4float %uint_32
+%_ptr_Input__arr_v4float_uint_32 = OpTypePointer Input %_arr_v4float_uint_32
+ %frexp_x_in = OpVariable %_ptr_Input__arr_v4float_uint_32 Input
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexp_exp_in = OpVariable %_ptr_Input__arr_v4float_uint_32 Input
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_in = OpVariable %_ptr_Input__arr_v4float_uint_32 Input
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_in = OpVariable %_ptr_Input__arr_v4float_uint_32 Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %21 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_0
+ %22 = OpLoad %float %21
+ %29 = OpAccessChain %_ptr_Input_v4float %gl_in %int_0 %int_0
+ %30 = OpLoad %v4float %29
+ %31 = OpVectorTimesScalar %v4float %30 %22
+ %32 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_1
+ %33 = OpLoad %float %32
+ %35 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0
+ %36 = OpLoad %v4float %35
+ %37 = OpVectorTimesScalar %v4float %36 %33
+ %38 = OpFAdd %v4float %31 %37
+ %40 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_2
+ %41 = OpLoad %float %40
+ %43 = OpAccessChain %_ptr_Input_v4float %gl_in %int_2 %int_0
+ %44 = OpLoad %v4float %43
+ %45 = OpVectorTimesScalar %v4float %44 %41
+ %46 = OpFAdd %v4float %38 %45
+ %48 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %48 %46
+ %53 = OpAccessChain %_ptr_Input_v4float %frexp_x_in %int_0
+ %54 = OpLoad %v4float %53
+ OpStore %frexp_x_out %54
+ %57 = OpAccessChain %_ptr_Input_v4float %frexp_exp_in %int_0
+ %58 = OpLoad %v4float %57
+ OpStore %frexp_exp_out %58
+ %61 = OpAccessChain %_ptr_Input_v4float %frexpStruct_x_in %int_0
+ %62 = OpLoad %v4float %61
+ OpStore %frexpStruct_x_out %62
+ %65 = OpAccessChain %_ptr_Input_v4float %frexpStruct_exp_in %int_0
+ %66 = OpLoad %v4float %65
+ OpStore %frexpStruct_exp_out %66
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (location = 0) flat in vec4 frexp_x_in;
+# layout (location = 1) flat in vec4 frexp_exp_in;
+# layout (location = 2) flat in vec4 frexpStruct_x_in;
+# layout (location = 3) flat in vec4 frexpStruct_exp_in;
+#
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+#
+# void main ()
+# {
+# frexp_x_out.rgba = frexp_x_in;
+# frexp_exp_out.rgba = frexp_exp_in;
+# frexpStruct_x_out.rgba = frexpStruct_x_in;
+# frexpStruct_exp_out.rgba = frexpStruct_exp_in;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %frexp_x_out %frexp_x_in %frexp_exp_out %frexp_exp_in %frexpStruct_x_out %frexpStruct_x_in %frexpStruct_exp_out %frexpStruct_exp_in
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %frexp_x_in = OpVariable %_ptr_Input_v4float Input
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexp_exp_in = OpVariable %_ptr_Input_v4float Input
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_in = OpVariable %_ptr_Input_v4float Input
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_in = OpVariable %_ptr_Input_v4float Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %12 = OpLoad %v4float %frexp_x_in
+ OpStore %frexp_x_out %12
+ %15 = OpLoad %v4float %frexp_exp_in
+ OpStore %frexp_exp_out %15
+ %18 = OpLoad %v4float %frexpStruct_x_in
+ OpStore %frexpStruct_x_out %18
+ %21 = OpLoad %v4float %frexpStruct_exp_in
+ OpStore %frexpStruct_exp_out %21
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH tesc_shader
+ ATTACH tese_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+#RUN test_pipeline DRAW_GRID POS 0 0 SIZE 144 144 CELLS 144 144
+RUN test_pipeline DRAW_ARRAY AS PATCH_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A tessellation evaluation shader test for FrexpStruct.
+
+DEVICE_FEATURE tessellationShader
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out uint ndx_out;
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# ndx_out = xcoord + ycoord * ndpSqrt;
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %ndx_out %_
+ OpDecorate %position Location 0
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+ %float_1 = OpConstant %float 1
+ %uint_1 = OpConstant %uint 1
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %ndx_out = OpVariable %_ptr_Output_uint Output
+ %uint_36 = OpConstant %uint 36
+ %v4float = OpTypeVector %float 4
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_1_02777779 = OpConstant %float 1.02777779
+ %float_18 = OpConstant %float 18
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %17 = OpLoad %float %16
+ %21 = OpFAdd %float %17 %float_1_02777779
+ %24 = OpFMul %float %21 %float_18
+ %25 = OpFSub %float %24 %float_1
+ %26 = OpConvertFToU %uint %25
+ %29 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %30 = OpLoad %float %29
+ %32 = OpFAdd %float %30 %float_1_02777779
+ %34 = OpFMul %float %32 %float_18
+ %35 = OpFSub %float %34 %float_1
+ %36 = OpConvertFToU %uint %35
+ %42 = OpIMul %uint %36 %uint_36
+ %43 = OpIAdd %uint %26 %42
+ OpStore %ndx_out %43
+ %51 = OpLoad %v2float %position
+ %53 = OpCompositeExtract %float %51 0
+ %54 = OpCompositeExtract %float %51 1
+ %55 = OpCompositeConstruct %v4float %53 %54 %float_0 %float_1
+ %57 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %57 %55
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER tessellation_control tesc_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (vertices = 3) out;
+#
+# layout (location = 0) flat in uint ndx_in[];
+# layout (location = 0) flat out uint ndx_out[];
+#
+# void main ()
+# {
+# gl_TessLevelInner[0] = 1.0;
+# gl_TessLevelInner[1] = 1.0;
+# gl_TessLevelOuter[0] = 1.0;
+# gl_TessLevelOuter[1] = 1.0;
+# gl_TessLevelOuter[2] = 1.0;
+# gl_TessLevelOuter[3] = 1.0;
+#
+# gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
+# ndx_out[gl_InvocationID] = ndx_in[gl_InvocationID];
+# }
+# END
+
+SHADER tessellation_control tesc_shader SPIRV-ASM
+ OpCapability Tessellation
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationControl %main "main" %gl_TessLevelInner %gl_TessLevelOuter %gl_out %gl_InvocationID %gl_in %ndx_out %ndx_in
+ OpExecutionMode %main OutputVertices 3
+ OpDecorate %gl_TessLevelInner Patch
+ OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner
+ OpDecorate %gl_TessLevelOuter Patch
+ OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpDecorate %gl_InvocationID BuiltIn InvocationId
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ OpDecorate %ndx_out Flat
+ OpDecorate %ndx_out Location 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_2 = OpConstant %uint 2
+%_arr_float_uint_2 = OpTypeArray %float %uint_2
+%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2
+%gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %float_1 = OpConstant %float 1
+%_ptr_Output_float = OpTypePointer Output %float
+ %int_1 = OpConstant %int 1
+ %uint_4 = OpConstant %uint 4
+%_arr_float_uint_4 = OpTypeArray %float %uint_4
+%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4
+%gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output
+ %int_2 = OpConstant %int 2
+ %int_3 = OpConstant %int 3
+ %v4float = OpTypeVector %float 4
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+ %uint_3 = OpConstant %uint 3
+%_arr_gl_PerVertex_uint_3 = OpTypeArray %gl_PerVertex %uint_3
+%_ptr_Output__arr_gl_PerVertex_uint_3 = OpTypePointer Output %_arr_gl_PerVertex_uint_3
+ %gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_uint_3 Output
+%_ptr_Input_int = OpTypePointer Input %int
+%gl_InvocationID = OpVariable %_ptr_Input_int Input
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+ %uint_32 = OpConstant %uint 32
+%_arr_gl_PerVertex_0_uint_32 = OpTypeArray %gl_PerVertex_0 %uint_32
+%_ptr_Input__arr_gl_PerVertex_0_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_32
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%_arr_uint_uint_3 = OpTypeArray %uint %uint_3
+%_ptr_Output__arr_uint_uint_3 = OpTypePointer Output %_arr_uint_uint_3
+ %ndx_out = OpVariable %_ptr_Output__arr_uint_uint_3 Output
+%_arr_uint_uint_32 = OpTypeArray %uint %uint_32
+%_ptr_Input__arr_uint_uint_32 = OpTypePointer Input %_arr_uint_uint_32
+ %ndx_in = OpVariable %_ptr_Input__arr_uint_uint_32 Input
+%_ptr_Input_uint = OpTypePointer Input %uint
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %16 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0
+ OpStore %16 %float_1
+ %18 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_1
+ OpStore %18 %float_1
+ %23 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0
+ OpStore %23 %float_1
+ %24 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1
+ OpStore %24 %float_1
+ %26 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2
+ OpStore %26 %float_1
+ %28 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_3
+ OpStore %28 %float_1
+ %39 = OpLoad %int %gl_InvocationID
+ %47 = OpAccessChain %_ptr_Input_v4float %gl_in %39 %int_0
+ %48 = OpLoad %v4float %47
+ %50 = OpAccessChain %_ptr_Output_v4float %gl_out %39 %int_0
+ OpStore %50 %48
+ %60 = OpAccessChain %_ptr_Input_uint %ndx_in %39
+ %61 = OpLoad %uint %60
+ %63 = OpAccessChain %_ptr_Output_uint %ndx_out %39
+ OpStore %63 %61
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER tessellation_evaluation tese_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+#
+# layout (triangles) in;
+#
+# layout (location = 0) flat in uint ndx_in[];
+# layout (location = 0) flat out vec4 frexp_x_out;
+# layout (location = 1) flat out vec4 frexp_exp_out;
+# layout (location = 2) flat out vec4 frexpStruct_x_out;
+# layout (location = 3) flat out vec4 frexpStruct_exp_out;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec4 in_values[ndp];
+# };
+#
+# struct frexpStructType
+# {
+# vec4 x;
+# ivec4 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec4 orig)
+# {
+# vec4 x;
+# ivec4 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# gl_Position = gl_TessCoord.x * gl_in[0].gl_Position +
+# gl_TessCoord.y * gl_in[1].gl_Position +
+# gl_TessCoord.z * gl_in[2].gl_Position;
+#
+# uvec4 in_uint = in_values[ndx_in[0]];
+# vec4 in_float = uintBitsToFloat(in_uint);
+# vec4 x;
+# ivec4 exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out = x;
+# frexp_exp_out = intBitsToFloat(exp);
+# frexpStruct_x_out = res.x;
+# frexpStruct_exp_out = intBitsToFloat(res.exp);
+# }
+# END
+
+SHADER tessellation_evaluation tese_shader SPIRV-ASM
+ OpCapability Tessellation
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationEvaluation %main "main" %_ %gl_TessCoord %gl_in %ndx_in %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out
+ OpExecutionMode %main Triangles
+ OpExecutionMode %main SpacingEqual
+ OpExecutionMode %main VertexOrderCcw
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ OpDecorate %gl_TessCoord BuiltIn TessCoord
+ OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex_0 Block
+ OpDecorate %_arr_v4uint_uint_1296 ArrayStride 16
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %__0 DescriptorSet 0
+ OpDecorate %__0 Binding 0
+ OpDecorate %ndx_in Flat
+ OpDecorate %ndx_in Location 0
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+ %int = OpTypeInt 32 1
+ %v4int = OpTypeVector %int 4
+%frexpStructType = OpTypeStruct %v4float %v4int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v4float
+%_ptr_Function_v4int = OpTypePointer Function %v4int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int_0 = OpConstant %int 0
+ %v3float = OpTypeVector %float 3
+%_ptr_Input_v3float = OpTypePointer Input %v3float
+%gl_TessCoord = OpVariable %_ptr_Input_v3float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1
+ %uint_32 = OpConstant %uint 32
+%_arr_gl_PerVertex_0_uint_32 = OpTypeArray %gl_PerVertex_0 %uint_32
+%_ptr_Input__arr_gl_PerVertex_0_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_32
+ %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %int_1 = OpConstant %int 1
+ %uint_2 = OpConstant %uint 2
+ %int_2 = OpConstant %int 2
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %v4uint = OpTypeVector %uint 4
+%_ptr_Function_v4uint = OpTypePointer Function %v4uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_v4uint_uint_1296 = OpTypeArray %v4uint %uint_1296
+ %block0 = OpTypeStruct %_arr_v4uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %__0 = OpVariable %_ptr_Uniform_block0 Uniform
+%_arr_uint_uint_32 = OpTypeArray %uint %uint_32
+%_ptr_Input__arr_uint_uint_32 = OpTypePointer Input %_arr_uint_uint_32
+ %ndx_in = OpVariable %_ptr_Input__arr_uint_uint_32 Input
+%_ptr_Input_uint = OpTypePointer Input %uint
+%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %in_uint = OpVariable %_ptr_Function_v4uint Function
+ %in_float = OpVariable %_ptr_Function_v4float Function
+ %x_0 = OpVariable %_ptr_Function_v4float Function
+ %exp_0 = OpVariable %_ptr_Function_v4int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ %41 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_0
+ %42 = OpLoad %float %41
+ %49 = OpAccessChain %_ptr_Input_v4float %gl_in %int_0 %int_0
+ %50 = OpLoad %v4float %49
+ %51 = OpVectorTimesScalar %v4float %50 %42
+ %52 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_1
+ %53 = OpLoad %float %52
+ %55 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0
+ %56 = OpLoad %v4float %55
+ %57 = OpVectorTimesScalar %v4float %56 %53
+ %58 = OpFAdd %v4float %51 %57
+ %60 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_2
+ %61 = OpLoad %float %60
+ %63 = OpAccessChain %_ptr_Input_v4float %gl_in %int_2 %int_0
+ %64 = OpLoad %v4float %63
+ %65 = OpVectorTimesScalar %v4float %64 %61
+ %66 = OpFAdd %v4float %58 %65
+ %68 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %68 %66
+ %81 = OpAccessChain %_ptr_Input_uint %ndx_in %int_0
+ %82 = OpLoad %uint %81
+ %84 = OpAccessChain %_ptr_Uniform_v4uint %__0 %int_0 %82
+ %85 = OpLoad %v4uint %84
+ OpStore %in_uint %85
+ %87 = OpLoad %v4uint %in_uint
+ %88 = OpBitcast %v4float %87
+ OpStore %in_float %88
+ %90 = OpLoad %v4float %in_float
+ %92 = OpExtInst %v4float %1 Frexp %90 %exp_0
+ OpStore %x_0 %92
+ %95 = OpLoad %v4float %in_float
+ %96 = OpExtInst %frexpStructType %1 FrexpStruct %95
+ OpStore %res_0 %96
+ %98 = OpLoad %v4float %x_0
+ OpStore %frexp_x_out %98
+ %100 = OpLoad %v4int %exp_0
+ %101 = OpBitcast %v4float %100
+ OpStore %frexp_exp_out %101
+ %103 = OpAccessChain %_ptr_Function_v4float %res_0 %int_0
+ %104 = OpLoad %v4float %103
+ OpStore %frexpStruct_x_out %104
+ %106 = OpAccessChain %_ptr_Function_v4int %res_0 %int_1
+ %107 = OpLoad %v4int %106
+ %108 = OpBitcast %v4float %107
+ OpStore %frexpStruct_exp_out %108
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (location = 0) flat in vec4 frexp_x_in;
+# layout (location = 1) flat in vec4 frexp_exp_in;
+# layout (location = 2) flat in vec4 frexpStruct_x_in;
+# layout (location = 3) flat in vec4 frexpStruct_exp_in;
+#
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+#
+# void main ()
+# {
+# frexp_x_out.rgba = frexp_x_in;
+# frexp_exp_out.rgba = frexp_exp_in;
+# frexpStruct_x_out.rgba = frexpStruct_x_in;
+# frexpStruct_exp_out.rgba = frexpStruct_exp_in;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %frexp_x_out %frexp_x_in %frexp_exp_out %frexp_exp_in %frexpStruct_x_out %frexpStruct_x_in %frexpStruct_exp_out %frexpStruct_exp_in
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %frexp_x_in = OpVariable %_ptr_Input_v4float Input
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexp_exp_in = OpVariable %_ptr_Input_v4float Input
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_in = OpVariable %_ptr_Input_v4float Input
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_in = OpVariable %_ptr_Input_v4float Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %12 = OpLoad %v4float %frexp_x_in
+ OpStore %frexp_x_out %12
+ %15 = OpLoad %v4float %frexp_exp_in
+ OpStore %frexp_exp_out %15
+ %18 = OpLoad %v4float %frexpStruct_x_in
+ OpStore %frexpStruct_x_out %18
+ %21 = OpLoad %v4float %frexpStruct_exp_in
+ OpStore %frexpStruct_exp_out %21
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH tesc_shader
+ ATTACH tese_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+#RUN test_pipeline DRAW_GRID POS 0 0 SIZE 144 144 CELLS 144 144
+RUN test_pipeline DRAW_ARRAY AS PATCH_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
--- /dev/null
+#!amber
+
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# A vertex shader test for FrexpStruct.
+
+# SHADER vertex vert_shader GLSL
+# #version 430
+# precision highp float;
+#
+# const uint ndp = 1296;
+# const uint ndpSqrt = uint(sqrt(ndp));
+# const float halfGridElementSize = 1.0 / float(ndpSqrt);
+#
+# layout (location = 0) in vec2 position;
+# layout (location = 0) flat out vec4 frexp_x_out;
+# layout (location = 1) flat out vec4 frexp_exp_out;
+# layout (location = 2) flat out vec4 frexpStruct_x_out;
+# layout (location = 3) flat out vec4 frexpStruct_exp_out;
+#
+# layout(set = 0, binding = 0) readonly buffer block0 {
+# uvec4 in_values[ndp];
+# };
+#
+# struct frexpStructType
+# {
+# vec4 x;
+# ivec4 exp;
+# };
+#
+# // Replaced with native function in SPIR-V.
+# frexpStructType frexpStruct (vec4 orig)
+# {
+# vec4 x;
+# ivec4 exp;
+# x = frexp(orig, exp);
+# frexpStructType res = { x, exp };
+# return res;
+# }
+#
+# void main ()
+# {
+# uint xcoord = uint(ndpSqrt * ((position.x + halfGridElementSize + 1) / 2) - 1);
+# uint ycoord = uint(ndpSqrt * ((position.y + halfGridElementSize + 1) / 2) - 1);
+# uint ndx = xcoord + ycoord * ndpSqrt;
+#
+# uvec4 in_uint = in_values[ndx];
+# vec4 in_float = uintBitsToFloat(in_uint);
+# vec4 x;
+# ivec4 exp;
+# frexpStructType res;
+#
+# x = frexp(in_float, exp);
+# res = frexpStruct(in_float);
+#
+# frexp_x_out = x;
+# frexp_exp_out = intBitsToFloat(exp);
+# frexpStruct_x_out = res.x;
+# frexpStruct_exp_out = intBitsToFloat(res.exp);
+#
+# gl_Position = vec4(position, 0, 1);
+#
+# return;
+# }
+# END
+
+SHADER vertex vert_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %position %frexp_x_out %frexp_exp_out %frexpStruct_x_out %frexpStruct_exp_out %__0
+ OpDecorate %position Location 0
+ OpDecorate %_arr_v4uint_uint_1296 ArrayStride 16
+ OpMemberDecorate %block0 0 NonWritable
+ OpMemberDecorate %block0 0 Offset 0
+ OpDecorate %block0 BufferBlock
+ OpDecorate %_ DescriptorSet 0
+ OpDecorate %_ Binding 0
+ OpDecorate %frexp_x_out Flat
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_exp_out Flat
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexpStruct_x_out Flat
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_exp_out Flat
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpDecorate %gl_PerVertex Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+ %int = OpTypeInt 32 1
+ %v4int = OpTypeVector %int 4
+%frexpStructType = OpTypeStruct %v4float %v4int
+ %12 = OpTypeFunction %frexpStructType %_ptr_Function_v4float
+%_ptr_Function_v4int = OpTypePointer Function %v4int
+%_ptr_Function_frexpStructType = OpTypePointer Function %frexpStructType
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %float_36 = OpConstant %float 36
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %position = OpVariable %_ptr_Input_v2float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+%float_0_027777778 = OpConstant %float 0.027777778
+ %float_1 = OpConstant %float 1
+ %float_2 = OpConstant %float 2
+ %uint_1 = OpConstant %uint 1
+ %uint_36 = OpConstant %uint 36
+ %v4uint = OpTypeVector %uint 4
+%_ptr_Function_v4uint = OpTypePointer Function %v4uint
+ %uint_1296 = OpConstant %uint 1296
+%_arr_v4uint_uint_1296 = OpTypeArray %v4uint %uint_1296
+ %block0 = OpTypeStruct %_arr_v4uint_uint_1296
+%_ptr_Uniform_block0 = OpTypePointer Uniform %block0
+ %_ = OpVariable %_ptr_Uniform_block0 Uniform
+ %int_0 = OpConstant %int 0
+%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+ %int_1 = OpConstant %int 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %__0 = OpVariable %_ptr_Output_gl_PerVertex Output
+ %float_0 = OpConstant %float 0
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %xcoord = OpVariable %_ptr_Function_uint Function
+ %ycoord = OpVariable %_ptr_Function_uint Function
+ %ndx = OpVariable %_ptr_Function_uint Function
+ %in_uint = OpVariable %_ptr_Function_v4uint Function
+ %in_float = OpVariable %_ptr_Function_v4float Function
+ %x_0 = OpVariable %_ptr_Function_v4float Function
+ %exp_0 = OpVariable %_ptr_Function_v4int Function
+ %res_0 = OpVariable %_ptr_Function_frexpStructType Function
+ %38 = OpAccessChain %_ptr_Input_float %position %uint_0
+ %39 = OpLoad %float %38
+ %41 = OpFAdd %float %39 %float_0_027777778
+ %43 = OpFAdd %float %41 %float_1
+ %45 = OpFDiv %float %43 %float_2
+ %46 = OpFMul %float %float_36 %45
+ %47 = OpFSub %float %46 %float_1
+ %48 = OpConvertFToU %uint %47
+ OpStore %xcoord %48
+ %51 = OpAccessChain %_ptr_Input_float %position %uint_1
+ %52 = OpLoad %float %51
+ %53 = OpFAdd %float %52 %float_0_027777778
+ %54 = OpFAdd %float %53 %float_1
+ %55 = OpFDiv %float %54 %float_2
+ %56 = OpFMul %float %float_36 %55
+ %57 = OpFSub %float %56 %float_1
+ %58 = OpConvertFToU %uint %57
+ OpStore %ycoord %58
+ %60 = OpLoad %uint %xcoord
+ %61 = OpLoad %uint %ycoord
+ %63 = OpIMul %uint %61 %uint_36
+ %64 = OpIAdd %uint %60 %63
+ OpStore %ndx %64
+ %74 = OpLoad %uint %ndx
+ %76 = OpAccessChain %_ptr_Uniform_v4uint %_ %int_0 %74
+ %77 = OpLoad %v4uint %76
+ OpStore %in_uint %77
+ %79 = OpLoad %v4uint %in_uint
+ %80 = OpBitcast %v4float %79
+ OpStore %in_float %80
+ %82 = OpLoad %v4float %in_float
+ %84 = OpExtInst %v4float %1 Frexp %82 %exp_0
+ OpStore %x_0 %84
+ %87 = OpLoad %v4float %in_float
+ %88 = OpExtInst %frexpStructType %1 FrexpStruct %87
+ OpStore %res_0 %88
+ %91 = OpLoad %v4float %x_0
+ OpStore %frexp_x_out %91
+ %93 = OpLoad %v4int %exp_0
+ %94 = OpBitcast %v4float %93
+ OpStore %frexp_exp_out %94
+ %96 = OpAccessChain %_ptr_Function_v4float %res_0 %int_0
+ %97 = OpLoad %v4float %96
+ OpStore %frexpStruct_x_out %97
+ %100 = OpAccessChain %_ptr_Function_v4int %res_0 %int_1
+ %101 = OpLoad %v4int %100
+ %102 = OpBitcast %v4float %101
+ OpStore %frexpStruct_exp_out %102
+ %107 = OpLoad %v2float %position
+ %109 = OpCompositeExtract %float %107 0
+ %110 = OpCompositeExtract %float %107 1
+ %111 = OpCompositeConstruct %v4float %109 %110 %float_0 %float_1
+ %112 = OpAccessChain %_ptr_Output_v4float %__0 %int_0
+ OpStore %112 %111
+ OpReturn
+ OpFunctionEnd
+END
+
+# SHADER fragment frag_shader GLSL
+# #version 430
+# precision highp float;
+#
+# layout (location = 0) flat in vec4 frexp_x_in;
+# layout (location = 1) flat in vec4 frexp_exp_in;
+# layout (location = 2) flat in vec4 frexpStruct_x_in;
+# layout (location = 3) flat in vec4 frexpStruct_exp_in;
+#
+# layout (location = 0) out vec4 frexp_x_out;
+# layout (location = 1) out vec4 frexp_exp_out;
+# layout (location = 2) out vec4 frexpStruct_x_out;
+# layout (location = 3) out vec4 frexpStruct_exp_out;
+#
+#
+# void main ()
+# {
+# frexp_x_out.rgba = frexp_x_in;
+# frexp_exp_out.rgba = frexp_exp_in;
+# frexpStruct_x_out.rgba = frexpStruct_x_in;
+# frexpStruct_exp_out.rgba = frexpStruct_exp_in;
+# }
+# END
+
+SHADER fragment frag_shader SPIRV-ASM
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %frexp_x_out %frexp_x_in %frexp_exp_out %frexp_exp_in %frexpStruct_x_out %frexpStruct_x_in %frexpStruct_exp_out %frexpStruct_exp_in
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %frexp_x_out Location 0
+ OpDecorate %frexp_x_in Flat
+ OpDecorate %frexp_x_in Location 0
+ OpDecorate %frexp_exp_out Location 1
+ OpDecorate %frexp_exp_in Flat
+ OpDecorate %frexp_exp_in Location 1
+ OpDecorate %frexpStruct_x_out Location 2
+ OpDecorate %frexpStruct_x_in Flat
+ OpDecorate %frexpStruct_x_in Location 2
+ OpDecorate %frexpStruct_exp_out Location 3
+ OpDecorate %frexpStruct_exp_in Flat
+ OpDecorate %frexpStruct_exp_in Location 3
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%frexp_x_out = OpVariable %_ptr_Output_v4float Output
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %frexp_x_in = OpVariable %_ptr_Input_v4float Input
+%frexp_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexp_exp_in = OpVariable %_ptr_Input_v4float Input
+%frexpStruct_x_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_x_in = OpVariable %_ptr_Input_v4float Input
+%frexpStruct_exp_out = OpVariable %_ptr_Output_v4float Output
+%frexpStruct_exp_in = OpVariable %_ptr_Input_v4float Input
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %12 = OpLoad %v4float %frexp_x_in
+ OpStore %frexp_x_out %12
+ %15 = OpLoad %v4float %frexp_exp_in
+ OpStore %frexp_exp_out %15
+ %18 = OpLoad %v4float %frexpStruct_x_in
+ OpStore %frexpStruct_x_out %18
+ %21 = OpLoad %v4float %frexpStruct_exp_in
+ OpStore %frexpStruct_exp_out %21
+ OpReturn
+ OpFunctionEnd
+END
+
+BUFFER buf_in DATA_TYPE uint32 SIZE 1296 FILE TEXT input.txt
+BUFFER vertices DATA_TYPE vec2<float> SIZE 7776 FILE TEXT grid_vertices.txt
+
+BUFFER frexp_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexp_exp FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_x FORMAT R32G32B32A32_SFLOAT
+BUFFER frexpStruct_exp FORMAT R32G32B32A32_SFLOAT
+
+PIPELINE graphics test_pipeline
+ FRAMEBUFFER_SIZE 144 144
+
+ ATTACH vert_shader
+ ATTACH frag_shader
+
+ VERTEX_DATA vertices LOCATION 0
+
+ BIND BUFFER buf_in AS storage DESCRIPTOR_SET 0 BINDING 0
+ BIND BUFFER frexp_x AS color LOCATION 0
+ BIND BUFFER frexp_exp AS color LOCATION 1
+ BIND BUFFER frexpStruct_x AS color LOCATION 2
+ BIND BUFFER frexpStruct_exp AS color LOCATION 3
+END
+
+RUN test_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 7776
+
+EXPECT frexp_x EQ_BUFFER frexpStruct_x
+EXPECT frexp_exp EQ_BUFFER frexpStruct_exp
const ComparisonCase amberTests[] =
{
- { "modfstruct", "modf and modfStruct" }
+ { "modfstruct", "modf and modfStruct" },
+ { "frexpstruct", "frexp and frexpStruct" }
};
for (ComparisonCase test : amberTests)
const ComparisonCase amberTests[] =
{
- { "modfstruct", "modf and modfStruct" }
+ { "modfstruct", "modf and modfStruct" },
+ { "frexpstruct", "frexp and frexpStruct" }
};
for (ComparisonCase test : amberTests)
dEQP-VK.spirv_assembly.instruction.compute.float16.arithmetic_4.opdot
dEQP-VK.spirv_assembly.instruction.compute.float16.arithmetic_4.opvectortimesscalar
dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_1.modfstruct
+dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_1.frexpstruct
dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_2.modfstruct
+dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_2.frexpstruct
dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_3.modfstruct
+dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_3.frexpstruct
dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_4.modfstruct
+dEQP-VK.spirv_assembly.instruction.compute.float32.comparison_4.frexpstruct
dEQP-VK.spirv_assembly.instruction.compute.bool.mixed_bitsize.b32b32b32b16
dEQP-VK.spirv_assembly.instruction.compute.bool.mixed_bitsize.b32b32b32b8
dEQP-VK.spirv_assembly.instruction.compute.bool.mixed_bitsize.b32b32b16b32
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.modfstruct_tese
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.modfstruct_geom
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.modfstruct_frag
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.frexpstruct_vert
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.frexpstruct_tesc
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.frexpstruct_tese
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.frexpstruct_geom
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_1.frexpstruct_frag
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.modfstruct_vert
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.modfstruct_tesc
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.modfstruct_tese
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.modfstruct_geom
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.modfstruct_frag
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.frexpstruct_vert
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.frexpstruct_tesc
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.frexpstruct_tese
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.frexpstruct_geom
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_2.frexpstruct_frag
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.modfstruct_vert
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.modfstruct_tesc
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.modfstruct_tese
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.modfstruct_geom
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.modfstruct_frag
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.frexpstruct_vert
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.frexpstruct_tesc
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.frexpstruct_tese
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.frexpstruct_geom
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_3.frexpstruct_frag
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.modfstruct_vert
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.modfstruct_tesc
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.modfstruct_tese
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.modfstruct_geom
dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.modfstruct_frag
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.frexpstruct_vert
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.frexpstruct_tesc
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.frexpstruct_tese
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.frexpstruct_geom
+dEQP-VK.spirv_assembly.instruction.graphics.float32.comparison_4.frexpstruct_frag
dEQP-VK.spirv_assembly.instruction.graphics.spirv_ids_abuse.sparse_ids_vert
dEQP-VK.spirv_assembly.instruction.graphics.spirv_ids_abuse.sparse_ids_tessc
dEQP-VK.spirv_assembly.instruction.graphics.spirv_ids_abuse.sparse_ids_tesse