Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 1 | // Copyright 2021 The Tint Authors. |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | #include "src/tint/transform/multiplanar_external_texture.h" |
| 16 | |
| 17 | #include <string> |
| 18 | #include <vector> |
| 19 | |
| 20 | #include "src/tint/ast/function.h" |
| 21 | #include "src/tint/program_builder.h" |
| 22 | #include "src/tint/sem/call.h" |
| 23 | #include "src/tint/sem/function.h" |
| 24 | #include "src/tint/sem/variable.h" |
dan sinclair | 3cbf3fc | 2023-01-21 19:16:15 +0000 | [diff] [blame] | 25 | #include "src/tint/type/texture_dimension.h" |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 26 | |
| 27 | TINT_INSTANTIATE_TYPEINFO(tint::transform::MultiplanarExternalTexture); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 28 | TINT_INSTANTIATE_TYPEINFO(tint::transform::MultiplanarExternalTexture::NewBindingPoints); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 29 | |
Ben Clayton | 0ce9ab0 | 2022-05-05 20:23:40 +0000 | [diff] [blame] | 30 | using namespace tint::number_suffixes; // NOLINT |
| 31 | |
dan sinclair | b5599d3 | 2022-04-07 16:55:14 +0000 | [diff] [blame] | 32 | namespace tint::transform { |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 33 | namespace { |
| 34 | |
Ben Clayton | c6b3814 | 2022-11-03 08:41:19 +0000 | [diff] [blame] | 35 | bool ShouldRun(const Program* program) { |
| 36 | for (auto* node : program->ASTNodes().Objects()) { |
Ben Clayton | 971318f | 2023-02-14 13:52:43 +0000 | [diff] [blame] | 37 | if (auto* expr = node->As<ast::Expression>()) { |
| 38 | if (Is<type::ExternalTexture>(program->TypeOf(expr))) { |
Ben Clayton | c6b3814 | 2022-11-03 08:41:19 +0000 | [diff] [blame] | 39 | return true; |
| 40 | } |
| 41 | } |
| 42 | } |
| 43 | return false; |
| 44 | } |
| 45 | |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 46 | /// This struct stores symbols for new bindings created as a result of transforming a |
| 47 | /// texture_external instance. |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 48 | struct NewBindingSymbols { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 49 | Symbol params; |
| 50 | Symbol plane_0; |
| 51 | Symbol plane_1; |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 52 | }; |
| 53 | } // namespace |
| 54 | |
Ben Clayton | c6b3814 | 2022-11-03 08:41:19 +0000 | [diff] [blame] | 55 | /// PIMPL state for the transform |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 56 | struct MultiplanarExternalTexture::State { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 57 | /// The clone context. |
| 58 | CloneContext& ctx; |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 59 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 60 | /// ProgramBuilder for the context |
| 61 | ProgramBuilder& b; |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 62 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 63 | /// Destination binding locations for the expanded texture_external provided |
| 64 | /// as input into the transform. |
| 65 | const NewBindingPoints* new_binding_points; |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 66 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 67 | /// Symbol for the GammaTransferParams |
| 68 | Symbol gamma_transfer_struct_sym; |
Brandon Jones | 41cbf02 | 2022-04-29 21:00:14 +0000 | [diff] [blame] | 69 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 70 | /// Symbol for the ExternalTextureParams struct |
| 71 | Symbol params_struct_sym; |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 72 | |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 73 | /// Symbol for the textureLoadExternal functions |
| 74 | utils::Hashmap<const sem::CallTarget*, Symbol, 2> texture_load_external_fns; |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 75 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 76 | /// Symbol for the textureSampleExternal function |
| 77 | Symbol texture_sample_external_sym; |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 78 | |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 79 | /// Symbol for the textureSampleExternalDEPRECATED function |
| 80 | Symbol texture_sample_external_deprecated_sym; |
| 81 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 82 | /// Symbol for the gammaCorrection function |
| 83 | Symbol gamma_correction_sym; |
Brandon Jones | 41cbf02 | 2022-04-29 21:00:14 +0000 | [diff] [blame] | 84 | |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 85 | /// Storage for new bindings that have been created corresponding to an original |
| 86 | /// texture_external binding. |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 87 | std::unordered_map<const sem::Variable*, NewBindingSymbols> new_binding_symbols; |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 88 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 89 | /// Constructor |
| 90 | /// @param context the clone |
| 91 | /// @param newBindingPoints the input destination binding locations for the |
| 92 | /// expanded texture_external |
| 93 | State(CloneContext& context, const NewBindingPoints* newBindingPoints) |
| 94 | : ctx(context), b(*context.dst), new_binding_points(newBindingPoints) {} |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 95 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 96 | /// Processes the module |
| 97 | void Process() { |
| 98 | auto& sem = ctx.src->Sem(); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 99 | |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 100 | // For each texture_external binding, we replace it with a texture_2d<f32> binding and |
| 101 | // create two additional bindings (one texture_2d<f32> to represent the secondary plane and |
| 102 | // one uniform buffer for the ExternalTextureParams struct). |
Ben Clayton | dcdf66e | 2022-06-17 12:48:51 +0000 | [diff] [blame] | 103 | for (auto* global : ctx.src->AST().GlobalVariables()) { |
dan sinclair | acdf6e1 | 2022-08-24 15:47:25 +0000 | [diff] [blame] | 104 | auto* sem_var = sem.Get<sem::GlobalVariable>(global); |
dan sinclair | 4595fb7 | 2022-12-08 14:14:10 +0000 | [diff] [blame] | 105 | if (!sem_var->Type()->UnwrapRef()->Is<type::ExternalTexture>()) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 106 | continue; |
| 107 | } |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 108 | |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 109 | // If the attributes are empty, then this must be a texture_external passed as a |
| 110 | // function parameter. These variables are transformed elsewhere. |
Ben Clayton | 783b169 | 2022-08-02 17:03:35 +0000 | [diff] [blame] | 111 | if (global->attributes.IsEmpty()) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 112 | continue; |
| 113 | } |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 114 | |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 115 | // If we find a texture_external binding, we know we must emit the ExternalTextureParams |
| 116 | // struct. |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 117 | if (!params_struct_sym.IsValid()) { |
| 118 | createExtTexParamsStructs(); |
| 119 | } |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 120 | |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 121 | // The binding points for the newly introduced bindings must have been provided to this |
| 122 | // transform. We fetch the new binding points by providing the original texture_external |
| 123 | // binding points into the passed map. |
dan sinclair | eebbdef | 2023-03-08 02:48:42 +0000 | [diff] [blame] | 124 | sem::BindingPoint bp = sem_var->BindingPoint(); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 125 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 126 | BindingsMap::const_iterator it = new_binding_points->bindings_map.find(bp); |
| 127 | if (it == new_binding_points->bindings_map.end()) { |
| 128 | b.Diagnostics().add_error( |
| 129 | diag::System::Transform, |
| 130 | "missing new binding points for texture_external at binding {" + |
| 131 | std::to_string(bp.group) + "," + std::to_string(bp.binding) + "}"); |
| 132 | continue; |
| 133 | } |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 134 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 135 | BindingPoints bps = it->second; |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 136 | |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 137 | // Symbols for the newly created bindings must be saved so they can be passed as |
| 138 | // parameters later. These are placed in a map and keyed by the source symbol associated |
| 139 | // with the texture_external binding that corresponds with the new destination bindings. |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 140 | // NewBindingSymbols new_binding_syms; |
| 141 | auto& syms = new_binding_symbols[sem_var]; |
Ben Clayton | 651d9e2 | 2023-02-09 10:34:14 +0000 | [diff] [blame] | 142 | syms.plane_0 = ctx.Clone(global->name->symbol); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 143 | syms.plane_1 = b.Symbols().New("ext_tex_plane_1"); |
dan sinclair | 3cbf3fc | 2023-01-21 19:16:15 +0000 | [diff] [blame] | 144 | b.GlobalVar(syms.plane_1, b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32()), |
dan sinclair | be4c9f4 | 2022-08-29 21:22:31 +0000 | [diff] [blame] | 145 | b.Group(AInt(bps.plane_1.group)), b.Binding(AInt(bps.plane_1.binding))); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 146 | syms.params = b.Symbols().New("ext_tex_params"); |
dan sinclair | 2a65163 | 2023-02-19 04:03:55 +0000 | [diff] [blame] | 147 | b.GlobalVar(syms.params, b.ty("ExternalTextureParams"), builtin::AddressSpace::kUniform, |
Ben Clayton | 2117f80 | 2023-02-03 14:01:43 +0000 | [diff] [blame] | 148 | b.Group(AInt(bps.params.group)), b.Binding(AInt(bps.params.binding))); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 149 | |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 150 | // Replace the original texture_external binding with a texture_2d<f32> binding. |
Ben Clayton | 783b169 | 2022-08-02 17:03:35 +0000 | [diff] [blame] | 151 | auto cloned_attributes = ctx.Clone(global->attributes); |
dan sinclair | 6e77b47 | 2022-10-20 13:38:28 +0000 | [diff] [blame] | 152 | const ast::Expression* cloned_initializer = ctx.Clone(global->initializer); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 153 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 154 | auto* replacement = |
dan sinclair | 3cbf3fc | 2023-01-21 19:16:15 +0000 | [diff] [blame] | 155 | b.Var(syms.plane_0, b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32()), |
dan sinclair | 6e77b47 | 2022-10-20 13:38:28 +0000 | [diff] [blame] | 156 | cloned_initializer, cloned_attributes); |
Ben Clayton | dcdf66e | 2022-06-17 12:48:51 +0000 | [diff] [blame] | 157 | ctx.Replace(global, replacement); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 158 | } |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 159 | |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 160 | // We must update all the texture_external parameters for user declared functions. |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 161 | for (auto* fn : ctx.src->AST().Functions()) { |
| 162 | for (const ast::Variable* param : fn->params) { |
| 163 | if (auto* sem_var = sem.Get(param)) { |
dan sinclair | 4595fb7 | 2022-12-08 14:14:10 +0000 | [diff] [blame] | 164 | if (!sem_var->Type()->UnwrapRef()->Is<type::ExternalTexture>()) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 165 | continue; |
| 166 | } |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 167 | // If we find a texture_external, we must ensure the ExternalTextureParams |
| 168 | // struct exists. |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 169 | if (!params_struct_sym.IsValid()) { |
| 170 | createExtTexParamsStructs(); |
| 171 | } |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 172 | // When a texture_external is found, we insert all components the |
| 173 | // texture_external into the parameter list. We must also place the new symbols |
| 174 | // into the transform state so they can be used when transforming function |
| 175 | // calls. |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 176 | auto& syms = new_binding_symbols[sem_var]; |
Ben Clayton | 651d9e2 | 2023-02-09 10:34:14 +0000 | [diff] [blame] | 177 | syms.plane_0 = ctx.Clone(param->name->symbol); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 178 | syms.plane_1 = b.Symbols().New("ext_tex_plane_1"); |
| 179 | syms.params = b.Symbols().New("ext_tex_params"); |
| 180 | auto tex2d_f32 = [&] { |
dan sinclair | 3cbf3fc | 2023-01-21 19:16:15 +0000 | [diff] [blame] | 181 | return b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32()); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 182 | }; |
| 183 | ctx.Replace(param, b.Param(syms.plane_0, tex2d_f32())); |
| 184 | ctx.InsertAfter(fn->params, param, b.Param(syms.plane_1, tex2d_f32())); |
| 185 | ctx.InsertAfter(fn->params, param, |
Ben Clayton | 2117f80 | 2023-02-03 14:01:43 +0000 | [diff] [blame] | 186 | b.Param(syms.params, b.ty(params_struct_sym))); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 187 | } |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 188 | } |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 189 | } |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 190 | |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 191 | // Transform the external texture builtin calls into calls to the external texture |
| 192 | // functions. |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 193 | ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::CallExpression* { |
Ben Clayton | e5a67ac | 2022-05-19 21:50:59 +0000 | [diff] [blame] | 194 | auto* call = sem.Get(expr)->UnwrapMaterialize()->As<sem::Call>(); |
| 195 | auto* builtin = call->Target()->As<sem::Builtin>(); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 196 | |
Ben Clayton | 958a464 | 2022-07-26 07:55:24 +0000 | [diff] [blame] | 197 | if (builtin && !builtin->Parameters().IsEmpty() && |
dan sinclair | 4595fb7 | 2022-12-08 14:14:10 +0000 | [diff] [blame] | 198 | builtin->Parameters()[0]->Type()->Is<type::ExternalTexture>() && |
dan sinclair | 9543f74 | 2023-03-09 01:20:16 +0000 | [diff] [blame] | 199 | builtin->Type() != builtin::Function::kTextureDimensions) { |
Ben Clayton | 2f9a988 | 2022-12-17 02:20:04 +0000 | [diff] [blame] | 200 | if (auto* var_user = |
Ben Clayton | 0b4a2f1 | 2023-02-05 22:59:40 +0000 | [diff] [blame] | 201 | sem.GetVal(expr->args[0])->UnwrapLoad()->As<sem::VariableUser>()) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 202 | auto it = new_binding_symbols.find(var_user->Variable()); |
| 203 | if (it == new_binding_symbols.end()) { |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 204 | // If valid new binding locations were not provided earlier, we would have |
| 205 | // been unable to create these symbols. An error message was emitted |
| 206 | // earlier, so just return early to avoid internal compiler errors and |
| 207 | // retain a clean error message. |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 208 | return nullptr; |
| 209 | } |
| 210 | auto& syms = it->second; |
| 211 | |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 212 | switch (builtin->Type()) { |
dan sinclair | 9543f74 | 2023-03-09 01:20:16 +0000 | [diff] [blame] | 213 | case builtin::Function::kTextureLoad: |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 214 | return createTextureLoad(call, syms); |
dan sinclair | 9543f74 | 2023-03-09 01:20:16 +0000 | [diff] [blame] | 215 | case builtin::Function::kTextureSampleBaseClampToEdge: |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 216 | return createTextureSampleBaseClampToEdge(expr, syms); |
| 217 | default: |
| 218 | break; |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 219 | } |
| 220 | } |
Ben Clayton | e5a67ac | 2022-05-19 21:50:59 +0000 | [diff] [blame] | 221 | } else if (call->Target()->Is<sem::Function>()) { |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 222 | // The call expression may be to a user-defined function that contains a |
| 223 | // texture_external parameter. These need to be expanded out to multiple plane |
| 224 | // textures and the texture parameters structure. |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 225 | for (auto* arg : expr->args) { |
Ben Clayton | 0b4a2f1 | 2023-02-05 22:59:40 +0000 | [diff] [blame] | 226 | if (auto* var_user = sem.GetVal(arg)->UnwrapLoad()->As<sem::VariableUser>()) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 227 | // Check if a parameter is a texture_external by trying to find |
| 228 | // it in the transform state. |
| 229 | auto it = new_binding_symbols.find(var_user->Variable()); |
| 230 | if (it != new_binding_symbols.end()) { |
| 231 | auto& syms = it->second; |
| 232 | // When we find a texture_external, we must unpack it into its |
| 233 | // components. |
| 234 | ctx.Replace(arg, b.Expr(syms.plane_0)); |
| 235 | ctx.InsertAfter(expr->args, arg, b.Expr(syms.plane_1)); |
| 236 | ctx.InsertAfter(expr->args, arg, b.Expr(syms.params)); |
| 237 | } |
| 238 | } |
| 239 | } |
| 240 | } |
| 241 | |
| 242 | return nullptr; |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 243 | }); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 244 | } |
| 245 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 246 | /// Creates the parameter structs associated with the transform. |
| 247 | void createExtTexParamsStructs() { |
| 248 | // Create GammaTransferParams struct. |
Ben Clayton | 783b169 | 2022-08-02 17:03:35 +0000 | [diff] [blame] | 249 | utils::Vector gamma_transfer_member_list{ |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 250 | b.Member("G", b.ty.f32()), b.Member("A", b.ty.f32()), b.Member("B", b.ty.f32()), |
| 251 | b.Member("C", b.ty.f32()), b.Member("D", b.ty.f32()), b.Member("E", b.ty.f32()), |
| 252 | b.Member("F", b.ty.f32()), b.Member("padding", b.ty.u32())}; |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 253 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 254 | gamma_transfer_struct_sym = b.Symbols().New("GammaTransferParams"); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 255 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 256 | b.Structure(gamma_transfer_struct_sym, gamma_transfer_member_list); |
| 257 | |
| 258 | // Create ExternalTextureParams struct. |
Ben Clayton | 783b169 | 2022-08-02 17:03:35 +0000 | [diff] [blame] | 259 | utils::Vector ext_tex_params_member_list{ |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 260 | b.Member("numPlanes", b.ty.u32()), |
jchen10 | ef62b58 | 2022-06-22 03:14:26 +0000 | [diff] [blame] | 261 | b.Member("doYuvToRgbConversionOnly", b.ty.u32()), |
Brandon Jones | 85ceb08 | 2022-11-30 21:32:26 +0000 | [diff] [blame] | 262 | b.Member("yuvToRgbConversionMatrix", b.ty.mat3x4<f32>()), |
Ben Clayton | 2117f80 | 2023-02-03 14:01:43 +0000 | [diff] [blame] | 263 | b.Member("gammaDecodeParams", b.ty("GammaTransferParams")), |
| 264 | b.Member("gammaEncodeParams", b.ty("GammaTransferParams")), |
Brandon Jones | 85ceb08 | 2022-11-30 21:32:26 +0000 | [diff] [blame] | 265 | b.Member("gamutConversionMatrix", b.ty.mat3x3<f32>()), |
Ben Clayton | 971318f | 2023-02-14 13:52:43 +0000 | [diff] [blame] | 266 | b.Member("coordTransformationMatrix", b.ty.mat3x2<f32>()), |
| 267 | }; |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 268 | |
| 269 | params_struct_sym = b.Symbols().New("ExternalTextureParams"); |
| 270 | |
| 271 | b.Structure(params_struct_sym, ext_tex_params_member_list); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 272 | } |
| 273 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 274 | /// Creates the gammaCorrection function if needed and returns a call |
| 275 | /// expression to it. |
| 276 | void createGammaCorrectionFn() { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 277 | gamma_correction_sym = b.Symbols().New("gammaCorrection"); |
| 278 | |
Ben Clayton | 7164b97 | 2022-06-15 10:02:37 +0000 | [diff] [blame] | 279 | b.Func( |
| 280 | gamma_correction_sym, |
Ben Clayton | 783b169 | 2022-08-02 17:03:35 +0000 | [diff] [blame] | 281 | utils::Vector{ |
Ben Clayton | 7164b97 | 2022-06-15 10:02:37 +0000 | [diff] [blame] | 282 | b.Param("v", b.ty.vec3<f32>()), |
Ben Clayton | 2117f80 | 2023-02-03 14:01:43 +0000 | [diff] [blame] | 283 | b.Param("params", b.ty(gamma_transfer_struct_sym)), |
Ben Clayton | 7164b97 | 2022-06-15 10:02:37 +0000 | [diff] [blame] | 284 | }, |
| 285 | b.ty.vec3<f32>(), |
Ben Clayton | 783b169 | 2022-08-02 17:03:35 +0000 | [diff] [blame] | 286 | utils::Vector{ |
Ben Clayton | 7164b97 | 2022-06-15 10:02:37 +0000 | [diff] [blame] | 287 | // let cond = abs(v) < vec3(params.D); |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 288 | b.Decl(b.Let("cond", b.LessThan(b.Call("abs", "v"), |
| 289 | b.vec3<f32>(b.MemberAccessor("params", "D"))))), |
Ben Clayton | 7164b97 | 2022-06-15 10:02:37 +0000 | [diff] [blame] | 290 | // let t = sign(v) * ((params.C * abs(v)) + params.F); |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 291 | b.Decl(b.Let("t", |
Ben Clayton | 7164b97 | 2022-06-15 10:02:37 +0000 | [diff] [blame] | 292 | b.Mul(b.Call("sign", "v"), |
| 293 | b.Add(b.Mul(b.MemberAccessor("params", "C"), b.Call("abs", "v")), |
| 294 | b.MemberAccessor("params", "F"))))), |
| 295 | // let f = (sign(v) * pow(((params.A * abs(v)) + params.B), |
| 296 | // vec3(params.G))) + params.E; |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 297 | b.Decl(b.Let("f", b.Mul(b.Call("sign", "v"), |
| 298 | b.Add(b.Call("pow", |
| 299 | b.Add(b.Mul(b.MemberAccessor("params", "A"), |
| 300 | b.Call("abs", "v")), |
| 301 | b.MemberAccessor("params", "B")), |
| 302 | b.vec3<f32>(b.MemberAccessor("params", "G"))), |
| 303 | b.MemberAccessor("params", "E"))))), |
Ben Clayton | 7164b97 | 2022-06-15 10:02:37 +0000 | [diff] [blame] | 304 | // return select(f, t, cond); |
| 305 | b.Return(b.Call("select", "f", "t", "cond")), |
| 306 | }); |
Brandon Jones | 41cbf02 | 2022-04-29 21:00:14 +0000 | [diff] [blame] | 307 | } |
| 308 | |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 309 | /// Constructs a StatementList containing all the statements making up the body of the texture |
| 310 | /// builtin function. |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 311 | /// @param call_type determines which function body to generate |
| 312 | /// @returns a statement list that makes of the body of the chosen function |
dan sinclair | 9543f74 | 2023-03-09 01:20:16 +0000 | [diff] [blame] | 313 | auto buildTextureBuiltinBody(builtin::Function call_type) { |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 314 | utils::Vector<const ast::Statement*, 16> stmts; |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 315 | const ast::CallExpression* single_plane_call = nullptr; |
| 316 | const ast::CallExpression* plane_0_call = nullptr; |
| 317 | const ast::CallExpression* plane_1_call = nullptr; |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 318 | switch (call_type) { |
dan sinclair | 9543f74 | 2023-03-09 01:20:16 +0000 | [diff] [blame] | 319 | case builtin::Function::kTextureSampleBaseClampToEdge: |
Ben Clayton | be367b7 | 2023-01-04 12:29:56 +0000 | [diff] [blame] | 320 | stmts.Push(b.Decl(b.Let( |
| 321 | "modifiedCoords", b.Mul(b.MemberAccessor("params", "coordTransformationMatrix"), |
| 322 | b.vec3<f32>("coord", 1_a))))); |
Brandon Jones | 85ceb08 | 2022-11-30 21:32:26 +0000 | [diff] [blame] | 323 | |
Ben Clayton | 01ac21c | 2023-02-07 16:14:25 +0000 | [diff] [blame] | 324 | stmts.Push(b.Decl( |
| 325 | b.Let("plane0_dims", |
| 326 | b.Call(b.ty.vec2<f32>(), b.Call("textureDimensions", "plane0", 0_a))))); |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 327 | stmts.Push( |
| 328 | b.Decl(b.Let("plane0_half_texel", b.Div(b.vec2<f32>(0.5_a), "plane0_dims")))); |
Brandon Jones | 85ceb08 | 2022-11-30 21:32:26 +0000 | [diff] [blame] | 329 | stmts.Push(b.Decl( |
| 330 | b.Let("plane0_clamped", b.Call("clamp", "modifiedCoords", "plane0_half_texel", |
| 331 | b.Sub(1_a, "plane0_half_texel"))))); |
Ben Clayton | 01ac21c | 2023-02-07 16:14:25 +0000 | [diff] [blame] | 332 | stmts.Push(b.Decl( |
| 333 | b.Let("plane1_dims", |
| 334 | b.Call(b.ty.vec2<f32>(), b.Call("textureDimensions", "plane1", 0_a))))); |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 335 | stmts.Push( |
| 336 | b.Decl(b.Let("plane1_half_texel", b.Div(b.vec2<f32>(0.5_a), "plane1_dims")))); |
Brandon Jones | 85ceb08 | 2022-11-30 21:32:26 +0000 | [diff] [blame] | 337 | stmts.Push(b.Decl( |
| 338 | b.Let("plane1_clamped", b.Call("clamp", "modifiedCoords", "plane1_half_texel", |
| 339 | b.Sub(1_a, "plane1_half_texel"))))); |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 340 | |
| 341 | // textureSampleLevel(plane0, smp, plane0_clamped, 0.0); |
| 342 | single_plane_call = |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 343 | b.Call("textureSampleLevel", "plane0", "smp", "plane0_clamped", 0_a); |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 344 | // textureSampleLevel(plane0, smp, plane0_clamped, 0.0); |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 345 | plane_0_call = b.Call("textureSampleLevel", "plane0", "smp", "plane0_clamped", 0_a); |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 346 | // textureSampleLevel(plane1, smp, plane1_clamped, 0.0); |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 347 | plane_1_call = b.Call("textureSampleLevel", "plane1", "smp", "plane1_clamped", 0_a); |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 348 | break; |
dan sinclair | 9543f74 | 2023-03-09 01:20:16 +0000 | [diff] [blame] | 349 | case builtin::Function::kTextureLoad: |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 350 | // textureLoad(plane0, coord, 0); |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 351 | single_plane_call = b.Call("textureLoad", "plane0", "coord", 0_a); |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 352 | // textureLoad(plane0, coord, 0); |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 353 | plane_0_call = b.Call("textureLoad", "plane0", "coord", 0_a); |
jchen10 | 39b7330 | 2023-02-23 13:03:52 +0000 | [diff] [blame] | 354 | // let coord1 = coord >> 1; |
| 355 | stmts.Push(b.Decl(b.Let("coord1", b.Shr("coord", b.vec2<u32>(1_a))))); |
| 356 | // textureLoad(plane1, coord1, 0); |
| 357 | plane_1_call = b.Call("textureLoad", "plane1", "coord1", 0_a); |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 358 | break; |
| 359 | default: |
| 360 | TINT_ICE(Transform, b.Diagnostics()) << "unhandled builtin: " << call_type; |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 361 | } |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 362 | |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 363 | // var color: vec3<f32>; |
| 364 | stmts.Push(b.Decl(b.Var("color", b.ty.vec3(b.ty.f32())))); |
| 365 | |
| 366 | // if ((params.numPlanes == 1u)) |
| 367 | stmts.Push( |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 368 | b.If(b.Equal(b.MemberAccessor("params", "numPlanes"), b.Expr(1_a)), |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 369 | b.Block( |
| 370 | // color = textureLoad(plane0, coord, 0).rgb; |
| 371 | b.Assign("color", b.MemberAccessor(single_plane_call, "rgb"))), |
James Price | 8aff0ed | 2022-05-02 14:53:36 +0000 | [diff] [blame] | 372 | b.Else(b.Block( |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 373 | // color = vec4<f32>(plane_0_call.r, plane_1_call.rg, 1.0) * |
| 374 | // params.yuvToRgbConversionMatrix; |
| 375 | b.Assign("color", |
| 376 | b.Mul(b.vec4<f32>(b.MemberAccessor(plane_0_call, "r"), |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 377 | b.MemberAccessor(plane_1_call, "rg"), 1_a), |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 378 | b.MemberAccessor("params", "yuvToRgbConversionMatrix"))))))); |
| 379 | |
| 380 | // if (params.doYuvToRgbConversionOnly == 0u) |
| 381 | stmts.Push( |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 382 | b.If(b.Equal(b.MemberAccessor("params", "doYuvToRgbConversionOnly"), b.Expr(0_a)), |
jchen10 | ef62b58 | 2022-06-22 03:14:26 +0000 | [diff] [blame] | 383 | b.Block( |
| 384 | // color = gammaConversion(color, gammaDecodeParams); |
| 385 | b.Assign("color", b.Call("gammaCorrection", "color", |
| 386 | b.MemberAccessor("params", "gammaDecodeParams"))), |
| 387 | // color = (params.gamutConversionMatrix * color); |
| 388 | b.Assign("color", |
| 389 | b.Mul(b.MemberAccessor("params", "gamutConversionMatrix"), "color")), |
| 390 | // color = gammaConversion(color, gammaEncodeParams); |
| 391 | b.Assign("color", b.Call("gammaCorrection", "color", |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 392 | b.MemberAccessor("params", "gammaEncodeParams")))))); |
| 393 | |
| 394 | // return vec4<f32>(color, 1.f); |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 395 | stmts.Push(b.Return(b.vec4<f32>("color", 1_a))); |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 396 | |
| 397 | return stmts; |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 398 | } |
| 399 | |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 400 | /// Creates the textureSampleExternal function if needed and returns a call expression to it. |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 401 | /// @param expr the call expression being transformed |
| 402 | /// @param syms the expanded symbols to be used in the new call |
| 403 | /// @returns a call expression to textureSampleExternal |
| 404 | const ast::CallExpression* createTextureSampleBaseClampToEdge(const ast::CallExpression* expr, |
| 405 | NewBindingSymbols syms) { |
| 406 | const ast::Expression* plane_0_binding_param = ctx.Clone(expr->args[0]); |
| 407 | |
Ben Clayton | 884f952 | 2023-01-12 22:52:57 +0000 | [diff] [blame] | 408 | if (TINT_UNLIKELY(expr->args.Length() != 3)) { |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 409 | TINT_ICE(Transform, b.Diagnostics()) |
| 410 | << "expected textureSampleBaseClampToEdge call with a " |
| 411 | "texture_external to have 3 parameters, found " |
| 412 | << expr->args.Length() << " parameters"; |
| 413 | } |
| 414 | |
| 415 | // TextureSampleExternal calls the gammaCorrection function, so ensure it |
| 416 | // exists. |
| 417 | if (!gamma_correction_sym.IsValid()) { |
| 418 | createGammaCorrectionFn(); |
| 419 | } |
| 420 | |
| 421 | if (!texture_sample_external_sym.IsValid()) { |
| 422 | texture_sample_external_sym = b.Symbols().New("textureSampleExternal"); |
| 423 | |
| 424 | // Emit the textureSampleExternal function. |
dan sinclair | 3cbf3fc | 2023-01-21 19:16:15 +0000 | [diff] [blame] | 425 | b.Func(texture_sample_external_sym, |
| 426 | utils::Vector{ |
| 427 | b.Param("plane0", |
| 428 | b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32())), |
| 429 | b.Param("plane1", |
| 430 | b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32())), |
dan sinclair | 3085e23 | 2023-01-23 16:24:12 +0000 | [diff] [blame] | 431 | b.Param("smp", b.ty.sampler(type::SamplerKind::kSampler)), |
dan sinclair | 3cbf3fc | 2023-01-21 19:16:15 +0000 | [diff] [blame] | 432 | b.Param("coord", b.ty.vec2(b.ty.f32())), |
Ben Clayton | 2117f80 | 2023-02-03 14:01:43 +0000 | [diff] [blame] | 433 | b.Param("params", b.ty(params_struct_sym)), |
dan sinclair | 3cbf3fc | 2023-01-21 19:16:15 +0000 | [diff] [blame] | 434 | }, |
| 435 | b.ty.vec4(b.ty.f32()), |
dan sinclair | 9543f74 | 2023-03-09 01:20:16 +0000 | [diff] [blame] | 436 | buildTextureBuiltinBody(builtin::Function::kTextureSampleBaseClampToEdge)); |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 437 | } |
| 438 | |
Ben Clayton | 999db74 | 2023-02-02 15:16:28 +0000 | [diff] [blame] | 439 | return b.Call(texture_sample_external_sym, utils::Vector{ |
| 440 | plane_0_binding_param, |
| 441 | b.Expr(syms.plane_1), |
| 442 | ctx.Clone(expr->args[1]), |
| 443 | ctx.Clone(expr->args[2]), |
| 444 | b.Expr(syms.params), |
| 445 | }); |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 446 | } |
| 447 | |
| 448 | /// Creates the textureLoadExternal function if needed and returns a call expression to it. |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 449 | /// @param call the call expression being transformed |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 450 | /// @param syms the expanded symbols to be used in the new call |
| 451 | /// @returns a call expression to textureLoadExternal |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 452 | const ast::CallExpression* createTextureLoad(const sem::Call* call, NewBindingSymbols syms) { |
Ben Clayton | 884f952 | 2023-01-12 22:52:57 +0000 | [diff] [blame] | 453 | if (TINT_UNLIKELY(call->Arguments().Length() != 2)) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 454 | TINT_ICE(Transform, b.Diagnostics()) |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 455 | << "expected textureLoad call with a texture_external to have 2 arguments, found " |
| 456 | << call->Arguments().Length() << " arguments"; |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 457 | } |
| 458 | |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 459 | auto& args = call->Arguments(); |
| 460 | |
| 461 | // TextureLoadExternal calls the gammaCorrection function, so ensure it exists. |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 462 | if (!gamma_correction_sym.IsValid()) { |
| 463 | createGammaCorrectionFn(); |
| 464 | } |
| 465 | |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 466 | auto texture_load_external_sym = texture_load_external_fns.GetOrCreate(call->Target(), [&] { |
| 467 | auto& sig = call->Target()->Signature(); |
| 468 | auto* coord_ty = sig.Parameter(sem::ParameterUsage::kCoords)->Type(); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 469 | |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 470 | auto name = b.Symbols().New("textureLoadExternal"); |
| 471 | |
| 472 | // Emit the textureLoadExternal() function. |
dan sinclair | 3cbf3fc | 2023-01-21 19:16:15 +0000 | [diff] [blame] | 473 | b.Func(name, |
| 474 | utils::Vector{ |
| 475 | b.Param("plane0", |
| 476 | b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32())), |
| 477 | b.Param("plane1", |
| 478 | b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32())), |
| 479 | b.Param("coord", CreateASTTypeFor(ctx, coord_ty)), |
Ben Clayton | 2117f80 | 2023-02-03 14:01:43 +0000 | [diff] [blame] | 480 | b.Param("params", b.ty(params_struct_sym)), |
dan sinclair | 3cbf3fc | 2023-01-21 19:16:15 +0000 | [diff] [blame] | 481 | }, |
| 482 | b.ty.vec4(b.ty.f32()), // |
dan sinclair | 9543f74 | 2023-03-09 01:20:16 +0000 | [diff] [blame] | 483 | buildTextureBuiltinBody(builtin::Function::kTextureLoad)); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 484 | |
Ben Clayton | da5424b | 2022-10-24 23:58:53 +0000 | [diff] [blame] | 485 | return name; |
| 486 | }); |
| 487 | |
| 488 | auto plane_0_binding_arg = ctx.Clone(args[0]->Declaration()); |
| 489 | |
| 490 | return b.Call(texture_load_external_sym, plane_0_binding_arg, syms.plane_1, |
| 491 | ctx.Clone(args[1]->Declaration()), syms.params); |
Brandon Jones | 41cbf02 | 2022-04-29 21:00:14 +0000 | [diff] [blame] | 492 | } |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 493 | }; |
| 494 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 495 | MultiplanarExternalTexture::NewBindingPoints::NewBindingPoints(BindingsMap inputBindingsMap) |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 496 | : bindings_map(std::move(inputBindingsMap)) {} |
dan sinclair | eebbdef | 2023-03-08 02:48:42 +0000 | [diff] [blame] | 497 | |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 498 | MultiplanarExternalTexture::NewBindingPoints::~NewBindingPoints() = default; |
| 499 | |
| 500 | MultiplanarExternalTexture::MultiplanarExternalTexture() = default; |
| 501 | MultiplanarExternalTexture::~MultiplanarExternalTexture() = default; |
| 502 | |
Ben Clayton | c4ebf2c | 2022-09-22 22:59:16 +0000 | [diff] [blame] | 503 | // Within this transform, an instance of a texture_external binding is unpacked into two |
| 504 | // texture_2d<f32> bindings representing two possible planes of a single texture and a uniform |
| 505 | // buffer binding representing a struct of parameters. Calls to texture builtins that contain a |
| 506 | // texture_external parameter will be transformed into a newly generated version of the function, |
| 507 | // which can perform the desired operation on a single RGBA plane or on separate Y and UV planes. |
Ben Clayton | c6b3814 | 2022-11-03 08:41:19 +0000 | [diff] [blame] | 508 | Transform::ApplyResult MultiplanarExternalTexture::Apply(const Program* src, |
| 509 | const DataMap& inputs, |
| 510 | DataMap&) const { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 511 | auto* new_binding_points = inputs.Get<NewBindingPoints>(); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 512 | |
Ben Clayton | c6b3814 | 2022-11-03 08:41:19 +0000 | [diff] [blame] | 513 | if (!ShouldRun(src)) { |
| 514 | return SkipTransform; |
| 515 | } |
| 516 | |
| 517 | ProgramBuilder b; |
| 518 | CloneContext ctx{&b, src, /* auto_clone_symbols */ true}; |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 519 | if (!new_binding_points) { |
Ben Clayton | c6b3814 | 2022-11-03 08:41:19 +0000 | [diff] [blame] | 520 | b.Diagnostics().add_error(diag::System::Transform, "missing new binding point data for " + |
| 521 | std::string(TypeInfo().name)); |
| 522 | return Program(std::move(b)); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 523 | } |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 524 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 525 | State state(ctx, new_binding_points); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 526 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 527 | state.Process(); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 528 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 529 | ctx.Clone(); |
Ben Clayton | c6b3814 | 2022-11-03 08:41:19 +0000 | [diff] [blame] | 530 | return Program(std::move(b)); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 531 | } |
| 532 | |
dan sinclair | b5599d3 | 2022-04-07 16:55:14 +0000 | [diff] [blame] | 533 | } // namespace tint::transform |