1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2010 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 * @author Jose Fonseca <jfonseca@vmware.com> 31bf215546Sopenharmony_ci */ 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci#include "pipe/p_defines.h" 34bf215546Sopenharmony_ci#include "pipe/p_shader_tokens.h" 35bf215546Sopenharmony_ci#include "gallivm/lp_bld_const.h" 36bf215546Sopenharmony_ci#include "gallivm/lp_bld_debug.h" 37bf215546Sopenharmony_ci#include "gallivm/lp_bld_type.h" 38bf215546Sopenharmony_ci#include "gallivm/lp_bld_sample.h" 39bf215546Sopenharmony_ci#include "gallivm/lp_bld_tgsi.h" 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci#include "util/u_debug.h" 43bf215546Sopenharmony_ci#include "util/u_memory.h" 44bf215546Sopenharmony_ci#include "util/u_pointer.h" 45bf215546Sopenharmony_ci#include "util/u_string.h" 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci#include "draw_llvm.h" 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci/** 51bf215546Sopenharmony_ci * This provides the bridge between the sampler state store in 52bf215546Sopenharmony_ci * lp_jit_context and lp_jit_texture and the sampler code 53bf215546Sopenharmony_ci * generator. It provides the texture layout information required by 54bf215546Sopenharmony_ci * the texture sampler code generator in terms of the state stored in 55bf215546Sopenharmony_ci * lp_jit_context and lp_jit_texture in runtime. 56bf215546Sopenharmony_ci */ 57bf215546Sopenharmony_cistruct draw_llvm_sampler_dynamic_state 58bf215546Sopenharmony_ci{ 59bf215546Sopenharmony_ci struct lp_sampler_dynamic_state base; 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci const struct draw_sampler_static_state *static_state; 62bf215546Sopenharmony_ci}; 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci/** 66bf215546Sopenharmony_ci * This is the bridge between our sampler and the TGSI translator. 67bf215546Sopenharmony_ci */ 68bf215546Sopenharmony_cistruct draw_llvm_sampler_soa 69bf215546Sopenharmony_ci{ 70bf215546Sopenharmony_ci struct lp_build_sampler_soa base; 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci struct draw_llvm_sampler_dynamic_state dynamic_state; 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci unsigned nr_samplers; 75bf215546Sopenharmony_ci}; 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_cistruct draw_llvm_image_dynamic_state 78bf215546Sopenharmony_ci{ 79bf215546Sopenharmony_ci struct lp_sampler_dynamic_state base; 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci const struct draw_image_static_state *static_state; 82bf215546Sopenharmony_ci}; 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_cistruct draw_llvm_image_soa 85bf215546Sopenharmony_ci{ 86bf215546Sopenharmony_ci struct lp_build_image_soa base; 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci struct draw_llvm_image_dynamic_state dynamic_state; 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci unsigned nr_images; 91bf215546Sopenharmony_ci}; 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci/** 94bf215546Sopenharmony_ci * Fetch the specified member of the lp_jit_texture structure. 95bf215546Sopenharmony_ci * \param emit_load if TRUE, emit the LLVM load instruction to actually 96bf215546Sopenharmony_ci * fetch the field's value. Otherwise, just emit the 97bf215546Sopenharmony_ci * GEP code to address the field. 98bf215546Sopenharmony_ci * 99bf215546Sopenharmony_ci * @sa http://llvm.org/docs/GetElementPtr.html 100bf215546Sopenharmony_ci */ 101bf215546Sopenharmony_cistatic LLVMValueRef 102bf215546Sopenharmony_cidraw_llvm_texture_member(const struct lp_sampler_dynamic_state *base, 103bf215546Sopenharmony_ci struct gallivm_state *gallivm, 104bf215546Sopenharmony_ci LLVMValueRef context_ptr, 105bf215546Sopenharmony_ci unsigned texture_unit, 106bf215546Sopenharmony_ci LLVMValueRef texture_unit_offset, 107bf215546Sopenharmony_ci unsigned member_index, 108bf215546Sopenharmony_ci const char *member_name, 109bf215546Sopenharmony_ci boolean emit_load) 110bf215546Sopenharmony_ci{ 111bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 112bf215546Sopenharmony_ci LLVMValueRef indices[4]; 113bf215546Sopenharmony_ci LLVMValueRef ptr; 114bf215546Sopenharmony_ci LLVMValueRef res; 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci assert(texture_unit < PIPE_MAX_SHADER_SAMPLER_VIEWS); 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci /* context[0] */ 119bf215546Sopenharmony_ci indices[0] = lp_build_const_int32(gallivm, 0); 120bf215546Sopenharmony_ci /* context[0].textures */ 121bf215546Sopenharmony_ci indices[1] = lp_build_const_int32(gallivm, DRAW_JIT_CTX_TEXTURES); 122bf215546Sopenharmony_ci /* context[0].textures[unit] */ 123bf215546Sopenharmony_ci indices[2] = lp_build_const_int32(gallivm, texture_unit); 124bf215546Sopenharmony_ci if (texture_unit_offset) { 125bf215546Sopenharmony_ci indices[2] = LLVMBuildAdd(gallivm->builder, indices[2], texture_unit_offset, ""); 126bf215546Sopenharmony_ci LLVMValueRef cond = LLVMBuildICmp(gallivm->builder, LLVMIntULT, indices[2], lp_build_const_int32(gallivm, PIPE_MAX_SHADER_SAMPLER_VIEWS), ""); 127bf215546Sopenharmony_ci indices[2] = LLVMBuildSelect(gallivm->builder, cond, indices[2], lp_build_const_int32(gallivm, texture_unit), ""); 128bf215546Sopenharmony_ci } 129bf215546Sopenharmony_ci /* context[0].textures[unit].member */ 130bf215546Sopenharmony_ci indices[3] = lp_build_const_int32(gallivm, member_index); 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci ptr = LLVMBuildGEP(builder, context_ptr, indices, ARRAY_SIZE(indices), ""); 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci if (emit_load) 135bf215546Sopenharmony_ci res = LLVMBuildLoad(builder, ptr, ""); 136bf215546Sopenharmony_ci else 137bf215546Sopenharmony_ci res = ptr; 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci lp_build_name(res, "context.texture%u.%s", texture_unit, member_name); 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci return res; 142bf215546Sopenharmony_ci} 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci/** 146bf215546Sopenharmony_ci * Fetch the specified member of the lp_jit_sampler structure. 147bf215546Sopenharmony_ci * \param emit_load if TRUE, emit the LLVM load instruction to actually 148bf215546Sopenharmony_ci * fetch the field's value. Otherwise, just emit the 149bf215546Sopenharmony_ci * GEP code to address the field. 150bf215546Sopenharmony_ci * 151bf215546Sopenharmony_ci * @sa http://llvm.org/docs/GetElementPtr.html 152bf215546Sopenharmony_ci */ 153bf215546Sopenharmony_cistatic LLVMValueRef 154bf215546Sopenharmony_cidraw_llvm_sampler_member(const struct lp_sampler_dynamic_state *base, 155bf215546Sopenharmony_ci struct gallivm_state *gallivm, 156bf215546Sopenharmony_ci LLVMValueRef context_ptr, 157bf215546Sopenharmony_ci unsigned sampler_unit, 158bf215546Sopenharmony_ci unsigned member_index, 159bf215546Sopenharmony_ci const char *member_name, 160bf215546Sopenharmony_ci boolean emit_load) 161bf215546Sopenharmony_ci{ 162bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 163bf215546Sopenharmony_ci LLVMValueRef indices[4]; 164bf215546Sopenharmony_ci LLVMValueRef ptr; 165bf215546Sopenharmony_ci LLVMValueRef res; 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci assert(sampler_unit < PIPE_MAX_SAMPLERS); 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci /* context[0] */ 170bf215546Sopenharmony_ci indices[0] = lp_build_const_int32(gallivm, 0); 171bf215546Sopenharmony_ci /* context[0].samplers */ 172bf215546Sopenharmony_ci indices[1] = lp_build_const_int32(gallivm, DRAW_JIT_CTX_SAMPLERS); 173bf215546Sopenharmony_ci /* context[0].samplers[unit] */ 174bf215546Sopenharmony_ci indices[2] = lp_build_const_int32(gallivm, sampler_unit); 175bf215546Sopenharmony_ci /* context[0].samplers[unit].member */ 176bf215546Sopenharmony_ci indices[3] = lp_build_const_int32(gallivm, member_index); 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci ptr = LLVMBuildGEP(builder, context_ptr, indices, ARRAY_SIZE(indices), ""); 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci if (emit_load) 181bf215546Sopenharmony_ci res = LLVMBuildLoad(builder, ptr, ""); 182bf215546Sopenharmony_ci else 183bf215546Sopenharmony_ci res = ptr; 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci lp_build_name(res, "context.sampler%u.%s", sampler_unit, member_name); 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ci return res; 188bf215546Sopenharmony_ci} 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci/** 191bf215546Sopenharmony_ci * Fetch the specified member of the lp_jit_texture structure. 192bf215546Sopenharmony_ci * \param emit_load if TRUE, emit the LLVM load instruction to actually 193bf215546Sopenharmony_ci * fetch the field's value. Otherwise, just emit the 194bf215546Sopenharmony_ci * GEP code to address the field. 195bf215546Sopenharmony_ci * 196bf215546Sopenharmony_ci * @sa http://llvm.org/docs/GetElementPtr.html 197bf215546Sopenharmony_ci */ 198bf215546Sopenharmony_cistatic LLVMValueRef 199bf215546Sopenharmony_cidraw_llvm_image_member(const struct lp_sampler_dynamic_state *base, 200bf215546Sopenharmony_ci struct gallivm_state *gallivm, 201bf215546Sopenharmony_ci LLVMValueRef context_ptr, 202bf215546Sopenharmony_ci unsigned image_unit, 203bf215546Sopenharmony_ci LLVMValueRef image_unit_offset, 204bf215546Sopenharmony_ci unsigned member_index, 205bf215546Sopenharmony_ci const char *member_name, 206bf215546Sopenharmony_ci boolean emit_load) 207bf215546Sopenharmony_ci{ 208bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 209bf215546Sopenharmony_ci LLVMValueRef indices[4]; 210bf215546Sopenharmony_ci LLVMValueRef ptr; 211bf215546Sopenharmony_ci LLVMValueRef res; 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci assert(image_unit < PIPE_MAX_SHADER_IMAGES); 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci /* context[0] */ 216bf215546Sopenharmony_ci indices[0] = lp_build_const_int32(gallivm, 0); 217bf215546Sopenharmony_ci /* context[0].textures */ 218bf215546Sopenharmony_ci indices[1] = lp_build_const_int32(gallivm, DRAW_JIT_CTX_IMAGES); 219bf215546Sopenharmony_ci /* context[0].textures[unit] */ 220bf215546Sopenharmony_ci indices[2] = lp_build_const_int32(gallivm, image_unit); 221bf215546Sopenharmony_ci if (image_unit_offset) { 222bf215546Sopenharmony_ci indices[2] = LLVMBuildAdd(gallivm->builder, indices[2], image_unit_offset, ""); 223bf215546Sopenharmony_ci LLVMValueRef cond = LLVMBuildICmp(gallivm->builder, LLVMIntULT, indices[2], lp_build_const_int32(gallivm, PIPE_MAX_SHADER_IMAGES), ""); 224bf215546Sopenharmony_ci indices[2] = LLVMBuildSelect(gallivm->builder, cond, indices[2], lp_build_const_int32(gallivm, image_unit), ""); 225bf215546Sopenharmony_ci } 226bf215546Sopenharmony_ci /* context[0].textures[unit].member */ 227bf215546Sopenharmony_ci indices[3] = lp_build_const_int32(gallivm, member_index); 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci ptr = LLVMBuildGEP(builder, context_ptr, indices, ARRAY_SIZE(indices), ""); 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci if (emit_load) 232bf215546Sopenharmony_ci res = LLVMBuildLoad(builder, ptr, ""); 233bf215546Sopenharmony_ci else 234bf215546Sopenharmony_ci res = ptr; 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_ci lp_build_name(res, "context.image%u.%s", image_unit, member_name); 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci return res; 239bf215546Sopenharmony_ci} 240bf215546Sopenharmony_ci 241bf215546Sopenharmony_ci/** 242bf215546Sopenharmony_ci * Helper macro to instantiate the functions that generate the code to 243bf215546Sopenharmony_ci * fetch the members of lp_jit_texture to fulfill the sampler code 244bf215546Sopenharmony_ci * generator requests. 245bf215546Sopenharmony_ci * 246bf215546Sopenharmony_ci * This complexity is the price we have to pay to keep the texture 247bf215546Sopenharmony_ci * sampler code generator a reusable module without dependencies to 248bf215546Sopenharmony_ci * llvmpipe internals. 249bf215546Sopenharmony_ci */ 250bf215546Sopenharmony_ci#define DRAW_LLVM_TEXTURE_MEMBER(_name, _index, _emit_load) \ 251bf215546Sopenharmony_ci static LLVMValueRef \ 252bf215546Sopenharmony_ci draw_llvm_texture_##_name( const struct lp_sampler_dynamic_state *base, \ 253bf215546Sopenharmony_ci struct gallivm_state *gallivm, \ 254bf215546Sopenharmony_ci LLVMValueRef context_ptr, \ 255bf215546Sopenharmony_ci unsigned texture_unit, \ 256bf215546Sopenharmony_ci LLVMValueRef texture_unit_offset) \ 257bf215546Sopenharmony_ci { \ 258bf215546Sopenharmony_ci return draw_llvm_texture_member(base, gallivm, context_ptr, \ 259bf215546Sopenharmony_ci texture_unit, texture_unit_offset, \ 260bf215546Sopenharmony_ci _index, #_name, _emit_load ); \ 261bf215546Sopenharmony_ci } 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ciDRAW_LLVM_TEXTURE_MEMBER(width, DRAW_JIT_TEXTURE_WIDTH, TRUE) 265bf215546Sopenharmony_ciDRAW_LLVM_TEXTURE_MEMBER(height, DRAW_JIT_TEXTURE_HEIGHT, TRUE) 266bf215546Sopenharmony_ciDRAW_LLVM_TEXTURE_MEMBER(depth, DRAW_JIT_TEXTURE_DEPTH, TRUE) 267bf215546Sopenharmony_ciDRAW_LLVM_TEXTURE_MEMBER(first_level,DRAW_JIT_TEXTURE_FIRST_LEVEL, TRUE) 268bf215546Sopenharmony_ciDRAW_LLVM_TEXTURE_MEMBER(last_level, DRAW_JIT_TEXTURE_LAST_LEVEL, TRUE) 269bf215546Sopenharmony_ciDRAW_LLVM_TEXTURE_MEMBER(base_ptr, DRAW_JIT_TEXTURE_BASE, TRUE) 270bf215546Sopenharmony_ciDRAW_LLVM_TEXTURE_MEMBER(row_stride, DRAW_JIT_TEXTURE_ROW_STRIDE, FALSE) 271bf215546Sopenharmony_ciDRAW_LLVM_TEXTURE_MEMBER(img_stride, DRAW_JIT_TEXTURE_IMG_STRIDE, FALSE) 272bf215546Sopenharmony_ciDRAW_LLVM_TEXTURE_MEMBER(mip_offsets, DRAW_JIT_TEXTURE_MIP_OFFSETS, FALSE) 273bf215546Sopenharmony_ciDRAW_LLVM_TEXTURE_MEMBER(num_samples, DRAW_JIT_TEXTURE_NUM_SAMPLES, TRUE) 274bf215546Sopenharmony_ciDRAW_LLVM_TEXTURE_MEMBER(sample_stride, DRAW_JIT_TEXTURE_SAMPLE_STRIDE, TRUE) 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_ci#define DRAW_LLVM_SAMPLER_MEMBER(_name, _index, _emit_load) \ 277bf215546Sopenharmony_ci static LLVMValueRef \ 278bf215546Sopenharmony_ci draw_llvm_sampler_##_name( const struct lp_sampler_dynamic_state *base, \ 279bf215546Sopenharmony_ci struct gallivm_state *gallivm, \ 280bf215546Sopenharmony_ci LLVMValueRef context_ptr, \ 281bf215546Sopenharmony_ci unsigned sampler_unit) \ 282bf215546Sopenharmony_ci { \ 283bf215546Sopenharmony_ci return draw_llvm_sampler_member(base, gallivm, context_ptr, \ 284bf215546Sopenharmony_ci sampler_unit, _index, #_name, _emit_load ); \ 285bf215546Sopenharmony_ci } 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_ciDRAW_LLVM_SAMPLER_MEMBER(min_lod, DRAW_JIT_SAMPLER_MIN_LOD, TRUE) 289bf215546Sopenharmony_ciDRAW_LLVM_SAMPLER_MEMBER(max_lod, DRAW_JIT_SAMPLER_MAX_LOD, TRUE) 290bf215546Sopenharmony_ciDRAW_LLVM_SAMPLER_MEMBER(lod_bias, DRAW_JIT_SAMPLER_LOD_BIAS, TRUE) 291bf215546Sopenharmony_ciDRAW_LLVM_SAMPLER_MEMBER(border_color, DRAW_JIT_SAMPLER_BORDER_COLOR, FALSE) 292bf215546Sopenharmony_ciDRAW_LLVM_SAMPLER_MEMBER(max_aniso, DRAW_JIT_SAMPLER_MAX_ANISO, TRUE) 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci#define DRAW_LLVM_IMAGE_MEMBER(_name, _index, _emit_load) \ 295bf215546Sopenharmony_ci static LLVMValueRef \ 296bf215546Sopenharmony_ci draw_llvm_image_##_name( const struct lp_sampler_dynamic_state *base, \ 297bf215546Sopenharmony_ci struct gallivm_state *gallivm, \ 298bf215546Sopenharmony_ci LLVMValueRef context_ptr, \ 299bf215546Sopenharmony_ci unsigned image_unit, LLVMValueRef image_unit_offset) \ 300bf215546Sopenharmony_ci { \ 301bf215546Sopenharmony_ci return draw_llvm_image_member(base, gallivm, context_ptr, \ 302bf215546Sopenharmony_ci image_unit, image_unit_offset, \ 303bf215546Sopenharmony_ci _index, #_name, _emit_load ); \ 304bf215546Sopenharmony_ci } 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ciDRAW_LLVM_IMAGE_MEMBER(width, DRAW_JIT_IMAGE_WIDTH, TRUE) 308bf215546Sopenharmony_ciDRAW_LLVM_IMAGE_MEMBER(height, DRAW_JIT_IMAGE_HEIGHT, TRUE) 309bf215546Sopenharmony_ciDRAW_LLVM_IMAGE_MEMBER(depth, DRAW_JIT_IMAGE_DEPTH, TRUE) 310bf215546Sopenharmony_ciDRAW_LLVM_IMAGE_MEMBER(base_ptr, DRAW_JIT_IMAGE_BASE, TRUE) 311bf215546Sopenharmony_ciDRAW_LLVM_IMAGE_MEMBER(row_stride, DRAW_JIT_IMAGE_ROW_STRIDE, TRUE) 312bf215546Sopenharmony_ciDRAW_LLVM_IMAGE_MEMBER(img_stride, DRAW_JIT_IMAGE_IMG_STRIDE, TRUE) 313bf215546Sopenharmony_ciDRAW_LLVM_IMAGE_MEMBER(num_samples, DRAW_JIT_IMAGE_NUM_SAMPLES, TRUE) 314bf215546Sopenharmony_ciDRAW_LLVM_IMAGE_MEMBER(sample_stride, DRAW_JIT_IMAGE_SAMPLE_STRIDE, TRUE) 315bf215546Sopenharmony_ci 316bf215546Sopenharmony_cistatic void 317bf215546Sopenharmony_cidraw_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler) 318bf215546Sopenharmony_ci{ 319bf215546Sopenharmony_ci FREE(sampler); 320bf215546Sopenharmony_ci} 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci/** 324bf215546Sopenharmony_ci * Fetch filtered values from texture. 325bf215546Sopenharmony_ci * The 'texel' parameter returns four vectors corresponding to R, G, B, A. 326bf215546Sopenharmony_ci */ 327bf215546Sopenharmony_cistatic void 328bf215546Sopenharmony_cidraw_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base, 329bf215546Sopenharmony_ci struct gallivm_state *gallivm, 330bf215546Sopenharmony_ci const struct lp_sampler_params *params) 331bf215546Sopenharmony_ci{ 332bf215546Sopenharmony_ci struct draw_llvm_sampler_soa *sampler = (struct draw_llvm_sampler_soa *)base; 333bf215546Sopenharmony_ci unsigned texture_index = params->texture_index; 334bf215546Sopenharmony_ci unsigned sampler_index = params->sampler_index; 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci assert(texture_index < PIPE_MAX_SHADER_SAMPLER_VIEWS); 337bf215546Sopenharmony_ci assert(sampler_index < PIPE_MAX_SAMPLERS); 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci if (params->texture_index_offset) { 340bf215546Sopenharmony_ci struct lp_build_sample_array_switch switch_info; 341bf215546Sopenharmony_ci memset(&switch_info, 0, sizeof(switch_info)); 342bf215546Sopenharmony_ci LLVMValueRef unit = LLVMBuildAdd(gallivm->builder, params->texture_index_offset, 343bf215546Sopenharmony_ci lp_build_const_int32(gallivm, texture_index), ""); 344bf215546Sopenharmony_ci lp_build_sample_array_init_soa(&switch_info, gallivm, params, unit, 345bf215546Sopenharmony_ci 0, sampler->nr_samplers); 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci for (unsigned i = 0; i < sampler->nr_samplers; i++) { 348bf215546Sopenharmony_ci lp_build_sample_array_case_soa(&switch_info, i, 349bf215546Sopenharmony_ci &sampler->dynamic_state.static_state[i].texture_state, 350bf215546Sopenharmony_ci &sampler->dynamic_state.static_state[i].sampler_state, 351bf215546Sopenharmony_ci &sampler->dynamic_state.base); 352bf215546Sopenharmony_ci } 353bf215546Sopenharmony_ci lp_build_sample_array_fini_soa(&switch_info); 354bf215546Sopenharmony_ci } else { 355bf215546Sopenharmony_ci lp_build_sample_soa(&sampler->dynamic_state.static_state[texture_index].texture_state, 356bf215546Sopenharmony_ci &sampler->dynamic_state.static_state[sampler_index].sampler_state, 357bf215546Sopenharmony_ci &sampler->dynamic_state.base, 358bf215546Sopenharmony_ci gallivm, params); 359bf215546Sopenharmony_ci } 360bf215546Sopenharmony_ci} 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci/** 364bf215546Sopenharmony_ci * Fetch the texture size. 365bf215546Sopenharmony_ci */ 366bf215546Sopenharmony_cistatic void 367bf215546Sopenharmony_cidraw_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa *base, 368bf215546Sopenharmony_ci struct gallivm_state *gallivm, 369bf215546Sopenharmony_ci const struct lp_sampler_size_query_params *params) 370bf215546Sopenharmony_ci{ 371bf215546Sopenharmony_ci struct draw_llvm_sampler_soa *sampler = (struct draw_llvm_sampler_soa *)base; 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci assert(params->texture_unit < PIPE_MAX_SHADER_SAMPLER_VIEWS); 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_ci lp_build_size_query_soa(gallivm, 376bf215546Sopenharmony_ci &sampler->dynamic_state.static_state[params->texture_unit].texture_state, 377bf215546Sopenharmony_ci &sampler->dynamic_state.base, 378bf215546Sopenharmony_ci params); 379bf215546Sopenharmony_ci} 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_cistruct lp_build_sampler_soa * 382bf215546Sopenharmony_cidraw_llvm_sampler_soa_create(const struct draw_sampler_static_state *static_state, 383bf215546Sopenharmony_ci unsigned nr_samplers) 384bf215546Sopenharmony_ci{ 385bf215546Sopenharmony_ci struct draw_llvm_sampler_soa *sampler; 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_ci sampler = CALLOC_STRUCT(draw_llvm_sampler_soa); 388bf215546Sopenharmony_ci if (!sampler) 389bf215546Sopenharmony_ci return NULL; 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_ci sampler->base.destroy = draw_llvm_sampler_soa_destroy; 392bf215546Sopenharmony_ci sampler->base.emit_tex_sample = draw_llvm_sampler_soa_emit_fetch_texel; 393bf215546Sopenharmony_ci sampler->base.emit_size_query = draw_llvm_sampler_soa_emit_size_query; 394bf215546Sopenharmony_ci sampler->dynamic_state.base.width = draw_llvm_texture_width; 395bf215546Sopenharmony_ci sampler->dynamic_state.base.height = draw_llvm_texture_height; 396bf215546Sopenharmony_ci sampler->dynamic_state.base.depth = draw_llvm_texture_depth; 397bf215546Sopenharmony_ci sampler->dynamic_state.base.first_level = draw_llvm_texture_first_level; 398bf215546Sopenharmony_ci sampler->dynamic_state.base.last_level = draw_llvm_texture_last_level; 399bf215546Sopenharmony_ci sampler->dynamic_state.base.row_stride = draw_llvm_texture_row_stride; 400bf215546Sopenharmony_ci sampler->dynamic_state.base.img_stride = draw_llvm_texture_img_stride; 401bf215546Sopenharmony_ci sampler->dynamic_state.base.base_ptr = draw_llvm_texture_base_ptr; 402bf215546Sopenharmony_ci sampler->dynamic_state.base.mip_offsets = draw_llvm_texture_mip_offsets; 403bf215546Sopenharmony_ci sampler->dynamic_state.base.num_samples = draw_llvm_texture_num_samples; 404bf215546Sopenharmony_ci sampler->dynamic_state.base.sample_stride = draw_llvm_texture_sample_stride; 405bf215546Sopenharmony_ci sampler->dynamic_state.base.min_lod = draw_llvm_sampler_min_lod; 406bf215546Sopenharmony_ci sampler->dynamic_state.base.max_lod = draw_llvm_sampler_max_lod; 407bf215546Sopenharmony_ci sampler->dynamic_state.base.lod_bias = draw_llvm_sampler_lod_bias; 408bf215546Sopenharmony_ci sampler->dynamic_state.base.border_color = draw_llvm_sampler_border_color; 409bf215546Sopenharmony_ci sampler->dynamic_state.base.max_aniso = draw_llvm_sampler_max_aniso; 410bf215546Sopenharmony_ci sampler->dynamic_state.static_state = static_state; 411bf215546Sopenharmony_ci 412bf215546Sopenharmony_ci sampler->nr_samplers = nr_samplers; 413bf215546Sopenharmony_ci return &sampler->base; 414bf215546Sopenharmony_ci} 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_cistatic void 417bf215546Sopenharmony_cidraw_llvm_image_soa_emit_op(const struct lp_build_image_soa *base, 418bf215546Sopenharmony_ci struct gallivm_state *gallivm, 419bf215546Sopenharmony_ci const struct lp_img_params *params) 420bf215546Sopenharmony_ci{ 421bf215546Sopenharmony_ci struct draw_llvm_image_soa *image = (struct draw_llvm_image_soa *)base; 422bf215546Sopenharmony_ci unsigned image_index = params->image_index; 423bf215546Sopenharmony_ci assert(image_index < PIPE_MAX_SHADER_IMAGES); 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_ci if (params->image_index_offset) { 426bf215546Sopenharmony_ci struct lp_build_img_op_array_switch switch_info; 427bf215546Sopenharmony_ci memset(&switch_info, 0, sizeof(switch_info)); 428bf215546Sopenharmony_ci LLVMValueRef unit = LLVMBuildAdd(gallivm->builder, params->image_index_offset, 429bf215546Sopenharmony_ci lp_build_const_int32(gallivm, image_index), ""); 430bf215546Sopenharmony_ci lp_build_image_op_switch_soa(&switch_info, gallivm, params, 431bf215546Sopenharmony_ci unit, 0, image->nr_images); 432bf215546Sopenharmony_ci 433bf215546Sopenharmony_ci for (unsigned i = 0; i < image->nr_images; i++) { 434bf215546Sopenharmony_ci lp_build_image_op_array_case(&switch_info, i, 435bf215546Sopenharmony_ci &image->dynamic_state.static_state[i].image_state, 436bf215546Sopenharmony_ci &image->dynamic_state.base); 437bf215546Sopenharmony_ci } 438bf215546Sopenharmony_ci lp_build_image_op_array_fini_soa(&switch_info); 439bf215546Sopenharmony_ci return; 440bf215546Sopenharmony_ci } 441bf215546Sopenharmony_ci lp_build_img_op_soa(&image->dynamic_state.static_state[image_index].image_state, 442bf215546Sopenharmony_ci &image->dynamic_state.base, 443bf215546Sopenharmony_ci gallivm, params, params->outdata); 444bf215546Sopenharmony_ci} 445bf215546Sopenharmony_ci/** 446bf215546Sopenharmony_ci * Fetch the texture size. 447bf215546Sopenharmony_ci */ 448bf215546Sopenharmony_cistatic void 449bf215546Sopenharmony_cidraw_llvm_image_soa_emit_size_query(const struct lp_build_image_soa *base, 450bf215546Sopenharmony_ci struct gallivm_state *gallivm, 451bf215546Sopenharmony_ci const struct lp_sampler_size_query_params *params) 452bf215546Sopenharmony_ci{ 453bf215546Sopenharmony_ci struct draw_llvm_image_soa *image = (struct draw_llvm_image_soa *)base; 454bf215546Sopenharmony_ci 455bf215546Sopenharmony_ci assert(params->texture_unit < PIPE_MAX_SHADER_IMAGES); 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci lp_build_size_query_soa(gallivm, 458bf215546Sopenharmony_ci &image->dynamic_state.static_state[params->texture_unit].image_state, 459bf215546Sopenharmony_ci &image->dynamic_state.base, 460bf215546Sopenharmony_ci params); 461bf215546Sopenharmony_ci} 462bf215546Sopenharmony_cistatic void 463bf215546Sopenharmony_cidraw_llvm_image_soa_destroy(struct lp_build_image_soa *image) 464bf215546Sopenharmony_ci{ 465bf215546Sopenharmony_ci FREE(image); 466bf215546Sopenharmony_ci} 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_cistruct lp_build_image_soa * 469bf215546Sopenharmony_cidraw_llvm_image_soa_create(const struct draw_image_static_state *static_state, 470bf215546Sopenharmony_ci unsigned nr_images) 471bf215546Sopenharmony_ci{ 472bf215546Sopenharmony_ci struct draw_llvm_image_soa *image; 473bf215546Sopenharmony_ci 474bf215546Sopenharmony_ci image = CALLOC_STRUCT(draw_llvm_image_soa); 475bf215546Sopenharmony_ci if (!image) 476bf215546Sopenharmony_ci return NULL; 477bf215546Sopenharmony_ci 478bf215546Sopenharmony_ci image->base.destroy = draw_llvm_image_soa_destroy; 479bf215546Sopenharmony_ci image->base.emit_op = draw_llvm_image_soa_emit_op; 480bf215546Sopenharmony_ci image->base.emit_size_query = draw_llvm_image_soa_emit_size_query; 481bf215546Sopenharmony_ci 482bf215546Sopenharmony_ci image->dynamic_state.base.width = draw_llvm_image_width; 483bf215546Sopenharmony_ci image->dynamic_state.base.height = draw_llvm_image_height; 484bf215546Sopenharmony_ci 485bf215546Sopenharmony_ci image->dynamic_state.base.depth = draw_llvm_image_depth; 486bf215546Sopenharmony_ci image->dynamic_state.base.base_ptr = draw_llvm_image_base_ptr; 487bf215546Sopenharmony_ci image->dynamic_state.base.row_stride = draw_llvm_image_row_stride; 488bf215546Sopenharmony_ci image->dynamic_state.base.img_stride = draw_llvm_image_img_stride; 489bf215546Sopenharmony_ci image->dynamic_state.base.num_samples = draw_llvm_image_num_samples; 490bf215546Sopenharmony_ci image->dynamic_state.base.sample_stride = draw_llvm_image_sample_stride; 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci image->dynamic_state.static_state = static_state; 493bf215546Sopenharmony_ci 494bf215546Sopenharmony_ci image->nr_images = nr_images; 495bf215546Sopenharmony_ci return &image->base; 496bf215546Sopenharmony_ci} 497