Bill Hollings | 103aabf | 2016-04-06 17:42:27 -0400 | [diff] [blame] | 1 | /* |
Hans-Kristian Arntzen | 4704482 | 2021-01-14 16:07:49 +0100 | [diff] [blame] | 2 | * Copyright 2016-2021 The Brenwill Workshop Ltd. |
Jon Leech | f2a6554 | 2021-05-08 01:47:48 -0700 | [diff] [blame] | 3 | * SPDX-License-Identifier: Apache-2.0 OR MIT |
Bill Hollings | 103aabf | 2016-04-06 17:42:27 -0400 | [diff] [blame] | 4 | * |
| 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | * you may not use this file except in compliance with the License. |
| 7 | * You may obtain a copy of the License at |
| 8 | * |
| 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | * |
| 11 | * Unless required by applicable law or agreed to in writing, software |
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | * See the License for the specific language governing permissions and |
| 15 | * limitations under the License. |
| 16 | */ |
| 17 | |
Hans-Kristian Arntzen | cf1e9e0 | 2020-11-25 15:22:08 +0100 | [diff] [blame] | 18 | /* |
| 19 | * At your option, you may choose to accept this material under either: |
| 20 | * 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or |
| 21 | * 2. The MIT License, found at <http://opensource.org/licenses/MIT>. |
Hans-Kristian Arntzen | cf1e9e0 | 2020-11-25 15:22:08 +0100 | [diff] [blame] | 22 | */ |
| 23 | |
Hans-Kristian Arntzen | dad4a34 | 2016-11-11 18:04:14 +0100 | [diff] [blame] | 24 | #ifndef SPIRV_CROSS_MSL_HPP |
| 25 | #define SPIRV_CROSS_MSL_HPP |
Bill Hollings | 103aabf | 2016-04-06 17:42:27 -0400 | [diff] [blame] | 26 | |
| 27 | #include "spirv_glsl.hpp" |
Bill Hollings | 8175750 | 2017-01-29 13:28:20 -0500 | [diff] [blame] | 28 | #include <map> |
Bill Hollings | 103aabf | 2016-04-06 17:42:27 -0400 | [diff] [blame] | 29 | #include <set> |
Hans-Kristian Arntzen | b4e0163 | 2019-06-21 16:02:22 +0200 | [diff] [blame] | 30 | #include <stddef.h> |
Bill Hollings | 1a5dc0e | 2016-12-18 21:42:10 -0500 | [diff] [blame] | 31 | #include <unordered_map> |
Bill Hollings | 32ae2ec | 2016-12-18 18:48:15 -0500 | [diff] [blame] | 32 | #include <unordered_set> |
Bill Hollings | 103aabf | 2016-04-06 17:42:27 -0400 | [diff] [blame] | 33 | |
Hans-Kristian Arntzen | 9b92e68 | 2019-03-29 10:29:44 +0100 | [diff] [blame] | 34 | namespace SPIRV_CROSS_NAMESPACE |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 35 | { |
Bill Hollings | 103aabf | 2016-04-06 17:42:27 -0400 | [diff] [blame] | 36 | |
Chip Davis | 5281d99 | 2020-06-13 23:03:30 -0500 | [diff] [blame] | 37 | // Indicates the format of a shader input. Currently limited to specifying |
| 38 | // if the input is an 8-bit unsigned integer, 16-bit unsigned integer, or |
Chip Davis | 6db79b8 | 2018-12-04 13:54:29 -0600 | [diff] [blame] | 39 | // some other format. |
Chip Davis | 5281d99 | 2020-06-13 23:03:30 -0500 | [diff] [blame] | 40 | enum MSLShaderInputFormat |
Chip Davis | 6db79b8 | 2018-12-04 13:54:29 -0600 | [diff] [blame] | 41 | { |
Chip Davis | 5281d99 | 2020-06-13 23:03:30 -0500 | [diff] [blame] | 42 | MSL_SHADER_INPUT_FORMAT_OTHER = 0, |
| 43 | MSL_SHADER_INPUT_FORMAT_UINT8 = 1, |
| 44 | MSL_SHADER_INPUT_FORMAT_UINT16 = 2, |
Chip Davis | 688c5fc | 2020-02-20 21:38:28 -0600 | [diff] [blame] | 45 | MSL_SHADER_INPUT_FORMAT_ANY16 = 3, |
| 46 | MSL_SHADER_INPUT_FORMAT_ANY32 = 4, |
Chip Davis | 5281d99 | 2020-06-13 23:03:30 -0500 | [diff] [blame] | 47 | |
| 48 | // Deprecated aliases. |
| 49 | MSL_VERTEX_FORMAT_OTHER = MSL_SHADER_INPUT_FORMAT_OTHER, |
| 50 | MSL_VERTEX_FORMAT_UINT8 = MSL_SHADER_INPUT_FORMAT_UINT8, |
| 51 | MSL_VERTEX_FORMAT_UINT16 = MSL_SHADER_INPUT_FORMAT_UINT16, |
| 52 | |
| 53 | MSL_SHADER_INPUT_FORMAT_INT_MAX = 0x7fffffff |
Chip Davis | 6db79b8 | 2018-12-04 13:54:29 -0600 | [diff] [blame] | 54 | }; |
Bill Hollings | 103aabf | 2016-04-06 17:42:27 -0400 | [diff] [blame] | 55 | |
Chip Davis | 5281d99 | 2020-06-13 23:03:30 -0500 | [diff] [blame] | 56 | // Defines MSL characteristics of an input variable at a particular location. |
| 57 | // After compilation, it is possible to query whether or not this location was used. |
| 58 | // If vecsize is nonzero, it must be greater than or equal to the vecsize declared in the shader, |
| 59 | // or behavior is undefined. |
| 60 | struct MSLShaderInput |
| 61 | { |
| 62 | uint32_t location = 0; |
Bill Hollings | 548a23d | 2021-09-20 17:57:11 -0400 | [diff] [blame] | 63 | uint32_t component = 0; |
Chip Davis | 5281d99 | 2020-06-13 23:03:30 -0500 | [diff] [blame] | 64 | MSLShaderInputFormat format = MSL_SHADER_INPUT_FORMAT_OTHER; |
| 65 | spv::BuiltIn builtin = spv::BuiltInMax; |
| 66 | uint32_t vecsize = 0; |
| 67 | }; |
| 68 | |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 69 | // Matches the binding index of a MSL resource for a binding within a descriptor set. |
| 70 | // Taken together, the stage, desc_set and binding combine to form a reference to a resource |
Bill Hollings | 4bdd49d | 2020-11-02 22:15:20 -0500 | [diff] [blame] | 71 | // descriptor used in a particular shading stage. The count field indicates the number of |
Bill Hollings | b7b0e80 | 2020-10-29 18:50:42 -0400 | [diff] [blame] | 72 | // resources consumed by this binding, if the binding represents an array of resources. |
| 73 | // If the resource array is a run-time-sized array, which are legal in GLSL or SPIR-V, this value |
| 74 | // will be used to declare the array size in MSL, which does not support run-time-sized arrays. |
Bill Hollings | 17dab61 | 2021-04-13 19:01:20 -0400 | [diff] [blame] | 75 | // If pad_argument_buffer_resources is enabled, the base_type and count values are used to |
| 76 | // specify the base type and array size of the resource in the argument buffer, if that resource |
| 77 | // is not defined and used by the shader. With pad_argument_buffer_resources enabled, this |
| 78 | // information will be used to pad the argument buffer structure, in order to align that |
| 79 | // structure consistently for all uses, across all shaders, of the descriptor set represented |
| 80 | // by the arugment buffer. If pad_argument_buffer_resources is disabled, base_type does not |
| 81 | // need to be populated, and if the resource is also not a run-time sized array, the count |
| 82 | // field does not need to be populated. |
Chip Davis | 1038170 | 2019-09-04 13:57:17 -0500 | [diff] [blame] | 83 | // If using MSL 2.0 argument buffers, the descriptor set is not marked as a discrete descriptor set, |
| 84 | // and (for iOS only) the resource is not a storage image (sampled != 2), the binding reference we |
| 85 | // remap to will become an [[id(N)]] attribute within the "descriptor set" argument buffer structure. |
Bill Hollings | 17dab61 | 2021-04-13 19:01:20 -0400 | [diff] [blame] | 86 | // For resources which are bound in the "classic" MSL 1.0 way or discrete descriptors, the remap will |
| 87 | // become a [[buffer(N)]], [[texture(N)]] or [[sampler(N)]] depending on the resource types used. |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 88 | struct MSLResourceBinding |
| 89 | { |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 90 | spv::ExecutionModel stage = spv::ExecutionModelMax; |
Bill Hollings | b3bfe22 | 2021-04-18 17:34:55 -0400 | [diff] [blame] | 91 | SPIRType::BaseType basetype = SPIRType::Unknown; |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 92 | uint32_t desc_set = 0; |
| 93 | uint32_t binding = 0; |
Bill Hollings | 4bdd49d | 2020-11-02 22:15:20 -0500 | [diff] [blame] | 94 | uint32_t count = 0; |
Hans-Kristian Arntzen | e74c21a | 2019-03-04 10:08:31 +0100 | [diff] [blame] | 95 | uint32_t msl_buffer = 0; |
| 96 | uint32_t msl_texture = 0; |
| 97 | uint32_t msl_sampler = 0; |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 98 | }; |
Bill Hollings | 8f30f07 | 2016-04-07 21:25:51 -0400 | [diff] [blame] | 99 | |
Hans-Kristian Arntzen | df58deb | 2018-04-17 17:43:10 +0200 | [diff] [blame] | 100 | enum MSLSamplerCoord |
| 101 | { |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 102 | MSL_SAMPLER_COORD_NORMALIZED = 0, |
| 103 | MSL_SAMPLER_COORD_PIXEL = 1, |
| 104 | MSL_SAMPLER_INT_MAX = 0x7fffffff |
Hans-Kristian Arntzen | df58deb | 2018-04-17 17:43:10 +0200 | [diff] [blame] | 105 | }; |
| 106 | |
| 107 | enum MSLSamplerFilter |
| 108 | { |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 109 | MSL_SAMPLER_FILTER_NEAREST = 0, |
| 110 | MSL_SAMPLER_FILTER_LINEAR = 1, |
| 111 | MSL_SAMPLER_FILTER_INT_MAX = 0x7fffffff |
Hans-Kristian Arntzen | df58deb | 2018-04-17 17:43:10 +0200 | [diff] [blame] | 112 | }; |
| 113 | |
| 114 | enum MSLSamplerMipFilter |
| 115 | { |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 116 | MSL_SAMPLER_MIP_FILTER_NONE = 0, |
| 117 | MSL_SAMPLER_MIP_FILTER_NEAREST = 1, |
| 118 | MSL_SAMPLER_MIP_FILTER_LINEAR = 2, |
| 119 | MSL_SAMPLER_MIP_FILTER_INT_MAX = 0x7fffffff |
Hans-Kristian Arntzen | df58deb | 2018-04-17 17:43:10 +0200 | [diff] [blame] | 120 | }; |
| 121 | |
| 122 | enum MSLSamplerAddress |
| 123 | { |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 124 | MSL_SAMPLER_ADDRESS_CLAMP_TO_ZERO = 0, |
| 125 | MSL_SAMPLER_ADDRESS_CLAMP_TO_EDGE = 1, |
| 126 | MSL_SAMPLER_ADDRESS_CLAMP_TO_BORDER = 2, |
| 127 | MSL_SAMPLER_ADDRESS_REPEAT = 3, |
| 128 | MSL_SAMPLER_ADDRESS_MIRRORED_REPEAT = 4, |
| 129 | MSL_SAMPLER_ADDRESS_INT_MAX = 0x7fffffff |
Hans-Kristian Arntzen | df58deb | 2018-04-17 17:43:10 +0200 | [diff] [blame] | 130 | }; |
| 131 | |
| 132 | enum MSLSamplerCompareFunc |
| 133 | { |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 134 | MSL_SAMPLER_COMPARE_FUNC_NEVER = 0, |
| 135 | MSL_SAMPLER_COMPARE_FUNC_LESS = 1, |
| 136 | MSL_SAMPLER_COMPARE_FUNC_LESS_EQUAL = 2, |
| 137 | MSL_SAMPLER_COMPARE_FUNC_GREATER = 3, |
| 138 | MSL_SAMPLER_COMPARE_FUNC_GREATER_EQUAL = 4, |
| 139 | MSL_SAMPLER_COMPARE_FUNC_EQUAL = 5, |
| 140 | MSL_SAMPLER_COMPARE_FUNC_NOT_EQUAL = 6, |
| 141 | MSL_SAMPLER_COMPARE_FUNC_ALWAYS = 7, |
| 142 | MSL_SAMPLER_COMPARE_FUNC_INT_MAX = 0x7fffffff |
Hans-Kristian Arntzen | df58deb | 2018-04-17 17:43:10 +0200 | [diff] [blame] | 143 | }; |
| 144 | |
| 145 | enum MSLSamplerBorderColor |
| 146 | { |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 147 | MSL_SAMPLER_BORDER_COLOR_TRANSPARENT_BLACK = 0, |
| 148 | MSL_SAMPLER_BORDER_COLOR_OPAQUE_BLACK = 1, |
| 149 | MSL_SAMPLER_BORDER_COLOR_OPAQUE_WHITE = 2, |
| 150 | MSL_SAMPLER_BORDER_COLOR_INT_MAX = 0x7fffffff |
Hans-Kristian Arntzen | df58deb | 2018-04-17 17:43:10 +0200 | [diff] [blame] | 151 | }; |
| 152 | |
Chip Davis | 39dce88 | 2019-08-02 15:11:19 -0500 | [diff] [blame] | 153 | enum MSLFormatResolution |
| 154 | { |
| 155 | MSL_FORMAT_RESOLUTION_444 = 0, |
| 156 | MSL_FORMAT_RESOLUTION_422, |
| 157 | MSL_FORMAT_RESOLUTION_420, |
| 158 | MSL_FORMAT_RESOLUTION_INT_MAX = 0x7fffffff |
| 159 | }; |
| 160 | |
| 161 | enum MSLChromaLocation |
| 162 | { |
| 163 | MSL_CHROMA_LOCATION_COSITED_EVEN = 0, |
| 164 | MSL_CHROMA_LOCATION_MIDPOINT, |
| 165 | MSL_CHROMA_LOCATION_INT_MAX = 0x7fffffff |
| 166 | }; |
| 167 | |
| 168 | enum MSLComponentSwizzle |
| 169 | { |
| 170 | MSL_COMPONENT_SWIZZLE_IDENTITY = 0, |
| 171 | MSL_COMPONENT_SWIZZLE_ZERO, |
| 172 | MSL_COMPONENT_SWIZZLE_ONE, |
| 173 | MSL_COMPONENT_SWIZZLE_R, |
| 174 | MSL_COMPONENT_SWIZZLE_G, |
| 175 | MSL_COMPONENT_SWIZZLE_B, |
| 176 | MSL_COMPONENT_SWIZZLE_A, |
| 177 | MSL_COMPONENT_SWIZZLE_INT_MAX = 0x7fffffff |
| 178 | }; |
| 179 | |
| 180 | enum MSLSamplerYCbCrModelConversion |
| 181 | { |
| 182 | MSL_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY = 0, |
| 183 | MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY, |
| 184 | MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_BT_709, |
| 185 | MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_BT_601, |
| 186 | MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_BT_2020, |
| 187 | MSL_SAMPLER_YCBCR_MODEL_CONVERSION_INT_MAX = 0x7fffffff |
| 188 | }; |
| 189 | |
| 190 | enum MSLSamplerYCbCrRange |
| 191 | { |
| 192 | MSL_SAMPLER_YCBCR_RANGE_ITU_FULL = 0, |
| 193 | MSL_SAMPLER_YCBCR_RANGE_ITU_NARROW, |
| 194 | MSL_SAMPLER_YCBCR_RANGE_INT_MAX = 0x7fffffff |
| 195 | }; |
| 196 | |
Hans-Kristian Arntzen | df58deb | 2018-04-17 17:43:10 +0200 | [diff] [blame] | 197 | struct MSLConstexprSampler |
| 198 | { |
Hans-Kristian Arntzen | e30a942 | 2018-04-18 16:19:55 +0200 | [diff] [blame] | 199 | MSLSamplerCoord coord = MSL_SAMPLER_COORD_NORMALIZED; |
| 200 | MSLSamplerFilter min_filter = MSL_SAMPLER_FILTER_NEAREST; |
| 201 | MSLSamplerFilter mag_filter = MSL_SAMPLER_FILTER_NEAREST; |
| 202 | MSLSamplerMipFilter mip_filter = MSL_SAMPLER_MIP_FILTER_NONE; |
| 203 | MSLSamplerAddress s_address = MSL_SAMPLER_ADDRESS_CLAMP_TO_EDGE; |
| 204 | MSLSamplerAddress t_address = MSL_SAMPLER_ADDRESS_CLAMP_TO_EDGE; |
| 205 | MSLSamplerAddress r_address = MSL_SAMPLER_ADDRESS_CLAMP_TO_EDGE; |
| 206 | MSLSamplerCompareFunc compare_func = MSL_SAMPLER_COMPARE_FUNC_NEVER; |
| 207 | MSLSamplerBorderColor border_color = MSL_SAMPLER_BORDER_COLOR_TRANSPARENT_BLACK; |
| 208 | float lod_clamp_min = 0.0f; |
| 209 | float lod_clamp_max = 1000.0f; |
| 210 | int max_anisotropy = 1; |
Hans-Kristian Arntzen | df58deb | 2018-04-17 17:43:10 +0200 | [diff] [blame] | 211 | |
Chip Davis | 39dce88 | 2019-08-02 15:11:19 -0500 | [diff] [blame] | 212 | // Sampler Y'CbCr conversion parameters |
| 213 | uint32_t planes = 0; |
| 214 | MSLFormatResolution resolution = MSL_FORMAT_RESOLUTION_444; |
| 215 | MSLSamplerFilter chroma_filter = MSL_SAMPLER_FILTER_NEAREST; |
| 216 | MSLChromaLocation x_chroma_offset = MSL_CHROMA_LOCATION_COSITED_EVEN; |
| 217 | MSLChromaLocation y_chroma_offset = MSL_CHROMA_LOCATION_COSITED_EVEN; |
| 218 | MSLComponentSwizzle swizzle[4]; // IDENTITY, IDENTITY, IDENTITY, IDENTITY |
| 219 | MSLSamplerYCbCrModelConversion ycbcr_model = MSL_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY; |
| 220 | MSLSamplerYCbCrRange ycbcr_range = MSL_SAMPLER_YCBCR_RANGE_ITU_FULL; |
| 221 | uint32_t bpc = 8; |
| 222 | |
Hans-Kristian Arntzen | e30a942 | 2018-04-18 16:19:55 +0200 | [diff] [blame] | 223 | bool compare_enable = false; |
| 224 | bool lod_clamp_enable = false; |
| 225 | bool anisotropy_enable = false; |
Chip Davis | 39dce88 | 2019-08-02 15:11:19 -0500 | [diff] [blame] | 226 | bool ycbcr_conversion_enable = false; |
| 227 | |
| 228 | MSLConstexprSampler() |
| 229 | { |
| 230 | for (uint32_t i = 0; i < 4; i++) |
| 231 | swizzle[i] = MSL_COMPONENT_SWIZZLE_IDENTITY; |
| 232 | } |
| 233 | bool swizzle_is_identity() const |
| 234 | { |
| 235 | return (swizzle[0] == MSL_COMPONENT_SWIZZLE_IDENTITY && swizzle[1] == MSL_COMPONENT_SWIZZLE_IDENTITY && |
| 236 | swizzle[2] == MSL_COMPONENT_SWIZZLE_IDENTITY && swizzle[3] == MSL_COMPONENT_SWIZZLE_IDENTITY); |
| 237 | } |
| 238 | bool swizzle_has_one_or_zero() const |
| 239 | { |
| 240 | return (swizzle[0] == MSL_COMPONENT_SWIZZLE_ZERO || swizzle[0] == MSL_COMPONENT_SWIZZLE_ONE || |
| 241 | swizzle[1] == MSL_COMPONENT_SWIZZLE_ZERO || swizzle[1] == MSL_COMPONENT_SWIZZLE_ONE || |
| 242 | swizzle[2] == MSL_COMPONENT_SWIZZLE_ZERO || swizzle[2] == MSL_COMPONENT_SWIZZLE_ONE || |
| 243 | swizzle[3] == MSL_COMPONENT_SWIZZLE_ZERO || swizzle[3] == MSL_COMPONENT_SWIZZLE_ONE); |
| 244 | } |
Hans-Kristian Arntzen | df58deb | 2018-04-17 17:43:10 +0200 | [diff] [blame] | 245 | }; |
| 246 | |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 247 | // Special constant used in a MSLResourceBinding desc_set |
| 248 | // element to indicate the bindings for the push constants. |
Hans-Kristian Arntzen | cc153f8 | 2020-01-09 11:18:14 +0100 | [diff] [blame] | 249 | // Kinda deprecated. Just use ResourceBindingPushConstant{DescriptorSet,Binding} directly. |
| 250 | static const uint32_t kPushConstDescSet = ResourceBindingPushConstantDescriptorSet; |
Bill Hollings | 103aabf | 2016-04-06 17:42:27 -0400 | [diff] [blame] | 251 | |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 252 | // Special constant used in a MSLResourceBinding binding |
| 253 | // element to indicate the bindings for the push constants. |
Hans-Kristian Arntzen | cc153f8 | 2020-01-09 11:18:14 +0100 | [diff] [blame] | 254 | // Kinda deprecated. Just use ResourceBindingPushConstant{DescriptorSet,Binding} directly. |
| 255 | static const uint32_t kPushConstBinding = ResourceBindingPushConstantBinding; |
Bill Hollings | 103aabf | 2016-04-06 17:42:27 -0400 | [diff] [blame] | 256 | |
Hans-Kristian Arntzen | eaf7afe | 2019-05-09 12:15:45 +0200 | [diff] [blame] | 257 | // Special constant used in a MSLResourceBinding binding |
| 258 | // element to indicate the buffer binding for swizzle buffers. |
| 259 | static const uint32_t kSwizzleBufferBinding = ~(1u); |
Hans-Kristian Arntzen | e47a77d | 2019-03-14 10:29:34 +0100 | [diff] [blame] | 260 | |
Hans-Kristian Arntzen | 7b9e0fb | 2019-05-27 11:59:29 +0200 | [diff] [blame] | 261 | // Special constant used in a MSLResourceBinding binding |
| 262 | // element to indicate the buffer binding for buffer size buffers to support OpArrayLength. |
| 263 | static const uint32_t kBufferSizeBufferBinding = ~(2u); |
| 264 | |
Hans-Kristian Arntzen | 048f238 | 2019-06-24 10:45:13 +0200 | [diff] [blame] | 265 | // Special constant used in a MSLResourceBinding binding |
| 266 | // element to indicate the buffer binding used for the argument buffer itself. |
| 267 | // This buffer binding should be kept as small as possible as all automatic bindings for buffers |
| 268 | // will start at max(kArgumentBufferBinding) + 1. |
| 269 | static const uint32_t kArgumentBufferBinding = ~(3u); |
| 270 | |
Hans-Kristian Arntzen | eaf7afe | 2019-05-09 12:15:45 +0200 | [diff] [blame] | 271 | static const uint32_t kMaxArgumentBuffers = 8; |
Chip Davis | f55253d | 2019-02-06 14:45:26 -0600 | [diff] [blame] | 272 | |
Corentin Wallez | bcd7153 | 2020-09-04 10:04:25 +0200 | [diff] [blame] | 273 | // The arbitrary maximum for the nesting of array of array copies. |
| 274 | static const uint32_t kArrayCopyMultidimMax = 6; |
| 275 | |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 276 | // Decompiles SPIR-V to Metal Shading Language |
| 277 | class CompilerMSL : public CompilerGLSL |
| 278 | { |
| 279 | public: |
Bill Hollings | 5550c87 | 2017-03-12 17:42:51 -0400 | [diff] [blame] | 280 | // Options for compiling to Metal Shading Language |
| 281 | struct Options |
| 282 | { |
Hans-Kristian Arntzen | 382101b | 2018-04-03 14:08:15 +0200 | [diff] [blame] | 283 | typedef enum |
| 284 | { |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 285 | iOS = 0, |
| 286 | macOS = 1 |
Bill Hollings | 3fcdce0 | 2017-12-26 13:39:07 -0500 | [diff] [blame] | 287 | } Platform; |
| 288 | |
| 289 | Platform platform = macOS; |
Bill Hollings | 1014847 | 2017-11-10 16:40:33 -0500 | [diff] [blame] | 290 | uint32_t msl_version = make_msl_version(1, 2); |
Hans-Kristian Arntzen | 9ddbd5a | 2018-06-28 23:00:26 +0200 | [diff] [blame] | 291 | uint32_t texel_buffer_texture_width = 4096; // Width of 2D Metal textures used as 1D texel buffers |
Chip Davis | 21d38f7 | 2020-10-13 13:20:49 -0500 | [diff] [blame] | 292 | uint32_t r32ui_linear_texture_alignment = 4; |
| 293 | uint32_t r32ui_alignment_constant_id = 65535; |
Hans-Kristian Arntzen | eaf7afe | 2019-05-09 12:15:45 +0200 | [diff] [blame] | 294 | uint32_t swizzle_buffer_index = 30; |
Chip Davis | 056c0e2 | 2019-02-06 15:17:14 -0600 | [diff] [blame] | 295 | uint32_t indirect_params_buffer_index = 29; |
| 296 | uint32_t shader_output_buffer_index = 28; |
Chip Davis | eb89c3a | 2019-02-03 23:58:46 -0600 | [diff] [blame] | 297 | uint32_t shader_patch_output_buffer_index = 27; |
| 298 | uint32_t shader_tess_factor_buffer_index = 26; |
Hans-Kristian Arntzen | 7b9e0fb | 2019-05-27 11:59:29 +0200 | [diff] [blame] | 299 | uint32_t buffer_size_buffer_index = 25; |
Chip Davis | 7eecf5a | 2019-05-31 12:06:20 -0500 | [diff] [blame] | 300 | uint32_t view_mask_buffer_index = 24; |
Chip Davis | cb35934 | 2019-09-05 23:14:12 -0500 | [diff] [blame] | 301 | uint32_t dynamic_offsets_buffer_index = 23; |
Chip Davis | 688c5fc | 2020-02-20 21:38:28 -0600 | [diff] [blame] | 302 | uint32_t shader_input_buffer_index = 22; |
| 303 | uint32_t shader_index_buffer_index = 21; |
Chip Davis | eb89c3a | 2019-02-03 23:58:46 -0600 | [diff] [blame] | 304 | uint32_t shader_input_wg_index = 0; |
Chip Davis | 6a58554 | 2019-07-12 21:50:50 -0500 | [diff] [blame] | 305 | uint32_t device_index = 0; |
Chip Davis | b29f83c | 2020-04-10 01:13:33 -0500 | [diff] [blame] | 306 | uint32_t enable_frag_output_mask = 0xffffffff; |
Tomek Ponitka | 18f23c4 | 2020-07-22 18:37:17 +0200 | [diff] [blame] | 307 | // Metal doesn't allow setting a fixed sample mask directly in the pipeline. |
| 308 | // We can evade this restriction by ANDing the internal sample_mask output |
| 309 | // of the shader with the additional fixed sample mask. |
| 310 | uint32_t additional_fixed_sample_mask = 0xffffffff; |
Bill Hollings | 1c18078 | 2017-11-05 21:34:42 -0500 | [diff] [blame] | 311 | bool enable_point_size_builtin = true; |
Chip Davis | b29f83c | 2020-04-10 01:13:33 -0500 | [diff] [blame] | 312 | bool enable_frag_depth_builtin = true; |
| 313 | bool enable_frag_stencil_ref_builtin = true; |
Bill Hollings | 0d6202e | 2018-07-26 16:40:32 -0400 | [diff] [blame] | 314 | bool disable_rasterization = false; |
Chip Davis | c51e5b7 | 2019-01-08 16:33:32 -0600 | [diff] [blame] | 315 | bool capture_output_to_buffer = false; |
Chip Davis | 2583321 | 2018-09-19 20:36:33 -0500 | [diff] [blame] | 316 | bool swizzle_texture_samples = false; |
Chip Davis | 41d9424 | 2019-02-05 23:47:50 -0600 | [diff] [blame] | 317 | bool tess_domain_origin_lower_left = false; |
Chip Davis | 7eecf5a | 2019-05-31 12:06:20 -0500 | [diff] [blame] | 318 | bool multiview = false; |
Chip Davis | cab7335 | 2020-08-23 16:44:41 -0500 | [diff] [blame] | 319 | bool multiview_layered_rendering = true; |
Chip Davis | 6a58554 | 2019-07-12 21:50:50 -0500 | [diff] [blame] | 320 | bool view_index_from_device_index = false; |
Chip Davis | fb5ee4c | 2019-07-22 13:08:04 -0500 | [diff] [blame] | 321 | bool dispatch_base = false; |
Bill Hollings | 4b5c6c1 | 2019-10-24 12:31:20 -0400 | [diff] [blame] | 322 | bool texture_1D_as_2D = false; |
Hans-Kristian Arntzen | a5f072d | 2019-03-15 13:07:59 +0100 | [diff] [blame] | 323 | |
| 324 | // Enable use of MSL 2.0 indirect argument buffers. |
| 325 | // MSL 2.0 must also be enabled. |
Hans-Kristian Arntzen | e47a77d | 2019-03-14 10:29:34 +0100 | [diff] [blame] | 326 | bool argument_buffers = false; |
Bill Hollings | bac657d | 2017-11-07 15:38:13 -0500 | [diff] [blame] | 327 | |
Lukas Hermanns | 7ad0a84 | 2019-09-23 18:05:04 -0400 | [diff] [blame] | 328 | // Ensures vertex and instance indices start at zero. This reflects the behavior of HLSL with SV_VertexID and SV_InstanceID. |
| 329 | bool enable_base_index_zero = false; |
| 330 | |
Hans-Kristian Arntzen | b8033d7 | 2019-01-14 14:53:47 +0100 | [diff] [blame] | 331 | // Fragment output in MSL must have at least as many components as the render pass. |
| 332 | // Add support to explicit pad out components. |
| 333 | bool pad_fragment_output_components = false; |
| 334 | |
Lukas Hermanns | 7ad0a84 | 2019-09-23 18:05:04 -0400 | [diff] [blame] | 335 | // Specifies whether the iOS target version supports the [[base_vertex]] and [[base_instance]] attributes. |
| 336 | bool ios_support_base_vertex_instance = false; |
| 337 | |
| 338 | // Use Metal's native frame-buffer fetch API for subpass inputs. |
Chip Davis | c20d594 | 2020-10-27 21:42:33 -0500 | [diff] [blame] | 339 | bool use_framebuffer_fetch_subpasses = false; |
Lukas Hermanns | 7ad0a84 | 2019-09-23 18:05:04 -0400 | [diff] [blame] | 340 | |
Lukas Hermanns | ffbd801 | 2019-10-09 11:22:25 -0400 | [diff] [blame] | 341 | // Enables use of "fma" intrinsic for invariant float math |
Mark Satterthwaite | 69b703f | 2019-08-14 11:25:18 -0400 | [diff] [blame] | 342 | bool invariant_float_math = false; |
Lukas Hermanns | 7ad0a84 | 2019-09-23 18:05:04 -0400 | [diff] [blame] | 343 | |
| 344 | // Emulate texturecube_array with texture2d_array for iOS where this type is not available |
| 345 | bool emulate_cube_array = false; |
| 346 | |
| 347 | // Allow user to enable decoration binding |
| 348 | bool enable_decoration_binding = false; |
Bill Hollings | bac657d | 2017-11-07 15:38:13 -0500 | [diff] [blame] | 349 | |
Hans-Kristian Arntzen | fc4f39b | 2019-04-23 12:17:21 +0200 | [diff] [blame] | 350 | // Requires MSL 2.1, use the native support for texel buffers. |
| 351 | bool texture_buffer_native = false; |
| 352 | |
Hans-Kristian Arntzen | c3bd136 | 2020-01-16 11:07:30 +0100 | [diff] [blame] | 353 | // Forces all resources which are part of an argument buffer to be considered active. |
| 354 | // This ensures ABI compatibility between shaders where some resources might be unused, |
| 355 | // and would otherwise declare a different IAB. |
| 356 | bool force_active_argument_buffer_resources = false; |
| 357 | |
Bill Hollings | 17dab61 | 2021-04-13 19:01:20 -0400 | [diff] [blame] | 358 | // Aligns each resource in an argument buffer to its assigned index value, id(N), |
| 359 | // by adding synthetic padding members in the argument buffer struct for any resources |
| 360 | // in the argument buffer that are not defined and used by the shader. This allows |
| 361 | // the shader to index into the correct argument in a descriptor set argument buffer |
| 362 | // that is shared across shaders, where not all resources in the argument buffer are |
| 363 | // defined in each shader. For this to work, an MSLResourceBinding must be provided for |
| 364 | // all descriptors in any descriptor set held in an argument buffer in the shader, and |
| 365 | // that MSLResourceBinding must have the basetype and count members populated correctly. |
| 366 | // The implementation here assumes any inline blocks in the argument buffer is provided |
| 367 | // in a Metal buffer, and doesn't take into consideration inline blocks that are |
| 368 | // optionally embedded directly into the argument buffer via add_inline_uniform_block(). |
| 369 | bool pad_argument_buffer_resources = false; |
| 370 | |
Hans-Kristian Arntzen | c9d4f9c | 2020-02-24 12:47:14 +0100 | [diff] [blame] | 371 | // Forces the use of plain arrays, which works around certain driver bugs on certain versions |
| 372 | // of Intel Macbooks. See https://github.com/KhronosGroup/SPIRV-Cross/issues/1210. |
| 373 | // May reduce performance in scenarios where arrays are copied around as value-types. |
| 374 | bool force_native_arrays = false; |
| 375 | |
Hans-Kristian Arntzen | ebf4636 | 2020-04-20 09:48:20 +0200 | [diff] [blame] | 376 | // If a shader writes clip distance, also emit user varyings which |
| 377 | // can be read in subsequent stages. |
| 378 | bool enable_clip_distance_user_varying = true; |
| 379 | |
Chip Davis | 688c5fc | 2020-02-20 21:38:28 -0600 | [diff] [blame] | 380 | // In a tessellation control shader, assume that more than one patch can be processed in a |
| 381 | // single workgroup. This requires changes to the way the InvocationId and PrimitiveId |
| 382 | // builtins are processed, but should result in more efficient usage of the GPU. |
| 383 | bool multi_patch_workgroup = false; |
| 384 | |
| 385 | // If set, a vertex shader will be compiled as part of a tessellation pipeline. |
| 386 | // It will be translated as a compute kernel, so it can use the global invocation ID |
| 387 | // to index the output buffer. |
| 388 | bool vertex_for_tessellation = false; |
| 389 | |
Chip Davis | 4cf840e | 2020-08-27 19:24:20 -0500 | [diff] [blame] | 390 | // Assume that SubpassData images have multiple layers. Layered input attachments |
| 391 | // are addressed relative to the Layer output from the vertex pipeline. This option |
| 392 | // has no effect with multiview, since all input attachments are assumed to be layered |
| 393 | // and will be addressed using the current ViewIndex. |
| 394 | bool arrayed_subpass_input = false; |
| 395 | |
Chip Davis | 6890835 | 2020-11-18 23:16:46 -0600 | [diff] [blame] | 396 | // Whether to use SIMD-group or quadgroup functions to implement group nnon-uniform |
| 397 | // operations. Some GPUs on iOS do not support the SIMD-group functions, only the |
| 398 | // quadgroup functions. |
| 399 | bool ios_use_simdgroup_functions = false; |
| 400 | |
| 401 | // If set, the subgroup size will be assumed to be one, and subgroup-related |
| 402 | // builtins and operations will be emitted accordingly. This mode is intended to |
| 403 | // be used by MoltenVK on hardware/software configurations which do not provide |
| 404 | // sufficient support for subgroups. |
| 405 | bool emulate_subgroups = false; |
| 406 | |
| 407 | // If nonzero, a fixed subgroup size to assume. Metal, similarly to VK_EXT_subgroup_size_control, |
| 408 | // allows the SIMD-group size (aka thread execution width) to vary depending on |
| 409 | // register usage and requirements. In certain circumstances--for example, a pipeline |
| 410 | // in MoltenVK without VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT-- |
| 411 | // this is undesirable. This fixes the value of the SubgroupSize builtin, instead of |
| 412 | // mapping it to the Metal builtin [[thread_execution_width]]. If the thread |
| 413 | // execution width is reduced, the extra invocations will appear to be inactive. |
| 414 | // If zero, the SubgroupSize will be allowed to vary, and the builtin will be mapped |
| 415 | // to the Metal [[thread_execution_width]] builtin. |
| 416 | uint32_t fixed_subgroup_size = 0; |
| 417 | |
Chip Davis | 688c5fc | 2020-02-20 21:38:28 -0600 | [diff] [blame] | 418 | enum class IndexType |
| 419 | { |
| 420 | None = 0, |
| 421 | UInt16 = 1, |
| 422 | UInt32 = 2 |
| 423 | }; |
| 424 | |
| 425 | // The type of index in the index buffer, if present. For a compute shader, Metal |
| 426 | // requires specifying the indexing at pipeline creation, rather than at draw time |
| 427 | // as with graphics pipelines. This means we must create three different pipelines, |
| 428 | // for no indexing, 16-bit indices, and 32-bit indices. Each requires different |
| 429 | // handling for the gl_VertexIndex builtin. We may as well, then, create three |
| 430 | // different shaders for these three scenarios. |
| 431 | IndexType vertex_index_type = IndexType::None; |
| 432 | |
Chip Davis | fd738e3 | 2020-11-20 15:41:46 -0600 | [diff] [blame] | 433 | // If set, a dummy [[sample_id]] input is added to a fragment shader if none is present. |
| 434 | // This will force the shader to run at sample rate, assuming Metal does not optimize |
| 435 | // the extra threads away. |
| 436 | bool force_sample_rate_shading = false; |
| 437 | |
Hans-Kristian Arntzen | 6ef47d6 | 2020-04-27 11:23:24 +0200 | [diff] [blame] | 438 | bool is_ios() const |
Bill Hollings | 3fcdce0 | 2017-12-26 13:39:07 -0500 | [diff] [blame] | 439 | { |
| 440 | return platform == iOS; |
| 441 | } |
Bill Hollings | 5ee6b46 | 2018-01-05 23:22:36 -0500 | [diff] [blame] | 442 | |
Hans-Kristian Arntzen | 6ef47d6 | 2020-04-27 11:23:24 +0200 | [diff] [blame] | 443 | bool is_macos() const |
Bill Hollings | 3fcdce0 | 2017-12-26 13:39:07 -0500 | [diff] [blame] | 444 | { |
| 445 | return platform == macOS; |
| 446 | } |
| 447 | |
Bill Hollings | bac657d | 2017-11-07 15:38:13 -0500 | [diff] [blame] | 448 | void set_msl_version(uint32_t major, uint32_t minor = 0, uint32_t patch = 0) |
| 449 | { |
Bill Hollings | 1014847 | 2017-11-10 16:40:33 -0500 | [diff] [blame] | 450 | msl_version = make_msl_version(major, minor, patch); |
Bill Hollings | bac657d | 2017-11-07 15:38:13 -0500 | [diff] [blame] | 451 | } |
| 452 | |
Chip Davis | fb5ee4c | 2019-07-22 13:08:04 -0500 | [diff] [blame] | 453 | bool supports_msl_version(uint32_t major, uint32_t minor = 0, uint32_t patch = 0) const |
Bill Hollings | bac657d | 2017-11-07 15:38:13 -0500 | [diff] [blame] | 454 | { |
Bill Hollings | 1014847 | 2017-11-10 16:40:33 -0500 | [diff] [blame] | 455 | return msl_version >= make_msl_version(major, minor, patch); |
| 456 | } |
| 457 | |
| 458 | static uint32_t make_msl_version(uint32_t major, uint32_t minor = 0, uint32_t patch = 0) |
| 459 | { |
| 460 | return (major * 10000) + (minor * 100) + patch; |
Bill Hollings | bac657d | 2017-11-07 15:38:13 -0500 | [diff] [blame] | 461 | } |
Bill Hollings | 5550c87 | 2017-03-12 17:42:51 -0400 | [diff] [blame] | 462 | }; |
Bill Hollings | 103aabf | 2016-04-06 17:42:27 -0400 | [diff] [blame] | 463 | |
Hans-Kristian Arntzen | a803e5a | 2018-03-09 15:25:25 +0100 | [diff] [blame] | 464 | const Options &get_msl_options() const |
| 465 | { |
| 466 | return msl_options; |
| 467 | } |
| 468 | |
Hans-Kristian Arntzen | a803e5a | 2018-03-09 15:25:25 +0100 | [diff] [blame] | 469 | void set_msl_options(const Options &opts) |
| 470 | { |
| 471 | msl_options = opts; |
Bill Hollings | 5550c87 | 2017-03-12 17:42:51 -0400 | [diff] [blame] | 472 | } |
| 473 | |
Bill Hollings | 0d6202e | 2018-07-26 16:40:32 -0400 | [diff] [blame] | 474 | // Provide feedback to calling API to allow runtime to disable pipeline |
| 475 | // rasterization if vertex shader requires rasterization to be disabled. |
| 476 | bool get_is_rasterization_disabled() const |
| 477 | { |
Chip Davis | eb89c3a | 2019-02-03 23:58:46 -0600 | [diff] [blame] | 478 | return is_rasterization_disabled && (get_entry_point().model == spv::ExecutionModelVertex || |
Chip Davis | 68b09f2 | 2019-02-19 16:44:57 -0600 | [diff] [blame] | 479 | get_entry_point().model == spv::ExecutionModelTessellationControl || |
| 480 | get_entry_point().model == spv::ExecutionModelTessellationEvaluation); |
Bill Hollings | 0d6202e | 2018-07-26 16:40:32 -0400 | [diff] [blame] | 481 | } |
| 482 | |
Chip Davis | 7107f40 | 2018-09-24 13:38:27 -0500 | [diff] [blame] | 483 | // Provide feedback to calling API to allow it to pass an auxiliary |
Hans-Kristian Arntzen | eaf7afe | 2019-05-09 12:15:45 +0200 | [diff] [blame] | 484 | // swizzle buffer if the shader needs it. |
| 485 | bool needs_swizzle_buffer() const |
Chip Davis | 7107f40 | 2018-09-24 13:38:27 -0500 | [diff] [blame] | 486 | { |
Hans-Kristian Arntzen | eaf7afe | 2019-05-09 12:15:45 +0200 | [diff] [blame] | 487 | return used_swizzle_buffer; |
Chip Davis | 7107f40 | 2018-09-24 13:38:27 -0500 | [diff] [blame] | 488 | } |
| 489 | |
Hans-Kristian Arntzen | 7b9e0fb | 2019-05-27 11:59:29 +0200 | [diff] [blame] | 490 | // Provide feedback to calling API to allow it to pass a buffer |
| 491 | // containing STORAGE_BUFFER buffer sizes to support OpArrayLength. |
| 492 | bool needs_buffer_size_buffer() const |
| 493 | { |
| 494 | return !buffers_requiring_array_length.empty(); |
| 495 | } |
| 496 | |
Chip Davis | 7eecf5a | 2019-05-31 12:06:20 -0500 | [diff] [blame] | 497 | // Provide feedback to calling API to allow it to pass a buffer |
| 498 | // containing the view mask for the current multiview subpass. |
| 499 | bool needs_view_mask_buffer() const |
| 500 | { |
Chip Davis | 6a58554 | 2019-07-12 21:50:50 -0500 | [diff] [blame] | 501 | return msl_options.multiview && !msl_options.view_index_from_device_index; |
Chip Davis | 7eecf5a | 2019-05-31 12:06:20 -0500 | [diff] [blame] | 502 | } |
| 503 | |
Chip Davis | fb5ee4c | 2019-07-22 13:08:04 -0500 | [diff] [blame] | 504 | // Provide feedback to calling API to allow it to pass a buffer |
| 505 | // containing the dispatch base workgroup ID. |
| 506 | bool needs_dispatch_base_buffer() const |
| 507 | { |
| 508 | return msl_options.dispatch_base && !msl_options.supports_msl_version(1, 2); |
| 509 | } |
| 510 | |
Chip Davis | ae87c41 | 2019-02-06 17:22:12 -0600 | [diff] [blame] | 511 | // Provide feedback to calling API to allow it to pass an output |
| 512 | // buffer if the shader needs it. |
| 513 | bool needs_output_buffer() const |
| 514 | { |
Hans-Kristian Arntzen | 333980a | 2019-09-05 12:43:40 +0200 | [diff] [blame] | 515 | return capture_output_to_buffer && stage_out_var_id != ID(0); |
Chip Davis | ae87c41 | 2019-02-06 17:22:12 -0600 | [diff] [blame] | 516 | } |
| 517 | |
Chip Davis | eb89c3a | 2019-02-03 23:58:46 -0600 | [diff] [blame] | 518 | // Provide feedback to calling API to allow it to pass a patch output |
| 519 | // buffer if the shader needs it. |
| 520 | bool needs_patch_output_buffer() const |
| 521 | { |
Hans-Kristian Arntzen | 333980a | 2019-09-05 12:43:40 +0200 | [diff] [blame] | 522 | return capture_output_to_buffer && patch_stage_out_var_id != ID(0); |
Chip Davis | eb89c3a | 2019-02-03 23:58:46 -0600 | [diff] [blame] | 523 | } |
| 524 | |
| 525 | // Provide feedback to calling API to allow it to pass an input threadgroup |
| 526 | // buffer if the shader needs it. |
| 527 | bool needs_input_threadgroup_mem() const |
| 528 | { |
Hans-Kristian Arntzen | 333980a | 2019-09-05 12:43:40 +0200 | [diff] [blame] | 529 | return capture_output_to_buffer && stage_in_var_id != ID(0); |
Chip Davis | eb89c3a | 2019-02-03 23:58:46 -0600 | [diff] [blame] | 530 | } |
| 531 | |
Hans-Kristian Arntzen | 3fe57d3 | 2019-04-09 12:46:23 +0200 | [diff] [blame] | 532 | explicit CompilerMSL(std::vector<uint32_t> spirv); |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 533 | CompilerMSL(const uint32_t *ir, size_t word_count); |
| 534 | explicit CompilerMSL(const ParsedIR &ir); |
| 535 | explicit CompilerMSL(ParsedIR &&ir); |
| 536 | |
Chip Davis | 5281d99 | 2020-06-13 23:03:30 -0500 | [diff] [blame] | 537 | // input is a shader input description used to fix up shader input variables. |
| 538 | // If shader inputs are provided, is_msl_shader_input_used() will return true after |
| 539 | // calling ::compile() if the location was used by the MSL code. |
Chip Davis | 688c5fc | 2020-02-20 21:38:28 -0600 | [diff] [blame] | 540 | void add_msl_shader_input(const MSLShaderInput &input); |
Chip Davis | 5281d99 | 2020-06-13 23:03:30 -0500 | [diff] [blame] | 541 | |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 542 | // resource is a resource binding to indicate the MSL buffer, |
| 543 | // texture or sampler index to use for a particular SPIR-V description set |
| 544 | // and binding. If resource bindings are provided, |
| 545 | // is_msl_resource_binding_used() will return true after calling ::compile() if |
| 546 | // the set/binding combination was used by the MSL code. |
| 547 | void add_msl_resource_binding(const MSLResourceBinding &resource); |
| 548 | |
Chip Davis | cb35934 | 2019-09-05 23:14:12 -0500 | [diff] [blame] | 549 | // desc_set and binding are the SPIR-V descriptor set and binding of a buffer resource |
| 550 | // in this shader. index is the index within the dynamic offset buffer to use. This |
| 551 | // function marks that resource as using a dynamic offset (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC |
| 552 | // or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC). This function only has any effect if argument buffers |
| 553 | // are enabled. If so, the buffer will have its address adjusted at the beginning of the shader with |
| 554 | // an offset taken from the dynamic offset buffer. |
| 555 | void add_dynamic_buffer(uint32_t desc_set, uint32_t binding, uint32_t index); |
| 556 | |
Chip Davis | fedbc35 | 2019-12-16 22:58:16 -0600 | [diff] [blame] | 557 | // desc_set and binding are the SPIR-V descriptor set and binding of a buffer resource |
| 558 | // in this shader. This function marks that resource as an inline uniform block |
| 559 | // (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT). This function only has any effect if argument buffers |
| 560 | // are enabled. If so, the buffer block will be directly embedded into the argument |
| 561 | // buffer, instead of being referenced indirectly via pointer. |
| 562 | void add_inline_uniform_block(uint32_t desc_set, uint32_t binding); |
| 563 | |
Hans-Kristian Arntzen | b3380ec | 2019-03-15 14:07:03 +0100 | [diff] [blame] | 564 | // When using MSL argument buffers, we can force "classic" MSL 1.0 binding schemes for certain descriptor sets. |
| 565 | // This corresponds to VK_KHR_push_descriptor in Vulkan. |
Hans-Kristian Arntzen | e2aadf8 | 2019-03-15 21:53:21 +0100 | [diff] [blame] | 566 | void add_discrete_descriptor_set(uint32_t desc_set); |
Hans-Kristian Arntzen | b3380ec | 2019-03-15 14:07:03 +0100 | [diff] [blame] | 567 | |
Hans-Kristian Arntzen | 4bb673a | 2019-10-14 12:51:48 +0200 | [diff] [blame] | 568 | // If an argument buffer is large enough, it may need to be in the device storage space rather than |
| 569 | // constant. Opt-in to this behavior here on a per set basis. |
| 570 | void set_argument_buffer_device_address_space(uint32_t desc_set, bool device_storage); |
| 571 | |
Chip Davis | 5281d99 | 2020-06-13 23:03:30 -0500 | [diff] [blame] | 572 | // Query after compilation is done. This allows you to check if an input location was used by the shader. |
| 573 | bool is_msl_shader_input_used(uint32_t location); |
| 574 | |
Hans-Kristian Arntzen | ce552f4 | 2021-02-17 12:21:21 +0100 | [diff] [blame] | 575 | // If not using add_msl_shader_input, it's possible |
| 576 | // that certain builtin attributes need to be automatically assigned locations. |
| 577 | // This is typical for tessellation builtin inputs such as tess levels, gl_Position, etc. |
| 578 | // This returns k_unknown_location if the location was explicitly assigned with |
| 579 | // add_msl_shader_input or the builtin is not used, otherwise returns N in [[attribute(N)]]. |
| 580 | uint32_t get_automatic_builtin_input_location(spv::BuiltIn builtin) const; |
| 581 | |
Hans-Kristian Arntzen | 30bb197 | 2019-06-10 15:41:36 +0200 | [diff] [blame] | 582 | // NOTE: Only resources which are remapped using add_msl_resource_binding will be reported here. |
| 583 | // Constexpr samplers are always assumed to be emitted. |
| 584 | // No specific MSLResourceBinding remapping is required for constexpr samplers as long as they are remapped |
| 585 | // by remap_constexpr_sampler(_by_binding). |
Hans-Kristian Arntzen | cc153f8 | 2020-01-09 11:18:14 +0100 | [diff] [blame] | 586 | bool is_msl_resource_binding_used(spv::ExecutionModel model, uint32_t set, uint32_t binding) const; |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 587 | |
Hans-Kristian Arntzen | 3a4a9ac | 2019-06-21 13:19:59 +0200 | [diff] [blame] | 588 | // This must only be called after a successful call to CompilerMSL::compile(). |
| 589 | // For a variable resource ID obtained through reflection API, report the automatically assigned resource index. |
| 590 | // If the descriptor set was part of an argument buffer, report the [[id(N)]], |
| 591 | // or [[buffer/texture/sampler]] binding for other resources. |
| 592 | // If the resource was a combined image sampler, report the image binding here, |
| 593 | // use the _secondary version of this call to query the sampler half of the resource. |
| 594 | // If no binding exists, uint32_t(-1) is returned. |
| 595 | uint32_t get_automatic_msl_resource_binding(uint32_t id) const; |
| 596 | |
| 597 | // Same as get_automatic_msl_resource_binding, but should only be used for combined image samplers, in which case the |
| 598 | // sampler's binding is returned instead. For any other resource type, -1 is returned. |
Hans-Kristian Arntzen | 6f1f677 | 2021-02-17 10:42:58 +0100 | [diff] [blame] | 599 | // Secondary bindings are also used for the auxillary image atomic buffer. |
Hans-Kristian Arntzen | 3a4a9ac | 2019-06-21 13:19:59 +0200 | [diff] [blame] | 600 | uint32_t get_automatic_msl_resource_binding_secondary(uint32_t id) const; |
| 601 | |
Chip Davis | 39dce88 | 2019-08-02 15:11:19 -0500 | [diff] [blame] | 602 | // Same as get_automatic_msl_resource_binding, but should only be used for combined image samplers for multiplanar images, |
| 603 | // in which case the second plane's binding is returned instead. For any other resource type, -1 is returned. |
| 604 | uint32_t get_automatic_msl_resource_binding_tertiary(uint32_t id) const; |
| 605 | |
| 606 | // Same as get_automatic_msl_resource_binding, but should only be used for combined image samplers for triplanar images, |
| 607 | // in which case the third plane's binding is returned instead. For any other resource type, -1 is returned. |
| 608 | uint32_t get_automatic_msl_resource_binding_quaternary(uint32_t id) const; |
| 609 | |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 610 | // Compiles the SPIR-V code into Metal Shading Language. |
| 611 | std::string compile() override; |
| 612 | |
| 613 | // Remap a sampler with ID to a constexpr sampler. |
| 614 | // Older iOS targets must use constexpr samplers in certain cases (PCF), |
| 615 | // so a static sampler must be used. |
| 616 | // The sampler will not consume a binding, but be declared in the entry point as a constexpr sampler. |
| 617 | // This can be used on both combined image/samplers (sampler2D) or standalone samplers. |
| 618 | // The remapped sampler must not be an array of samplers. |
Hans-Kristian Arntzen | 30bb197 | 2019-06-10 15:41:36 +0200 | [diff] [blame] | 619 | // Prefer remap_constexpr_sampler_by_binding unless you're also doing reflection anyways. |
Hans-Kristian Arntzen | 333980a | 2019-09-05 12:43:40 +0200 | [diff] [blame] | 620 | void remap_constexpr_sampler(VariableID id, const MSLConstexprSampler &sampler); |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 621 | |
Hans-Kristian Arntzen | 30bb197 | 2019-06-10 15:41:36 +0200 | [diff] [blame] | 622 | // Same as remap_constexpr_sampler, except you provide set/binding, rather than variable ID. |
| 623 | // Remaps based on ID take priority over set/binding remaps. |
| 624 | void remap_constexpr_sampler_by_binding(uint32_t desc_set, uint32_t binding, const MSLConstexprSampler &sampler); |
| 625 | |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 626 | // If using CompilerMSL::Options::pad_fragment_output_components, override the number of components we expect |
| 627 | // to use for a particular location. The default is 4 if number of components is not overridden. |
| 628 | void set_fragment_output_components(uint32_t location, uint32_t components); |
| 629 | |
Hans-Kristian Arntzen | bd1ee43 | 2020-10-14 14:52:18 +0200 | [diff] [blame] | 630 | void set_combined_sampler_suffix(const char *suffix); |
| 631 | const char *get_combined_sampler_suffix() const; |
| 632 | |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 633 | protected: |
Bill Hollings | 8f6df77 | 2017-05-19 18:14:08 -0400 | [diff] [blame] | 634 | // An enum of SPIR-V functions that are implemented in additional |
| 635 | // source code that is added to the shader if necessary. |
| 636 | enum SPVFuncImpl |
| 637 | { |
| 638 | SPVFuncImplNone, |
| 639 | SPVFuncImplMod, |
| 640 | SPVFuncImplRadians, |
| 641 | SPVFuncImplDegrees, |
| 642 | SPVFuncImplFindILsb, |
| 643 | SPVFuncImplFindSMsb, |
| 644 | SPVFuncImplFindUMsb, |
Connor McLaughlin | 1dd676c | 2018-11-07 22:24:21 +1000 | [diff] [blame] | 645 | SPVFuncImplSSign, |
Hans-Kristian Arntzen | 38d1982 | 2018-09-11 12:58:03 +0200 | [diff] [blame] | 646 | SPVFuncImplArrayCopyMultidimBase, |
| 647 | // Unfortunately, we cannot use recursive templates in the MSL compiler properly, |
| 648 | // so stamp out variants up to some arbitrary maximum. |
| 649 | SPVFuncImplArrayCopy = SPVFuncImplArrayCopyMultidimBase + 1, |
| 650 | SPVFuncImplArrayOfArrayCopy2Dim = SPVFuncImplArrayCopyMultidimBase + 2, |
| 651 | SPVFuncImplArrayOfArrayCopy3Dim = SPVFuncImplArrayCopyMultidimBase + 3, |
| 652 | SPVFuncImplArrayOfArrayCopy4Dim = SPVFuncImplArrayCopyMultidimBase + 4, |
| 653 | SPVFuncImplArrayOfArrayCopy5Dim = SPVFuncImplArrayCopyMultidimBase + 5, |
| 654 | SPVFuncImplArrayOfArrayCopy6Dim = SPVFuncImplArrayCopyMultidimBase + 6, |
Bill Hollings | 4c5142b | 2018-06-26 17:30:21 -0400 | [diff] [blame] | 655 | SPVFuncImplTexelBufferCoords, |
Lukas Hermanns | 50ac686 | 2019-09-18 14:03:54 -0400 | [diff] [blame] | 656 | SPVFuncImplImage2DAtomicCoords, // Emulate texture2D atomic operations |
Lukas Hermanns | 51be601 | 2019-09-17 15:10:39 -0400 | [diff] [blame] | 657 | SPVFuncImplFMul, |
| 658 | SPVFuncImplFAdd, |
Hans-Kristian Arntzen | e47a30e | 2021-05-07 12:28:08 +0200 | [diff] [blame] | 659 | SPVFuncImplFSub, |
Bill Hollings | 5742047 | 2021-09-23 16:26:02 -0400 | [diff] [blame] | 660 | SPVFuncImplQuantizeToF16, |
Lukas Hermanns | 51be601 | 2019-09-17 15:10:39 -0400 | [diff] [blame] | 661 | SPVFuncImplCubemapTo2DArrayFace, |
Lukas Hermanns | 50ac686 | 2019-09-18 14:03:54 -0400 | [diff] [blame] | 662 | SPVFuncImplUnsafeArray, // Allow Metal to use the array<T> template to make arrays a value type |
Bill Hollings | 8f6df77 | 2017-05-19 18:14:08 -0400 | [diff] [blame] | 663 | SPVFuncImplInverse4x4, |
Hans-Kristian Arntzen | 6a12ff7 | 2018-02-23 16:48:16 +0100 | [diff] [blame] | 664 | SPVFuncImplInverse3x3, |
| 665 | SPVFuncImplInverse2x2, |
Chip Davis | 39dce88 | 2019-08-02 15:11:19 -0500 | [diff] [blame] | 666 | // It is very important that this come before *Swizzle and ChromaReconstruct*, to ensure it's |
| 667 | // emitted before them. |
| 668 | SPVFuncImplForwardArgs, |
| 669 | // Likewise, this must come before *Swizzle. |
| 670 | SPVFuncImplGetSwizzle, |
Chip Davis | 2583321 | 2018-09-19 20:36:33 -0500 | [diff] [blame] | 671 | SPVFuncImplTextureSwizzle, |
Chip Davis | 39dce88 | 2019-08-02 15:11:19 -0500 | [diff] [blame] | 672 | SPVFuncImplGatherSwizzle, |
| 673 | SPVFuncImplGatherCompareSwizzle, |
Chip Davis | 1264e27 | 2020-10-21 01:51:48 -0500 | [diff] [blame] | 674 | SPVFuncImplSubgroupBroadcast, |
| 675 | SPVFuncImplSubgroupBroadcastFirst, |
Chip Davis | 9d94157 | 2019-05-15 16:03:30 -0500 | [diff] [blame] | 676 | SPVFuncImplSubgroupBallot, |
| 677 | SPVFuncImplSubgroupBallotBitExtract, |
| 678 | SPVFuncImplSubgroupBallotFindLSB, |
| 679 | SPVFuncImplSubgroupBallotFindMSB, |
| 680 | SPVFuncImplSubgroupBallotBitCount, |
| 681 | SPVFuncImplSubgroupAllEqual, |
Chip Davis | 1264e27 | 2020-10-21 01:51:48 -0500 | [diff] [blame] | 682 | SPVFuncImplSubgroupShuffle, |
| 683 | SPVFuncImplSubgroupShuffleXor, |
| 684 | SPVFuncImplSubgroupShuffleUp, |
| 685 | SPVFuncImplSubgroupShuffleDown, |
| 686 | SPVFuncImplQuadBroadcast, |
| 687 | SPVFuncImplQuadSwap, |
Hans-Kristian Arntzen | 041f103 | 2019-07-03 12:24:58 +0200 | [diff] [blame] | 688 | SPVFuncImplReflectScalar, |
| 689 | SPVFuncImplRefractScalar, |
Hans-Kristian Arntzen | c7eda1b | 2019-07-17 11:24:31 +0200 | [diff] [blame] | 690 | SPVFuncImplFaceForwardScalar, |
Chip Davis | 39dce88 | 2019-08-02 15:11:19 -0500 | [diff] [blame] | 691 | SPVFuncImplChromaReconstructNearest2Plane, |
| 692 | SPVFuncImplChromaReconstructNearest3Plane, |
| 693 | SPVFuncImplChromaReconstructLinear422CositedEven2Plane, |
| 694 | SPVFuncImplChromaReconstructLinear422CositedEven3Plane, |
| 695 | SPVFuncImplChromaReconstructLinear422Midpoint2Plane, |
| 696 | SPVFuncImplChromaReconstructLinear422Midpoint3Plane, |
| 697 | SPVFuncImplChromaReconstructLinear420XCositedEvenYCositedEven2Plane, |
| 698 | SPVFuncImplChromaReconstructLinear420XCositedEvenYCositedEven3Plane, |
| 699 | SPVFuncImplChromaReconstructLinear420XMidpointYCositedEven2Plane, |
| 700 | SPVFuncImplChromaReconstructLinear420XMidpointYCositedEven3Plane, |
| 701 | SPVFuncImplChromaReconstructLinear420XCositedEvenYMidpoint2Plane, |
| 702 | SPVFuncImplChromaReconstructLinear420XCositedEvenYMidpoint3Plane, |
| 703 | SPVFuncImplChromaReconstructLinear420XMidpointYMidpoint2Plane, |
| 704 | SPVFuncImplChromaReconstructLinear420XMidpointYMidpoint3Plane, |
| 705 | SPVFuncImplExpandITUFullRange, |
| 706 | SPVFuncImplExpandITUNarrowRange, |
| 707 | SPVFuncImplConvertYCbCrBT709, |
| 708 | SPVFuncImplConvertYCbCrBT601, |
| 709 | SPVFuncImplConvertYCbCrBT2020, |
| 710 | SPVFuncImplDynamicImageSampler, |
Bill Hollings | 8f6df77 | 2017-05-19 18:14:08 -0400 | [diff] [blame] | 711 | }; |
| 712 | |
Lukas Hermanns | 7ad0a84 | 2019-09-23 18:05:04 -0400 | [diff] [blame] | 713 | // If the underlying resource has been used for comparison then duplicate loads of that resource must be too |
| 714 | // Use Metal's native frame-buffer fetch API for subpass inputs. |
Hans-Kristian Arntzen | 275974e | 2020-06-04 15:50:28 +0200 | [diff] [blame] | 715 | void emit_texture_op(const Instruction &i, bool sparse) override; |
Chip Davis | d323369 | 2018-08-31 13:46:02 -0500 | [diff] [blame] | 716 | void emit_binary_unord_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op); |
Bill Hollings | f5f9104 | 2016-10-27 18:47:17 -0400 | [diff] [blame] | 717 | void emit_instruction(const Instruction &instr) override; |
Hans-Kristian Arntzen | 67aad48 | 2016-11-12 10:04:50 +0100 | [diff] [blame] | 718 | void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args, |
| 719 | uint32_t count) override; |
Chip Davis | ca91fcf | 2019-07-11 11:49:34 -0500 | [diff] [blame] | 720 | void emit_spv_amd_shader_trinary_minmax_op(uint32_t result_type, uint32_t result_id, uint32_t op, |
| 721 | const uint32_t *args, uint32_t count) override; |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 722 | void emit_header() override; |
Hans-Kristian Arntzen | e8e5884 | 2018-03-12 13:09:25 +0100 | [diff] [blame] | 723 | void emit_function_prototype(SPIRFunction &func, const Bitset &return_flags) override; |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 724 | void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) override; |
Chip Davis | 9d94157 | 2019-05-15 16:03:30 -0500 | [diff] [blame] | 725 | void emit_subgroup_op(const Instruction &i) override; |
Hans-Kristian Arntzen | 275974e | 2020-06-04 15:50:28 +0200 | [diff] [blame] | 726 | std::string to_texture_op(const Instruction &i, bool sparse, bool *forward, |
Chip Davis | 39dce88 | 2019-08-02 15:11:19 -0500 | [diff] [blame] | 727 | SmallVector<uint32_t> &inherited_expressions) override; |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 728 | void emit_fixup() override; |
Chip Davis | c51e5b7 | 2019-01-08 16:33:32 -0600 | [diff] [blame] | 729 | std::string to_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index, |
| 730 | const std::string &qualifier = ""); |
Bill Hollings | dc69427 | 2017-03-11 12:17:22 -0500 | [diff] [blame] | 731 | void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index, |
msiglreith | d096f5c | 2017-11-27 16:00:56 +0100 | [diff] [blame] | 732 | const std::string &qualifier = "", uint32_t base_offset = 0) override; |
Hans-Kristian Arntzen | be2fccd | 2019-07-22 10:23:39 +0200 | [diff] [blame] | 733 | void emit_struct_padding_target(const SPIRType &type) override; |
Bill Hollings | b41e148 | 2017-05-29 20:45:05 -0400 | [diff] [blame] | 734 | std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override; |
Hans-Kristian Arntzen | d62b3c2 | 2021-06-03 12:00:29 +0200 | [diff] [blame] | 735 | void emit_block_hints(const SPIRBlock &block) override; |
Lukas Hermanns | f3a6d28 | 2019-09-27 15:49:54 -0400 | [diff] [blame] | 736 | |
| 737 | // Allow Metal to use the array<T> template to make arrays a value type |
| 738 | std::string type_to_array_glsl(const SPIRType &type) override; |
Bill Hollings | 5fb1ca4 | 2021-09-03 18:20:49 -0400 | [diff] [blame] | 739 | std::string constant_op_expression(const SPIRConstantOp &cop) override; |
Lukas Hermanns | f3a6d28 | 2019-09-27 15:49:54 -0400 | [diff] [blame] | 740 | |
| 741 | // Threadgroup arrays can't have a wrapper type |
| 742 | std::string variable_decl(const SPIRVariable &variable) override; |
| 743 | |
Hans-Kristian Arntzen | ae7bb41 | 2021-04-06 15:50:02 +0200 | [diff] [blame] | 744 | bool variable_decl_is_remapped_storage(const SPIRVariable &variable, spv::StorageClass storage) const override; |
Hans-Kristian Arntzen | f2b5fb3 | 2021-03-26 17:23:44 +0100 | [diff] [blame] | 745 | |
Lukas Hermanns | f3a6d28 | 2019-09-27 15:49:54 -0400 | [diff] [blame] | 746 | // GCC workaround of lambdas calling protected functions (for older GCC versions) |
| 747 | std::string variable_decl(const SPIRType &type, const std::string &name, uint32_t id = 0) override; |
| 748 | |
Bill Hollings | b41e148 | 2017-05-29 20:45:05 -0400 | [diff] [blame] | 749 | std::string image_type_glsl(const SPIRType &type, uint32_t id = 0) override; |
Bill Hollings | b7b0e80 | 2020-10-29 18:50:42 -0400 | [diff] [blame] | 750 | std::string sampler_type(const SPIRType &type, uint32_t id); |
Hans-Kristian Arntzen | c8d6091 | 2017-07-24 10:07:02 +0200 | [diff] [blame] | 751 | std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage) override; |
Chip Davis | 39dce88 | 2019-08-02 15:11:19 -0500 | [diff] [blame] | 752 | std::string to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id) override; |
Hans-Kristian Arntzen | 61c31c6 | 2017-03-07 13:27:04 +0100 | [diff] [blame] | 753 | std::string to_name(uint32_t id, bool allow_alias = true) const override; |
Hans-Kristian Arntzen | cbe0cca | 2020-06-05 15:49:17 +0200 | [diff] [blame] | 754 | std::string to_function_name(const TextureFunctionNameArguments &args) override; |
| 755 | std::string to_function_args(const TextureFunctionArguments &args, bool *p_forward) override; |
Hans-Kristian Arntzen | 2bf57d6 | 2018-07-05 15:29:49 +0200 | [diff] [blame] | 756 | std::string to_initializer_expression(const SPIRVariable &var) override; |
Hans-Kristian Arntzen | b8905bb | 2020-03-26 11:21:23 +0100 | [diff] [blame] | 757 | std::string to_zero_initialized_expression(uint32_t type_id) override; |
Lukas Hermanns | 7ad0a84 | 2019-09-23 18:05:04 -0400 | [diff] [blame] | 758 | |
Hans-Kristian Arntzen | 3fa2b14 | 2019-07-23 12:23:41 +0200 | [diff] [blame] | 759 | std::string unpack_expression_type(std::string expr_str, const SPIRType &type, uint32_t physical_type_id, |
| 760 | bool is_packed, bool row_major) override; |
Hans-Kristian Arntzen | 14afb96 | 2019-07-22 12:03:12 +0200 | [diff] [blame] | 761 | |
Lukas Hermanns | 6673a67 | 2019-10-22 11:06:16 -0400 | [diff] [blame] | 762 | // Returns true for BuiltInSampleMask because gl_SampleMask[] is an array in SPIR-V, but [[sample_mask]] is a scalar in Metal. |
| 763 | bool builtin_translates_to_nonarray(spv::BuiltIn builtin) const override; |
| 764 | |
Bill Hollings | 8f6df77 | 2017-05-19 18:14:08 -0400 | [diff] [blame] | 765 | std::string bitcast_glsl_op(const SPIRType &result_type, const SPIRType &argument_type) override; |
Hans-Kristian Arntzen | 5e5d1c2 | 2020-04-21 23:27:33 +0200 | [diff] [blame] | 766 | bool emit_complex_bitcast(uint32_t result_id, uint32_t id, uint32_t op0) override; |
Bill Hollings | b41e148 | 2017-05-29 20:45:05 -0400 | [diff] [blame] | 767 | bool skip_argument(uint32_t id) const override; |
Chip Davis | 3bfb2f9 | 2018-12-03 02:06:33 -0600 | [diff] [blame] | 768 | std::string to_member_reference(uint32_t base, const SPIRType &type, uint32_t index, bool ptr_chain) override; |
Bill Hollings | 1c18078 | 2017-11-05 21:34:42 -0500 | [diff] [blame] | 769 | std::string to_qualifiers_glsl(uint32_t id) override; |
| 770 | void replace_illegal_names() override; |
Bill Hollings | e83e2b2 | 2017-11-15 22:44:42 -0500 | [diff] [blame] | 771 | void declare_undefined_values() override; |
Hans-Kristian Arntzen | 1a9c960 | 2018-02-08 13:06:29 +0100 | [diff] [blame] | 772 | void declare_constant_arrays(); |
Lukas Hermanns | 7ad0a84 | 2019-09-23 18:05:04 -0400 | [diff] [blame] | 773 | |
Hans-Kristian Arntzen | c4ff129 | 2021-01-04 09:40:11 +0100 | [diff] [blame] | 774 | void replace_illegal_entry_point_names(); |
| 775 | void sync_entry_point_aliases_and_names(); |
| 776 | |
| 777 | static const std::unordered_set<std::string> &get_reserved_keyword_set(); |
| 778 | static const std::unordered_set<std::string> &get_illegal_func_names(); |
| 779 | |
Lukas Hermanns | 50ac686 | 2019-09-18 14:03:54 -0400 | [diff] [blame] | 780 | // Constant arrays of non-primitive types (i.e. matrices) won't link properly into Metal libraries |
Mark Satterthwaite | 8596bf5 | 2019-08-13 18:20:02 -0400 | [diff] [blame] | 781 | void declare_complex_constant_arrays(); |
Lukas Hermanns | 7ad0a84 | 2019-09-23 18:05:04 -0400 | [diff] [blame] | 782 | |
Chip Davis | 6b79880 | 2019-02-15 17:21:38 -0600 | [diff] [blame] | 783 | bool is_patch_block(const SPIRType &type); |
Bill Hollings | 8890578 | 2018-01-04 16:33:45 -0500 | [diff] [blame] | 784 | bool is_non_native_row_major_matrix(uint32_t id) override; |
| 785 | bool member_is_non_native_row_major_matrix(const SPIRType &type, uint32_t index) override; |
Hans-Kristian Arntzen | 3fa2b14 | 2019-07-23 12:23:41 +0200 | [diff] [blame] | 786 | std::string convert_row_major_matrix(std::string exp_str, const SPIRType &exp_type, uint32_t physical_type_id, |
| 787 | bool is_packed) override; |
Bill Hollings | 103aabf | 2016-04-06 17:42:27 -0400 | [diff] [blame] | 788 | |
Bill Hollings | 4c198bb | 2017-01-20 11:24:44 -0500 | [diff] [blame] | 789 | void preprocess_op_codes(); |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 790 | void localize_global_variables(); |
Bill Hollings | ac00c60 | 2016-10-24 09:24:24 -0400 | [diff] [blame] | 791 | void extract_global_variables_from_functions(); |
Bill Hollings | 1c18078 | 2017-11-05 21:34:42 -0500 | [diff] [blame] | 792 | void mark_packable_structs(); |
| 793 | void mark_as_packable(SPIRType &type); |
Robert Konrad | a778c36 | 2017-01-15 16:39:03 +0100 | [diff] [blame] | 794 | |
Bill Hollings | e4f0dde | 2017-01-31 11:02:44 -0500 | [diff] [blame] | 795 | std::unordered_map<uint32_t, std::set<uint32_t>> function_global_vars; |
| 796 | void extract_global_variables_from_function(uint32_t func_id, std::set<uint32_t> &added_arg_ids, |
Bill Hollings | 32ae2ec | 2016-12-18 18:48:15 -0500 | [diff] [blame] | 797 | std::unordered_set<uint32_t> &global_var_ids, |
| 798 | std::unordered_set<uint32_t> &processed_func_ids); |
Chip Davis | eb89c3a | 2019-02-03 23:58:46 -0600 | [diff] [blame] | 799 | uint32_t add_interface_block(spv::StorageClass storage, bool patch = false); |
| 800 | uint32_t add_interface_block_pointer(uint32_t ib_var_id, spv::StorageClass storage); |
Hans-Kristian Arntzen | 5345756 | 2019-01-08 11:03:59 +0100 | [diff] [blame] | 801 | |
Hans-Kristian Arntzen | 93f3265 | 2020-01-07 14:05:55 +0100 | [diff] [blame] | 802 | struct InterfaceBlockMeta |
| 803 | { |
| 804 | struct LocationMeta |
| 805 | { |
Hans-Kristian Arntzen | 99ae0d3 | 2021-05-21 13:03:05 +0200 | [diff] [blame] | 806 | uint32_t base_type_id = 0; |
Hans-Kristian Arntzen | 93f3265 | 2020-01-07 14:05:55 +0100 | [diff] [blame] | 807 | uint32_t num_components = 0; |
Hans-Kristian Arntzen | 99ae0d3 | 2021-05-21 13:03:05 +0200 | [diff] [blame] | 808 | bool flat = false; |
| 809 | bool noperspective = false; |
| 810 | bool centroid = false; |
| 811 | bool sample = false; |
Hans-Kristian Arntzen | 93f3265 | 2020-01-07 14:05:55 +0100 | [diff] [blame] | 812 | }; |
| 813 | std::unordered_map<uint32_t, LocationMeta> location_meta; |
| 814 | bool strip_array = false; |
Hans-Kristian Arntzen | 425e968 | 2021-04-07 17:02:30 +0200 | [diff] [blame] | 815 | bool allow_local_declaration = false; |
Hans-Kristian Arntzen | 93f3265 | 2020-01-07 14:05:55 +0100 | [diff] [blame] | 816 | }; |
| 817 | |
Hans-Kristian Arntzen | 7b9a591 | 2021-04-16 11:26:47 +0200 | [diff] [blame] | 818 | std::string to_tesc_invocation_id(); |
Hans-Kristian Arntzen | 23da445 | 2021-04-14 13:13:13 +0200 | [diff] [blame] | 819 | void emit_local_masked_variable(const SPIRVariable &masked_var, bool strip_array); |
Hans-Kristian Arntzen | 5345756 | 2019-01-08 11:03:59 +0100 | [diff] [blame] | 820 | void add_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref, SPIRType &ib_type, |
Hans-Kristian Arntzen | 93f3265 | 2020-01-07 14:05:55 +0100 | [diff] [blame] | 821 | SPIRVariable &var, InterfaceBlockMeta &meta); |
Hans-Kristian Arntzen | 5345756 | 2019-01-08 11:03:59 +0100 | [diff] [blame] | 822 | void add_composite_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref, |
Hans-Kristian Arntzen | 93f3265 | 2020-01-07 14:05:55 +0100 | [diff] [blame] | 823 | SPIRType &ib_type, SPIRVariable &var, InterfaceBlockMeta &meta); |
Hans-Kristian Arntzen | 5345756 | 2019-01-08 11:03:59 +0100 | [diff] [blame] | 824 | void add_plain_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref, |
Hans-Kristian Arntzen | 93f3265 | 2020-01-07 14:05:55 +0100 | [diff] [blame] | 825 | SPIRType &ib_type, SPIRVariable &var, InterfaceBlockMeta &meta); |
Hans-Kristian Arntzen | 99ae0d3 | 2021-05-21 13:03:05 +0200 | [diff] [blame] | 826 | bool add_component_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref, |
| 827 | SPIRVariable &var, const SPIRType &type, |
| 828 | InterfaceBlockMeta &meta); |
Hans-Kristian Arntzen | 5345756 | 2019-01-08 11:03:59 +0100 | [diff] [blame] | 829 | void add_plain_member_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref, |
Chip Davis | eb89c3a | 2019-02-03 23:58:46 -0600 | [diff] [blame] | 830 | SPIRType &ib_type, SPIRVariable &var, uint32_t index, |
Hans-Kristian Arntzen | 93f3265 | 2020-01-07 14:05:55 +0100 | [diff] [blame] | 831 | InterfaceBlockMeta &meta); |
Hans-Kristian Arntzen | 5345756 | 2019-01-08 11:03:59 +0100 | [diff] [blame] | 832 | void add_composite_member_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref, |
Chip Davis | eb89c3a | 2019-02-03 23:58:46 -0600 | [diff] [blame] | 833 | SPIRType &ib_type, SPIRVariable &var, uint32_t index, |
Hans-Kristian Arntzen | 93f3265 | 2020-01-07 14:05:55 +0100 | [diff] [blame] | 834 | InterfaceBlockMeta &meta); |
Chip Davis | f3c0942 | 2019-02-22 12:11:17 -0600 | [diff] [blame] | 835 | void add_tess_level_input_to_interface_block(const std::string &ib_var_ref, SPIRType &ib_type, SPIRVariable &var); |
Chip Davis | eb89c3a | 2019-02-03 23:58:46 -0600 | [diff] [blame] | 836 | |
| 837 | void fix_up_interface_member_indices(spv::StorageClass storage, uint32_t ib_type_id); |
Hans-Kristian Arntzen | 5345756 | 2019-01-08 11:03:59 +0100 | [diff] [blame] | 838 | |
Hans-Kristian Arntzen | faf80b0 | 2021-04-09 18:55:10 +0200 | [diff] [blame] | 839 | void mark_location_as_used_by_shader(uint32_t location, const SPIRType &type, |
| 840 | spv::StorageClass storage, bool fallback = false); |
Bill Hollings | 2964e32 | 2018-02-13 14:44:40 -0500 | [diff] [blame] | 841 | uint32_t ensure_correct_builtin_type(uint32_t type_id, spv::BuiltIn builtin); |
Bill Hollings | 548a23d | 2021-09-20 17:57:11 -0400 | [diff] [blame] | 842 | uint32_t ensure_correct_input_type(uint32_t type_id, uint32_t location, uint32_t component, |
Hans-Kristian Arntzen | 40f628f | 2021-04-09 10:45:05 +0200 | [diff] [blame] | 843 | uint32_t num_components, bool strip_array); |
Robert Konrad | a778c36 | 2017-01-15 16:39:03 +0100 | [diff] [blame] | 844 | |
Lukas Hermanns | 51be601 | 2019-09-17 15:10:39 -0400 | [diff] [blame] | 845 | void emit_custom_templates(); |
Bill Hollings | 1f83856 | 2017-06-15 15:24:22 -0400 | [diff] [blame] | 846 | void emit_custom_functions(); |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 847 | void emit_resources(); |
Hans-Kristian Arntzen | d92de00 | 2019-01-10 09:49:33 +0100 | [diff] [blame] | 848 | void emit_specialization_constants_and_structs(); |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 849 | void emit_interface_block(uint32_t ib_var_id); |
Bill Hollings | 1c18078 | 2017-11-05 21:34:42 -0500 | [diff] [blame] | 850 | bool maybe_emit_array_assignment(uint32_t id_lhs, uint32_t id_rhs); |
Bill Hollings | 4bdd49d | 2020-11-02 22:15:20 -0500 | [diff] [blame] | 851 | uint32_t get_resource_array_size(uint32_t id) const; |
Hans-Kristian Arntzen | 27b75c2 | 2019-07-19 12:53:10 +0200 | [diff] [blame] | 852 | |
Chip Davis | f500d2f | 2019-01-16 17:52:53 -0600 | [diff] [blame] | 853 | void fix_up_shader_inputs_outputs(); |
Bill Hollings | 8f30f07 | 2016-04-07 21:25:51 -0400 | [diff] [blame] | 854 | |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 855 | std::string func_type_decl(SPIRType &type); |
Hans-Kristian Arntzen | e47a77d | 2019-03-14 10:29:34 +0100 | [diff] [blame] | 856 | std::string entry_point_args_classic(bool append_comma); |
| 857 | std::string entry_point_args_argument_buffer(bool append_comma); |
| 858 | std::string entry_point_arg_stage_in(); |
| 859 | void entry_point_args_builtin(std::string &args); |
Hans-Kristian Arntzen | e2aadf8 | 2019-03-15 21:53:21 +0100 | [diff] [blame] | 860 | void entry_point_args_discrete_descriptors(std::string &args); |
Bill Hollings | ac00c60 | 2016-10-24 09:24:24 -0400 | [diff] [blame] | 861 | std::string to_qualified_member_name(const SPIRType &type, uint32_t index); |
Bill Hollings | c2e6013 | 2016-11-27 15:00:06 -0500 | [diff] [blame] | 862 | std::string ensure_valid_name(std::string name, std::string pfx); |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 863 | std::string to_sampler_expression(uint32_t id); |
Chip Davis | 664df22 | 2019-01-13 17:31:50 -0600 | [diff] [blame] | 864 | std::string to_swizzle_expression(uint32_t id); |
Hans-Kristian Arntzen | 7b9e0fb | 2019-05-27 11:59:29 +0200 | [diff] [blame] | 865 | std::string to_buffer_size_expression(uint32_t id); |
Chip Davis | fd738e3 | 2020-11-20 15:41:46 -0600 | [diff] [blame] | 866 | bool is_sample_rate() const; |
丛越 | d52ec1e | 2021-10-21 17:46:45 +0800 | [diff] [blame] | 867 | bool is_intersection_query() const; |
Chip Davis | 5e13f7f | 2020-07-22 15:25:10 -0600 | [diff] [blame] | 868 | bool is_direct_input_builtin(spv::BuiltIn builtin); |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 869 | std::string builtin_qualifier(spv::BuiltIn builtin); |
Hans-Kristian Arntzen | 2e1cee5 | 2019-06-13 11:33:40 +0200 | [diff] [blame] | 870 | std::string builtin_type_decl(spv::BuiltIn builtin, uint32_t id = 0); |
Bill Hollings | 8175750 | 2017-01-29 13:28:20 -0500 | [diff] [blame] | 871 | std::string built_in_func_arg(spv::BuiltIn builtin, bool prefix_comma); |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 872 | std::string member_attribute_qualifier(const SPIRType &type, uint32_t index); |
Bill Hollings | 86dfac1 | 2021-09-18 18:55:12 -0400 | [diff] [blame] | 873 | std::string member_location_attribute_qualifier(const SPIRType &type, uint32_t index); |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 874 | std::string argument_decl(const SPIRFunction::Parameter &arg); |
Bill Hollings | 561dc03 | 2017-04-25 16:32:16 -0400 | [diff] [blame] | 875 | std::string round_fp_tex_coords(std::string tex_coords, bool coord_is_fp); |
Chip Davis | 39dce88 | 2019-08-02 15:11:19 -0500 | [diff] [blame] | 876 | uint32_t get_metal_resource_index(SPIRVariable &var, SPIRType::BaseType basetype, uint32_t plane = 0); |
Hans-Kristian Arntzen | ce552f4 | 2021-02-17 12:21:21 +0100 | [diff] [blame] | 877 | uint32_t get_member_location(uint32_t type_id, uint32_t index, uint32_t *comp = nullptr) const; |
| 878 | uint32_t get_or_allocate_builtin_input_member_location(spv::BuiltIn builtin, |
| 879 | uint32_t type_id, uint32_t index, uint32_t *comp = nullptr); |
Hans-Kristian Arntzen | a86308b | 2019-07-18 13:34:47 +0200 | [diff] [blame] | 880 | |
Hans-Kristian Arntzen | 85704f7 | 2021-02-17 13:18:47 +0100 | [diff] [blame] | 881 | uint32_t get_physical_tess_level_array_size(spv::BuiltIn builtin) const; |
| 882 | |
Hans-Kristian Arntzen | a86308b | 2019-07-18 13:34:47 +0200 | [diff] [blame] | 883 | // MSL packing rules. These compute the effective packing rules as observed by the MSL compiler in the MSL output. |
| 884 | // These values can change depending on various extended decorations which control packing rules. |
| 885 | // We need to make these rules match up with SPIR-V declared rules. |
Hans-Kristian Arntzen | b09b8d3 | 2019-07-18 16:39:25 +0200 | [diff] [blame] | 886 | uint32_t get_declared_type_size_msl(const SPIRType &type, bool packed, bool row_major) const; |
| 887 | uint32_t get_declared_type_array_stride_msl(const SPIRType &type, bool packed, bool row_major) const; |
| 888 | uint32_t get_declared_type_matrix_stride_msl(const SPIRType &type, bool packed, bool row_major) const; |
| 889 | uint32_t get_declared_type_alignment_msl(const SPIRType &type, bool packed, bool row_major) const; |
Hans-Kristian Arntzen | c160d52 | 2019-07-18 13:48:27 +0200 | [diff] [blame] | 890 | |
| 891 | uint32_t get_declared_struct_member_size_msl(const SPIRType &struct_type, uint32_t index) const; |
| 892 | uint32_t get_declared_struct_member_array_stride_msl(const SPIRType &struct_type, uint32_t index) const; |
| 893 | uint32_t get_declared_struct_member_matrix_stride_msl(const SPIRType &struct_type, uint32_t index) const; |
| 894 | uint32_t get_declared_struct_member_alignment_msl(const SPIRType &struct_type, uint32_t index) const; |
| 895 | |
Chip Davis | 688c5fc | 2020-02-20 21:38:28 -0600 | [diff] [blame] | 896 | uint32_t get_declared_input_size_msl(const SPIRType &struct_type, uint32_t index) const; |
| 897 | uint32_t get_declared_input_array_stride_msl(const SPIRType &struct_type, uint32_t index) const; |
| 898 | uint32_t get_declared_input_matrix_stride_msl(const SPIRType &struct_type, uint32_t index) const; |
| 899 | uint32_t get_declared_input_alignment_msl(const SPIRType &struct_type, uint32_t index) const; |
| 900 | |
Hans-Kristian Arntzen | c160d52 | 2019-07-18 13:48:27 +0200 | [diff] [blame] | 901 | const SPIRType &get_physical_member_type(const SPIRType &struct_type, uint32_t index) const; |
Chip Davis | 688c5fc | 2020-02-20 21:38:28 -0600 | [diff] [blame] | 902 | SPIRType get_presumed_input_type(const SPIRType &struct_type, uint32_t index) const; |
Hans-Kristian Arntzen | c160d52 | 2019-07-18 13:48:27 +0200 | [diff] [blame] | 903 | |
Hans-Kristian Arntzen | 3fa2b14 | 2019-07-23 12:23:41 +0200 | [diff] [blame] | 904 | uint32_t get_declared_struct_size_msl(const SPIRType &struct_type, bool ignore_alignment = false, |
| 905 | bool ignore_padding = false) const; |
Hans-Kristian Arntzen | a86308b | 2019-07-18 13:34:47 +0200 | [diff] [blame] | 906 | |
Bill Hollings | a2b8a0e | 2016-12-28 18:36:42 -0500 | [diff] [blame] | 907 | std::string to_component_argument(uint32_t id); |
Hans-Kristian Arntzen | a86308b | 2019-07-18 13:34:47 +0200 | [diff] [blame] | 908 | void align_struct(SPIRType &ib_type, std::unordered_set<uint32_t> &aligned_structs); |
Hans-Kristian Arntzen | e90d816 | 2019-07-19 14:18:14 +0200 | [diff] [blame] | 909 | void mark_scalar_layout_structs(const SPIRType &ib_type); |
Hans-Kristian Arntzen | 5c1cb7a | 2019-07-23 15:24:53 +0200 | [diff] [blame] | 910 | void mark_struct_members_packed(const SPIRType &type); |
Hans-Kristian Arntzen | b09b8d3 | 2019-07-18 16:39:25 +0200 | [diff] [blame] | 911 | void ensure_member_packing_rules_msl(SPIRType &ib_type, uint32_t index); |
| 912 | bool validate_member_packing_rules_msl(const SPIRType &type, uint32_t index) const; |
Bill Hollings | 8f6df77 | 2017-05-19 18:14:08 -0400 | [diff] [blame] | 913 | std::string get_argument_address_space(const SPIRVariable &argument); |
Chip Davis | df18d98 | 2019-07-26 01:06:35 -0500 | [diff] [blame] | 914 | std::string get_type_address_space(const SPIRType &type, uint32_t id, bool argument = false); |
Chip Davis | 058f1a0 | 2019-07-10 11:17:40 -0500 | [diff] [blame] | 915 | const char *to_restrict(uint32_t id, bool space = true); |
Chip Davis | eb89c3a | 2019-02-03 23:58:46 -0600 | [diff] [blame] | 916 | SPIRType &get_stage_in_struct_type(); |
Chip Davis | c51e5b7 | 2019-01-08 16:33:32 -0600 | [diff] [blame] | 917 | SPIRType &get_stage_out_struct_type(); |
Chip Davis | e75add4 | 2019-02-05 18:13:26 -0600 | [diff] [blame] | 918 | SPIRType &get_patch_stage_in_struct_type(); |
Chip Davis | eb89c3a | 2019-02-03 23:58:46 -0600 | [diff] [blame] | 919 | SPIRType &get_patch_stage_out_struct_type(); |
| 920 | std::string get_tess_factor_struct_name(); |
Chip Davis | 884bc6d | 2020-07-22 15:25:10 -0600 | [diff] [blame] | 921 | SPIRType &get_uint_type(); |
| 922 | uint32_t get_uint_type_id(); |
Hans-Kristian Arntzen | fce8870 | 2022-01-17 15:29:13 +0100 | [diff] [blame] | 923 | void emit_atomic_func_op(uint32_t result_type, uint32_t result_id, const char *op, spv::Op opcode, |
| 924 | uint32_t mem_order_1, uint32_t mem_order_2, bool has_mem_order_2, uint32_t op0, uint32_t op1 = 0, |
Chip Davis | 06edf80 | 2018-09-13 08:56:23 -0500 | [diff] [blame] | 925 | bool op1_is_pointer = false, bool op1_is_literal = false, uint32_t op2 = 0); |
Bill Hollings | 8f6df77 | 2017-05-19 18:14:08 -0400 | [diff] [blame] | 926 | const char *get_memory_order(uint32_t spv_mem_sem); |
| 927 | void add_pragma_line(const std::string &line); |
Bill Hollings | 607b0d6 | 2018-02-11 16:52:57 -0500 | [diff] [blame] | 928 | void add_typedef_line(const std::string &line); |
Bill Hollings | 1c18078 | 2017-11-05 21:34:42 -0500 | [diff] [blame] | 929 | void emit_barrier(uint32_t id_exe_scope, uint32_t id_mem_scope, uint32_t id_mem_sem); |
Hans-Kristian Arntzen | ae9ca7d | 2021-04-19 11:46:30 +0200 | [diff] [blame] | 930 | void emit_array_copy(const std::string &lhs, uint32_t lhs_id, uint32_t rhs_id, |
| 931 | spv::StorageClass lhs_storage, spv::StorageClass rhs_storage) override; |
Hans-Kristian Arntzen | 0912427 | 2018-02-09 11:27:23 +0100 | [diff] [blame] | 932 | void build_implicit_builtins(); |
Hans-Kristian Arntzen | 7b9e0fb | 2019-05-27 11:59:29 +0200 | [diff] [blame] | 933 | uint32_t build_constant_uint_array_pointer(); |
Hans-Kristian Arntzen | df58deb | 2018-04-17 17:43:10 +0200 | [diff] [blame] | 934 | void emit_entry_point_declarations() override; |
Bill Hollings | 248e9ae | 2021-11-12 14:17:00 -0500 | [diff] [blame] | 935 | bool uses_explicit_early_fragment_test(); |
| 936 | |
Hans-Kristian Arntzen | 702e086 | 2018-02-09 12:13:33 +0100 | [diff] [blame] | 937 | uint32_t builtin_frag_coord_id = 0; |
Chip Davis | 39bc101 | 2018-09-12 14:05:52 -0500 | [diff] [blame] | 938 | uint32_t builtin_sample_id_id = 0; |
Tomek Ponitka | 18f23c4 | 2020-07-22 18:37:17 +0200 | [diff] [blame] | 939 | uint32_t builtin_sample_mask_id = 0; |
Chip Davis | c51e5b7 | 2019-01-08 16:33:32 -0600 | [diff] [blame] | 940 | uint32_t builtin_vertex_idx_id = 0; |
| 941 | uint32_t builtin_base_vertex_id = 0; |
| 942 | uint32_t builtin_instance_idx_id = 0; |
| 943 | uint32_t builtin_base_instance_id = 0; |
Chip Davis | 7eecf5a | 2019-05-31 12:06:20 -0500 | [diff] [blame] | 944 | uint32_t builtin_view_idx_id = 0; |
| 945 | uint32_t builtin_layer_id = 0; |
Chip Davis | eb89c3a | 2019-02-03 23:58:46 -0600 | [diff] [blame] | 946 | uint32_t builtin_invocation_id_id = 0; |
| 947 | uint32_t builtin_primitive_id_id = 0; |
Chip Davis | 9d94157 | 2019-05-15 16:03:30 -0500 | [diff] [blame] | 948 | uint32_t builtin_subgroup_invocation_id_id = 0; |
| 949 | uint32_t builtin_subgroup_size_id = 0; |
Chip Davis | fb5ee4c | 2019-07-22 13:08:04 -0500 | [diff] [blame] | 950 | uint32_t builtin_dispatch_base_id = 0; |
Chip Davis | 688c5fc | 2020-02-20 21:38:28 -0600 | [diff] [blame] | 951 | uint32_t builtin_stage_input_size_id = 0; |
Chip Davis | 6890835 | 2020-11-18 23:16:46 -0600 | [diff] [blame] | 952 | uint32_t builtin_local_invocation_index_id = 0; |
| 953 | uint32_t builtin_workgroup_size_id = 0; |
Hans-Kristian Arntzen | eaf7afe | 2019-05-09 12:15:45 +0200 | [diff] [blame] | 954 | uint32_t swizzle_buffer_id = 0; |
Hans-Kristian Arntzen | 7b9e0fb | 2019-05-27 11:59:29 +0200 | [diff] [blame] | 955 | uint32_t buffer_size_buffer_id = 0; |
Chip Davis | 7eecf5a | 2019-05-31 12:06:20 -0500 | [diff] [blame] | 956 | uint32_t view_mask_buffer_id = 0; |
Chip Davis | cb35934 | 2019-09-05 23:14:12 -0500 | [diff] [blame] | 957 | uint32_t dynamic_offsets_buffer_id = 0; |
Chip Davis | 884bc6d | 2020-07-22 15:25:10 -0600 | [diff] [blame] | 958 | uint32_t uint_type_id = 0; |
Bill Hollings | 17dab61 | 2021-04-13 19:01:20 -0400 | [diff] [blame] | 959 | uint32_t argument_buffer_padding_buffer_type_id = 0; |
| 960 | uint32_t argument_buffer_padding_image_type_id = 0; |
| 961 | uint32_t argument_buffer_padding_sampler_type_id = 0; |
Bill Hollings | 103aabf | 2016-04-06 17:42:27 -0400 | [diff] [blame] | 962 | |
Tomek Ponitka | 18f23c4 | 2020-07-22 18:37:17 +0200 | [diff] [blame] | 963 | bool does_shader_write_sample_mask = false; |
| 964 | |
Hans-Kristian Arntzen | edf247f | 2021-10-25 10:55:11 +0200 | [diff] [blame] | 965 | void cast_to_variable_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type) override; |
| 966 | void cast_from_variable_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type) override; |
Hans-Kristian Arntzen | 73d9da7 | 2019-01-17 12:21:16 +0100 | [diff] [blame] | 967 | void emit_store_statement(uint32_t lhs_expression, uint32_t rhs_expression) override; |
Hans-Kristian Arntzen | d94d20f | 2018-06-22 11:30:13 +0200 | [diff] [blame] | 968 | |
Chip Davis | c11374c | 2018-09-24 12:10:27 -0500 | [diff] [blame] | 969 | void analyze_sampled_image_usage(); |
Chip Davis | 4302c5a | 2018-09-22 19:36:11 -0500 | [diff] [blame] | 970 | |
Hans-Kristian Arntzen | 75ed738 | 2021-04-14 15:10:02 +0200 | [diff] [blame] | 971 | bool access_chain_needs_stage_io_builtin_translation(uint32_t base) override; |
Hans-Kristian Arntzen | fa5b206 | 2020-07-01 13:02:11 +0200 | [diff] [blame] | 972 | void prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type, spv::StorageClass storage, |
| 973 | bool &is_packed) override; |
Chip Davis | aca9b68 | 2020-11-02 20:56:46 -0600 | [diff] [blame] | 974 | void fix_up_interpolant_access_chain(const uint32_t *ops, uint32_t length); |
Chip Davis | e75add4 | 2019-02-05 18:13:26 -0600 | [diff] [blame] | 975 | bool emit_tessellation_access_chain(const uint32_t *ops, uint32_t length); |
Hans-Kristian Arntzen | 27d6d45 | 2019-10-25 16:41:02 +0200 | [diff] [blame] | 976 | bool emit_tessellation_io_load(uint32_t result_type, uint32_t id, uint32_t ptr); |
Chip Davis | 8095434 | 2019-02-20 00:33:46 -0600 | [diff] [blame] | 977 | bool is_out_of_bounds_tessellation_level(uint32_t id_lhs); |
Hans-Kristian Arntzen | 878c502 | 2019-02-14 09:28:17 +0100 | [diff] [blame] | 978 | |
Lukas Hermanns | 9f9276f | 2019-09-19 14:44:30 -0400 | [diff] [blame] | 979 | void ensure_builtin(spv::StorageClass storage, spv::BuiltIn builtin); |
Lukas Hermanns | 7ad0a84 | 2019-09-23 18:05:04 -0400 | [diff] [blame] | 980 | |
Hans-Kristian Arntzen | 314efdc | 2019-05-31 13:19:33 +0200 | [diff] [blame] | 981 | void mark_implicit_builtin(spv::StorageClass storage, spv::BuiltIn builtin, uint32_t id); |
| 982 | |
Hans-Kristian Arntzen | c76b99b | 2019-06-27 15:04:22 +0200 | [diff] [blame] | 983 | std::string convert_to_f32(const std::string &expr, uint32_t components); |
| 984 | |
Hans-Kristian Arntzen | a803e5a | 2018-03-09 15:25:25 +0100 | [diff] [blame] | 985 | Options msl_options; |
Bill Hollings | 8f6df77 | 2017-05-19 18:14:08 -0400 | [diff] [blame] | 986 | std::set<SPVFuncImpl> spv_function_implementations; |
Chip Davis | 688c5fc | 2020-02-20 21:38:28 -0600 | [diff] [blame] | 987 | // Must be ordered to ensure declarations are in a specific order. |
Bill Hollings | 548a23d | 2021-09-20 17:57:11 -0400 | [diff] [blame] | 988 | std::map<LocationComponentPair, MSLShaderInput> inputs_by_location; |
Chip Davis | 5281d99 | 2020-06-13 23:03:30 -0500 | [diff] [blame] | 989 | std::unordered_map<uint32_t, MSLShaderInput> inputs_by_builtin; |
Hans-Kristian Arntzen | aa271c1 | 2021-02-17 11:29:33 +0100 | [diff] [blame] | 990 | std::unordered_set<uint32_t> location_inputs_in_use; |
Hans-Kristian Arntzen | faf80b0 | 2021-04-09 18:55:10 +0200 | [diff] [blame] | 991 | std::unordered_set<uint32_t> location_inputs_in_use_fallback; |
Hans-Kristian Arntzen | b8033d7 | 2019-01-14 14:53:47 +0100 | [diff] [blame] | 992 | std::unordered_map<uint32_t, uint32_t> fragment_output_components; |
Hans-Kristian Arntzen | ce552f4 | 2021-02-17 12:21:21 +0100 | [diff] [blame] | 993 | std::unordered_map<uint32_t, uint32_t> builtin_to_automatic_input_location; |
Bill Hollings | 6371d9e | 2018-01-06 00:51:25 -0500 | [diff] [blame] | 994 | std::set<std::string> pragma_lines; |
Bill Hollings | 607b0d6 | 2018-02-11 16:52:57 -0500 | [diff] [blame] | 995 | std::set<std::string> typedef_lines; |
Hans-Kristian Arntzen | a489ba7 | 2019-04-02 11:19:03 +0200 | [diff] [blame] | 996 | SmallVector<uint32_t> vars_needing_early_declaration; |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 997 | |
Hans-Kristian Arntzen | 30bb197 | 2019-06-10 15:41:36 +0200 | [diff] [blame] | 998 | std::unordered_map<StageSetBinding, std::pair<MSLResourceBinding, bool>, InternalHasher> resource_bindings; |
Bill Hollings | 9866cf4 | 2021-04-16 09:05:15 -0400 | [diff] [blame] | 999 | std::unordered_map<StageSetBinding, uint32_t, InternalHasher> resource_arg_buff_idx_to_binding_number; |
Hans-Kristian Arntzen | 909040e | 2019-07-09 15:31:01 +0200 | [diff] [blame] | 1000 | |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 1001 | uint32_t next_metal_resource_index_buffer = 0; |
| 1002 | uint32_t next_metal_resource_index_texture = 0; |
| 1003 | uint32_t next_metal_resource_index_sampler = 0; |
Hans-Kristian Arntzen | 909040e | 2019-07-09 15:31:01 +0200 | [diff] [blame] | 1004 | // Intentionally uninitialized, works around MSVC 2013 bug. |
| 1005 | uint32_t next_metal_resource_ids[kMaxArgumentBuffers]; |
Hans-Kristian Arntzen | 9bbdccd | 2019-02-12 11:11:29 +0100 | [diff] [blame] | 1006 | |
Hans-Kristian Arntzen | 333980a | 2019-09-05 12:43:40 +0200 | [diff] [blame] | 1007 | VariableID stage_in_var_id = 0; |
| 1008 | VariableID stage_out_var_id = 0; |
| 1009 | VariableID patch_stage_in_var_id = 0; |
| 1010 | VariableID patch_stage_out_var_id = 0; |
| 1011 | VariableID stage_in_ptr_var_id = 0; |
| 1012 | VariableID stage_out_ptr_var_id = 0; |
Hans-Kristian Arntzen | 5e9c2d0 | 2021-04-09 14:59:45 +0200 | [diff] [blame] | 1013 | VariableID stage_out_masked_builtin_type_id = 0; |
Hans-Kristian Arntzen | 4ac1259 | 2019-10-24 12:41:37 +0200 | [diff] [blame] | 1014 | |
| 1015 | // Handle HLSL-style 0-based vertex/instance index. |
| 1016 | enum class TriState |
| 1017 | { |
Hans-Kristian Arntzen | 39bd5f1 | 2019-10-28 12:55:14 +0100 | [diff] [blame] | 1018 | Neutral, |
| 1019 | No, |
| 1020 | Yes |
Hans-Kristian Arntzen | 4ac1259 | 2019-10-24 12:41:37 +0200 | [diff] [blame] | 1021 | }; |
| 1022 | TriState needs_base_vertex_arg = TriState::Neutral; |
| 1023 | TriState needs_base_instance_arg = TriState::Neutral; |
| 1024 | |
Chip Davis | 4302c5a | 2018-09-22 19:36:11 -0500 | [diff] [blame] | 1025 | bool has_sampled_images = false; |
Lukas Hermanns | 50ac686 | 2019-09-18 14:03:54 -0400 | [diff] [blame] | 1026 | bool builtin_declaration = false; // Handle HLSL-style 0-based vertex/instance index. |
Hans-Kristian Arntzen | c9d4f9c | 2020-02-24 12:47:14 +0100 | [diff] [blame] | 1027 | |
| 1028 | bool is_using_builtin_array = false; // Force the use of C style array declaration. |
| 1029 | bool using_builtin_array() const; |
| 1030 | |
Bill Hollings | 0d6202e | 2018-07-26 16:40:32 -0400 | [diff] [blame] | 1031 | bool is_rasterization_disabled = false; |
Chip Davis | c51e5b7 | 2019-01-08 16:33:32 -0600 | [diff] [blame] | 1032 | bool capture_output_to_buffer = false; |
Hans-Kristian Arntzen | eaf7afe | 2019-05-09 12:15:45 +0200 | [diff] [blame] | 1033 | bool needs_swizzle_buffer_def = false; |
| 1034 | bool used_swizzle_buffer = false; |
Chip Davis | f3c0942 | 2019-02-22 12:11:17 -0600 | [diff] [blame] | 1035 | bool added_builtin_tess_level = false; |
Chip Davis | 9d94157 | 2019-05-15 16:03:30 -0500 | [diff] [blame] | 1036 | bool needs_subgroup_invocation_id = false; |
Chip Davis | 065b5bd | 2020-10-20 23:59:30 -0500 | [diff] [blame] | 1037 | bool needs_subgroup_size = false; |
Chip Davis | aca9b68 | 2020-11-02 20:56:46 -0600 | [diff] [blame] | 1038 | bool needs_sample_id = false; |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 1039 | std::string qual_pos_var_name; |
| 1040 | std::string stage_in_var_name = "in"; |
| 1041 | std::string stage_out_var_name = "out"; |
Chip Davis | e75add4 | 2019-02-05 18:13:26 -0600 | [diff] [blame] | 1042 | std::string patch_stage_in_var_name = "patchIn"; |
Chip Davis | eb89c3a | 2019-02-03 23:58:46 -0600 | [diff] [blame] | 1043 | std::string patch_stage_out_var_name = "patchOut"; |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 1044 | std::string sampler_name_suffix = "Smplr"; |
Chip Davis | 664df22 | 2019-01-13 17:31:50 -0600 | [diff] [blame] | 1045 | std::string swizzle_name_suffix = "Swzl"; |
Hans-Kristian Arntzen | 7b9e0fb | 2019-05-27 11:59:29 +0200 | [diff] [blame] | 1046 | std::string buffer_size_name_suffix = "BufferSize"; |
Chip Davis | 39dce88 | 2019-08-02 15:11:19 -0500 | [diff] [blame] | 1047 | std::string plane_name_suffix = "Plane"; |
Chip Davis | eb89c3a | 2019-02-03 23:58:46 -0600 | [diff] [blame] | 1048 | std::string input_wg_var_name = "gl_in"; |
Chip Davis | 688c5fc | 2020-02-20 21:38:28 -0600 | [diff] [blame] | 1049 | std::string input_buffer_var_name = "spvIn"; |
Chip Davis | c51e5b7 | 2019-01-08 16:33:32 -0600 | [diff] [blame] | 1050 | std::string output_buffer_var_name = "spvOut"; |
Chip Davis | eb89c3a | 2019-02-03 23:58:46 -0600 | [diff] [blame] | 1051 | std::string patch_output_buffer_var_name = "spvPatchOut"; |
| 1052 | std::string tess_factor_buffer_var_name = "spvTessLevel"; |
Chip Davis | 688c5fc | 2020-02-20 21:38:28 -0600 | [diff] [blame] | 1053 | std::string index_buffer_var_name = "spvIndices"; |
Bill Hollings | 1c18078 | 2017-11-05 21:34:42 -0500 | [diff] [blame] | 1054 | spv::Op previous_instruction_opcode = spv::OpNop; |
Bill Hollings | 103aabf | 2016-04-06 17:42:27 -0400 | [diff] [blame] | 1055 | |
Hans-Kristian Arntzen | 30bb197 | 2019-06-10 15:41:36 +0200 | [diff] [blame] | 1056 | // Must be ordered since declaration is in a specific order. |
| 1057 | std::map<uint32_t, MSLConstexprSampler> constexpr_samplers_by_id; |
| 1058 | std::unordered_map<SetBindingPair, MSLConstexprSampler, InternalHasher> constexpr_samplers_by_binding; |
| 1059 | const MSLConstexprSampler *find_constexpr_sampler(uint32_t id) const; |
| 1060 | |
Hans-Kristian Arntzen | 7b9e0fb | 2019-05-27 11:59:29 +0200 | [diff] [blame] | 1061 | std::unordered_set<uint32_t> buffers_requiring_array_length; |
Hans-Kristian Arntzen | a489ba7 | 2019-04-02 11:19:03 +0200 | [diff] [blame] | 1062 | SmallVector<uint32_t> buffer_arrays; |
Hans-Kristian Arntzen | 6edbf0c | 2019-10-24 11:30:20 +0200 | [diff] [blame] | 1063 | std::unordered_set<uint32_t> atomic_image_vars; // Emulate texture2D atomic operations |
Chip Davis | aca9b68 | 2020-11-02 20:56:46 -0600 | [diff] [blame] | 1064 | std::unordered_set<uint32_t> pull_model_inputs; |
Hans-Kristian Arntzen | df58deb | 2018-04-17 17:43:10 +0200 | [diff] [blame] | 1065 | |
Chip Davis | cb35934 | 2019-09-05 23:14:12 -0500 | [diff] [blame] | 1066 | // Must be ordered since array is in a specific order. |
| 1067 | std::map<SetBindingPair, std::pair<uint32_t, uint32_t>> buffers_requiring_dynamic_offset; |
| 1068 | |
Chip Davis | b29f83c | 2020-04-10 01:13:33 -0500 | [diff] [blame] | 1069 | SmallVector<uint32_t> disabled_frag_outputs; |
| 1070 | |
Chip Davis | fedbc35 | 2019-12-16 22:58:16 -0600 | [diff] [blame] | 1071 | std::unordered_set<SetBindingPair, InternalHasher> inline_uniform_blocks; |
Chip Davis | fedbc35 | 2019-12-16 22:58:16 -0600 | [diff] [blame] | 1072 | |
Hans-Kristian Arntzen | e47a77d | 2019-03-14 10:29:34 +0100 | [diff] [blame] | 1073 | uint32_t argument_buffer_ids[kMaxArgumentBuffers]; |
Hans-Kristian Arntzen | e2aadf8 | 2019-03-15 21:53:21 +0100 | [diff] [blame] | 1074 | uint32_t argument_buffer_discrete_mask = 0; |
Hans-Kristian Arntzen | 4bb673a | 2019-10-14 12:51:48 +0200 | [diff] [blame] | 1075 | uint32_t argument_buffer_device_storage_mask = 0; |
| 1076 | |
Hans-Kristian Arntzen | e47a77d | 2019-03-14 10:29:34 +0100 | [diff] [blame] | 1077 | void analyze_argument_buffers(); |
Hans-Kristian Arntzen | b3380ec | 2019-03-15 14:07:03 +0100 | [diff] [blame] | 1078 | bool descriptor_set_is_argument_buffer(uint32_t desc_set) const; |
Bill Hollings | 9866cf4 | 2021-04-16 09:05:15 -0400 | [diff] [blame] | 1079 | MSLResourceBinding &get_argument_buffer_resource(uint32_t desc_set, uint32_t arg_idx); |
Bill Hollings | b3bfe22 | 2021-04-18 17:34:55 -0400 | [diff] [blame] | 1080 | void add_argument_buffer_padding_buffer_type(SPIRType &struct_type, uint32_t &mbr_idx, uint32_t &arg_buff_index, MSLResourceBinding &rez_bind); |
| 1081 | void add_argument_buffer_padding_image_type(SPIRType &struct_type, uint32_t &mbr_idx, uint32_t &arg_buff_index, MSLResourceBinding &rez_bind); |
| 1082 | void add_argument_buffer_padding_sampler_type(SPIRType &struct_type, uint32_t &mbr_idx, uint32_t &arg_buff_index, MSLResourceBinding &rez_bind); |
Bill Hollings | daba0df | 2021-04-17 15:20:53 -0400 | [diff] [blame] | 1083 | void add_argument_buffer_padding_type(uint32_t mbr_type_id, SPIRType &struct_type, uint32_t &mbr_idx, uint32_t &arg_buff_index, uint32_t count); |
Hans-Kristian Arntzen | e47a77d | 2019-03-14 10:29:34 +0100 | [diff] [blame] | 1084 | |
Hans-Kristian Arntzen | b8033d7 | 2019-01-14 14:53:47 +0100 | [diff] [blame] | 1085 | uint32_t get_target_components_for_fragment_location(uint32_t location) const; |
Hans-Kristian Arntzen | d573a95 | 2020-07-01 11:42:58 +0200 | [diff] [blame] | 1086 | uint32_t build_extended_vector_type(uint32_t type_id, uint32_t components, |
| 1087 | SPIRType::BaseType basetype = SPIRType::Unknown); |
Chip Davis | aca9b68 | 2020-11-02 20:56:46 -0600 | [diff] [blame] | 1088 | uint32_t build_msl_interpolant_type(uint32_t type_id, bool is_noperspective); |
Hans-Kristian Arntzen | b8033d7 | 2019-01-14 14:53:47 +0100 | [diff] [blame] | 1089 | |
Hans-Kristian Arntzen | 23db744 | 2019-04-09 12:28:46 +0200 | [diff] [blame] | 1090 | bool suppress_missing_prototypes = false; |
| 1091 | |
Chip Davis | 39dce88 | 2019-08-02 15:11:19 -0500 | [diff] [blame] | 1092 | void add_spv_func_and_recompile(SPVFuncImpl spv_func); |
| 1093 | |
Hans-Kristian Arntzen | c3bd136 | 2020-01-16 11:07:30 +0100 | [diff] [blame] | 1094 | void activate_argument_buffer_resources(); |
| 1095 | |
Hans-Kristian Arntzen | 6ef47d6 | 2020-04-27 11:23:24 +0200 | [diff] [blame] | 1096 | bool type_is_msl_framebuffer_fetch(const SPIRType &type) const; |
Hans-Kristian Arntzen | 97796e0 | 2021-02-26 12:50:24 +0100 | [diff] [blame] | 1097 | bool type_is_pointer(const SPIRType &type) const; |
| 1098 | bool type_is_pointer_to_pointer(const SPIRType &type) const; |
Hans-Kristian Arntzen | 893a011 | 2021-01-07 15:00:45 +0100 | [diff] [blame] | 1099 | bool is_supported_argument_buffer_type(const SPIRType &type) const; |
Hans-Kristian Arntzen | 6ef47d6 | 2020-04-27 11:23:24 +0200 | [diff] [blame] | 1100 | |
Hans-Kristian Arntzen | 46c48ee | 2021-04-08 11:47:35 +0200 | [diff] [blame] | 1101 | bool variable_storage_requires_stage_io(spv::StorageClass storage) const; |
| 1102 | |
Bill Hollings | ebb5098 | 2021-07-13 21:22:13 -0400 | [diff] [blame] | 1103 | bool has_additional_fixed_sample_mask() const { return msl_options.additional_fixed_sample_mask != 0xffffffff; } |
| 1104 | std::string additional_fixed_sample_mask_str() const; |
| 1105 | |
Bill Hollings | 4c198bb | 2017-01-20 11:24:44 -0500 | [diff] [blame] | 1106 | // OpcodeHandler that handles several MSL preprocessing operations. |
Bill Hollings | 2d0d328 | 2017-01-20 11:33:59 -0500 | [diff] [blame] | 1107 | struct OpCodePreprocessor : OpcodeHandler |
Bill Hollings | aca1b55 | 2016-12-04 12:32:58 -0500 | [diff] [blame] | 1108 | { |
Bill Hollings | 2d0d328 | 2017-01-20 11:33:59 -0500 | [diff] [blame] | 1109 | OpCodePreprocessor(CompilerMSL &compiler_) |
Bill Hollings | 7d38f18 | 2016-12-21 16:31:13 -0500 | [diff] [blame] | 1110 | : compiler(compiler_) |
Bill Hollings | 7d38f18 | 2016-12-21 16:31:13 -0500 | [diff] [blame] | 1111 | { |
| 1112 | } |
| 1113 | |
| 1114 | bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override; |
Bill Hollings | 1c18078 | 2017-11-05 21:34:42 -0500 | [diff] [blame] | 1115 | CompilerMSL::SPVFuncImpl get_spv_func_impl(spv::Op opcode, const uint32_t *args); |
Bill Hollings | c3d74e1 | 2018-07-27 16:53:36 -0400 | [diff] [blame] | 1116 | void check_resource_write(uint32_t var_id); |
Bill Hollings | 7d38f18 | 2016-12-21 16:31:13 -0500 | [diff] [blame] | 1117 | |
Bill Hollings | 2d0d328 | 2017-01-20 11:33:59 -0500 | [diff] [blame] | 1118 | CompilerMSL &compiler; |
Bill Hollings | 1c18078 | 2017-11-05 21:34:42 -0500 | [diff] [blame] | 1119 | std::unordered_map<uint32_t, uint32_t> result_types; |
Hans-Kristian Arntzen | 6edbf0c | 2019-10-24 11:30:20 +0200 | [diff] [blame] | 1120 | std::unordered_map<uint32_t, uint32_t> image_pointers; // Emulate texture2D atomic operations |
Bill Hollings | 2d0d328 | 2017-01-20 11:33:59 -0500 | [diff] [blame] | 1121 | bool suppress_missing_prototypes = false; |
Bill Hollings | 8f6df77 | 2017-05-19 18:14:08 -0400 | [diff] [blame] | 1122 | bool uses_atomics = false; |
Bill Hollings | c3d74e1 | 2018-07-27 16:53:36 -0400 | [diff] [blame] | 1123 | bool uses_resource_write = false; |
Chip Davis | 9d94157 | 2019-05-15 16:03:30 -0500 | [diff] [blame] | 1124 | bool needs_subgroup_invocation_id = false; |
Chip Davis | 065b5bd | 2020-10-20 23:59:30 -0500 | [diff] [blame] | 1125 | bool needs_subgroup_size = false; |
Chip Davis | aca9b68 | 2020-11-02 20:56:46 -0600 | [diff] [blame] | 1126 | bool needs_sample_id = false; |
Bill Hollings | aca1b55 | 2016-12-04 12:32:58 -0500 | [diff] [blame] | 1127 | }; |
| 1128 | |
Chip Davis | 4302c5a | 2018-09-22 19:36:11 -0500 | [diff] [blame] | 1129 | // OpcodeHandler that scans for uses of sampled images |
| 1130 | struct SampledImageScanner : OpcodeHandler |
| 1131 | { |
| 1132 | SampledImageScanner(CompilerMSL &compiler_) |
| 1133 | : compiler(compiler_) |
| 1134 | { |
| 1135 | } |
| 1136 | |
| 1137 | bool handle(spv::Op opcode, const uint32_t *args, uint32_t) override; |
Chip Davis | 4302c5a | 2018-09-22 19:36:11 -0500 | [diff] [blame] | 1138 | |
| 1139 | CompilerMSL &compiler; |
| 1140 | }; |
| 1141 | |
Bill Hollings | 7d38f18 | 2016-12-21 16:31:13 -0500 | [diff] [blame] | 1142 | // Sorts the members of a SPIRType and associated Meta info based on a settable sorting |
| 1143 | // aspect, which defines which aspect of the struct members will be used to sort them. |
| 1144 | // Regardless of the sorting aspect, built-in members always appear at the end of the struct. |
| 1145 | struct MemberSorter |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 1146 | { |
Bill Hollings | 7d38f18 | 2016-12-21 16:31:13 -0500 | [diff] [blame] | 1147 | enum SortAspect |
| 1148 | { |
Hans-Kristian Arntzen | 9a144bb | 2021-03-26 11:00:35 +0100 | [diff] [blame] | 1149 | LocationThenBuiltInType, |
| 1150 | Offset |
Bill Hollings | 7d38f18 | 2016-12-21 16:31:13 -0500 | [diff] [blame] | 1151 | }; |
| 1152 | |
| 1153 | void sort(); |
| 1154 | bool operator()(uint32_t mbr_idx1, uint32_t mbr_idx2); |
Bill Hollings | 484931d | 2017-02-28 21:44:36 -0500 | [diff] [blame] | 1155 | MemberSorter(SPIRType &t, Meta &m, SortAspect sa); |
| 1156 | |
Bill Hollings | 7d38f18 | 2016-12-21 16:31:13 -0500 | [diff] [blame] | 1157 | SPIRType &type; |
| 1158 | Meta &meta; |
| 1159 | SortAspect sort_aspect; |
| 1160 | }; |
Hans-Kristian Arntzen | 4b8ed53 | 2016-05-05 09:33:18 +0200 | [diff] [blame] | 1161 | }; |
Hans-Kristian Arntzen | a489ba7 | 2019-04-02 11:19:03 +0200 | [diff] [blame] | 1162 | } // namespace SPIRV_CROSS_NAMESPACE |
Bill Hollings | 103aabf | 2016-04-06 17:42:27 -0400 | [diff] [blame] | 1163 | |
| 1164 | #endif |