1#!amber 2# Copyright 2020 The Amber Authors. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# https://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16DEVICE_EXTENSION VK_KHR_variable_pointers 17DEVICE_EXTENSION VK_KHR_storage_buffer_storage_class 18DEVICE_FEATURE VariablePointerFeatures.variablePointers 19DEVICE_FEATURE VariablePointerFeatures.variablePointersStorageBuffer 20 21# Based on the following GLSL shader pseudocode: 22# 23#SHADER compute compute_shader GLSL 24##version 430 25# 26#layout(set = 0, binding = 0) buffer InputData 27#{ 28# int data[10]; 29#} input0[2]; 30# 31#layout(set = 0, binding = 1) buffer InputData 32#{ 33# int data[10]; 34#} input1[2]; 35# 36#layout(set = 0, binding = 2) buffer Result 37#{ 38# int result; 39#}; 40# 41#layout(push_constant) uniform Indices 42#{ 43# int idx0; 44# int idx1; 45# int idx2; 46#}; 47# 48# 49#void main() 50#{ 51# InputData input[]* = (idx0 == 0) ? &input0 : &input1; 52# result = input[idx1].data[idx2]; 53#} 54#END 55 56SHADER compute compute_shader SPIRV-ASM 57 OpCapability Shader 58 OpCapability VariablePointers 59 OpExtension "SPV_KHR_variable_pointers" 60 %1 = OpExtInstImport "GLSL.std.450" 61 OpMemoryModel Logical GLSL450 62 OpEntryPoint GLCompute %main "main" 63 OpExecutionMode %main LocalSize 1 1 1 64 OpSource GLSL 430 65 OpMemberDecorate %Indices 0 Offset 0 66 OpMemberDecorate %Indices 1 Offset 4 67 OpMemberDecorate %Indices 2 Offset 8 68 OpDecorate %Indices Block 69 OpMemberDecorate %Result 0 Offset 0 70 OpDecorate %Result Block 71 OpDecorate %result DescriptorSet 0 72 OpDecorate %result Binding 2 73 OpDecorate %_arr_int_int_10 ArrayStride 16 74 OpMemberDecorate %InputData 0 Offset 0 75 OpDecorate %InputData Block 76 OpDecorate %input0 DescriptorSet 0 77 OpDecorate %input0 Binding 0 78 OpDecorate %input1 DescriptorSet 0 79 OpDecorate %input1 Binding 1 80 %void = OpTypeVoid 81 %bool = OpTypeBool 82 %int = OpTypeInt 32 1 83 %void_func = OpTypeFunction %void 84 %Indices = OpTypeStruct %int %int %int 85%_ptr_PushConstant_Indices = OpTypePointer PushConstant %Indices 86 %indices = OpVariable %_ptr_PushConstant_Indices PushConstant 87 %int_0 = OpConstant %int 0 88 %int_1 = OpConstant %int 1 89 %int_2 = OpConstant %int 2 90 %int_10 = OpConstant %int 10 91%_ptr_PushConstant_int = OpTypePointer PushConstant %int 92 %Result = OpTypeStruct %int 93%_ptr_StorageBuffer_Result = OpTypePointer StorageBuffer %Result 94 %result = OpVariable %_ptr_StorageBuffer_Result StorageBuffer 95%_arr_int_int_10 = OpTypeArray %int %int_10 96 %InputData = OpTypeStruct %_arr_int_int_10 97%_arr_InputData_int_2 = OpTypeArray %InputData %int_2 98%_ptr_StorageBuffer__arr_InputData_int_2 = OpTypePointer StorageBuffer %_arr_InputData_int_2 99%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int 100 %input0 = OpVariable %_ptr_StorageBuffer__arr_InputData_int_2 StorageBuffer 101 %input1 = OpVariable %_ptr_StorageBuffer__arr_InputData_int_2 StorageBuffer 102 %main = OpFunction %void None %void_func 103 %label = OpLabel 104 %idx0_ptr = OpAccessChain %_ptr_PushConstant_int %indices %int_0 105 %idx0 = OpLoad %int %idx0_ptr 106 %idx1_ptr = OpAccessChain %_ptr_PushConstant_int %indices %int_1 107 %idx1 = OpLoad %int %idx1_ptr 108 %idx2_ptr = OpAccessChain %_ptr_PushConstant_int %indices %int_2 109 %idx2 = OpLoad %int %idx2_ptr 110 %idx0_zero = OpIEqual %bool %idx0 %int_0 111%variable_ptr = OpSelect %_ptr_StorageBuffer__arr_InputData_int_2 %idx0_zero %input0 %input1 112%input_data_ptr = OpAccessChain %_ptr_StorageBuffer_int %variable_ptr %idx1 %int_0 %idx2 113 %input_data = OpLoad %int %input_data_ptr 114%result_data_ptr = OpAccessChain %_ptr_StorageBuffer_int %result %int_0 115 OpStore %result_data_ptr %input_data 116 OpReturn 117 OpFunctionEnd 118END 119 120BUFFER buf0 DATA_TYPE int32 SIZE 1024 SERIES_FROM 0 INC_BY 1 121BUFFER buf1 DATA_TYPE int32 SIZE 1024 SERIES_FROM 1 INC_BY 1 122BUFFER buf2 DATA_TYPE int32 SIZE 1024 SERIES_FROM 2 INC_BY 1 123BUFFER buf3 DATA_TYPE int32 SIZE 1024 SERIES_FROM 3 INC_BY 1 124BUFFER indices0 DATA_TYPE int32 DATA 1250 1 2 126END 127BUFFER indices1 DATA_TYPE int32 DATA 1281 1 2 129END 130BUFFER result DATA_TYPE int32 DATA 1310 132END 133 134# This pipeline will select input from buf1 which has a dynamic offset of 256 bytes. 135# The sequence in that buffer starts from 1, and the array stride in the shader is 136# 16 bytes. The shader reads an array element number 2. Thus the expected value is: 137# 256/4 + 1 + 2 * 4 = 73. 138PIPELINE compute pipeline0 139 ATTACH compute_shader 140 141 BIND BUFFER_ARRAY buf0 buf1 AS storage_dynamic DESCRIPTOR_SET 0 BINDING 0 OFFSET 0 256 142 BIND BUFFER_ARRAY buf2 buf3 AS storage_dynamic DESCRIPTOR_SET 0 BINDING 1 OFFSET 512 768 143 BIND BUFFER indices0 AS push_constant 144 BIND BUFFER result AS storage DESCRIPTOR_SET 0 BINDING 2 145END 146 147RUN pipeline0 1 1 1 148 149EXPECT result IDX 0 EQ 73 150 151# This pipeline will select input from buf3 which has a dynamic offset of 768 bytes. 152# The sequence in that buffer starts from 3, and the array stride in the shader is 153# 16 bytes. The shader reads an array element number 2. Thus the expected value is: 154# 768/4 + 3 + 2 * 4 = 203. 155PIPELINE compute pipeline1 156 ATTACH compute_shader 157 158 BIND BUFFER_ARRAY buf0 buf1 AS storage_dynamic DESCRIPTOR_SET 0 BINDING 0 OFFSET 0 256 159 BIND BUFFER_ARRAY buf2 buf3 AS storage_dynamic DESCRIPTOR_SET 0 BINDING 1 OFFSET 512 768 160 BIND BUFFER indices1 AS push_constant 161 BIND BUFFER result AS storage DESCRIPTOR_SET 0 BINDING 2 162END 163 164RUN pipeline1 1 1 1 165 166EXPECT result IDX 0 EQ 203 167