1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2009 VMware, Inc. 4bf215546Sopenharmony_ci * All rights reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci/** 29bf215546Sopenharmony_ci * Texture sampling code generation 30bf215546Sopenharmony_ci * 31bf215546Sopenharmony_ci * This file is nothing more than ugly glue between three largely independent 32bf215546Sopenharmony_ci * entities: 33bf215546Sopenharmony_ci * - TGSI -> LLVM translation (i.e., lp_build_tgsi_soa) 34bf215546Sopenharmony_ci * - texture sampling code generation (i.e., lp_build_sample_soa) 35bf215546Sopenharmony_ci * - LLVM pipe driver 36bf215546Sopenharmony_ci * 37bf215546Sopenharmony_ci * All interesting code is in the functions mentioned above. There is really 38bf215546Sopenharmony_ci * nothing to see here. 39bf215546Sopenharmony_ci * 40bf215546Sopenharmony_ci * @author Jose Fonseca <jfonseca@vmware.com> 41bf215546Sopenharmony_ci */ 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci#include "pipe/p_defines.h" 44bf215546Sopenharmony_ci#include "pipe/p_shader_tokens.h" 45bf215546Sopenharmony_ci#include "gallivm/lp_bld_debug.h" 46bf215546Sopenharmony_ci#include "gallivm/lp_bld_const.h" 47bf215546Sopenharmony_ci#include "gallivm/lp_bld_type.h" 48bf215546Sopenharmony_ci#include "gallivm/lp_bld_sample.h" 49bf215546Sopenharmony_ci#include "gallivm/lp_bld_tgsi.h" 50bf215546Sopenharmony_ci#include "lp_jit.h" 51bf215546Sopenharmony_ci#include "lp_tex_sample.h" 52bf215546Sopenharmony_ci#include "lp_state_fs.h" 53bf215546Sopenharmony_ci#include "lp_debug.h" 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci/** 57bf215546Sopenharmony_ci * This provides the bridge between the sampler state store in 58bf215546Sopenharmony_ci * lp_jit_context and lp_jit_texture and the sampler code 59bf215546Sopenharmony_ci * generator. It provides the texture layout information required by 60bf215546Sopenharmony_ci * the texture sampler code generator in terms of the state stored in 61bf215546Sopenharmony_ci * lp_jit_context and lp_jit_texture in runtime. 62bf215546Sopenharmony_ci */ 63bf215546Sopenharmony_cistruct llvmpipe_sampler_dynamic_state 64bf215546Sopenharmony_ci{ 65bf215546Sopenharmony_ci struct lp_sampler_dynamic_state base; 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci const struct lp_sampler_static_state *static_state; 68bf215546Sopenharmony_ci}; 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci/** 72bf215546Sopenharmony_ci * This is the bridge between our sampler and the TGSI translator. 73bf215546Sopenharmony_ci */ 74bf215546Sopenharmony_cistruct lp_llvm_sampler_soa 75bf215546Sopenharmony_ci{ 76bf215546Sopenharmony_ci struct lp_build_sampler_soa base; 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci struct llvmpipe_sampler_dynamic_state dynamic_state; 79bf215546Sopenharmony_ci unsigned nr_samplers; 80bf215546Sopenharmony_ci}; 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_cistruct llvmpipe_image_dynamic_state 84bf215546Sopenharmony_ci{ 85bf215546Sopenharmony_ci struct lp_sampler_dynamic_state base; 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci const struct lp_image_static_state *static_state; 88bf215546Sopenharmony_ci}; 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci/** 92bf215546Sopenharmony_ci * This is the bridge between our images and the TGSI translator. 93bf215546Sopenharmony_ci */ 94bf215546Sopenharmony_cistruct lp_llvm_image_soa 95bf215546Sopenharmony_ci{ 96bf215546Sopenharmony_ci struct lp_build_image_soa base; 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci struct llvmpipe_image_dynamic_state dynamic_state; 99bf215546Sopenharmony_ci unsigned nr_images; 100bf215546Sopenharmony_ci}; 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci/** 104bf215546Sopenharmony_ci * Fetch the specified member of the lp_jit_texture structure. 105bf215546Sopenharmony_ci * \param emit_load if TRUE, emit the LLVM load instruction to actually 106bf215546Sopenharmony_ci * fetch the field's value. Otherwise, just emit the 107bf215546Sopenharmony_ci * GEP code to address the field. 108bf215546Sopenharmony_ci * 109bf215546Sopenharmony_ci * @sa http://llvm.org/docs/GetElementPtr.html 110bf215546Sopenharmony_ci */ 111bf215546Sopenharmony_cistatic LLVMValueRef 112bf215546Sopenharmony_cilp_llvm_texture_member(const struct lp_sampler_dynamic_state *base, 113bf215546Sopenharmony_ci struct gallivm_state *gallivm, 114bf215546Sopenharmony_ci LLVMValueRef context_ptr, 115bf215546Sopenharmony_ci unsigned texture_unit, 116bf215546Sopenharmony_ci LLVMValueRef texture_unit_offset, 117bf215546Sopenharmony_ci unsigned member_index, 118bf215546Sopenharmony_ci const char *member_name, 119bf215546Sopenharmony_ci boolean emit_load) 120bf215546Sopenharmony_ci{ 121bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 122bf215546Sopenharmony_ci LLVMValueRef indices[4]; 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci assert(texture_unit < PIPE_MAX_SHADER_SAMPLER_VIEWS); 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci /* context[0] */ 127bf215546Sopenharmony_ci indices[0] = lp_build_const_int32(gallivm, 0); 128bf215546Sopenharmony_ci /* context[0].textures */ 129bf215546Sopenharmony_ci indices[1] = lp_build_const_int32(gallivm, LP_JIT_CTX_TEXTURES); 130bf215546Sopenharmony_ci /* context[0].textures[unit] */ 131bf215546Sopenharmony_ci indices[2] = lp_build_const_int32(gallivm, texture_unit); 132bf215546Sopenharmony_ci if (texture_unit_offset) { 133bf215546Sopenharmony_ci indices[2] = LLVMBuildAdd(gallivm->builder, indices[2], 134bf215546Sopenharmony_ci texture_unit_offset, ""); 135bf215546Sopenharmony_ci LLVMValueRef cond = 136bf215546Sopenharmony_ci LLVMBuildICmp(gallivm->builder, LLVMIntULT, 137bf215546Sopenharmony_ci indices[2], 138bf215546Sopenharmony_ci lp_build_const_int32(gallivm, 139bf215546Sopenharmony_ci PIPE_MAX_SHADER_SAMPLER_VIEWS), ""); 140bf215546Sopenharmony_ci indices[2] = LLVMBuildSelect(gallivm->builder, cond, indices[2], 141bf215546Sopenharmony_ci lp_build_const_int32(gallivm, 142bf215546Sopenharmony_ci texture_unit), ""); 143bf215546Sopenharmony_ci } 144bf215546Sopenharmony_ci /* context[0].textures[unit].member */ 145bf215546Sopenharmony_ci indices[3] = lp_build_const_int32(gallivm, member_index); 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci LLVMValueRef ptr = 148bf215546Sopenharmony_ci LLVMBuildGEP(builder, context_ptr, indices, ARRAY_SIZE(indices), ""); 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci LLVMValueRef res = emit_load ? LLVMBuildLoad(builder, ptr, "") : ptr; 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci lp_build_name(res, "context.texture%u.%s", texture_unit, member_name); 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci return res; 155bf215546Sopenharmony_ci} 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci/** 159bf215546Sopenharmony_ci * Helper macro to instantiate the functions that generate the code to 160bf215546Sopenharmony_ci * fetch the members of lp_jit_texture to fulfill the sampler code 161bf215546Sopenharmony_ci * generator requests. 162bf215546Sopenharmony_ci * 163bf215546Sopenharmony_ci * This complexity is the price we have to pay to keep the texture 164bf215546Sopenharmony_ci * sampler code generator a reusable module without dependencies to 165bf215546Sopenharmony_ci * llvmpipe internals. 166bf215546Sopenharmony_ci */ 167bf215546Sopenharmony_ci#define LP_LLVM_TEXTURE_MEMBER(_name, _index, _emit_load) \ 168bf215546Sopenharmony_ci static LLVMValueRef \ 169bf215546Sopenharmony_ci lp_llvm_texture_##_name( const struct lp_sampler_dynamic_state *base, \ 170bf215546Sopenharmony_ci struct gallivm_state *gallivm, \ 171bf215546Sopenharmony_ci LLVMValueRef context_ptr, \ 172bf215546Sopenharmony_ci unsigned texture_unit, \ 173bf215546Sopenharmony_ci LLVMValueRef texture_unit_offset) \ 174bf215546Sopenharmony_ci { \ 175bf215546Sopenharmony_ci return lp_llvm_texture_member(base, gallivm, context_ptr, \ 176bf215546Sopenharmony_ci texture_unit, texture_unit_offset, \ 177bf215546Sopenharmony_ci _index, #_name, _emit_load ); \ 178bf215546Sopenharmony_ci } 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ciLP_LLVM_TEXTURE_MEMBER(width, LP_JIT_TEXTURE_WIDTH, TRUE) 182bf215546Sopenharmony_ciLP_LLVM_TEXTURE_MEMBER(height, LP_JIT_TEXTURE_HEIGHT, TRUE) 183bf215546Sopenharmony_ciLP_LLVM_TEXTURE_MEMBER(depth, LP_JIT_TEXTURE_DEPTH, TRUE) 184bf215546Sopenharmony_ciLP_LLVM_TEXTURE_MEMBER(first_level, LP_JIT_TEXTURE_FIRST_LEVEL, TRUE) 185bf215546Sopenharmony_ciLP_LLVM_TEXTURE_MEMBER(last_level, LP_JIT_TEXTURE_LAST_LEVEL, TRUE) 186bf215546Sopenharmony_ciLP_LLVM_TEXTURE_MEMBER(base_ptr, LP_JIT_TEXTURE_BASE, TRUE) 187bf215546Sopenharmony_ciLP_LLVM_TEXTURE_MEMBER(row_stride, LP_JIT_TEXTURE_ROW_STRIDE, FALSE) 188bf215546Sopenharmony_ciLP_LLVM_TEXTURE_MEMBER(img_stride, LP_JIT_TEXTURE_IMG_STRIDE, FALSE) 189bf215546Sopenharmony_ciLP_LLVM_TEXTURE_MEMBER(mip_offsets, LP_JIT_TEXTURE_MIP_OFFSETS, FALSE) 190bf215546Sopenharmony_ciLP_LLVM_TEXTURE_MEMBER(num_samples, LP_JIT_TEXTURE_NUM_SAMPLES, TRUE) 191bf215546Sopenharmony_ciLP_LLVM_TEXTURE_MEMBER(sample_stride, LP_JIT_TEXTURE_SAMPLE_STRIDE, TRUE) 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci/** 195bf215546Sopenharmony_ci * Fetch the specified member of the lp_jit_sampler structure. 196bf215546Sopenharmony_ci * \param emit_load if TRUE, emit the LLVM load instruction to actually 197bf215546Sopenharmony_ci * fetch the field's value. Otherwise, just emit the 198bf215546Sopenharmony_ci * GEP code to address the field. 199bf215546Sopenharmony_ci * 200bf215546Sopenharmony_ci * @sa http://llvm.org/docs/GetElementPtr.html 201bf215546Sopenharmony_ci */ 202bf215546Sopenharmony_cistatic LLVMValueRef 203bf215546Sopenharmony_cilp_llvm_sampler_member(const struct lp_sampler_dynamic_state *base, 204bf215546Sopenharmony_ci struct gallivm_state *gallivm, 205bf215546Sopenharmony_ci LLVMValueRef context_ptr, 206bf215546Sopenharmony_ci unsigned sampler_unit, 207bf215546Sopenharmony_ci unsigned member_index, 208bf215546Sopenharmony_ci const char *member_name, 209bf215546Sopenharmony_ci boolean emit_load) 210bf215546Sopenharmony_ci{ 211bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 212bf215546Sopenharmony_ci LLVMValueRef indices[4]; 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci assert(sampler_unit < PIPE_MAX_SAMPLERS); 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ci /* context[0] */ 217bf215546Sopenharmony_ci indices[0] = lp_build_const_int32(gallivm, 0); 218bf215546Sopenharmony_ci /* context[0].samplers */ 219bf215546Sopenharmony_ci indices[1] = lp_build_const_int32(gallivm, LP_JIT_CTX_SAMPLERS); 220bf215546Sopenharmony_ci /* context[0].samplers[unit] */ 221bf215546Sopenharmony_ci indices[2] = lp_build_const_int32(gallivm, sampler_unit); 222bf215546Sopenharmony_ci /* context[0].samplers[unit].member */ 223bf215546Sopenharmony_ci indices[3] = lp_build_const_int32(gallivm, member_index); 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci LLVMValueRef ptr = 226bf215546Sopenharmony_ci LLVMBuildGEP(builder, context_ptr, indices, ARRAY_SIZE(indices), ""); 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci LLVMValueRef res = emit_load ? LLVMBuildLoad(builder, ptr, "") : ptr; 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci lp_build_name(res, "context.sampler%u.%s", sampler_unit, member_name); 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci return res; 233bf215546Sopenharmony_ci} 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_ci#define LP_LLVM_SAMPLER_MEMBER(_name, _index, _emit_load) \ 237bf215546Sopenharmony_ci static LLVMValueRef \ 238bf215546Sopenharmony_ci lp_llvm_sampler_##_name( const struct lp_sampler_dynamic_state *base, \ 239bf215546Sopenharmony_ci struct gallivm_state *gallivm, \ 240bf215546Sopenharmony_ci LLVMValueRef context_ptr, \ 241bf215546Sopenharmony_ci unsigned sampler_unit) \ 242bf215546Sopenharmony_ci { \ 243bf215546Sopenharmony_ci return lp_llvm_sampler_member(base, gallivm, context_ptr, \ 244bf215546Sopenharmony_ci sampler_unit, _index, #_name, _emit_load ); \ 245bf215546Sopenharmony_ci } 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ciLP_LLVM_SAMPLER_MEMBER(min_lod, LP_JIT_SAMPLER_MIN_LOD, TRUE) 249bf215546Sopenharmony_ciLP_LLVM_SAMPLER_MEMBER(max_lod, LP_JIT_SAMPLER_MAX_LOD, TRUE) 250bf215546Sopenharmony_ciLP_LLVM_SAMPLER_MEMBER(lod_bias, LP_JIT_SAMPLER_LOD_BIAS, TRUE) 251bf215546Sopenharmony_ciLP_LLVM_SAMPLER_MEMBER(border_color, LP_JIT_SAMPLER_BORDER_COLOR, FALSE) 252bf215546Sopenharmony_ciLP_LLVM_SAMPLER_MEMBER(max_aniso, LP_JIT_SAMPLER_MAX_ANISO, TRUE) 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci/** 256bf215546Sopenharmony_ci * Fetch the specified member of the lp_jit_image structure. 257bf215546Sopenharmony_ci * \param emit_load if TRUE, emit the LLVM load instruction to actually 258bf215546Sopenharmony_ci * fetch the field's value. Otherwise, just emit the 259bf215546Sopenharmony_ci * GEP code to address the field. 260bf215546Sopenharmony_ci * 261bf215546Sopenharmony_ci * @sa http://llvm.org/docs/GetElementPtr.html 262bf215546Sopenharmony_ci */ 263bf215546Sopenharmony_cistatic LLVMValueRef 264bf215546Sopenharmony_cilp_llvm_image_member(const struct lp_sampler_dynamic_state *base, 265bf215546Sopenharmony_ci struct gallivm_state *gallivm, 266bf215546Sopenharmony_ci LLVMValueRef context_ptr, 267bf215546Sopenharmony_ci unsigned image_unit, 268bf215546Sopenharmony_ci LLVMValueRef image_unit_offset, 269bf215546Sopenharmony_ci unsigned member_index, 270bf215546Sopenharmony_ci const char *member_name, 271bf215546Sopenharmony_ci boolean emit_load) 272bf215546Sopenharmony_ci{ 273bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 274bf215546Sopenharmony_ci LLVMValueRef indices[4]; 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_ci assert(image_unit < PIPE_MAX_SHADER_IMAGES); 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci /* context[0] */ 279bf215546Sopenharmony_ci indices[0] = lp_build_const_int32(gallivm, 0); 280bf215546Sopenharmony_ci /* context[0].images */ 281bf215546Sopenharmony_ci indices[1] = lp_build_const_int32(gallivm, LP_JIT_CTX_IMAGES); 282bf215546Sopenharmony_ci /* context[0].images[unit] */ 283bf215546Sopenharmony_ci indices[2] = lp_build_const_int32(gallivm, image_unit); 284bf215546Sopenharmony_ci if (image_unit_offset) { 285bf215546Sopenharmony_ci indices[2] = LLVMBuildAdd(gallivm->builder, indices[2], image_unit_offset, ""); 286bf215546Sopenharmony_ci LLVMValueRef cond = LLVMBuildICmp(gallivm->builder, LLVMIntULT, indices[2], lp_build_const_int32(gallivm, PIPE_MAX_SHADER_IMAGES), ""); 287bf215546Sopenharmony_ci indices[2] = LLVMBuildSelect(gallivm->builder, cond, indices[2], lp_build_const_int32(gallivm, image_unit), ""); 288bf215546Sopenharmony_ci } 289bf215546Sopenharmony_ci /* context[0].images[unit].member */ 290bf215546Sopenharmony_ci indices[3] = lp_build_const_int32(gallivm, member_index); 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci LLVMValueRef ptr = 293bf215546Sopenharmony_ci LLVMBuildGEP(builder, context_ptr, indices, ARRAY_SIZE(indices), ""); 294bf215546Sopenharmony_ci 295bf215546Sopenharmony_ci LLVMValueRef res = emit_load ? LLVMBuildLoad(builder, ptr, "") : ptr; 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci lp_build_name(res, "context.image%u.%s", image_unit, member_name); 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci return res; 300bf215546Sopenharmony_ci} 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci/** 304bf215546Sopenharmony_ci * Helper macro to instantiate the functions that generate the code to 305bf215546Sopenharmony_ci * fetch the members of lp_jit_image to fulfill the sampler code 306bf215546Sopenharmony_ci * generator requests. 307bf215546Sopenharmony_ci * 308bf215546Sopenharmony_ci * This complexity is the price we have to pay to keep the image 309bf215546Sopenharmony_ci * sampler code generator a reusable module without dependencies to 310bf215546Sopenharmony_ci * llvmpipe internals. 311bf215546Sopenharmony_ci */ 312bf215546Sopenharmony_ci#define LP_LLVM_IMAGE_MEMBER(_name, _index, _emit_load) \ 313bf215546Sopenharmony_ci static LLVMValueRef \ 314bf215546Sopenharmony_ci lp_llvm_image_##_name( const struct lp_sampler_dynamic_state *base, \ 315bf215546Sopenharmony_ci struct gallivm_state *gallivm, \ 316bf215546Sopenharmony_ci LLVMValueRef context_ptr, \ 317bf215546Sopenharmony_ci unsigned image_unit, LLVMValueRef image_unit_offset) \ 318bf215546Sopenharmony_ci { \ 319bf215546Sopenharmony_ci return lp_llvm_image_member(base, gallivm, context_ptr, \ 320bf215546Sopenharmony_ci image_unit, image_unit_offset, \ 321bf215546Sopenharmony_ci _index, #_name, _emit_load ); \ 322bf215546Sopenharmony_ci } 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci 325bf215546Sopenharmony_ciLP_LLVM_IMAGE_MEMBER(width, LP_JIT_IMAGE_WIDTH, TRUE) 326bf215546Sopenharmony_ciLP_LLVM_IMAGE_MEMBER(height, LP_JIT_IMAGE_HEIGHT, TRUE) 327bf215546Sopenharmony_ciLP_LLVM_IMAGE_MEMBER(depth, LP_JIT_IMAGE_DEPTH, TRUE) 328bf215546Sopenharmony_ciLP_LLVM_IMAGE_MEMBER(base_ptr, LP_JIT_IMAGE_BASE, TRUE) 329bf215546Sopenharmony_ciLP_LLVM_IMAGE_MEMBER(row_stride, LP_JIT_IMAGE_ROW_STRIDE, TRUE) 330bf215546Sopenharmony_ciLP_LLVM_IMAGE_MEMBER(img_stride, LP_JIT_IMAGE_IMG_STRIDE, TRUE) 331bf215546Sopenharmony_ciLP_LLVM_IMAGE_MEMBER(num_samples, LP_JIT_IMAGE_NUM_SAMPLES, TRUE) 332bf215546Sopenharmony_ciLP_LLVM_IMAGE_MEMBER(sample_stride, LP_JIT_IMAGE_SAMPLE_STRIDE, TRUE) 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci#if LP_USE_TEXTURE_CACHE 336bf215546Sopenharmony_cistatic LLVMValueRef 337bf215546Sopenharmony_cilp_llvm_texture_cache_ptr(const struct lp_sampler_dynamic_state *base, 338bf215546Sopenharmony_ci struct gallivm_state *gallivm, 339bf215546Sopenharmony_ci LLVMValueRef thread_data_ptr, 340bf215546Sopenharmony_ci unsigned unit) 341bf215546Sopenharmony_ci{ 342bf215546Sopenharmony_ci /* We use the same cache for all units */ 343bf215546Sopenharmony_ci (void)unit; 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci return lp_jit_thread_data_cache(gallivm, thread_data_ptr); 346bf215546Sopenharmony_ci} 347bf215546Sopenharmony_ci#endif 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_cistatic void 351bf215546Sopenharmony_cilp_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler) 352bf215546Sopenharmony_ci{ 353bf215546Sopenharmony_ci FREE(sampler); 354bf215546Sopenharmony_ci} 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ci/** 358bf215546Sopenharmony_ci * Fetch filtered values from texture. 359bf215546Sopenharmony_ci * The 'texel' parameter returns four vectors corresponding to R, G, B, A. 360bf215546Sopenharmony_ci */ 361bf215546Sopenharmony_cistatic void 362bf215546Sopenharmony_cilp_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base, 363bf215546Sopenharmony_ci struct gallivm_state *gallivm, 364bf215546Sopenharmony_ci const struct lp_sampler_params *params) 365bf215546Sopenharmony_ci{ 366bf215546Sopenharmony_ci struct lp_llvm_sampler_soa *sampler = (struct lp_llvm_sampler_soa *)base; 367bf215546Sopenharmony_ci const unsigned texture_index = params->texture_index; 368bf215546Sopenharmony_ci const unsigned sampler_index = params->sampler_index; 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_ci assert(sampler_index < PIPE_MAX_SAMPLERS); 371bf215546Sopenharmony_ci assert(texture_index < PIPE_MAX_SHADER_SAMPLER_VIEWS); 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci if (LP_PERF & PERF_NO_TEX) { 374bf215546Sopenharmony_ci lp_build_sample_nop(gallivm, params->type, params->coords, params->texel); 375bf215546Sopenharmony_ci return; 376bf215546Sopenharmony_ci } 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci if (params->texture_index_offset) { 379bf215546Sopenharmony_ci LLVMValueRef unit = 380bf215546Sopenharmony_ci LLVMBuildAdd(gallivm->builder, params->texture_index_offset, 381bf215546Sopenharmony_ci lp_build_const_int32(gallivm, texture_index), ""); 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci struct lp_build_sample_array_switch switch_info; 384bf215546Sopenharmony_ci memset(&switch_info, 0, sizeof(switch_info)); 385bf215546Sopenharmony_ci lp_build_sample_array_init_soa(&switch_info, gallivm, params, unit, 386bf215546Sopenharmony_ci 0, sampler->nr_samplers); 387bf215546Sopenharmony_ci // build the switch cases 388bf215546Sopenharmony_ci for (unsigned i = 0; i < sampler->nr_samplers; i++) { 389bf215546Sopenharmony_ci lp_build_sample_array_case_soa(&switch_info, i, 390bf215546Sopenharmony_ci &sampler->dynamic_state.static_state[i].texture_state, 391bf215546Sopenharmony_ci &sampler->dynamic_state.static_state[i].sampler_state, 392bf215546Sopenharmony_ci &sampler->dynamic_state.base); 393bf215546Sopenharmony_ci } 394bf215546Sopenharmony_ci lp_build_sample_array_fini_soa(&switch_info); 395bf215546Sopenharmony_ci } else { 396bf215546Sopenharmony_ci lp_build_sample_soa(&sampler->dynamic_state.static_state[texture_index].texture_state, 397bf215546Sopenharmony_ci &sampler->dynamic_state.static_state[sampler_index].sampler_state, 398bf215546Sopenharmony_ci &sampler->dynamic_state.base, 399bf215546Sopenharmony_ci gallivm, params); 400bf215546Sopenharmony_ci } 401bf215546Sopenharmony_ci} 402bf215546Sopenharmony_ci 403bf215546Sopenharmony_ci 404bf215546Sopenharmony_ci/** 405bf215546Sopenharmony_ci * Fetch the texture size. 406bf215546Sopenharmony_ci */ 407bf215546Sopenharmony_cistatic void 408bf215546Sopenharmony_cilp_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa *base, 409bf215546Sopenharmony_ci struct gallivm_state *gallivm, 410bf215546Sopenharmony_ci const struct lp_sampler_size_query_params *params) 411bf215546Sopenharmony_ci{ 412bf215546Sopenharmony_ci struct lp_llvm_sampler_soa *sampler = (struct lp_llvm_sampler_soa *)base; 413bf215546Sopenharmony_ci 414bf215546Sopenharmony_ci assert(params->texture_unit < PIPE_MAX_SHADER_SAMPLER_VIEWS); 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_ci lp_build_size_query_soa(gallivm, 417bf215546Sopenharmony_ci &sampler->dynamic_state.static_state[params->texture_unit].texture_state, 418bf215546Sopenharmony_ci &sampler->dynamic_state.base, 419bf215546Sopenharmony_ci params); 420bf215546Sopenharmony_ci} 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_cistruct lp_build_sampler_soa * 424bf215546Sopenharmony_cilp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state, 425bf215546Sopenharmony_ci unsigned nr_samplers) 426bf215546Sopenharmony_ci{ 427bf215546Sopenharmony_ci assert(static_state); 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci struct lp_llvm_sampler_soa *sampler = CALLOC_STRUCT(lp_llvm_sampler_soa); 430bf215546Sopenharmony_ci if (!sampler) 431bf215546Sopenharmony_ci return NULL; 432bf215546Sopenharmony_ci 433bf215546Sopenharmony_ci sampler->base.destroy = lp_llvm_sampler_soa_destroy; 434bf215546Sopenharmony_ci sampler->base.emit_tex_sample = lp_llvm_sampler_soa_emit_fetch_texel; 435bf215546Sopenharmony_ci sampler->base.emit_size_query = lp_llvm_sampler_soa_emit_size_query; 436bf215546Sopenharmony_ci sampler->dynamic_state.base.width = lp_llvm_texture_width; 437bf215546Sopenharmony_ci sampler->dynamic_state.base.height = lp_llvm_texture_height; 438bf215546Sopenharmony_ci sampler->dynamic_state.base.depth = lp_llvm_texture_depth; 439bf215546Sopenharmony_ci sampler->dynamic_state.base.first_level = lp_llvm_texture_first_level; 440bf215546Sopenharmony_ci sampler->dynamic_state.base.last_level = lp_llvm_texture_last_level; 441bf215546Sopenharmony_ci sampler->dynamic_state.base.base_ptr = lp_llvm_texture_base_ptr; 442bf215546Sopenharmony_ci sampler->dynamic_state.base.row_stride = lp_llvm_texture_row_stride; 443bf215546Sopenharmony_ci sampler->dynamic_state.base.img_stride = lp_llvm_texture_img_stride; 444bf215546Sopenharmony_ci sampler->dynamic_state.base.mip_offsets = lp_llvm_texture_mip_offsets; 445bf215546Sopenharmony_ci sampler->dynamic_state.base.num_samples = lp_llvm_texture_num_samples; 446bf215546Sopenharmony_ci sampler->dynamic_state.base.sample_stride = lp_llvm_texture_sample_stride; 447bf215546Sopenharmony_ci sampler->dynamic_state.base.min_lod = lp_llvm_sampler_min_lod; 448bf215546Sopenharmony_ci sampler->dynamic_state.base.max_lod = lp_llvm_sampler_max_lod; 449bf215546Sopenharmony_ci sampler->dynamic_state.base.lod_bias = lp_llvm_sampler_lod_bias; 450bf215546Sopenharmony_ci sampler->dynamic_state.base.border_color = lp_llvm_sampler_border_color; 451bf215546Sopenharmony_ci sampler->dynamic_state.base.max_aniso = lp_llvm_sampler_max_aniso; 452bf215546Sopenharmony_ci 453bf215546Sopenharmony_ci#if LP_USE_TEXTURE_CACHE 454bf215546Sopenharmony_ci sampler->dynamic_state.base.cache_ptr = lp_llvm_texture_cache_ptr; 455bf215546Sopenharmony_ci#endif 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci sampler->dynamic_state.static_state = static_state; 458bf215546Sopenharmony_ci 459bf215546Sopenharmony_ci sampler->nr_samplers = nr_samplers; 460bf215546Sopenharmony_ci return &sampler->base; 461bf215546Sopenharmony_ci} 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci 464bf215546Sopenharmony_cistatic void 465bf215546Sopenharmony_cilp_llvm_image_soa_destroy(struct lp_build_image_soa *image) 466bf215546Sopenharmony_ci{ 467bf215546Sopenharmony_ci FREE(image); 468bf215546Sopenharmony_ci} 469bf215546Sopenharmony_ci 470bf215546Sopenharmony_ci 471bf215546Sopenharmony_cistatic void 472bf215546Sopenharmony_cilp_llvm_image_soa_emit_op(const struct lp_build_image_soa *base, 473bf215546Sopenharmony_ci struct gallivm_state *gallivm, 474bf215546Sopenharmony_ci const struct lp_img_params *params) 475bf215546Sopenharmony_ci{ 476bf215546Sopenharmony_ci struct lp_llvm_image_soa *image = (struct lp_llvm_image_soa *)base; 477bf215546Sopenharmony_ci const unsigned image_index = params->image_index; 478bf215546Sopenharmony_ci assert(image_index < PIPE_MAX_SHADER_IMAGES); 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_ci if (params->image_index_offset) { 481bf215546Sopenharmony_ci struct lp_build_img_op_array_switch switch_info; 482bf215546Sopenharmony_ci memset(&switch_info, 0, sizeof(switch_info)); 483bf215546Sopenharmony_ci LLVMValueRef unit = LLVMBuildAdd(gallivm->builder, 484bf215546Sopenharmony_ci params->image_index_offset, 485bf215546Sopenharmony_ci lp_build_const_int32(gallivm, 486bf215546Sopenharmony_ci image_index), ""); 487bf215546Sopenharmony_ci 488bf215546Sopenharmony_ci lp_build_image_op_switch_soa(&switch_info, gallivm, params, 489bf215546Sopenharmony_ci unit, 0, image->nr_images); 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci for (unsigned i = 0; i < image->nr_images; i++) { 492bf215546Sopenharmony_ci lp_build_image_op_array_case(&switch_info, i, 493bf215546Sopenharmony_ci &image->dynamic_state.static_state[i].image_state, 494bf215546Sopenharmony_ci &image->dynamic_state.base); 495bf215546Sopenharmony_ci } 496bf215546Sopenharmony_ci lp_build_image_op_array_fini_soa(&switch_info); 497bf215546Sopenharmony_ci } else { 498bf215546Sopenharmony_ci lp_build_img_op_soa(&image->dynamic_state.static_state[image_index].image_state, 499bf215546Sopenharmony_ci &image->dynamic_state.base, 500bf215546Sopenharmony_ci gallivm, params, params->outdata); 501bf215546Sopenharmony_ci } 502bf215546Sopenharmony_ci} 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_ci 505bf215546Sopenharmony_ci/** 506bf215546Sopenharmony_ci * Fetch the texture size. 507bf215546Sopenharmony_ci */ 508bf215546Sopenharmony_cistatic void 509bf215546Sopenharmony_cilp_llvm_image_soa_emit_size_query(const struct lp_build_image_soa *base, 510bf215546Sopenharmony_ci struct gallivm_state *gallivm, 511bf215546Sopenharmony_ci const struct lp_sampler_size_query_params *params) 512bf215546Sopenharmony_ci{ 513bf215546Sopenharmony_ci struct lp_llvm_image_soa *image = (struct lp_llvm_image_soa *)base; 514bf215546Sopenharmony_ci 515bf215546Sopenharmony_ci assert(params->texture_unit < PIPE_MAX_SHADER_IMAGES); 516bf215546Sopenharmony_ci 517bf215546Sopenharmony_ci lp_build_size_query_soa(gallivm, 518bf215546Sopenharmony_ci &image->dynamic_state.static_state[params->texture_unit].image_state, 519bf215546Sopenharmony_ci &image->dynamic_state.base, 520bf215546Sopenharmony_ci params); 521bf215546Sopenharmony_ci} 522bf215546Sopenharmony_ci 523bf215546Sopenharmony_ci 524bf215546Sopenharmony_cistruct lp_build_image_soa * 525bf215546Sopenharmony_cilp_llvm_image_soa_create(const struct lp_image_static_state *static_state, 526bf215546Sopenharmony_ci unsigned nr_images) 527bf215546Sopenharmony_ci{ 528bf215546Sopenharmony_ci struct lp_llvm_image_soa *image = CALLOC_STRUCT(lp_llvm_image_soa); 529bf215546Sopenharmony_ci if (!image) 530bf215546Sopenharmony_ci return NULL; 531bf215546Sopenharmony_ci 532bf215546Sopenharmony_ci image->base.destroy = lp_llvm_image_soa_destroy; 533bf215546Sopenharmony_ci image->base.emit_op = lp_llvm_image_soa_emit_op; 534bf215546Sopenharmony_ci image->base.emit_size_query = lp_llvm_image_soa_emit_size_query; 535bf215546Sopenharmony_ci 536bf215546Sopenharmony_ci image->dynamic_state.base.width = lp_llvm_image_width; 537bf215546Sopenharmony_ci image->dynamic_state.base.height = lp_llvm_image_height; 538bf215546Sopenharmony_ci 539bf215546Sopenharmony_ci image->dynamic_state.base.depth = lp_llvm_image_depth; 540bf215546Sopenharmony_ci image->dynamic_state.base.base_ptr = lp_llvm_image_base_ptr; 541bf215546Sopenharmony_ci image->dynamic_state.base.row_stride = lp_llvm_image_row_stride; 542bf215546Sopenharmony_ci image->dynamic_state.base.img_stride = lp_llvm_image_img_stride; 543bf215546Sopenharmony_ci image->dynamic_state.base.num_samples = lp_llvm_image_num_samples; 544bf215546Sopenharmony_ci image->dynamic_state.base.sample_stride = lp_llvm_image_sample_stride; 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci image->dynamic_state.static_state = static_state; 547bf215546Sopenharmony_ci 548bf215546Sopenharmony_ci image->nr_images = nr_images; 549bf215546Sopenharmony_ci return &image->base; 550bf215546Sopenharmony_ci} 551