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#include "draw_llvm.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "draw_context.h" 31bf215546Sopenharmony_ci#include "draw_vs.h" 32bf215546Sopenharmony_ci#include "draw_gs.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci#include "gallivm/lp_bld_arit.h" 35bf215546Sopenharmony_ci#include "gallivm/lp_bld_arit_overflow.h" 36bf215546Sopenharmony_ci#include "gallivm/lp_bld_bitarit.h" 37bf215546Sopenharmony_ci#include "gallivm/lp_bld_gather.h" 38bf215546Sopenharmony_ci#include "gallivm/lp_bld_logic.h" 39bf215546Sopenharmony_ci#include "gallivm/lp_bld_const.h" 40bf215546Sopenharmony_ci#include "gallivm/lp_bld_coro.h" 41bf215546Sopenharmony_ci#include "gallivm/lp_bld_swizzle.h" 42bf215546Sopenharmony_ci#include "gallivm/lp_bld_struct.h" 43bf215546Sopenharmony_ci#include "gallivm/lp_bld_type.h" 44bf215546Sopenharmony_ci#include "gallivm/lp_bld_flow.h" 45bf215546Sopenharmony_ci#include "gallivm/lp_bld_debug.h" 46bf215546Sopenharmony_ci#include "gallivm/lp_bld_tgsi.h" 47bf215546Sopenharmony_ci#include "gallivm/lp_bld_nir.h" 48bf215546Sopenharmony_ci#include "gallivm/lp_bld_printf.h" 49bf215546Sopenharmony_ci#include "gallivm/lp_bld_intr.h" 50bf215546Sopenharmony_ci#include "gallivm/lp_bld_init.h" 51bf215546Sopenharmony_ci#include "gallivm/lp_bld_type.h" 52bf215546Sopenharmony_ci#include "gallivm/lp_bld_pack.h" 53bf215546Sopenharmony_ci#include "gallivm/lp_bld_format.h" 54bf215546Sopenharmony_ci#include "gallivm/lp_bld_misc.h" 55bf215546Sopenharmony_ci#include "tgsi/tgsi_exec.h" 56bf215546Sopenharmony_ci#include "tgsi/tgsi_dump.h" 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci#include "util/u_math.h" 59bf215546Sopenharmony_ci#include "util/u_pointer.h" 60bf215546Sopenharmony_ci#include "util/u_string.h" 61bf215546Sopenharmony_ci#include "nir_serialize.h" 62bf215546Sopenharmony_ci#include "util/mesa-sha1.h" 63bf215546Sopenharmony_ci#define DEBUG_STORE 0 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_cistatic void 67bf215546Sopenharmony_cidraw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *var); 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_cistruct draw_gs_llvm_iface { 71bf215546Sopenharmony_ci struct lp_build_gs_iface base; 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ci struct draw_gs_llvm_variant *variant; 74bf215546Sopenharmony_ci LLVMValueRef input; 75bf215546Sopenharmony_ci}; 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_cistatic inline const struct draw_gs_llvm_iface * 78bf215546Sopenharmony_cidraw_gs_llvm_iface(const struct lp_build_gs_iface *iface) 79bf215546Sopenharmony_ci{ 80bf215546Sopenharmony_ci return (const struct draw_gs_llvm_iface *)iface; 81bf215546Sopenharmony_ci} 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_cistruct draw_tcs_llvm_iface { 84bf215546Sopenharmony_ci struct lp_build_tcs_iface base; 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci struct draw_tcs_llvm_variant *variant; 87bf215546Sopenharmony_ci LLVMValueRef input; 88bf215546Sopenharmony_ci LLVMValueRef output; 89bf215546Sopenharmony_ci}; 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_cistatic inline const struct draw_tcs_llvm_iface * 92bf215546Sopenharmony_cidraw_tcs_llvm_iface(const struct lp_build_tcs_iface *iface) 93bf215546Sopenharmony_ci{ 94bf215546Sopenharmony_ci return (const struct draw_tcs_llvm_iface *)iface; 95bf215546Sopenharmony_ci} 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_cistruct draw_tes_llvm_iface { 98bf215546Sopenharmony_ci struct lp_build_tes_iface base; 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci struct draw_tes_llvm_variant *variant; 101bf215546Sopenharmony_ci LLVMValueRef input; 102bf215546Sopenharmony_ci}; 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_cistatic inline const struct draw_tes_llvm_iface * 105bf215546Sopenharmony_cidraw_tes_llvm_iface(const struct lp_build_tes_iface *iface) 106bf215546Sopenharmony_ci{ 107bf215546Sopenharmony_ci return (const struct draw_tes_llvm_iface *)iface; 108bf215546Sopenharmony_ci} 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ci/** 111bf215546Sopenharmony_ci * Create LLVM type for draw_vertex_buffer. 112bf215546Sopenharmony_ci */ 113bf215546Sopenharmony_cistatic LLVMTypeRef 114bf215546Sopenharmony_cicreate_jit_dvbuffer_type(struct gallivm_state *gallivm, 115bf215546Sopenharmony_ci const char *struct_name) 116bf215546Sopenharmony_ci{ 117bf215546Sopenharmony_ci LLVMTargetDataRef target = gallivm->target; 118bf215546Sopenharmony_ci LLVMTypeRef dvbuffer_type; 119bf215546Sopenharmony_ci LLVMTypeRef elem_types[DRAW_JIT_DVBUFFER_NUM_FIELDS]; 120bf215546Sopenharmony_ci LLVMTypeRef int32_type = LLVMInt32TypeInContext(gallivm->context); 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci elem_types[DRAW_JIT_DVBUFFER_MAP] = 123bf215546Sopenharmony_ci LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 8), 0); 124bf215546Sopenharmony_ci elem_types[DRAW_JIT_DVBUFFER_SIZE] = int32_type; 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci dvbuffer_type = LLVMStructTypeInContext(gallivm->context, elem_types, 127bf215546Sopenharmony_ci ARRAY_SIZE(elem_types), 0); 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci (void) target; /* silence unused var warning for non-debug build */ 130bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_vertex_buffer, map, 131bf215546Sopenharmony_ci target, dvbuffer_type, 132bf215546Sopenharmony_ci DRAW_JIT_DVBUFFER_MAP); 133bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_vertex_buffer, size, 134bf215546Sopenharmony_ci target, dvbuffer_type, 135bf215546Sopenharmony_ci DRAW_JIT_DVBUFFER_SIZE); 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci return dvbuffer_type; 138bf215546Sopenharmony_ci} 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci/** 141bf215546Sopenharmony_ci * Create LLVM type for struct draw_jit_texture 142bf215546Sopenharmony_ci */ 143bf215546Sopenharmony_cistatic LLVMTypeRef 144bf215546Sopenharmony_cicreate_jit_texture_type(struct gallivm_state *gallivm, const char *struct_name) 145bf215546Sopenharmony_ci{ 146bf215546Sopenharmony_ci LLVMTargetDataRef target = gallivm->target; 147bf215546Sopenharmony_ci LLVMTypeRef texture_type; 148bf215546Sopenharmony_ci LLVMTypeRef elem_types[DRAW_JIT_TEXTURE_NUM_FIELDS]; 149bf215546Sopenharmony_ci LLVMTypeRef int32_type = LLVMInt32TypeInContext(gallivm->context); 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci elem_types[DRAW_JIT_TEXTURE_WIDTH] = 152bf215546Sopenharmony_ci elem_types[DRAW_JIT_TEXTURE_HEIGHT] = 153bf215546Sopenharmony_ci elem_types[DRAW_JIT_TEXTURE_DEPTH] = 154bf215546Sopenharmony_ci elem_types[DRAW_JIT_TEXTURE_NUM_SAMPLES] = 155bf215546Sopenharmony_ci elem_types[DRAW_JIT_TEXTURE_SAMPLE_STRIDE] = 156bf215546Sopenharmony_ci elem_types[DRAW_JIT_TEXTURE_FIRST_LEVEL] = 157bf215546Sopenharmony_ci elem_types[DRAW_JIT_TEXTURE_LAST_LEVEL] = int32_type; 158bf215546Sopenharmony_ci elem_types[DRAW_JIT_TEXTURE_BASE] = 159bf215546Sopenharmony_ci LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); 160bf215546Sopenharmony_ci elem_types[DRAW_JIT_TEXTURE_ROW_STRIDE] = 161bf215546Sopenharmony_ci elem_types[DRAW_JIT_TEXTURE_IMG_STRIDE] = 162bf215546Sopenharmony_ci elem_types[DRAW_JIT_TEXTURE_MIP_OFFSETS] = 163bf215546Sopenharmony_ci LLVMArrayType(int32_type, PIPE_MAX_TEXTURE_LEVELS); 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci texture_type = LLVMStructTypeInContext(gallivm->context, elem_types, 166bf215546Sopenharmony_ci ARRAY_SIZE(elem_types), 0); 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci (void) target; /* silence unused var warning for non-debug build */ 169bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, width, 170bf215546Sopenharmony_ci target, texture_type, 171bf215546Sopenharmony_ci DRAW_JIT_TEXTURE_WIDTH); 172bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, height, 173bf215546Sopenharmony_ci target, texture_type, 174bf215546Sopenharmony_ci DRAW_JIT_TEXTURE_HEIGHT); 175bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, depth, 176bf215546Sopenharmony_ci target, texture_type, 177bf215546Sopenharmony_ci DRAW_JIT_TEXTURE_DEPTH); 178bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, base, 179bf215546Sopenharmony_ci target, texture_type, 180bf215546Sopenharmony_ci DRAW_JIT_TEXTURE_BASE); 181bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, row_stride, 182bf215546Sopenharmony_ci target, texture_type, 183bf215546Sopenharmony_ci DRAW_JIT_TEXTURE_ROW_STRIDE); 184bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, img_stride, 185bf215546Sopenharmony_ci target, texture_type, 186bf215546Sopenharmony_ci DRAW_JIT_TEXTURE_IMG_STRIDE); 187bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, first_level, 188bf215546Sopenharmony_ci target, texture_type, 189bf215546Sopenharmony_ci DRAW_JIT_TEXTURE_FIRST_LEVEL); 190bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, last_level, 191bf215546Sopenharmony_ci target, texture_type, 192bf215546Sopenharmony_ci DRAW_JIT_TEXTURE_LAST_LEVEL); 193bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, mip_offsets, 194bf215546Sopenharmony_ci target, texture_type, 195bf215546Sopenharmony_ci DRAW_JIT_TEXTURE_MIP_OFFSETS); 196bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, num_samples, 197bf215546Sopenharmony_ci target, texture_type, 198bf215546Sopenharmony_ci DRAW_JIT_TEXTURE_NUM_SAMPLES); 199bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, sample_stride, 200bf215546Sopenharmony_ci target, texture_type, 201bf215546Sopenharmony_ci DRAW_JIT_TEXTURE_SAMPLE_STRIDE); 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci LP_CHECK_STRUCT_SIZE(struct draw_jit_texture, target, texture_type); 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci return texture_type; 206bf215546Sopenharmony_ci} 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci/** 210bf215546Sopenharmony_ci * Create LLVM type for struct draw_jit_sampler 211bf215546Sopenharmony_ci */ 212bf215546Sopenharmony_cistatic LLVMTypeRef 213bf215546Sopenharmony_cicreate_jit_sampler_type(struct gallivm_state *gallivm, const char *struct_name) 214bf215546Sopenharmony_ci{ 215bf215546Sopenharmony_ci LLVMTargetDataRef target = gallivm->target; 216bf215546Sopenharmony_ci LLVMTypeRef sampler_type; 217bf215546Sopenharmony_ci LLVMTypeRef elem_types[DRAW_JIT_SAMPLER_NUM_FIELDS]; 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci elem_types[DRAW_JIT_SAMPLER_MIN_LOD] = 220bf215546Sopenharmony_ci elem_types[DRAW_JIT_SAMPLER_MAX_LOD] = 221bf215546Sopenharmony_ci elem_types[DRAW_JIT_SAMPLER_LOD_BIAS] = 222bf215546Sopenharmony_ci elem_types[DRAW_JIT_SAMPLER_MAX_ANISO] = LLVMFloatTypeInContext(gallivm->context); 223bf215546Sopenharmony_ci elem_types[DRAW_JIT_SAMPLER_BORDER_COLOR] = 224bf215546Sopenharmony_ci LLVMArrayType(LLVMFloatTypeInContext(gallivm->context), 4); 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci sampler_type = LLVMStructTypeInContext(gallivm->context, elem_types, 227bf215546Sopenharmony_ci ARRAY_SIZE(elem_types), 0); 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci (void) target; /* silence unused var warning for non-debug build */ 230bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_sampler, min_lod, 231bf215546Sopenharmony_ci target, sampler_type, 232bf215546Sopenharmony_ci DRAW_JIT_SAMPLER_MIN_LOD); 233bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_sampler, max_lod, 234bf215546Sopenharmony_ci target, sampler_type, 235bf215546Sopenharmony_ci DRAW_JIT_SAMPLER_MAX_LOD); 236bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_sampler, lod_bias, 237bf215546Sopenharmony_ci target, sampler_type, 238bf215546Sopenharmony_ci DRAW_JIT_SAMPLER_LOD_BIAS); 239bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_sampler, border_color, 240bf215546Sopenharmony_ci target, sampler_type, 241bf215546Sopenharmony_ci DRAW_JIT_SAMPLER_BORDER_COLOR); 242bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_sampler, max_aniso, 243bf215546Sopenharmony_ci target, sampler_type, 244bf215546Sopenharmony_ci DRAW_JIT_SAMPLER_MAX_ANISO); 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci LP_CHECK_STRUCT_SIZE(struct draw_jit_sampler, target, sampler_type); 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci return sampler_type; 249bf215546Sopenharmony_ci} 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci/** 252bf215546Sopenharmony_ci * Create LLVM type for struct draw_jit_texture 253bf215546Sopenharmony_ci */ 254bf215546Sopenharmony_cistatic LLVMTypeRef 255bf215546Sopenharmony_cicreate_jit_image_type(struct gallivm_state *gallivm, const char *struct_name) 256bf215546Sopenharmony_ci{ 257bf215546Sopenharmony_ci LLVMTargetDataRef target = gallivm->target; 258bf215546Sopenharmony_ci LLVMTypeRef image_type; 259bf215546Sopenharmony_ci LLVMTypeRef elem_types[DRAW_JIT_IMAGE_NUM_FIELDS]; 260bf215546Sopenharmony_ci LLVMTypeRef int32_type = LLVMInt32TypeInContext(gallivm->context); 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_ci elem_types[DRAW_JIT_IMAGE_WIDTH] = 263bf215546Sopenharmony_ci elem_types[DRAW_JIT_IMAGE_HEIGHT] = 264bf215546Sopenharmony_ci elem_types[DRAW_JIT_IMAGE_DEPTH] = 265bf215546Sopenharmony_ci elem_types[DRAW_JIT_IMAGE_ROW_STRIDE] = 266bf215546Sopenharmony_ci elem_types[DRAW_JIT_IMAGE_IMG_STRIDE] = 267bf215546Sopenharmony_ci elem_types[DRAW_JIT_IMAGE_NUM_SAMPLES] = 268bf215546Sopenharmony_ci elem_types[DRAW_JIT_IMAGE_SAMPLE_STRIDE] = int32_type; 269bf215546Sopenharmony_ci elem_types[DRAW_JIT_IMAGE_BASE] = 270bf215546Sopenharmony_ci LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci image_type = LLVMStructTypeInContext(gallivm->context, elem_types, 273bf215546Sopenharmony_ci ARRAY_SIZE(elem_types), 0); 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ci (void) target; /* silence unused var warning for non-debug build */ 276bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_image, width, 277bf215546Sopenharmony_ci target, image_type, 278bf215546Sopenharmony_ci DRAW_JIT_IMAGE_WIDTH); 279bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_image, height, 280bf215546Sopenharmony_ci target, image_type, 281bf215546Sopenharmony_ci DRAW_JIT_IMAGE_HEIGHT); 282bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_image, depth, 283bf215546Sopenharmony_ci target, image_type, 284bf215546Sopenharmony_ci DRAW_JIT_IMAGE_DEPTH); 285bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_image, base, 286bf215546Sopenharmony_ci target, image_type, 287bf215546Sopenharmony_ci DRAW_JIT_IMAGE_BASE); 288bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_image, row_stride, 289bf215546Sopenharmony_ci target, image_type, 290bf215546Sopenharmony_ci DRAW_JIT_IMAGE_ROW_STRIDE); 291bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_image, img_stride, 292bf215546Sopenharmony_ci target, image_type, 293bf215546Sopenharmony_ci DRAW_JIT_IMAGE_IMG_STRIDE); 294bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_image, num_samples, 295bf215546Sopenharmony_ci target, image_type, 296bf215546Sopenharmony_ci DRAW_JIT_IMAGE_NUM_SAMPLES); 297bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_image, sample_stride, 298bf215546Sopenharmony_ci target, image_type, 299bf215546Sopenharmony_ci DRAW_JIT_IMAGE_SAMPLE_STRIDE); 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci LP_CHECK_STRUCT_SIZE(struct draw_jit_image, target, image_type); 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci return image_type; 304bf215546Sopenharmony_ci} 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_ci/** 307bf215546Sopenharmony_ci * Create LLVM type for struct draw_jit_context 308bf215546Sopenharmony_ci */ 309bf215546Sopenharmony_cistatic LLVMTypeRef 310bf215546Sopenharmony_cicreate_jit_context_type(struct gallivm_state *gallivm, const char *struct_name) 311bf215546Sopenharmony_ci{ 312bf215546Sopenharmony_ci LLVMTypeRef texture_type = create_jit_texture_type(gallivm, "texture"); 313bf215546Sopenharmony_ci LLVMTypeRef sampler_type = create_jit_sampler_type(gallivm, "sampler"); 314bf215546Sopenharmony_ci LLVMTypeRef image_type = create_jit_image_type(gallivm, "image"); 315bf215546Sopenharmony_ci 316bf215546Sopenharmony_ci LLVMTargetDataRef target = gallivm->target; 317bf215546Sopenharmony_ci LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context); 318bf215546Sopenharmony_ci LLVMTypeRef int_type = LLVMInt32TypeInContext(gallivm->context); 319bf215546Sopenharmony_ci LLVMTypeRef elem_types[DRAW_JIT_CTX_NUM_FIELDS]; 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci elem_types[DRAW_JIT_CTX_CONSTANTS] = LLVMArrayType(LLVMPointerType(float_type, 0), LP_MAX_TGSI_CONST_BUFFERS); 322bf215546Sopenharmony_ci elem_types[DRAW_JIT_CTX_NUM_CONSTANTS] = LLVMArrayType(int_type, LP_MAX_TGSI_CONST_BUFFERS); 323bf215546Sopenharmony_ci elem_types[DRAW_JIT_CTX_PLANES] = LLVMPointerType(LLVMArrayType(LLVMArrayType(float_type, 4), DRAW_TOTAL_CLIP_PLANES), 0); 324bf215546Sopenharmony_ci elem_types[DRAW_JIT_CTX_VIEWPORT] = LLVMPointerType(float_type, 0); 325bf215546Sopenharmony_ci elem_types[DRAW_JIT_CTX_TEXTURES] = LLVMArrayType(texture_type, PIPE_MAX_SHADER_SAMPLER_VIEWS); 326bf215546Sopenharmony_ci elem_types[DRAW_JIT_CTX_SAMPLERS] = LLVMArrayType(sampler_type, PIPE_MAX_SAMPLERS); 327bf215546Sopenharmony_ci elem_types[DRAW_JIT_CTX_IMAGES] = LLVMArrayType(image_type, PIPE_MAX_SHADER_IMAGES); 328bf215546Sopenharmony_ci elem_types[DRAW_JIT_CTX_SSBOS] = LLVMArrayType(LLVMPointerType(int_type, 0), LP_MAX_TGSI_SHADER_BUFFERS); 329bf215546Sopenharmony_ci elem_types[DRAW_JIT_CTX_NUM_SSBOS] = LLVMArrayType(int_type, LP_MAX_TGSI_SHADER_BUFFERS); 330bf215546Sopenharmony_ci elem_types[DRAW_JIT_CTX_ANISO_FILTER_TABLE] = LLVMPointerType(float_type, 0); 331bf215546Sopenharmony_ci LLVMTypeRef context_type = LLVMStructTypeInContext(gallivm->context, elem_types, ARRAY_SIZE(elem_types), 0); 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ci (void) target; /* silence unused var warning for non-debug build */ 334bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, vs_constants, 335bf215546Sopenharmony_ci target, context_type, DRAW_JIT_CTX_CONSTANTS); 336bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, num_vs_constants, 337bf215546Sopenharmony_ci target, context_type, DRAW_JIT_CTX_NUM_CONSTANTS); 338bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, planes, 339bf215546Sopenharmony_ci target, context_type, DRAW_JIT_CTX_PLANES); 340bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, viewports, 341bf215546Sopenharmony_ci target, context_type, DRAW_JIT_CTX_VIEWPORT); 342bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, textures, 343bf215546Sopenharmony_ci target, context_type, 344bf215546Sopenharmony_ci DRAW_JIT_CTX_TEXTURES); 345bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, samplers, 346bf215546Sopenharmony_ci target, context_type, 347bf215546Sopenharmony_ci DRAW_JIT_CTX_SAMPLERS); 348bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, images, 349bf215546Sopenharmony_ci target, context_type, DRAW_JIT_CTX_IMAGES); 350bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, vs_ssbos, 351bf215546Sopenharmony_ci target, context_type, DRAW_JIT_CTX_SSBOS); 352bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, num_vs_ssbos, 353bf215546Sopenharmony_ci target, context_type, DRAW_JIT_CTX_NUM_SSBOS); 354bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, aniso_filter_table, 355bf215546Sopenharmony_ci target, context_type, DRAW_JIT_CTX_ANISO_FILTER_TABLE); 356bf215546Sopenharmony_ci LP_CHECK_STRUCT_SIZE(struct draw_jit_context, 357bf215546Sopenharmony_ci target, context_type); 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci return context_type; 360bf215546Sopenharmony_ci} 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci/** 364bf215546Sopenharmony_ci * Create LLVM type for struct draw_gs_jit_context 365bf215546Sopenharmony_ci */ 366bf215546Sopenharmony_cistatic LLVMTypeRef 367bf215546Sopenharmony_cicreate_gs_jit_context_type(struct gallivm_state *gallivm, 368bf215546Sopenharmony_ci unsigned vector_length, 369bf215546Sopenharmony_ci LLVMTypeRef texture_type, LLVMTypeRef sampler_type, 370bf215546Sopenharmony_ci LLVMTypeRef image_type, 371bf215546Sopenharmony_ci const char *struct_name) 372bf215546Sopenharmony_ci{ 373bf215546Sopenharmony_ci LLVMTargetDataRef target = gallivm->target; 374bf215546Sopenharmony_ci LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context); 375bf215546Sopenharmony_ci LLVMTypeRef int_type = LLVMInt32TypeInContext(gallivm->context); 376bf215546Sopenharmony_ci LLVMTypeRef elem_types[DRAW_GS_JIT_CTX_NUM_FIELDS]; 377bf215546Sopenharmony_ci LLVMTypeRef context_type; 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci elem_types[0] = LLVMArrayType(LLVMPointerType(float_type, 0), /* constants */ 380bf215546Sopenharmony_ci LP_MAX_TGSI_CONST_BUFFERS); 381bf215546Sopenharmony_ci elem_types[1] = LLVMArrayType(int_type, /* num_constants */ 382bf215546Sopenharmony_ci LP_MAX_TGSI_CONST_BUFFERS); 383bf215546Sopenharmony_ci elem_types[2] = LLVMPointerType(LLVMArrayType(LLVMArrayType(float_type, 4), 384bf215546Sopenharmony_ci DRAW_TOTAL_CLIP_PLANES), 0); 385bf215546Sopenharmony_ci elem_types[3] = LLVMPointerType(float_type, 0); /* viewports */ 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_ci elem_types[4] = LLVMArrayType(texture_type, 388bf215546Sopenharmony_ci PIPE_MAX_SHADER_SAMPLER_VIEWS); /* textures */ 389bf215546Sopenharmony_ci elem_types[5] = LLVMArrayType(sampler_type, 390bf215546Sopenharmony_ci PIPE_MAX_SAMPLERS); /* samplers */ 391bf215546Sopenharmony_ci elem_types[6] = LLVMArrayType(image_type, 392bf215546Sopenharmony_ci PIPE_MAX_SHADER_IMAGES); /* images */ 393bf215546Sopenharmony_ci elem_types[7] = LLVMPointerType(LLVMPointerType(int_type, 0), 0); 394bf215546Sopenharmony_ci elem_types[8] = LLVMPointerType(LLVMVectorType(int_type, 395bf215546Sopenharmony_ci vector_length), 0); 396bf215546Sopenharmony_ci elem_types[9] = LLVMPointerType(LLVMVectorType(int_type, 397bf215546Sopenharmony_ci vector_length), 0); 398bf215546Sopenharmony_ci 399bf215546Sopenharmony_ci elem_types[10] = LLVMArrayType(LLVMPointerType(int_type, 0), /* ssbos */ 400bf215546Sopenharmony_ci LP_MAX_TGSI_SHADER_BUFFERS); 401bf215546Sopenharmony_ci elem_types[11] = LLVMArrayType(int_type, /* num_ssbos */ 402bf215546Sopenharmony_ci LP_MAX_TGSI_SHADER_BUFFERS); 403bf215546Sopenharmony_ci elem_types[12] = LLVMPointerType(float_type, 0); /* aniso table */ 404bf215546Sopenharmony_ci context_type = LLVMStructTypeInContext(gallivm->context, elem_types, 405bf215546Sopenharmony_ci ARRAY_SIZE(elem_types), 0); 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci (void) target; /* silence unused var warning for non-debug build */ 408bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, constants, 409bf215546Sopenharmony_ci target, context_type, DRAW_GS_JIT_CTX_CONSTANTS); 410bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, num_constants, 411bf215546Sopenharmony_ci target, context_type, DRAW_GS_JIT_CTX_NUM_CONSTANTS); 412bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, planes, 413bf215546Sopenharmony_ci target, context_type, DRAW_GS_JIT_CTX_PLANES); 414bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, viewports, 415bf215546Sopenharmony_ci target, context_type, DRAW_GS_JIT_CTX_VIEWPORT); 416bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, textures, 417bf215546Sopenharmony_ci target, context_type, 418bf215546Sopenharmony_ci DRAW_GS_JIT_CTX_TEXTURES); 419bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, samplers, 420bf215546Sopenharmony_ci target, context_type, 421bf215546Sopenharmony_ci DRAW_GS_JIT_CTX_SAMPLERS); 422bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, prim_lengths, 423bf215546Sopenharmony_ci target, context_type, 424bf215546Sopenharmony_ci DRAW_GS_JIT_CTX_PRIM_LENGTHS); 425bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, emitted_vertices, 426bf215546Sopenharmony_ci target, context_type, 427bf215546Sopenharmony_ci DRAW_GS_JIT_CTX_EMITTED_VERTICES); 428bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, emitted_prims, 429bf215546Sopenharmony_ci target, context_type, 430bf215546Sopenharmony_ci DRAW_GS_JIT_CTX_EMITTED_PRIMS); 431bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, ssbos, 432bf215546Sopenharmony_ci target, context_type, DRAW_GS_JIT_CTX_SSBOS); 433bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, num_ssbos, 434bf215546Sopenharmony_ci target, context_type, DRAW_GS_JIT_CTX_NUM_SSBOS); 435bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, images, 436bf215546Sopenharmony_ci target, context_type, DRAW_GS_JIT_CTX_IMAGES); 437bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, aniso_filter_table, 438bf215546Sopenharmony_ci target, context_type, DRAW_GS_JIT_CTX_ANISO_FILTER_TABLE); 439bf215546Sopenharmony_ci LP_CHECK_STRUCT_SIZE(struct draw_gs_jit_context, 440bf215546Sopenharmony_ci target, context_type); 441bf215546Sopenharmony_ci 442bf215546Sopenharmony_ci return context_type; 443bf215546Sopenharmony_ci} 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_cistatic LLVMTypeRef 447bf215546Sopenharmony_cicreate_gs_jit_input_type(struct gallivm_state *gallivm) 448bf215546Sopenharmony_ci{ 449bf215546Sopenharmony_ci LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context); 450bf215546Sopenharmony_ci LLVMTypeRef input_array; 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci input_array = LLVMVectorType(float_type, TGSI_NUM_CHANNELS); /* num primitives */ 453bf215546Sopenharmony_ci input_array = LLVMArrayType(input_array, TGSI_NUM_CHANNELS); /* num channels */ 454bf215546Sopenharmony_ci input_array = LLVMArrayType(input_array, PIPE_MAX_SHADER_INPUTS); /* num attrs per vertex */ 455bf215546Sopenharmony_ci input_array = LLVMPointerType(input_array, 0); /* num vertices per prim */ 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci return input_array; 458bf215546Sopenharmony_ci} 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_ci/** 461bf215546Sopenharmony_ci * Create LLVM type for struct pipe_vertex_buffer 462bf215546Sopenharmony_ci */ 463bf215546Sopenharmony_cistatic LLVMTypeRef 464bf215546Sopenharmony_cicreate_jit_vertex_buffer_type(struct gallivm_state *gallivm, 465bf215546Sopenharmony_ci const char *struct_name) 466bf215546Sopenharmony_ci{ 467bf215546Sopenharmony_ci LLVMTargetDataRef target = gallivm->target; 468bf215546Sopenharmony_ci LLVMTypeRef elem_types[4]; 469bf215546Sopenharmony_ci LLVMTypeRef vb_type; 470bf215546Sopenharmony_ci 471bf215546Sopenharmony_ci elem_types[0] = LLVMInt16TypeInContext(gallivm->context); 472bf215546Sopenharmony_ci elem_types[1] = LLVMInt8TypeInContext(gallivm->context); 473bf215546Sopenharmony_ci elem_types[2] = LLVMInt32TypeInContext(gallivm->context); 474bf215546Sopenharmony_ci elem_types[3] = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); 475bf215546Sopenharmony_ci 476bf215546Sopenharmony_ci vb_type = LLVMStructTypeInContext(gallivm->context, elem_types, 477bf215546Sopenharmony_ci ARRAY_SIZE(elem_types), 0); 478bf215546Sopenharmony_ci 479bf215546Sopenharmony_ci (void) target; /* silence unused var warning for non-debug build */ 480bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, stride, 481bf215546Sopenharmony_ci target, vb_type, 0); 482bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, is_user_buffer, 483bf215546Sopenharmony_ci target, vb_type, 1); 484bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, buffer_offset, 485bf215546Sopenharmony_ci target, vb_type, 2); 486bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, buffer.resource, 487bf215546Sopenharmony_ci target, vb_type, 3); 488bf215546Sopenharmony_ci 489bf215546Sopenharmony_ci LP_CHECK_STRUCT_SIZE(struct pipe_vertex_buffer, target, vb_type); 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci return vb_type; 492bf215546Sopenharmony_ci} 493bf215546Sopenharmony_ci 494bf215546Sopenharmony_ci 495bf215546Sopenharmony_ci/** 496bf215546Sopenharmony_ci * Create LLVM type for struct vertex_header; 497bf215546Sopenharmony_ci */ 498bf215546Sopenharmony_cistatic LLVMTypeRef 499bf215546Sopenharmony_cicreate_jit_vertex_header(struct gallivm_state *gallivm, int data_elems) 500bf215546Sopenharmony_ci{ 501bf215546Sopenharmony_ci LLVMTargetDataRef target = gallivm->target; 502bf215546Sopenharmony_ci LLVMTypeRef elem_types[3]; 503bf215546Sopenharmony_ci LLVMTypeRef vertex_header; 504bf215546Sopenharmony_ci char struct_name[24]; 505bf215546Sopenharmony_ci 506bf215546Sopenharmony_ci snprintf(struct_name, 23, "vertex_header%d", data_elems); 507bf215546Sopenharmony_ci 508bf215546Sopenharmony_ci elem_types[DRAW_JIT_VERTEX_VERTEX_ID] = LLVMIntTypeInContext(gallivm->context, 32); 509bf215546Sopenharmony_ci elem_types[DRAW_JIT_VERTEX_CLIP_POS] = LLVMArrayType(LLVMFloatTypeInContext(gallivm->context), 4); 510bf215546Sopenharmony_ci elem_types[DRAW_JIT_VERTEX_DATA] = LLVMArrayType(elem_types[1], data_elems); 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_ci vertex_header = LLVMStructTypeInContext(gallivm->context, elem_types, 513bf215546Sopenharmony_ci ARRAY_SIZE(elem_types), 0); 514bf215546Sopenharmony_ci 515bf215546Sopenharmony_ci /* these are bit-fields and we can't take address of them 516bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct vertex_header, clipmask, 517bf215546Sopenharmony_ci target, vertex_header, 518bf215546Sopenharmony_ci DRAW_JIT_VERTEX_CLIPMASK); 519bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct vertex_header, edgeflag, 520bf215546Sopenharmony_ci target, vertex_header, 521bf215546Sopenharmony_ci DRAW_JIT_VERTEX_EDGEFLAG); 522bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct vertex_header, pad, 523bf215546Sopenharmony_ci target, vertex_header, 524bf215546Sopenharmony_ci DRAW_JIT_VERTEX_PAD); 525bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct vertex_header, vertex_id, 526bf215546Sopenharmony_ci target, vertex_header, 527bf215546Sopenharmony_ci DRAW_JIT_VERTEX_VERTEX_ID); 528bf215546Sopenharmony_ci */ 529bf215546Sopenharmony_ci (void) target; /* silence unused var warning for non-debug build */ 530bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct vertex_header, clip_pos, 531bf215546Sopenharmony_ci target, vertex_header, 532bf215546Sopenharmony_ci DRAW_JIT_VERTEX_CLIP_POS); 533bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct vertex_header, data, 534bf215546Sopenharmony_ci target, vertex_header, 535bf215546Sopenharmony_ci DRAW_JIT_VERTEX_DATA); 536bf215546Sopenharmony_ci 537bf215546Sopenharmony_ci assert(LLVMABISizeOfType(target, vertex_header) == 538bf215546Sopenharmony_ci offsetof(struct vertex_header, data[data_elems])); 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_ci return vertex_header; 541bf215546Sopenharmony_ci} 542bf215546Sopenharmony_ci 543bf215546Sopenharmony_ci/** 544bf215546Sopenharmony_ci * Create LLVM type for struct draw_tcs_jit_context 545bf215546Sopenharmony_ci */ 546bf215546Sopenharmony_cistatic LLVMTypeRef 547bf215546Sopenharmony_cicreate_tcs_jit_context_type(struct gallivm_state *gallivm, 548bf215546Sopenharmony_ci unsigned vector_length, 549bf215546Sopenharmony_ci LLVMTypeRef texture_type, LLVMTypeRef sampler_type, 550bf215546Sopenharmony_ci LLVMTypeRef image_type, 551bf215546Sopenharmony_ci const char *struct_name) 552bf215546Sopenharmony_ci{ 553bf215546Sopenharmony_ci LLVMTargetDataRef target = gallivm->target; 554bf215546Sopenharmony_ci LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context); 555bf215546Sopenharmony_ci LLVMTypeRef int_type = LLVMInt32TypeInContext(gallivm->context); 556bf215546Sopenharmony_ci LLVMTypeRef elem_types[DRAW_TCS_JIT_CTX_NUM_FIELDS]; 557bf215546Sopenharmony_ci LLVMTypeRef context_type; 558bf215546Sopenharmony_ci 559bf215546Sopenharmony_ci elem_types[0] = LLVMArrayType(LLVMPointerType(float_type, 0), /* constants */ 560bf215546Sopenharmony_ci LP_MAX_TGSI_CONST_BUFFERS); 561bf215546Sopenharmony_ci elem_types[1] = LLVMArrayType(int_type, /* num_constants */ 562bf215546Sopenharmony_ci LP_MAX_TGSI_CONST_BUFFERS); 563bf215546Sopenharmony_ci elem_types[2] = LLVMInt32TypeInContext(gallivm->context); 564bf215546Sopenharmony_ci elem_types[3] = LLVMInt32TypeInContext(gallivm->context); 565bf215546Sopenharmony_ci 566bf215546Sopenharmony_ci elem_types[4] = LLVMArrayType(texture_type, 567bf215546Sopenharmony_ci PIPE_MAX_SHADER_SAMPLER_VIEWS); /* textures */ 568bf215546Sopenharmony_ci elem_types[5] = LLVMArrayType(sampler_type, 569bf215546Sopenharmony_ci PIPE_MAX_SAMPLERS); /* samplers */ 570bf215546Sopenharmony_ci elem_types[6] = LLVMArrayType(image_type, 571bf215546Sopenharmony_ci PIPE_MAX_SHADER_IMAGES); /* images */ 572bf215546Sopenharmony_ci 573bf215546Sopenharmony_ci elem_types[7] = LLVMArrayType(LLVMPointerType(int_type, 0), /* ssbos */ 574bf215546Sopenharmony_ci LP_MAX_TGSI_SHADER_BUFFERS); 575bf215546Sopenharmony_ci elem_types[8] = LLVMArrayType(int_type, /* num_ssbos */ 576bf215546Sopenharmony_ci LP_MAX_TGSI_SHADER_BUFFERS); 577bf215546Sopenharmony_ci elem_types[9] = LLVMPointerType(float_type, 0); /* aniso table */ 578bf215546Sopenharmony_ci context_type = LLVMStructTypeInContext(gallivm->context, elem_types, 579bf215546Sopenharmony_ci ARRAY_SIZE(elem_types), 0); 580bf215546Sopenharmony_ci 581bf215546Sopenharmony_ci (void) target; /* silence unused var warning for non-debug build */ 582bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_tcs_jit_context, constants, 583bf215546Sopenharmony_ci target, context_type, DRAW_TCS_JIT_CTX_CONSTANTS); 584bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_tcs_jit_context, num_constants, 585bf215546Sopenharmony_ci target, context_type, DRAW_TCS_JIT_CTX_NUM_CONSTANTS); 586bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_tcs_jit_context, textures, 587bf215546Sopenharmony_ci target, context_type, 588bf215546Sopenharmony_ci DRAW_TCS_JIT_CTX_TEXTURES); 589bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_tcs_jit_context, samplers, 590bf215546Sopenharmony_ci target, context_type, 591bf215546Sopenharmony_ci DRAW_TCS_JIT_CTX_SAMPLERS); 592bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_tcs_jit_context, ssbos, 593bf215546Sopenharmony_ci target, context_type, DRAW_TCS_JIT_CTX_SSBOS); 594bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_tcs_jit_context, num_ssbos, 595bf215546Sopenharmony_ci target, context_type, DRAW_TCS_JIT_CTX_NUM_SSBOS); 596bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_tcs_jit_context, images, 597bf215546Sopenharmony_ci target, context_type, DRAW_TCS_JIT_CTX_IMAGES); 598bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_tcs_jit_context, aniso_filter_table, 599bf215546Sopenharmony_ci target, context_type, DRAW_TCS_JIT_CTX_ANISO_FILTER_TABLE); 600bf215546Sopenharmony_ci LP_CHECK_STRUCT_SIZE(struct draw_tcs_jit_context, 601bf215546Sopenharmony_ci target, context_type); 602bf215546Sopenharmony_ci 603bf215546Sopenharmony_ci return context_type; 604bf215546Sopenharmony_ci} 605bf215546Sopenharmony_ci 606bf215546Sopenharmony_cistatic LLVMTypeRef 607bf215546Sopenharmony_cicreate_tcs_jit_input_type(struct gallivm_state *gallivm) 608bf215546Sopenharmony_ci{ 609bf215546Sopenharmony_ci LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context); 610bf215546Sopenharmony_ci LLVMTypeRef input_array; 611bf215546Sopenharmony_ci 612bf215546Sopenharmony_ci input_array = LLVMArrayType(float_type, TGSI_NUM_CHANNELS); /* num channels */ 613bf215546Sopenharmony_ci input_array = LLVMArrayType(input_array, NUM_TCS_INPUTS); /* num attrs per vertex */ 614bf215546Sopenharmony_ci input_array = LLVMPointerType(input_array, 0); /* num vertices per prim */ 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci return input_array; 617bf215546Sopenharmony_ci} 618bf215546Sopenharmony_ci 619bf215546Sopenharmony_cistatic LLVMTypeRef 620bf215546Sopenharmony_cicreate_tcs_jit_output_type(struct gallivm_state *gallivm) 621bf215546Sopenharmony_ci{ 622bf215546Sopenharmony_ci LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context); 623bf215546Sopenharmony_ci LLVMTypeRef output_array; 624bf215546Sopenharmony_ci 625bf215546Sopenharmony_ci output_array = LLVMArrayType(float_type, TGSI_NUM_CHANNELS); /* num channels */ 626bf215546Sopenharmony_ci output_array = LLVMArrayType(output_array, PIPE_MAX_SHADER_INPUTS); /* num attrs per vertex */ 627bf215546Sopenharmony_ci output_array = LLVMPointerType(output_array, 0); /* num vertices per prim */ 628bf215546Sopenharmony_ci 629bf215546Sopenharmony_ci return output_array; 630bf215546Sopenharmony_ci} 631bf215546Sopenharmony_ci 632bf215546Sopenharmony_cistatic LLVMTypeRef 633bf215546Sopenharmony_cicreate_tes_jit_input_deref_type(struct gallivm_state *gallivm) 634bf215546Sopenharmony_ci{ 635bf215546Sopenharmony_ci LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context); 636bf215546Sopenharmony_ci LLVMTypeRef input_array; 637bf215546Sopenharmony_ci 638bf215546Sopenharmony_ci input_array = LLVMArrayType(float_type, TGSI_NUM_CHANNELS); /* num channels */ 639bf215546Sopenharmony_ci input_array = LLVMArrayType(input_array, PIPE_MAX_SHADER_INPUTS); /* num attrs per vertex */ 640bf215546Sopenharmony_ci 641bf215546Sopenharmony_ci return input_array; 642bf215546Sopenharmony_ci} 643bf215546Sopenharmony_ci 644bf215546Sopenharmony_ci/** 645bf215546Sopenharmony_ci * Create LLVM type for struct draw_tes_jit_context 646bf215546Sopenharmony_ci */ 647bf215546Sopenharmony_cistatic LLVMTypeRef 648bf215546Sopenharmony_cicreate_tes_jit_context_type(struct gallivm_state *gallivm, 649bf215546Sopenharmony_ci unsigned vector_length, 650bf215546Sopenharmony_ci LLVMTypeRef texture_type, LLVMTypeRef sampler_type, 651bf215546Sopenharmony_ci LLVMTypeRef image_type, 652bf215546Sopenharmony_ci const char *struct_name) 653bf215546Sopenharmony_ci{ 654bf215546Sopenharmony_ci LLVMTargetDataRef target = gallivm->target; 655bf215546Sopenharmony_ci LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context); 656bf215546Sopenharmony_ci LLVMTypeRef int_type = LLVMInt32TypeInContext(gallivm->context); 657bf215546Sopenharmony_ci LLVMTypeRef elem_types[DRAW_TCS_JIT_CTX_NUM_FIELDS]; 658bf215546Sopenharmony_ci LLVMTypeRef context_type; 659bf215546Sopenharmony_ci 660bf215546Sopenharmony_ci elem_types[0] = LLVMArrayType(LLVMPointerType(float_type, 0), /* constants */ 661bf215546Sopenharmony_ci LP_MAX_TGSI_CONST_BUFFERS); 662bf215546Sopenharmony_ci elem_types[1] = LLVMArrayType(int_type, /* num_constants */ 663bf215546Sopenharmony_ci LP_MAX_TGSI_CONST_BUFFERS); 664bf215546Sopenharmony_ci elem_types[2] = LLVMInt32TypeInContext(gallivm->context); 665bf215546Sopenharmony_ci elem_types[3] = LLVMInt32TypeInContext(gallivm->context); 666bf215546Sopenharmony_ci 667bf215546Sopenharmony_ci elem_types[4] = LLVMArrayType(texture_type, 668bf215546Sopenharmony_ci PIPE_MAX_SHADER_SAMPLER_VIEWS); /* textures */ 669bf215546Sopenharmony_ci elem_types[5] = LLVMArrayType(sampler_type, 670bf215546Sopenharmony_ci PIPE_MAX_SAMPLERS); /* samplers */ 671bf215546Sopenharmony_ci elem_types[6] = LLVMArrayType(image_type, 672bf215546Sopenharmony_ci PIPE_MAX_SHADER_IMAGES); /* images */ 673bf215546Sopenharmony_ci 674bf215546Sopenharmony_ci elem_types[7] = LLVMArrayType(LLVMPointerType(int_type, 0), /* ssbos */ 675bf215546Sopenharmony_ci LP_MAX_TGSI_SHADER_BUFFERS); 676bf215546Sopenharmony_ci elem_types[8] = LLVMArrayType(int_type, /* num_ssbos */ 677bf215546Sopenharmony_ci LP_MAX_TGSI_SHADER_BUFFERS); 678bf215546Sopenharmony_ci elem_types[9] = LLVMPointerType(float_type, 0); /* aniso table */ 679bf215546Sopenharmony_ci context_type = LLVMStructTypeInContext(gallivm->context, elem_types, 680bf215546Sopenharmony_ci ARRAY_SIZE(elem_types), 0); 681bf215546Sopenharmony_ci 682bf215546Sopenharmony_ci (void) target; /* silence unused var warning for non-debug build */ 683bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_tes_jit_context, constants, 684bf215546Sopenharmony_ci target, context_type, DRAW_TCS_JIT_CTX_CONSTANTS); 685bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_tes_jit_context, num_constants, 686bf215546Sopenharmony_ci target, context_type, DRAW_TCS_JIT_CTX_NUM_CONSTANTS); 687bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_tes_jit_context, textures, 688bf215546Sopenharmony_ci target, context_type, 689bf215546Sopenharmony_ci DRAW_TCS_JIT_CTX_TEXTURES); 690bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_tes_jit_context, samplers, 691bf215546Sopenharmony_ci target, context_type, 692bf215546Sopenharmony_ci DRAW_TCS_JIT_CTX_SAMPLERS); 693bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_tes_jit_context, ssbos, 694bf215546Sopenharmony_ci target, context_type, DRAW_TCS_JIT_CTX_SSBOS); 695bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_tes_jit_context, num_ssbos, 696bf215546Sopenharmony_ci target, context_type, DRAW_TCS_JIT_CTX_NUM_SSBOS); 697bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_tes_jit_context, images, 698bf215546Sopenharmony_ci target, context_type, DRAW_TCS_JIT_CTX_IMAGES); 699bf215546Sopenharmony_ci LP_CHECK_MEMBER_OFFSET(struct draw_tcs_jit_context, aniso_filter_table, 700bf215546Sopenharmony_ci target, context_type, DRAW_TCS_JIT_CTX_ANISO_FILTER_TABLE); 701bf215546Sopenharmony_ci LP_CHECK_STRUCT_SIZE(struct draw_tes_jit_context, 702bf215546Sopenharmony_ci target, context_type); 703bf215546Sopenharmony_ci 704bf215546Sopenharmony_ci return context_type; 705bf215546Sopenharmony_ci} 706bf215546Sopenharmony_ci 707bf215546Sopenharmony_ci/** 708bf215546Sopenharmony_ci * Create LLVM types for various structures. 709bf215546Sopenharmony_ci */ 710bf215546Sopenharmony_cistatic void 711bf215546Sopenharmony_cicreate_jit_types(struct draw_llvm_variant *variant) 712bf215546Sopenharmony_ci{ 713bf215546Sopenharmony_ci struct gallivm_state *gallivm = variant->gallivm; 714bf215546Sopenharmony_ci 715bf215546Sopenharmony_ci variant->context_type = create_jit_context_type(gallivm, "draw_jit_context"); 716bf215546Sopenharmony_ci variant->context_ptr_type = LLVMPointerType(variant->context_type, 0); 717bf215546Sopenharmony_ci 718bf215546Sopenharmony_ci variant->buffer_type = create_jit_dvbuffer_type(gallivm, "draw_vertex_buffer"); 719bf215546Sopenharmony_ci variant->buffer_ptr_type = LLVMPointerType(variant->buffer_type, 0); 720bf215546Sopenharmony_ci 721bf215546Sopenharmony_ci variant->vb_type = create_jit_vertex_buffer_type(gallivm, "pipe_vertex_buffer"); 722bf215546Sopenharmony_ci variant->vb_ptr_type = LLVMPointerType(variant->vb_type, 0); 723bf215546Sopenharmony_ci} 724bf215546Sopenharmony_ci 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_cistatic LLVMTypeRef 727bf215546Sopenharmony_ciget_context_ptr_type(struct draw_llvm_variant *variant) 728bf215546Sopenharmony_ci{ 729bf215546Sopenharmony_ci if (!variant->context_ptr_type) 730bf215546Sopenharmony_ci create_jit_types(variant); 731bf215546Sopenharmony_ci return variant->context_ptr_type; 732bf215546Sopenharmony_ci} 733bf215546Sopenharmony_ci 734bf215546Sopenharmony_ci 735bf215546Sopenharmony_cistatic LLVMTypeRef 736bf215546Sopenharmony_ciget_buffer_ptr_type(struct draw_llvm_variant *variant) 737bf215546Sopenharmony_ci{ 738bf215546Sopenharmony_ci if (!variant->buffer_ptr_type) 739bf215546Sopenharmony_ci create_jit_types(variant); 740bf215546Sopenharmony_ci return variant->buffer_ptr_type; 741bf215546Sopenharmony_ci} 742bf215546Sopenharmony_ci 743bf215546Sopenharmony_ci 744bf215546Sopenharmony_cistatic LLVMTypeRef 745bf215546Sopenharmony_ciget_vb_ptr_type(struct draw_llvm_variant *variant) 746bf215546Sopenharmony_ci{ 747bf215546Sopenharmony_ci if (!variant->vb_ptr_type) 748bf215546Sopenharmony_ci create_jit_types(variant); 749bf215546Sopenharmony_ci return variant->vb_ptr_type; 750bf215546Sopenharmony_ci} 751bf215546Sopenharmony_ci 752bf215546Sopenharmony_cistatic LLVMTypeRef 753bf215546Sopenharmony_ciget_vertex_header_ptr_type(struct draw_llvm_variant *variant) 754bf215546Sopenharmony_ci{ 755bf215546Sopenharmony_ci assert(variant->vertex_header_ptr_type); 756bf215546Sopenharmony_ci return variant->vertex_header_ptr_type; 757bf215546Sopenharmony_ci} 758bf215546Sopenharmony_ci 759bf215546Sopenharmony_ci 760bf215546Sopenharmony_ci/** 761bf215546Sopenharmony_ci * Create per-context LLVM info. 762bf215546Sopenharmony_ci */ 763bf215546Sopenharmony_cistruct draw_llvm * 764bf215546Sopenharmony_cidraw_llvm_create(struct draw_context *draw, LLVMContextRef context) 765bf215546Sopenharmony_ci{ 766bf215546Sopenharmony_ci struct draw_llvm *llvm; 767bf215546Sopenharmony_ci 768bf215546Sopenharmony_ci if (!lp_build_init()) 769bf215546Sopenharmony_ci return NULL; 770bf215546Sopenharmony_ci 771bf215546Sopenharmony_ci llvm = CALLOC_STRUCT( draw_llvm ); 772bf215546Sopenharmony_ci if (!llvm) 773bf215546Sopenharmony_ci return NULL; 774bf215546Sopenharmony_ci 775bf215546Sopenharmony_ci llvm->draw = draw; 776bf215546Sopenharmony_ci 777bf215546Sopenharmony_ci llvm->context = context; 778bf215546Sopenharmony_ci if (!llvm->context) { 779bf215546Sopenharmony_ci llvm->context = LLVMContextCreate(); 780bf215546Sopenharmony_ci 781bf215546Sopenharmony_ci#if LLVM_VERSION_MAJOR >= 15 782bf215546Sopenharmony_ci LLVMContextSetOpaquePointers(llvm->context, false); 783bf215546Sopenharmony_ci#endif 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_ci llvm->context_owned = true; 786bf215546Sopenharmony_ci } 787bf215546Sopenharmony_ci if (!llvm->context) 788bf215546Sopenharmony_ci goto fail; 789bf215546Sopenharmony_ci 790bf215546Sopenharmony_ci llvm->nr_variants = 0; 791bf215546Sopenharmony_ci list_inithead(&llvm->vs_variants_list.list); 792bf215546Sopenharmony_ci 793bf215546Sopenharmony_ci llvm->nr_gs_variants = 0; 794bf215546Sopenharmony_ci list_inithead(&llvm->gs_variants_list.list); 795bf215546Sopenharmony_ci 796bf215546Sopenharmony_ci llvm->nr_tcs_variants = 0; 797bf215546Sopenharmony_ci list_inithead(&llvm->tcs_variants_list.list); 798bf215546Sopenharmony_ci 799bf215546Sopenharmony_ci llvm->nr_tes_variants = 0; 800bf215546Sopenharmony_ci list_inithead(&llvm->tes_variants_list.list); 801bf215546Sopenharmony_ci 802bf215546Sopenharmony_ci return llvm; 803bf215546Sopenharmony_ci 804bf215546Sopenharmony_cifail: 805bf215546Sopenharmony_ci draw_llvm_destroy(llvm); 806bf215546Sopenharmony_ci return NULL; 807bf215546Sopenharmony_ci} 808bf215546Sopenharmony_ci 809bf215546Sopenharmony_ci 810bf215546Sopenharmony_ci/** 811bf215546Sopenharmony_ci * Free per-context LLVM info. 812bf215546Sopenharmony_ci */ 813bf215546Sopenharmony_civoid 814bf215546Sopenharmony_cidraw_llvm_destroy(struct draw_llvm *llvm) 815bf215546Sopenharmony_ci{ 816bf215546Sopenharmony_ci if (llvm->context_owned) 817bf215546Sopenharmony_ci LLVMContextDispose(llvm->context); 818bf215546Sopenharmony_ci llvm->context = NULL; 819bf215546Sopenharmony_ci 820bf215546Sopenharmony_ci /* XXX free other draw_llvm data? */ 821bf215546Sopenharmony_ci FREE(llvm); 822bf215546Sopenharmony_ci} 823bf215546Sopenharmony_ci 824bf215546Sopenharmony_cistatic void 825bf215546Sopenharmony_cidraw_get_ir_cache_key(struct nir_shader *nir, 826bf215546Sopenharmony_ci const void *key, size_t key_size, 827bf215546Sopenharmony_ci uint32_t val_32bit, 828bf215546Sopenharmony_ci unsigned char ir_sha1_cache_key[20]) 829bf215546Sopenharmony_ci{ 830bf215546Sopenharmony_ci struct blob blob = { 0 }; 831bf215546Sopenharmony_ci unsigned ir_size; 832bf215546Sopenharmony_ci void *ir_binary; 833bf215546Sopenharmony_ci 834bf215546Sopenharmony_ci blob_init(&blob); 835bf215546Sopenharmony_ci nir_serialize(&blob, nir, true); 836bf215546Sopenharmony_ci ir_binary = blob.data; 837bf215546Sopenharmony_ci ir_size = blob.size; 838bf215546Sopenharmony_ci 839bf215546Sopenharmony_ci struct mesa_sha1 ctx; 840bf215546Sopenharmony_ci _mesa_sha1_init(&ctx); 841bf215546Sopenharmony_ci _mesa_sha1_update(&ctx, key, key_size); 842bf215546Sopenharmony_ci _mesa_sha1_update(&ctx, ir_binary, ir_size); 843bf215546Sopenharmony_ci _mesa_sha1_update(&ctx, &val_32bit, 4); 844bf215546Sopenharmony_ci _mesa_sha1_final(&ctx, ir_sha1_cache_key); 845bf215546Sopenharmony_ci 846bf215546Sopenharmony_ci blob_finish(&blob); 847bf215546Sopenharmony_ci} 848bf215546Sopenharmony_ci 849bf215546Sopenharmony_ci/** 850bf215546Sopenharmony_ci * Create LLVM-generated code for a vertex shader. 851bf215546Sopenharmony_ci */ 852bf215546Sopenharmony_cistruct draw_llvm_variant * 853bf215546Sopenharmony_cidraw_llvm_create_variant(struct draw_llvm *llvm, 854bf215546Sopenharmony_ci unsigned num_inputs, 855bf215546Sopenharmony_ci const struct draw_llvm_variant_key *key) 856bf215546Sopenharmony_ci{ 857bf215546Sopenharmony_ci struct draw_llvm_variant *variant; 858bf215546Sopenharmony_ci struct llvm_vertex_shader *shader = 859bf215546Sopenharmony_ci llvm_vertex_shader(llvm->draw->vs.vertex_shader); 860bf215546Sopenharmony_ci char module_name[64]; 861bf215546Sopenharmony_ci unsigned char ir_sha1_cache_key[20]; 862bf215546Sopenharmony_ci struct lp_cached_code cached = { 0 }; 863bf215546Sopenharmony_ci bool needs_caching = false; 864bf215546Sopenharmony_ci variant = MALLOC(sizeof *variant + 865bf215546Sopenharmony_ci shader->variant_key_size - 866bf215546Sopenharmony_ci sizeof variant->key); 867bf215546Sopenharmony_ci if (!variant) 868bf215546Sopenharmony_ci return NULL; 869bf215546Sopenharmony_ci 870bf215546Sopenharmony_ci variant->llvm = llvm; 871bf215546Sopenharmony_ci variant->shader = shader; 872bf215546Sopenharmony_ci memcpy(&variant->key, key, shader->variant_key_size); 873bf215546Sopenharmony_ci 874bf215546Sopenharmony_ci snprintf(module_name, sizeof(module_name), "draw_llvm_vs_variant%u", 875bf215546Sopenharmony_ci variant->shader->variants_cached); 876bf215546Sopenharmony_ci 877bf215546Sopenharmony_ci if (shader->base.state.ir.nir && llvm->draw->disk_cache_cookie) { 878bf215546Sopenharmony_ci draw_get_ir_cache_key(shader->base.state.ir.nir, 879bf215546Sopenharmony_ci key, 880bf215546Sopenharmony_ci shader->variant_key_size, 881bf215546Sopenharmony_ci num_inputs, 882bf215546Sopenharmony_ci ir_sha1_cache_key); 883bf215546Sopenharmony_ci 884bf215546Sopenharmony_ci llvm->draw->disk_cache_find_shader(llvm->draw->disk_cache_cookie, 885bf215546Sopenharmony_ci &cached, 886bf215546Sopenharmony_ci ir_sha1_cache_key); 887bf215546Sopenharmony_ci if (!cached.data_size) 888bf215546Sopenharmony_ci needs_caching = true; 889bf215546Sopenharmony_ci } 890bf215546Sopenharmony_ci variant->gallivm = gallivm_create(module_name, llvm->context, &cached); 891bf215546Sopenharmony_ci 892bf215546Sopenharmony_ci create_jit_types(variant); 893bf215546Sopenharmony_ci 894bf215546Sopenharmony_ci if (gallivm_debug & (GALLIVM_DEBUG_TGSI | GALLIVM_DEBUG_IR)) { 895bf215546Sopenharmony_ci if (llvm->draw->vs.vertex_shader->state.type == PIPE_SHADER_IR_TGSI) 896bf215546Sopenharmony_ci tgsi_dump(llvm->draw->vs.vertex_shader->state.tokens, 0); 897bf215546Sopenharmony_ci else 898bf215546Sopenharmony_ci nir_print_shader(llvm->draw->vs.vertex_shader->state.ir.nir, stderr); 899bf215546Sopenharmony_ci draw_llvm_dump_variant_key(&variant->key); 900bf215546Sopenharmony_ci } 901bf215546Sopenharmony_ci 902bf215546Sopenharmony_ci variant->vertex_header_type = create_jit_vertex_header(variant->gallivm, num_inputs); 903bf215546Sopenharmony_ci variant->vertex_header_ptr_type = LLVMPointerType(variant->vertex_header_type, 0); 904bf215546Sopenharmony_ci 905bf215546Sopenharmony_ci draw_llvm_generate(llvm, variant); 906bf215546Sopenharmony_ci 907bf215546Sopenharmony_ci gallivm_compile_module(variant->gallivm); 908bf215546Sopenharmony_ci 909bf215546Sopenharmony_ci variant->jit_func = (draw_jit_vert_func) 910bf215546Sopenharmony_ci gallivm_jit_function(variant->gallivm, variant->function); 911bf215546Sopenharmony_ci 912bf215546Sopenharmony_ci if (needs_caching) 913bf215546Sopenharmony_ci llvm->draw->disk_cache_insert_shader(llvm->draw->disk_cache_cookie, 914bf215546Sopenharmony_ci &cached, 915bf215546Sopenharmony_ci ir_sha1_cache_key); 916bf215546Sopenharmony_ci gallivm_free_ir(variant->gallivm); 917bf215546Sopenharmony_ci 918bf215546Sopenharmony_ci variant->list_item_global.base = variant; 919bf215546Sopenharmony_ci variant->list_item_local.base = variant; 920bf215546Sopenharmony_ci /*variant->no = */shader->variants_created++; 921bf215546Sopenharmony_ci variant->list_item_global.base = variant; 922bf215546Sopenharmony_ci 923bf215546Sopenharmony_ci return variant; 924bf215546Sopenharmony_ci} 925bf215546Sopenharmony_ci 926bf215546Sopenharmony_cistatic void 927bf215546Sopenharmony_cido_clamp_vertex_color(struct gallivm_state *gallivm, 928bf215546Sopenharmony_ci struct lp_type type, 929bf215546Sopenharmony_ci const struct tgsi_shader_info *info, 930bf215546Sopenharmony_ci LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS]) 931bf215546Sopenharmony_ci{ 932bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 933bf215546Sopenharmony_ci LLVMValueRef out; 934bf215546Sopenharmony_ci unsigned chan, attrib; 935bf215546Sopenharmony_ci struct lp_build_context bld; 936bf215546Sopenharmony_ci lp_build_context_init(&bld, gallivm, type); 937bf215546Sopenharmony_ci 938bf215546Sopenharmony_ci for (attrib = 0; attrib < info->num_outputs; ++attrib) { 939bf215546Sopenharmony_ci for (chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) { 940bf215546Sopenharmony_ci if (outputs[attrib][chan]) { 941bf215546Sopenharmony_ci switch (info->output_semantic_name[attrib]) { 942bf215546Sopenharmony_ci case TGSI_SEMANTIC_COLOR: 943bf215546Sopenharmony_ci case TGSI_SEMANTIC_BCOLOR: 944bf215546Sopenharmony_ci out = LLVMBuildLoad2(builder, LLVMTypeOf(bld.zero), outputs[attrib][chan], ""); 945bf215546Sopenharmony_ci out = lp_build_clamp(&bld, out, bld.zero, bld.one); 946bf215546Sopenharmony_ci LLVMBuildStore(builder, out, outputs[attrib][chan]); 947bf215546Sopenharmony_ci break; 948bf215546Sopenharmony_ci } 949bf215546Sopenharmony_ci } 950bf215546Sopenharmony_ci } 951bf215546Sopenharmony_ci } 952bf215546Sopenharmony_ci} 953bf215546Sopenharmony_ci 954bf215546Sopenharmony_cistatic void 955bf215546Sopenharmony_cigenerate_vs(struct draw_llvm_variant *variant, 956bf215546Sopenharmony_ci LLVMBuilderRef builder, 957bf215546Sopenharmony_ci struct lp_type vs_type, 958bf215546Sopenharmony_ci LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS], 959bf215546Sopenharmony_ci const LLVMValueRef (*inputs)[TGSI_NUM_CHANNELS], 960bf215546Sopenharmony_ci const struct lp_bld_tgsi_system_values *system_values, 961bf215546Sopenharmony_ci LLVMValueRef context_ptr, 962bf215546Sopenharmony_ci const struct lp_build_sampler_soa *draw_sampler, 963bf215546Sopenharmony_ci const struct lp_build_image_soa *draw_image, 964bf215546Sopenharmony_ci boolean clamp_vertex_color, 965bf215546Sopenharmony_ci struct lp_build_mask_context *bld_mask) 966bf215546Sopenharmony_ci{ 967bf215546Sopenharmony_ci struct draw_llvm *llvm = variant->llvm; 968bf215546Sopenharmony_ci const struct tgsi_token *tokens = llvm->draw->vs.vertex_shader->state.tokens; 969bf215546Sopenharmony_ci LLVMValueRef consts_ptr = 970bf215546Sopenharmony_ci draw_jit_context_vs_constants(variant, context_ptr); 971bf215546Sopenharmony_ci LLVMValueRef num_consts_ptr = 972bf215546Sopenharmony_ci draw_jit_context_num_vs_constants(variant, context_ptr); 973bf215546Sopenharmony_ci LLVMValueRef ssbos_ptr = 974bf215546Sopenharmony_ci draw_jit_context_vs_ssbos(variant, context_ptr); 975bf215546Sopenharmony_ci LLVMValueRef num_ssbos_ptr = 976bf215546Sopenharmony_ci draw_jit_context_num_vs_ssbos(variant, context_ptr); 977bf215546Sopenharmony_ci 978bf215546Sopenharmony_ci struct lp_build_tgsi_params params; 979bf215546Sopenharmony_ci memset(¶ms, 0, sizeof(params)); 980bf215546Sopenharmony_ci 981bf215546Sopenharmony_ci params.type = vs_type; 982bf215546Sopenharmony_ci params.mask = bld_mask; 983bf215546Sopenharmony_ci params.consts_ptr = consts_ptr; 984bf215546Sopenharmony_ci params.const_sizes_ptr = num_consts_ptr; 985bf215546Sopenharmony_ci params.system_values = system_values; 986bf215546Sopenharmony_ci params.inputs = inputs; 987bf215546Sopenharmony_ci params.context_ptr = context_ptr; 988bf215546Sopenharmony_ci params.sampler = draw_sampler; 989bf215546Sopenharmony_ci params.info = &llvm->draw->vs.vertex_shader->info; 990bf215546Sopenharmony_ci params.ssbo_ptr = ssbos_ptr; 991bf215546Sopenharmony_ci params.ssbo_sizes_ptr = num_ssbos_ptr; 992bf215546Sopenharmony_ci params.image = draw_image; 993bf215546Sopenharmony_ci params.aniso_filter_table = draw_jit_context_aniso_filter_table(variant, context_ptr); 994bf215546Sopenharmony_ci 995bf215546Sopenharmony_ci if (llvm->draw->vs.vertex_shader->state.ir.nir && 996bf215546Sopenharmony_ci llvm->draw->vs.vertex_shader->state.type == PIPE_SHADER_IR_NIR) 997bf215546Sopenharmony_ci lp_build_nir_soa(variant->gallivm, 998bf215546Sopenharmony_ci llvm->draw->vs.vertex_shader->state.ir.nir, 999bf215546Sopenharmony_ci ¶ms, 1000bf215546Sopenharmony_ci outputs); 1001bf215546Sopenharmony_ci else 1002bf215546Sopenharmony_ci lp_build_tgsi_soa(variant->gallivm, 1003bf215546Sopenharmony_ci tokens, 1004bf215546Sopenharmony_ci ¶ms, 1005bf215546Sopenharmony_ci outputs); 1006bf215546Sopenharmony_ci 1007bf215546Sopenharmony_ci if (clamp_vertex_color) { 1008bf215546Sopenharmony_ci const struct tgsi_shader_info *info = &llvm->draw->vs.vertex_shader->info; 1009bf215546Sopenharmony_ci do_clamp_vertex_color(variant->gallivm, 1010bf215546Sopenharmony_ci vs_type, info, 1011bf215546Sopenharmony_ci outputs); 1012bf215546Sopenharmony_ci } 1013bf215546Sopenharmony_ci} 1014bf215546Sopenharmony_ci 1015bf215546Sopenharmony_ci 1016bf215546Sopenharmony_cistatic void 1017bf215546Sopenharmony_cifetch_instanced(struct gallivm_state *gallivm, 1018bf215546Sopenharmony_ci const struct util_format_description *format_desc, 1019bf215546Sopenharmony_ci struct lp_type vs_type, 1020bf215546Sopenharmony_ci LLVMValueRef vb_stride, 1021bf215546Sopenharmony_ci LLVMValueRef map_ptr, 1022bf215546Sopenharmony_ci LLVMValueRef buffer_size_adj, 1023bf215546Sopenharmony_ci LLVMValueRef *inputs, 1024bf215546Sopenharmony_ci LLVMValueRef index) 1025bf215546Sopenharmony_ci{ 1026bf215546Sopenharmony_ci LLVMTypeRef i32_t = LLVMInt32TypeInContext(gallivm->context); 1027bf215546Sopenharmony_ci LLVMTypeRef aosf_t, aosi_t; 1028bf215546Sopenharmony_ci LLVMValueRef zero = LLVMConstNull(i32_t); 1029bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 1030bf215546Sopenharmony_ci LLVMValueRef stride, buffer_overflowed, aos, index_valid; 1031bf215546Sopenharmony_ci unsigned i; 1032bf215546Sopenharmony_ci 1033bf215546Sopenharmony_ci aosf_t = lp_build_vec_type(gallivm, lp_float32_vec4_type()); 1034bf215546Sopenharmony_ci aosi_t = lp_build_vec_type(gallivm, lp_int32_vec4_type()); 1035bf215546Sopenharmony_ci 1036bf215546Sopenharmony_ci /* This mul can overflow. Wraparound is ok. */ 1037bf215546Sopenharmony_ci stride = LLVMBuildMul(builder, vb_stride, index, ""); 1038bf215546Sopenharmony_ci 1039bf215546Sopenharmony_ci buffer_overflowed = LLVMBuildICmp(builder, LLVMIntUGE, 1040bf215546Sopenharmony_ci stride, buffer_size_adj, 1041bf215546Sopenharmony_ci "buffer_overflowed"); 1042bf215546Sopenharmony_ci 1043bf215546Sopenharmony_ci if (0) { 1044bf215546Sopenharmony_ci lp_build_print_value(gallivm, " instance index = ", index); 1045bf215546Sopenharmony_ci lp_build_print_value(gallivm, " buffer overflowed = ", buffer_overflowed); 1046bf215546Sopenharmony_ci } 1047bf215546Sopenharmony_ci 1048bf215546Sopenharmony_ci index_valid = LLVMBuildNot(builder, buffer_overflowed, ""); 1049bf215546Sopenharmony_ci index_valid = LLVMBuildSExt(builder, index_valid, i32_t, ""); 1050bf215546Sopenharmony_ci stride = LLVMBuildAnd(builder, stride, index_valid, ""); 1051bf215546Sopenharmony_ci 1052bf215546Sopenharmony_ci aos = lp_build_fetch_rgba_aos(gallivm, 1053bf215546Sopenharmony_ci format_desc, 1054bf215546Sopenharmony_ci lp_float32_vec4_type(), 1055bf215546Sopenharmony_ci FALSE, 1056bf215546Sopenharmony_ci map_ptr, 1057bf215546Sopenharmony_ci stride, zero, zero, 1058bf215546Sopenharmony_ci NULL); 1059bf215546Sopenharmony_ci 1060bf215546Sopenharmony_ci index_valid = lp_build_broadcast(gallivm, aosi_t, index_valid); 1061bf215546Sopenharmony_ci aos = LLVMBuildBitCast(builder, aos, aosi_t, ""); 1062bf215546Sopenharmony_ci aos = LLVMBuildAnd(builder, aos, index_valid, ""); 1063bf215546Sopenharmony_ci aos = LLVMBuildBitCast(builder, aos, aosf_t, ""); 1064bf215546Sopenharmony_ci 1065bf215546Sopenharmony_ci for (i = 0; i < TGSI_NUM_CHANNELS; i++) { 1066bf215546Sopenharmony_ci LLVMValueRef index = lp_build_const_int32(gallivm, i); 1067bf215546Sopenharmony_ci inputs[i] = lp_build_extract_broadcast(gallivm, 1068bf215546Sopenharmony_ci lp_float32_vec4_type(), 1069bf215546Sopenharmony_ci vs_type, aos, index); 1070bf215546Sopenharmony_ci } 1071bf215546Sopenharmony_ci} 1072bf215546Sopenharmony_ci 1073bf215546Sopenharmony_ci 1074bf215546Sopenharmony_cistatic void 1075bf215546Sopenharmony_cifetch_vector(struct gallivm_state *gallivm, 1076bf215546Sopenharmony_ci const struct util_format_description *format_desc, 1077bf215546Sopenharmony_ci struct lp_type vs_type, 1078bf215546Sopenharmony_ci LLVMValueRef vb_stride, 1079bf215546Sopenharmony_ci LLVMValueRef map_ptr, 1080bf215546Sopenharmony_ci LLVMValueRef buffer_size_adj, 1081bf215546Sopenharmony_ci LLVMValueRef *inputs, 1082bf215546Sopenharmony_ci LLVMValueRef indices) 1083bf215546Sopenharmony_ci{ 1084bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 1085bf215546Sopenharmony_ci struct lp_build_context blduivec; 1086bf215546Sopenharmony_ci struct lp_type fetch_type = vs_type; 1087bf215546Sopenharmony_ci LLVMValueRef offset, valid_mask; 1088bf215546Sopenharmony_ci unsigned i; 1089bf215546Sopenharmony_ci 1090bf215546Sopenharmony_ci lp_build_context_init(&blduivec, gallivm, lp_uint_type(vs_type)); 1091bf215546Sopenharmony_ci 1092bf215546Sopenharmony_ci vb_stride = lp_build_broadcast_scalar(&blduivec, vb_stride); 1093bf215546Sopenharmony_ci buffer_size_adj = lp_build_broadcast_scalar(&blduivec, buffer_size_adj); 1094bf215546Sopenharmony_ci 1095bf215546Sopenharmony_ci /* This mul can overflow. Wraparound is ok. */ 1096bf215546Sopenharmony_ci offset = lp_build_mul(&blduivec, vb_stride, indices); 1097bf215546Sopenharmony_ci 1098bf215546Sopenharmony_ci valid_mask = lp_build_compare(gallivm, blduivec.type, 1099bf215546Sopenharmony_ci PIPE_FUNC_LESS, offset, buffer_size_adj); 1100bf215546Sopenharmony_ci 1101bf215546Sopenharmony_ci /* not valid elements use offset 0 */ 1102bf215546Sopenharmony_ci offset = LLVMBuildAnd(builder, offset, valid_mask, ""); 1103bf215546Sopenharmony_ci 1104bf215546Sopenharmony_ci if (0) { 1105bf215546Sopenharmony_ci lp_build_print_value(gallivm, " indices = ", indices); 1106bf215546Sopenharmony_ci lp_build_print_value(gallivm, " offsets = ", offset); 1107bf215546Sopenharmony_ci lp_build_print_value(gallivm, " valid_mask = ", valid_mask); 1108bf215546Sopenharmony_ci } 1109bf215546Sopenharmony_ci 1110bf215546Sopenharmony_ci /* 1111bf215546Sopenharmony_ci * Unlike fetch_instanced, use SoA fetch instead of multiple AoS fetches. 1112bf215546Sopenharmony_ci * This should always produce better code. 1113bf215546Sopenharmony_ci */ 1114bf215546Sopenharmony_ci 1115bf215546Sopenharmony_ci /* The type handling is annoying here... */ 1116bf215546Sopenharmony_ci if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB && 1117bf215546Sopenharmony_ci format_desc->channel[0].pure_integer) { 1118bf215546Sopenharmony_ci if (format_desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED) { 1119bf215546Sopenharmony_ci fetch_type = lp_type_int_vec(vs_type.width, vs_type.width * vs_type.length); 1120bf215546Sopenharmony_ci } 1121bf215546Sopenharmony_ci else if (format_desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED) { 1122bf215546Sopenharmony_ci fetch_type = lp_type_uint_vec(vs_type.width, vs_type.width * vs_type.length); 1123bf215546Sopenharmony_ci } 1124bf215546Sopenharmony_ci } 1125bf215546Sopenharmony_ci 1126bf215546Sopenharmony_ci lp_build_fetch_rgba_soa(gallivm, format_desc, 1127bf215546Sopenharmony_ci fetch_type, FALSE, map_ptr, offset, 1128bf215546Sopenharmony_ci blduivec.zero, blduivec.zero, 1129bf215546Sopenharmony_ci NULL, inputs); 1130bf215546Sopenharmony_ci 1131bf215546Sopenharmony_ci for (i = 0; i < TGSI_NUM_CHANNELS; i++) { 1132bf215546Sopenharmony_ci inputs[i] = LLVMBuildBitCast(builder, inputs[i], 1133bf215546Sopenharmony_ci lp_build_vec_type(gallivm, vs_type), ""); 1134bf215546Sopenharmony_ci } 1135bf215546Sopenharmony_ci 1136bf215546Sopenharmony_ci /* out-of-bound fetches return all zeros */ 1137bf215546Sopenharmony_ci for (i = 0; i < format_desc->nr_channels; i++) { 1138bf215546Sopenharmony_ci inputs[i] = LLVMBuildBitCast(builder, inputs[i], blduivec.vec_type, ""); 1139bf215546Sopenharmony_ci inputs[i] = LLVMBuildAnd(builder, inputs[i], valid_mask, ""); 1140bf215546Sopenharmony_ci inputs[i] = LLVMBuildBitCast(builder, inputs[i], 1141bf215546Sopenharmony_ci lp_build_vec_type(gallivm, vs_type), ""); 1142bf215546Sopenharmony_ci } 1143bf215546Sopenharmony_ci} 1144bf215546Sopenharmony_ci 1145bf215546Sopenharmony_ci 1146bf215546Sopenharmony_cistatic void 1147bf215546Sopenharmony_cistore_aos(struct gallivm_state *gallivm, 1148bf215546Sopenharmony_ci LLVMTypeRef io_type, 1149bf215546Sopenharmony_ci LLVMValueRef io_ptr, 1150bf215546Sopenharmony_ci LLVMValueRef index, 1151bf215546Sopenharmony_ci LLVMValueRef value) 1152bf215546Sopenharmony_ci{ 1153bf215546Sopenharmony_ci LLVMTypeRef data_ptr_type = LLVMPointerType(lp_build_vec_type(gallivm, lp_float32_vec4_type()), 0); 1154bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 1155bf215546Sopenharmony_ci LLVMValueRef data_ptr = draw_jit_header_data(gallivm, io_type, io_ptr); 1156bf215546Sopenharmony_ci LLVMValueRef indices[3]; 1157bf215546Sopenharmony_ci 1158bf215546Sopenharmony_ci indices[0] = lp_build_const_int32(gallivm, 0); 1159bf215546Sopenharmony_ci indices[1] = index; 1160bf215546Sopenharmony_ci indices[2] = lp_build_const_int32(gallivm, 0); 1161bf215546Sopenharmony_ci 1162bf215546Sopenharmony_ci data_ptr = LLVMBuildGEP(builder, data_ptr, indices, 3, ""); 1163bf215546Sopenharmony_ci data_ptr = LLVMBuildPointerCast(builder, data_ptr, data_ptr_type, ""); 1164bf215546Sopenharmony_ci 1165bf215546Sopenharmony_ci#if DEBUG_STORE 1166bf215546Sopenharmony_ci lp_build_printf(gallivm, " ---- %p storing attribute %d (io = %p)\n", data_ptr, index, io_ptr); 1167bf215546Sopenharmony_ci#endif 1168bf215546Sopenharmony_ci 1169bf215546Sopenharmony_ci /* Unaligned store due to the vertex header */ 1170bf215546Sopenharmony_ci LLVMSetAlignment(LLVMBuildStore(builder, value, data_ptr), sizeof(float)); 1171bf215546Sopenharmony_ci} 1172bf215546Sopenharmony_ci 1173bf215546Sopenharmony_ci/** 1174bf215546Sopenharmony_ci * Adjust the mask to architecture endianess. The mask will the store in struct: 1175bf215546Sopenharmony_ci * 1176bf215546Sopenharmony_ci * struct vertex_header { 1177bf215546Sopenharmony_ci * unsigned clipmask:DRAW_TOTAL_CLIP_PLANES; 1178bf215546Sopenharmony_ci * unsigned edgeflag:1; 1179bf215546Sopenharmony_ci * unsigned pad:1; 1180bf215546Sopenharmony_ci * unsigned vertex_id:16; 1181bf215546Sopenharmony_ci * [...] 1182bf215546Sopenharmony_ci * } 1183bf215546Sopenharmony_ci * 1184bf215546Sopenharmony_ci * On little-endian machine nothing needs to done, however on bit-endian machine 1185bf215546Sopenharmony_ci * the mask's fields need to be adjusted with the algorithm: 1186bf215546Sopenharmony_ci * 1187bf215546Sopenharmony_ci * uint32_t reverse (uint32_t x) 1188bf215546Sopenharmony_ci * { 1189bf215546Sopenharmony_ci * return (x >> 16) | // vertex_id 1190bf215546Sopenharmony_ci * ((x & 0x3fff) << 18) | // clipmask 1191bf215546Sopenharmony_ci * ((x & 0x4000) << 3) | // edgeflag 1192bf215546Sopenharmony_ci * ((x & 0x8000) << 1); // pad 1193bf215546Sopenharmony_ci * } 1194bf215546Sopenharmony_ci */ 1195bf215546Sopenharmony_cistatic LLVMValueRef 1196bf215546Sopenharmony_ciadjust_mask(struct gallivm_state *gallivm, 1197bf215546Sopenharmony_ci LLVMValueRef mask) 1198bf215546Sopenharmony_ci{ 1199bf215546Sopenharmony_ci#if UTIL_ARCH_BIG_ENDIAN 1200bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 1201bf215546Sopenharmony_ci LLVMValueRef vertex_id; 1202bf215546Sopenharmony_ci LLVMValueRef clipmask; 1203bf215546Sopenharmony_ci LLVMValueRef pad; 1204bf215546Sopenharmony_ci LLVMValueRef edgeflag; 1205bf215546Sopenharmony_ci 1206bf215546Sopenharmony_ci vertex_id = LLVMBuildLShr(builder, mask, lp_build_const_int32(gallivm, 16), ""); 1207bf215546Sopenharmony_ci clipmask = LLVMBuildAnd(builder, mask, lp_build_const_int32(gallivm, 0x3fff), ""); 1208bf215546Sopenharmony_ci clipmask = LLVMBuildShl(builder, clipmask, lp_build_const_int32(gallivm, 18), ""); 1209bf215546Sopenharmony_ci if (0) { 1210bf215546Sopenharmony_ci pad = LLVMBuildAnd(builder, mask, lp_build_const_int32(gallivm, 0x8000), ""); 1211bf215546Sopenharmony_ci pad = LLVMBuildShl(builder, pad, lp_build_const_int32(gallivm, 1), ""); 1212bf215546Sopenharmony_ci } 1213bf215546Sopenharmony_ci edgeflag = LLVMBuildAnd(builder, mask, lp_build_const_int32(gallivm, 0x4000), ""); 1214bf215546Sopenharmony_ci edgeflag = LLVMBuildShl(builder, edgeflag, lp_build_const_int32(gallivm, 3), ""); 1215bf215546Sopenharmony_ci 1216bf215546Sopenharmony_ci mask = LLVMBuildOr(builder, vertex_id, clipmask, ""); 1217bf215546Sopenharmony_ci if (0) { 1218bf215546Sopenharmony_ci mask = LLVMBuildOr(builder, mask, pad, ""); 1219bf215546Sopenharmony_ci } 1220bf215546Sopenharmony_ci mask = LLVMBuildOr(builder, mask, edgeflag, ""); 1221bf215546Sopenharmony_ci#endif 1222bf215546Sopenharmony_ci return mask; 1223bf215546Sopenharmony_ci} 1224bf215546Sopenharmony_ci 1225bf215546Sopenharmony_cistatic void 1226bf215546Sopenharmony_cistore_aos_array(struct gallivm_state *gallivm, 1227bf215546Sopenharmony_ci struct lp_type soa_type, 1228bf215546Sopenharmony_ci LLVMTypeRef io_type, 1229bf215546Sopenharmony_ci LLVMValueRef io_ptr, 1230bf215546Sopenharmony_ci LLVMValueRef *indices, 1231bf215546Sopenharmony_ci LLVMValueRef* aos, 1232bf215546Sopenharmony_ci int attrib, 1233bf215546Sopenharmony_ci int num_outputs, 1234bf215546Sopenharmony_ci LLVMValueRef clipmask, 1235bf215546Sopenharmony_ci boolean need_edgeflag) 1236bf215546Sopenharmony_ci{ 1237bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 1238bf215546Sopenharmony_ci LLVMValueRef attr_index = lp_build_const_int32(gallivm, attrib); 1239bf215546Sopenharmony_ci LLVMValueRef inds[LP_MAX_VECTOR_WIDTH / 32]; 1240bf215546Sopenharmony_ci LLVMValueRef linear_inds[LP_MAX_VECTOR_WIDTH / 32]; 1241bf215546Sopenharmony_ci LLVMValueRef io_ptrs[LP_MAX_VECTOR_WIDTH / 32]; 1242bf215546Sopenharmony_ci int vector_length = soa_type.length; 1243bf215546Sopenharmony_ci int i; 1244bf215546Sopenharmony_ci 1245bf215546Sopenharmony_ci assert(TGSI_NUM_CHANNELS == 4); 1246bf215546Sopenharmony_ci 1247bf215546Sopenharmony_ci for (i = 0; i < vector_length; i++) { 1248bf215546Sopenharmony_ci linear_inds[i] = lp_build_const_int32(gallivm, i); 1249bf215546Sopenharmony_ci if (indices) { 1250bf215546Sopenharmony_ci inds[i] = indices[i]; 1251bf215546Sopenharmony_ci } else { 1252bf215546Sopenharmony_ci inds[i] = linear_inds[i]; 1253bf215546Sopenharmony_ci } 1254bf215546Sopenharmony_ci io_ptrs[i] = LLVMBuildGEP2(builder, io_type, io_ptr, &inds[i], 1, ""); 1255bf215546Sopenharmony_ci } 1256bf215546Sopenharmony_ci 1257bf215546Sopenharmony_ci if (attrib == 0) { 1258bf215546Sopenharmony_ci /* store vertex header for each of the n vertices */ 1259bf215546Sopenharmony_ci LLVMValueRef val, cliptmp; 1260bf215546Sopenharmony_ci int vertex_id_pad_edgeflag; 1261bf215546Sopenharmony_ci 1262bf215546Sopenharmony_ci /* If this assertion fails, it means we need to update the bit twidding 1263bf215546Sopenharmony_ci * code here. See struct vertex_header in draw_private.h. 1264bf215546Sopenharmony_ci */ 1265bf215546Sopenharmony_ci assert(DRAW_TOTAL_CLIP_PLANES==14); 1266bf215546Sopenharmony_ci /* initialize vertex id:16 = 0xffff, pad:1 = 0, edgeflag:1 = 1 */ 1267bf215546Sopenharmony_ci if (!need_edgeflag) { 1268bf215546Sopenharmony_ci vertex_id_pad_edgeflag = (0xffff << 16) | (1 << DRAW_TOTAL_CLIP_PLANES); 1269bf215546Sopenharmony_ci } 1270bf215546Sopenharmony_ci else { 1271bf215546Sopenharmony_ci vertex_id_pad_edgeflag = (0xffff << 16); 1272bf215546Sopenharmony_ci } 1273bf215546Sopenharmony_ci val = lp_build_const_int_vec(gallivm, lp_int_type(soa_type), 1274bf215546Sopenharmony_ci vertex_id_pad_edgeflag); 1275bf215546Sopenharmony_ci /* OR with the clipmask */ 1276bf215546Sopenharmony_ci cliptmp = LLVMBuildOr(builder, val, clipmask, ""); 1277bf215546Sopenharmony_ci for (i = 0; i < vector_length; i++) { 1278bf215546Sopenharmony_ci LLVMValueRef id_ptr = draw_jit_header_id(gallivm, io_type, io_ptrs[i]); 1279bf215546Sopenharmony_ci val = LLVMBuildExtractElement(builder, cliptmp, linear_inds[i], ""); 1280bf215546Sopenharmony_ci val = adjust_mask(gallivm, val); 1281bf215546Sopenharmony_ci#if DEBUG_STORE 1282bf215546Sopenharmony_ci lp_build_printf(gallivm, "io = %p, index %d, clipmask = %x\n", 1283bf215546Sopenharmony_ci io_ptrs[i], inds[i], val); 1284bf215546Sopenharmony_ci#endif 1285bf215546Sopenharmony_ci LLVMBuildStore(builder, val, id_ptr); 1286bf215546Sopenharmony_ci } 1287bf215546Sopenharmony_ci } 1288bf215546Sopenharmony_ci 1289bf215546Sopenharmony_ci /* store for each of the n vertices */ 1290bf215546Sopenharmony_ci for (i = 0; i < vector_length; i++) { 1291bf215546Sopenharmony_ci store_aos(gallivm, io_type, io_ptrs[i], attr_index, aos[i]); 1292bf215546Sopenharmony_ci } 1293bf215546Sopenharmony_ci} 1294bf215546Sopenharmony_ci 1295bf215546Sopenharmony_ci 1296bf215546Sopenharmony_cistatic void 1297bf215546Sopenharmony_ciconvert_to_aos(struct gallivm_state *gallivm, 1298bf215546Sopenharmony_ci LLVMTypeRef io_type, 1299bf215546Sopenharmony_ci LLVMValueRef io, 1300bf215546Sopenharmony_ci LLVMValueRef *indices, 1301bf215546Sopenharmony_ci LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS], 1302bf215546Sopenharmony_ci LLVMValueRef clipmask, 1303bf215546Sopenharmony_ci int num_outputs, 1304bf215546Sopenharmony_ci struct lp_type soa_type, 1305bf215546Sopenharmony_ci boolean need_edgeflag) 1306bf215546Sopenharmony_ci{ 1307bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 1308bf215546Sopenharmony_ci unsigned chan, attrib, i; 1309bf215546Sopenharmony_ci 1310bf215546Sopenharmony_ci#if DEBUG_STORE 1311bf215546Sopenharmony_ci lp_build_printf(gallivm, " # storing begin\n"); 1312bf215546Sopenharmony_ci#endif 1313bf215546Sopenharmony_ci for (attrib = 0; attrib < num_outputs; ++attrib) { 1314bf215546Sopenharmony_ci LLVMValueRef soa[TGSI_NUM_CHANNELS]; 1315bf215546Sopenharmony_ci LLVMValueRef aos[LP_MAX_VECTOR_WIDTH / 32]; 1316bf215546Sopenharmony_ci for (chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) { 1317bf215546Sopenharmony_ci if (outputs[attrib][chan]) { 1318bf215546Sopenharmony_ci LLVMValueRef out = LLVMBuildLoad(builder, outputs[attrib][chan], ""); 1319bf215546Sopenharmony_ci lp_build_name(out, "output%u.%c", attrib, "xyzw"[chan]); 1320bf215546Sopenharmony_ci#if DEBUG_STORE 1321bf215546Sopenharmony_ci lp_build_printf(gallivm, "output %d : %d ", 1322bf215546Sopenharmony_ci LLVMConstInt(LLVMInt32TypeInContext(gallivm->context), 1323bf215546Sopenharmony_ci attrib, 0), 1324bf215546Sopenharmony_ci LLVMConstInt(LLVMInt32TypeInContext(gallivm->context), 1325bf215546Sopenharmony_ci chan, 0)); 1326bf215546Sopenharmony_ci lp_build_print_value(gallivm, "val = ", out); 1327bf215546Sopenharmony_ci { 1328bf215546Sopenharmony_ci LLVMValueRef iv = 1329bf215546Sopenharmony_ci LLVMBuildBitCast(builder, out, lp_build_int_vec_type(gallivm, soa_type), ""); 1330bf215546Sopenharmony_ci 1331bf215546Sopenharmony_ci lp_build_print_value(gallivm, " ival = ", iv); 1332bf215546Sopenharmony_ci } 1333bf215546Sopenharmony_ci#endif 1334bf215546Sopenharmony_ci soa[chan] = out; 1335bf215546Sopenharmony_ci } 1336bf215546Sopenharmony_ci else { 1337bf215546Sopenharmony_ci soa[chan] = 0; 1338bf215546Sopenharmony_ci } 1339bf215546Sopenharmony_ci } 1340bf215546Sopenharmony_ci 1341bf215546Sopenharmony_ci 1342bf215546Sopenharmony_ci if (soa_type.length == TGSI_NUM_CHANNELS) { 1343bf215546Sopenharmony_ci lp_build_transpose_aos(gallivm, soa_type, soa, aos); 1344bf215546Sopenharmony_ci } else { 1345bf215546Sopenharmony_ci lp_build_transpose_aos(gallivm, soa_type, soa, soa); 1346bf215546Sopenharmony_ci 1347bf215546Sopenharmony_ci for (i = 0; i < soa_type.length; ++i) { 1348bf215546Sopenharmony_ci aos[i] = lp_build_extract_range(gallivm, 1349bf215546Sopenharmony_ci soa[i % TGSI_NUM_CHANNELS], 1350bf215546Sopenharmony_ci (i / TGSI_NUM_CHANNELS) * TGSI_NUM_CHANNELS, 1351bf215546Sopenharmony_ci TGSI_NUM_CHANNELS); 1352bf215546Sopenharmony_ci } 1353bf215546Sopenharmony_ci } 1354bf215546Sopenharmony_ci 1355bf215546Sopenharmony_ci store_aos_array(gallivm, 1356bf215546Sopenharmony_ci soa_type, 1357bf215546Sopenharmony_ci io_type, 1358bf215546Sopenharmony_ci io, 1359bf215546Sopenharmony_ci indices, 1360bf215546Sopenharmony_ci aos, 1361bf215546Sopenharmony_ci attrib, 1362bf215546Sopenharmony_ci num_outputs, 1363bf215546Sopenharmony_ci clipmask, 1364bf215546Sopenharmony_ci need_edgeflag); 1365bf215546Sopenharmony_ci } 1366bf215546Sopenharmony_ci#if DEBUG_STORE 1367bf215546Sopenharmony_ci lp_build_printf(gallivm, " # storing end\n"); 1368bf215546Sopenharmony_ci#endif 1369bf215546Sopenharmony_ci} 1370bf215546Sopenharmony_ci 1371bf215546Sopenharmony_ci 1372bf215546Sopenharmony_ci/** 1373bf215546Sopenharmony_ci * Stores original vertex positions in clip coordinates 1374bf215546Sopenharmony_ci */ 1375bf215546Sopenharmony_cistatic void 1376bf215546Sopenharmony_cistore_clip(struct gallivm_state *gallivm, 1377bf215546Sopenharmony_ci const struct lp_type vs_type, 1378bf215546Sopenharmony_ci LLVMTypeRef io_type, 1379bf215546Sopenharmony_ci LLVMValueRef io_ptr, 1380bf215546Sopenharmony_ci LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS], 1381bf215546Sopenharmony_ci int idx) 1382bf215546Sopenharmony_ci{ 1383bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 1384bf215546Sopenharmony_ci LLVMValueRef soa[4]; 1385bf215546Sopenharmony_ci LLVMValueRef aos[LP_MAX_VECTOR_LENGTH]; 1386bf215546Sopenharmony_ci LLVMValueRef io_ptrs[LP_MAX_VECTOR_WIDTH / 32]; 1387bf215546Sopenharmony_ci LLVMValueRef inds[LP_MAX_VECTOR_WIDTH / 32]; 1388bf215546Sopenharmony_ci LLVMValueRef clip_ptrs[LP_MAX_VECTOR_WIDTH / 32]; 1389bf215546Sopenharmony_ci LLVMTypeRef clip_ptr_type = 1390bf215546Sopenharmony_ci LLVMPointerType(LLVMVectorType(LLVMFloatTypeInContext(gallivm->context), 1391bf215546Sopenharmony_ci 4), 0); 1392bf215546Sopenharmony_ci int i, j; 1393bf215546Sopenharmony_ci 1394bf215546Sopenharmony_ci for (i = 0; i < vs_type.length; i++) { 1395bf215546Sopenharmony_ci inds[i] = lp_build_const_int32(gallivm, i); 1396bf215546Sopenharmony_ci io_ptrs[i] = LLVMBuildGEP2(builder, io_type, io_ptr, &inds[i], 1, ""); 1397bf215546Sopenharmony_ci } 1398bf215546Sopenharmony_ci 1399bf215546Sopenharmony_ci soa[0] = LLVMBuildLoad(builder, outputs[idx][0], ""); /*x0 x1 .. xn*/ 1400bf215546Sopenharmony_ci soa[1] = LLVMBuildLoad(builder, outputs[idx][1], ""); /*y0 y1 .. yn*/ 1401bf215546Sopenharmony_ci soa[2] = LLVMBuildLoad(builder, outputs[idx][2], ""); /*z0 z1 .. zn*/ 1402bf215546Sopenharmony_ci soa[3] = LLVMBuildLoad(builder, outputs[idx][3], ""); /*w0 w1 .. wn*/ 1403bf215546Sopenharmony_ci 1404bf215546Sopenharmony_ci for (i = 0; i < vs_type.length; i++) { 1405bf215546Sopenharmony_ci clip_ptrs[i] = draw_jit_header_clip_pos(gallivm, io_type, io_ptrs[i]); 1406bf215546Sopenharmony_ci } 1407bf215546Sopenharmony_ci 1408bf215546Sopenharmony_ci lp_build_transpose_aos(gallivm, vs_type, soa, soa); 1409bf215546Sopenharmony_ci for (i = 0; i < vs_type.length; ++i) { 1410bf215546Sopenharmony_ci aos[i] = lp_build_extract_range(gallivm, 1411bf215546Sopenharmony_ci soa[i % TGSI_NUM_CHANNELS], 1412bf215546Sopenharmony_ci (i / TGSI_NUM_CHANNELS) * TGSI_NUM_CHANNELS, 1413bf215546Sopenharmony_ci TGSI_NUM_CHANNELS); 1414bf215546Sopenharmony_ci } 1415bf215546Sopenharmony_ci 1416bf215546Sopenharmony_ci for (j = 0; j < vs_type.length; j++) { 1417bf215546Sopenharmony_ci LLVMValueRef clip_ptr; 1418bf215546Sopenharmony_ci 1419bf215546Sopenharmony_ci clip_ptr = LLVMBuildPointerCast(builder, clip_ptrs[j], clip_ptr_type, ""); 1420bf215546Sopenharmony_ci 1421bf215546Sopenharmony_ci /* Unaligned store */ 1422bf215546Sopenharmony_ci LLVMSetAlignment(LLVMBuildStore(builder, aos[j], clip_ptr), sizeof(float)); 1423bf215546Sopenharmony_ci } 1424bf215546Sopenharmony_ci} 1425bf215546Sopenharmony_ci 1426bf215546Sopenharmony_ci 1427bf215546Sopenharmony_ci/** 1428bf215546Sopenharmony_ci * Transforms the outputs for viewport mapping 1429bf215546Sopenharmony_ci */ 1430bf215546Sopenharmony_cistatic void 1431bf215546Sopenharmony_cigenerate_viewport(struct draw_llvm_variant *variant, 1432bf215546Sopenharmony_ci LLVMBuilderRef builder, 1433bf215546Sopenharmony_ci struct lp_type vs_type, 1434bf215546Sopenharmony_ci LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS], 1435bf215546Sopenharmony_ci LLVMValueRef context_ptr) 1436bf215546Sopenharmony_ci{ 1437bf215546Sopenharmony_ci int i; 1438bf215546Sopenharmony_ci struct gallivm_state *gallivm = variant->gallivm; 1439bf215546Sopenharmony_ci struct lp_type f32_type = vs_type; 1440bf215546Sopenharmony_ci const unsigned pos = variant->llvm->draw->vs.position_output; 1441bf215546Sopenharmony_ci LLVMTypeRef vs_type_llvm = lp_build_vec_type(gallivm, vs_type); 1442bf215546Sopenharmony_ci LLVMValueRef out3 = LLVMBuildLoad2(builder, vs_type_llvm, outputs[pos][3], ""); /*w0 w1 .. wn*/ 1443bf215546Sopenharmony_ci LLVMValueRef const1 = lp_build_const_vec(gallivm, f32_type, 1.0); /*1.0 1.0 1.0 1.0*/ 1444bf215546Sopenharmony_ci LLVMValueRef vp_ptr = draw_jit_context_viewports(variant, context_ptr); 1445bf215546Sopenharmony_ci 1446bf215546Sopenharmony_ci /* We treat pipe_viewport_state as a float array */ 1447bf215546Sopenharmony_ci const int scale_index_offset = offsetof(struct pipe_viewport_state, scale) / sizeof(float); 1448bf215546Sopenharmony_ci const int trans_index_offset = offsetof(struct pipe_viewport_state, translate) / sizeof(float); 1449bf215546Sopenharmony_ci 1450bf215546Sopenharmony_ci /* for 1/w convention*/ 1451bf215546Sopenharmony_ci out3 = LLVMBuildFDiv(builder, const1, out3, ""); 1452bf215546Sopenharmony_ci LLVMBuildStore(builder, out3, outputs[pos][3]); 1453bf215546Sopenharmony_ci 1454bf215546Sopenharmony_ci LLVMTypeRef elem_type = lp_build_elem_type(gallivm, vs_type); 1455bf215546Sopenharmony_ci 1456bf215546Sopenharmony_ci /* Viewport Mapping */ 1457bf215546Sopenharmony_ci for (i=0; i<3; i++) { 1458bf215546Sopenharmony_ci LLVMValueRef out = LLVMBuildLoad2(builder, vs_type_llvm, outputs[pos][i], ""); /*x0 x1 .. xn*/ 1459bf215546Sopenharmony_ci LLVMValueRef scale; 1460bf215546Sopenharmony_ci LLVMValueRef trans; 1461bf215546Sopenharmony_ci LLVMValueRef scale_i; 1462bf215546Sopenharmony_ci LLVMValueRef trans_i; 1463bf215546Sopenharmony_ci LLVMValueRef index; 1464bf215546Sopenharmony_ci 1465bf215546Sopenharmony_ci index = lp_build_const_int32(gallivm, i + scale_index_offset); 1466bf215546Sopenharmony_ci scale_i = LLVMBuildGEP2(builder, elem_type, vp_ptr, &index, 1, ""); 1467bf215546Sopenharmony_ci 1468bf215546Sopenharmony_ci index = lp_build_const_int32(gallivm, i + trans_index_offset); 1469bf215546Sopenharmony_ci trans_i = LLVMBuildGEP2(builder, elem_type, vp_ptr, &index, 1, ""); 1470bf215546Sopenharmony_ci 1471bf215546Sopenharmony_ci scale = lp_build_broadcast(gallivm, vs_type_llvm, 1472bf215546Sopenharmony_ci LLVMBuildLoad2(builder, elem_type, scale_i, "scale")); 1473bf215546Sopenharmony_ci trans = lp_build_broadcast(gallivm, vs_type_llvm, 1474bf215546Sopenharmony_ci LLVMBuildLoad2(builder, elem_type, trans_i, "trans")); 1475bf215546Sopenharmony_ci 1476bf215546Sopenharmony_ci /* divide by w */ 1477bf215546Sopenharmony_ci out = LLVMBuildFMul(builder, out, out3, ""); 1478bf215546Sopenharmony_ci /* mult by scale, add translation */ 1479bf215546Sopenharmony_ci out = lp_build_fmuladd(builder, out, scale, trans); 1480bf215546Sopenharmony_ci 1481bf215546Sopenharmony_ci /* store transformed outputs */ 1482bf215546Sopenharmony_ci LLVMBuildStore(builder, out, outputs[pos][i]); 1483bf215546Sopenharmony_ci } 1484bf215546Sopenharmony_ci 1485bf215546Sopenharmony_ci} 1486bf215546Sopenharmony_ci 1487bf215546Sopenharmony_ci 1488bf215546Sopenharmony_ci/** 1489bf215546Sopenharmony_ci * Returns clipmask as nxi32 bitmask for the n vertices 1490bf215546Sopenharmony_ci */ 1491bf215546Sopenharmony_cistatic LLVMValueRef 1492bf215546Sopenharmony_cigenerate_clipmask(struct draw_llvm *llvm, 1493bf215546Sopenharmony_ci struct gallivm_state *gallivm, 1494bf215546Sopenharmony_ci struct lp_type vs_type, 1495bf215546Sopenharmony_ci LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS], 1496bf215546Sopenharmony_ci struct draw_llvm_variant_key *key, 1497bf215546Sopenharmony_ci LLVMTypeRef context_type, 1498bf215546Sopenharmony_ci LLVMValueRef context_ptr, 1499bf215546Sopenharmony_ci boolean *have_clipdist) 1500bf215546Sopenharmony_ci{ 1501bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 1502bf215546Sopenharmony_ci LLVMValueRef mask; /* stores the <nxi32> clipmasks */ 1503bf215546Sopenharmony_ci LLVMValueRef test, temp; 1504bf215546Sopenharmony_ci LLVMValueRef zero, shift; 1505bf215546Sopenharmony_ci LLVMValueRef pos_x, pos_y, pos_z, pos_w; 1506bf215546Sopenharmony_ci LLVMValueRef cv_x, cv_y, cv_z, cv_w; 1507bf215546Sopenharmony_ci LLVMValueRef plane1, planes, plane_ptr, sum; 1508bf215546Sopenharmony_ci struct lp_type f32_type = vs_type; 1509bf215546Sopenharmony_ci struct lp_type i32_type = lp_int_type(vs_type); 1510bf215546Sopenharmony_ci const unsigned pos = llvm->draw->vs.position_output; 1511bf215546Sopenharmony_ci const unsigned cv = llvm->draw->vs.clipvertex_output; 1512bf215546Sopenharmony_ci int num_written_clipdistance = llvm->draw->vs.vertex_shader->info.num_written_clipdistance; 1513bf215546Sopenharmony_ci boolean have_cd = false; 1514bf215546Sopenharmony_ci boolean clip_user = key->clip_user; 1515bf215546Sopenharmony_ci unsigned ucp_enable = key->ucp_enable; 1516bf215546Sopenharmony_ci unsigned cd[2]; 1517bf215546Sopenharmony_ci 1518bf215546Sopenharmony_ci cd[0] = llvm->draw->vs.ccdistance_output[0]; 1519bf215546Sopenharmony_ci cd[1] = llvm->draw->vs.ccdistance_output[1]; 1520bf215546Sopenharmony_ci 1521bf215546Sopenharmony_ci if (cd[0] != pos || cd[1] != pos) 1522bf215546Sopenharmony_ci have_cd = true; 1523bf215546Sopenharmony_ci 1524bf215546Sopenharmony_ci if (num_written_clipdistance && !clip_user) { 1525bf215546Sopenharmony_ci clip_user = true; 1526bf215546Sopenharmony_ci ucp_enable = (1 << num_written_clipdistance) - 1; 1527bf215546Sopenharmony_ci } 1528bf215546Sopenharmony_ci 1529bf215546Sopenharmony_ci mask = lp_build_const_int_vec(gallivm, i32_type, 0); 1530bf215546Sopenharmony_ci temp = lp_build_const_int_vec(gallivm, i32_type, 0); 1531bf215546Sopenharmony_ci zero = lp_build_const_vec(gallivm, f32_type, 0); /* 0.0f 0.0f 0.0f 0.0f */ 1532bf215546Sopenharmony_ci shift = lp_build_const_int_vec(gallivm, i32_type, 1); /* 1 1 1 1 */ 1533bf215546Sopenharmony_ci 1534bf215546Sopenharmony_ci LLVMTypeRef vec_type = LLVMTypeOf(zero); 1535bf215546Sopenharmony_ci 1536bf215546Sopenharmony_ci /* 1537bf215546Sopenharmony_ci * load clipvertex and position from correct locations. 1538bf215546Sopenharmony_ci * if they are the same just load them once. 1539bf215546Sopenharmony_ci */ 1540bf215546Sopenharmony_ci pos_x = LLVMBuildLoad2(builder, vec_type, outputs[pos][0], ""); /*x0 x1 .. xn */ 1541bf215546Sopenharmony_ci pos_y = LLVMBuildLoad2(builder, vec_type, outputs[pos][1], ""); /*y0 y1 .. yn */ 1542bf215546Sopenharmony_ci pos_z = LLVMBuildLoad2(builder, vec_type, outputs[pos][2], ""); /*z0 z1 .. zn */ 1543bf215546Sopenharmony_ci pos_w = LLVMBuildLoad2(builder, vec_type, outputs[pos][3], ""); /*w0 w1 .. wn */ 1544bf215546Sopenharmony_ci 1545bf215546Sopenharmony_ci if (clip_user && cv != pos) { 1546bf215546Sopenharmony_ci cv_x = LLVMBuildLoad2(builder, vec_type, outputs[cv][0], ""); /*x0 x1 .. xn */ 1547bf215546Sopenharmony_ci cv_y = LLVMBuildLoad2(builder, vec_type, outputs[cv][1], ""); /*y0 y1 .. yn */ 1548bf215546Sopenharmony_ci cv_z = LLVMBuildLoad2(builder, vec_type, outputs[cv][2], ""); /*z0 z1 .. zn */ 1549bf215546Sopenharmony_ci cv_w = LLVMBuildLoad2(builder, vec_type, outputs[cv][3], ""); /*w0 w1 .. wn */ 1550bf215546Sopenharmony_ci } else { 1551bf215546Sopenharmony_ci cv_x = pos_x; 1552bf215546Sopenharmony_ci cv_y = pos_y; 1553bf215546Sopenharmony_ci cv_z = pos_z; 1554bf215546Sopenharmony_ci cv_w = pos_w; 1555bf215546Sopenharmony_ci } 1556bf215546Sopenharmony_ci 1557bf215546Sopenharmony_ci /* 1558bf215546Sopenharmony_ci * Be careful with the comparisons and NaNs (using llvm's unordered 1559bf215546Sopenharmony_ci * comparisons here). 1560bf215546Sopenharmony_ci */ 1561bf215546Sopenharmony_ci /* Cliptest, for hardwired planes */ 1562bf215546Sopenharmony_ci /* 1563bf215546Sopenharmony_ci * XXX should take guardband into account (currently not in key). 1564bf215546Sopenharmony_ci * Otherwise might run the draw pipeline stages for nothing. 1565bf215546Sopenharmony_ci */ 1566bf215546Sopenharmony_ci if (key->clip_xy) { 1567bf215546Sopenharmony_ci /* plane 1 */ 1568bf215546Sopenharmony_ci test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, pos_x , pos_w); 1569bf215546Sopenharmony_ci temp = shift; 1570bf215546Sopenharmony_ci test = LLVMBuildAnd(builder, test, temp, ""); 1571bf215546Sopenharmony_ci mask = test; 1572bf215546Sopenharmony_ci 1573bf215546Sopenharmony_ci /* plane 2 */ 1574bf215546Sopenharmony_ci test = LLVMBuildFAdd(builder, pos_x, pos_w, ""); 1575bf215546Sopenharmony_ci test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, zero, test); 1576bf215546Sopenharmony_ci temp = LLVMBuildShl(builder, temp, shift, ""); 1577bf215546Sopenharmony_ci test = LLVMBuildAnd(builder, test, temp, ""); 1578bf215546Sopenharmony_ci mask = LLVMBuildOr(builder, mask, test, ""); 1579bf215546Sopenharmony_ci 1580bf215546Sopenharmony_ci /* plane 3 */ 1581bf215546Sopenharmony_ci test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, pos_y, pos_w); 1582bf215546Sopenharmony_ci temp = LLVMBuildShl(builder, temp, shift, ""); 1583bf215546Sopenharmony_ci test = LLVMBuildAnd(builder, test, temp, ""); 1584bf215546Sopenharmony_ci mask = LLVMBuildOr(builder, mask, test, ""); 1585bf215546Sopenharmony_ci 1586bf215546Sopenharmony_ci /* plane 4 */ 1587bf215546Sopenharmony_ci test = LLVMBuildFAdd(builder, pos_y, pos_w, ""); 1588bf215546Sopenharmony_ci test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, zero, test); 1589bf215546Sopenharmony_ci temp = LLVMBuildShl(builder, temp, shift, ""); 1590bf215546Sopenharmony_ci test = LLVMBuildAnd(builder, test, temp, ""); 1591bf215546Sopenharmony_ci mask = LLVMBuildOr(builder, mask, test, ""); 1592bf215546Sopenharmony_ci } 1593bf215546Sopenharmony_ci 1594bf215546Sopenharmony_ci if (key->clip_z) { 1595bf215546Sopenharmony_ci temp = lp_build_const_int_vec(gallivm, i32_type, 16); 1596bf215546Sopenharmony_ci if (key->clip_halfz) { 1597bf215546Sopenharmony_ci /* plane 5 */ 1598bf215546Sopenharmony_ci test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, zero, pos_z); 1599bf215546Sopenharmony_ci test = LLVMBuildAnd(builder, test, temp, ""); 1600bf215546Sopenharmony_ci mask = LLVMBuildOr(builder, mask, test, ""); 1601bf215546Sopenharmony_ci } 1602bf215546Sopenharmony_ci else { 1603bf215546Sopenharmony_ci /* plane 5 */ 1604bf215546Sopenharmony_ci test = LLVMBuildFAdd(builder, pos_z, pos_w, ""); 1605bf215546Sopenharmony_ci test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, zero, test); 1606bf215546Sopenharmony_ci test = LLVMBuildAnd(builder, test, temp, ""); 1607bf215546Sopenharmony_ci mask = LLVMBuildOr(builder, mask, test, ""); 1608bf215546Sopenharmony_ci } 1609bf215546Sopenharmony_ci /* plane 6 */ 1610bf215546Sopenharmony_ci test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, pos_z, pos_w); 1611bf215546Sopenharmony_ci temp = LLVMBuildShl(builder, temp, shift, ""); 1612bf215546Sopenharmony_ci test = LLVMBuildAnd(builder, test, temp, ""); 1613bf215546Sopenharmony_ci mask = LLVMBuildOr(builder, mask, test, ""); 1614bf215546Sopenharmony_ci } 1615bf215546Sopenharmony_ci 1616bf215546Sopenharmony_ci if (clip_user) { 1617bf215546Sopenharmony_ci LLVMValueRef planes_ptr = draw_jit_context_planes(gallivm, context_type, context_ptr); 1618bf215546Sopenharmony_ci LLVMValueRef indices[3]; 1619bf215546Sopenharmony_ci LLVMValueRef is_nan_or_inf; 1620bf215546Sopenharmony_ci 1621bf215546Sopenharmony_ci /* userclip planes */ 1622bf215546Sopenharmony_ci while (ucp_enable) { 1623bf215546Sopenharmony_ci unsigned plane_idx = ffs(ucp_enable)-1; 1624bf215546Sopenharmony_ci ucp_enable &= ~(1 << plane_idx); 1625bf215546Sopenharmony_ci plane_idx += 6; 1626bf215546Sopenharmony_ci 1627bf215546Sopenharmony_ci if (have_cd && num_written_clipdistance) { 1628bf215546Sopenharmony_ci LLVMValueRef clipdist; 1629bf215546Sopenharmony_ci int i; 1630bf215546Sopenharmony_ci i = plane_idx - 6; 1631bf215546Sopenharmony_ci 1632bf215546Sopenharmony_ci *have_clipdist = TRUE; 1633bf215546Sopenharmony_ci if (i < 4) { 1634bf215546Sopenharmony_ci clipdist = LLVMBuildLoad2(builder, vec_type, outputs[cd[0]][i], ""); 1635bf215546Sopenharmony_ci } else { 1636bf215546Sopenharmony_ci clipdist = LLVMBuildLoad2(builder, vec_type, outputs[cd[1]][i-4], ""); 1637bf215546Sopenharmony_ci } 1638bf215546Sopenharmony_ci test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, zero, clipdist); 1639bf215546Sopenharmony_ci is_nan_or_inf = lp_build_is_inf_or_nan(gallivm, vs_type, clipdist); 1640bf215546Sopenharmony_ci test = LLVMBuildOr(builder, test, is_nan_or_inf, ""); 1641bf215546Sopenharmony_ci temp = lp_build_const_int_vec(gallivm, i32_type, 1LL << plane_idx); 1642bf215546Sopenharmony_ci test = LLVMBuildAnd(builder, test, temp, ""); 1643bf215546Sopenharmony_ci mask = LLVMBuildOr(builder, mask, test, ""); 1644bf215546Sopenharmony_ci } else { 1645bf215546Sopenharmony_ci LLVMTypeRef vs_elem_type = lp_build_elem_type(gallivm, vs_type); 1646bf215546Sopenharmony_ci LLVMTypeRef vs_type_llvm = lp_build_vec_type(gallivm, vs_type); 1647bf215546Sopenharmony_ci indices[0] = lp_build_const_int32(gallivm, 0); 1648bf215546Sopenharmony_ci indices[1] = lp_build_const_int32(gallivm, plane_idx); 1649bf215546Sopenharmony_ci 1650bf215546Sopenharmony_ci for (int i = 0; i < 4; ++i) { 1651bf215546Sopenharmony_ci indices[2] = lp_build_const_int32(gallivm, i); 1652bf215546Sopenharmony_ci plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, ""); 1653bf215546Sopenharmony_ci plane1 = LLVMBuildLoad2(builder, vs_elem_type, plane_ptr, 1654bf215546Sopenharmony_ci (const char *[]){"plane_x", "plane_y", "plane_z", "plane_w"}[i]); 1655bf215546Sopenharmony_ci planes = lp_build_broadcast(gallivm, vs_type_llvm, plane1); 1656bf215546Sopenharmony_ci if (i == 0) { 1657bf215546Sopenharmony_ci sum = LLVMBuildFMul(builder, planes, cv_x, ""); 1658bf215546Sopenharmony_ci } else { 1659bf215546Sopenharmony_ci sum = lp_build_fmuladd(builder, planes, 1660bf215546Sopenharmony_ci (LLVMValueRef[]){cv_x, cv_y, cv_z, cv_w}[i], sum); 1661bf215546Sopenharmony_ci } 1662bf215546Sopenharmony_ci } 1663bf215546Sopenharmony_ci 1664bf215546Sopenharmony_ci test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, zero, sum); 1665bf215546Sopenharmony_ci temp = lp_build_const_int_vec(gallivm, i32_type, 1LL << plane_idx); 1666bf215546Sopenharmony_ci test = LLVMBuildAnd(builder, test, temp, ""); 1667bf215546Sopenharmony_ci mask = LLVMBuildOr(builder, mask, test, ""); 1668bf215546Sopenharmony_ci } 1669bf215546Sopenharmony_ci } 1670bf215546Sopenharmony_ci } 1671bf215546Sopenharmony_ci if (key->need_edgeflags) { 1672bf215546Sopenharmony_ci /* 1673bf215546Sopenharmony_ci * This isn't really part of clipmask but stored the same in vertex 1674bf215546Sopenharmony_ci * header later, so do it here. 1675bf215546Sopenharmony_ci */ 1676bf215546Sopenharmony_ci unsigned edge_attr = llvm->draw->vs.edgeflag_output; 1677bf215546Sopenharmony_ci LLVMValueRef one = lp_build_const_vec(gallivm, f32_type, 1.0); 1678bf215546Sopenharmony_ci LLVMValueRef edgeflag = LLVMBuildLoad2(builder, vec_type, outputs[edge_attr][0], ""); 1679bf215546Sopenharmony_ci test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_EQUAL, one, edgeflag); 1680bf215546Sopenharmony_ci temp = lp_build_const_int_vec(gallivm, i32_type, 1681bf215546Sopenharmony_ci 1LL << DRAW_TOTAL_CLIP_PLANES); 1682bf215546Sopenharmony_ci test = LLVMBuildAnd(builder, test, temp, ""); 1683bf215546Sopenharmony_ci mask = LLVMBuildOr(builder, mask, test, ""); 1684bf215546Sopenharmony_ci } 1685bf215546Sopenharmony_ci return mask; 1686bf215546Sopenharmony_ci} 1687bf215546Sopenharmony_ci 1688bf215546Sopenharmony_ci 1689bf215546Sopenharmony_ci/** 1690bf215546Sopenharmony_ci * Returns boolean if any clipping has occurred 1691bf215546Sopenharmony_ci * Used zero/one i8 value to represent boolean 1692bf215546Sopenharmony_ci */ 1693bf215546Sopenharmony_cistatic LLVMValueRef 1694bf215546Sopenharmony_ciclipmask_booli8(struct gallivm_state *gallivm, 1695bf215546Sopenharmony_ci const struct lp_type vs_type, 1696bf215546Sopenharmony_ci LLVMValueRef clipmask_bool_ptr, 1697bf215546Sopenharmony_ci boolean edgeflag_in_clipmask) 1698bf215546Sopenharmony_ci{ 1699bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 1700bf215546Sopenharmony_ci LLVMTypeRef int8_type = LLVMInt8TypeInContext(gallivm->context); 1701bf215546Sopenharmony_ci LLVMValueRef clipmask_bool = LLVMBuildLoad(builder, clipmask_bool_ptr, ""); 1702bf215546Sopenharmony_ci LLVMValueRef ret; 1703bf215546Sopenharmony_ci struct lp_build_context bldivec; 1704bf215546Sopenharmony_ci 1705bf215546Sopenharmony_ci lp_build_context_init(&bldivec, gallivm, lp_int_type(vs_type)); 1706bf215546Sopenharmony_ci 1707bf215546Sopenharmony_ci /* 1708bf215546Sopenharmony_ci * We need to invert the edgeflag bit from the clipmask here 1709bf215546Sopenharmony_ci * (because the result is really if we want to run the pipeline or not 1710bf215546Sopenharmony_ci * and we (may) need it if edgeflag was 0). 1711bf215546Sopenharmony_ci */ 1712bf215546Sopenharmony_ci if (edgeflag_in_clipmask) { 1713bf215546Sopenharmony_ci LLVMValueRef edge = lp_build_const_int_vec(gallivm, bldivec.type, 1714bf215546Sopenharmony_ci 1LL << DRAW_TOTAL_CLIP_PLANES); 1715bf215546Sopenharmony_ci clipmask_bool = LLVMBuildXor(builder, clipmask_bool, edge, ""); 1716bf215546Sopenharmony_ci } 1717bf215546Sopenharmony_ci 1718bf215546Sopenharmony_ci /* 1719bf215546Sopenharmony_ci * XXX: probably should mask off bits from the mask which come from 1720bf215546Sopenharmony_ci * vertices which were beyond the count (i.e. indices_valid for 1721bf215546Sopenharmony_ci * linear fetches, for elts ones we don't have the correct mask 1722bf215546Sopenharmony_ci * right now). Otherwise might run the pipeline for nothing, 1723bf215546Sopenharmony_ci * though everything should still work. 1724bf215546Sopenharmony_ci */ 1725bf215546Sopenharmony_ci ret = lp_build_any_true_range(&bldivec, vs_type.length, clipmask_bool); 1726bf215546Sopenharmony_ci ret = LLVMBuildZExt(builder, ret, int8_type, ""); 1727bf215546Sopenharmony_ci return ret; 1728bf215546Sopenharmony_ci} 1729bf215546Sopenharmony_ci 1730bf215546Sopenharmony_cistatic LLVMValueRef 1731bf215546Sopenharmony_cidraw_gs_llvm_fetch_input(const struct lp_build_gs_iface *gs_iface, 1732bf215546Sopenharmony_ci struct lp_build_context * bld, 1733bf215546Sopenharmony_ci boolean is_vindex_indirect, 1734bf215546Sopenharmony_ci LLVMValueRef vertex_index, 1735bf215546Sopenharmony_ci boolean is_aindex_indirect, 1736bf215546Sopenharmony_ci LLVMValueRef attrib_index, 1737bf215546Sopenharmony_ci LLVMValueRef swizzle_index) 1738bf215546Sopenharmony_ci{ 1739bf215546Sopenharmony_ci const struct draw_gs_llvm_iface *gs = draw_gs_llvm_iface(gs_iface); 1740bf215546Sopenharmony_ci struct gallivm_state *gallivm = bld->gallivm; 1741bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 1742bf215546Sopenharmony_ci LLVMValueRef indices[3]; 1743bf215546Sopenharmony_ci LLVMValueRef res; 1744bf215546Sopenharmony_ci struct lp_type type = bld->type; 1745bf215546Sopenharmony_ci 1746bf215546Sopenharmony_ci if (is_vindex_indirect || is_aindex_indirect) { 1747bf215546Sopenharmony_ci int i; 1748bf215546Sopenharmony_ci res = bld->zero; 1749bf215546Sopenharmony_ci for (i = 0; i < type.length; ++i) { 1750bf215546Sopenharmony_ci LLVMValueRef idx = lp_build_const_int32(gallivm, i); 1751bf215546Sopenharmony_ci LLVMValueRef vert_chan_index = vertex_index; 1752bf215546Sopenharmony_ci LLVMValueRef attr_chan_index = attrib_index; 1753bf215546Sopenharmony_ci LLVMValueRef channel_vec, value; 1754bf215546Sopenharmony_ci 1755bf215546Sopenharmony_ci if (is_vindex_indirect) { 1756bf215546Sopenharmony_ci vert_chan_index = LLVMBuildExtractElement(builder, 1757bf215546Sopenharmony_ci vertex_index, idx, ""); 1758bf215546Sopenharmony_ci } 1759bf215546Sopenharmony_ci if (is_aindex_indirect) { 1760bf215546Sopenharmony_ci attr_chan_index = LLVMBuildExtractElement(builder, 1761bf215546Sopenharmony_ci attrib_index, idx, ""); 1762bf215546Sopenharmony_ci } 1763bf215546Sopenharmony_ci 1764bf215546Sopenharmony_ci indices[0] = vert_chan_index; 1765bf215546Sopenharmony_ci indices[1] = attr_chan_index; 1766bf215546Sopenharmony_ci indices[2] = swizzle_index; 1767bf215546Sopenharmony_ci 1768bf215546Sopenharmony_ci channel_vec = LLVMBuildGEP(builder, gs->input, indices, 3, ""); 1769bf215546Sopenharmony_ci channel_vec = LLVMBuildLoad(builder, channel_vec, ""); 1770bf215546Sopenharmony_ci value = LLVMBuildExtractElement(builder, channel_vec, idx, ""); 1771bf215546Sopenharmony_ci 1772bf215546Sopenharmony_ci res = LLVMBuildInsertElement(builder, res, value, idx, ""); 1773bf215546Sopenharmony_ci } 1774bf215546Sopenharmony_ci } else { 1775bf215546Sopenharmony_ci indices[0] = vertex_index; 1776bf215546Sopenharmony_ci indices[1] = attrib_index; 1777bf215546Sopenharmony_ci indices[2] = swizzle_index; 1778bf215546Sopenharmony_ci 1779bf215546Sopenharmony_ci res = LLVMBuildGEP(builder, gs->input, indices, 3, ""); 1780bf215546Sopenharmony_ci res = LLVMBuildLoad(builder, res, ""); 1781bf215546Sopenharmony_ci } 1782bf215546Sopenharmony_ci 1783bf215546Sopenharmony_ci return res; 1784bf215546Sopenharmony_ci} 1785bf215546Sopenharmony_ci 1786bf215546Sopenharmony_cistatic void 1787bf215546Sopenharmony_cidraw_gs_llvm_emit_vertex(const struct lp_build_gs_iface *gs_base, 1788bf215546Sopenharmony_ci struct lp_build_context * bld, 1789bf215546Sopenharmony_ci LLVMValueRef (*outputs)[4], 1790bf215546Sopenharmony_ci LLVMValueRef emitted_vertices_vec, 1791bf215546Sopenharmony_ci LLVMValueRef mask_vec, LLVMValueRef stream_id) 1792bf215546Sopenharmony_ci{ 1793bf215546Sopenharmony_ci const struct draw_gs_llvm_iface *gs_iface = draw_gs_llvm_iface(gs_base); 1794bf215546Sopenharmony_ci struct draw_gs_llvm_variant *variant = gs_iface->variant; 1795bf215546Sopenharmony_ci struct gallivm_state *gallivm = variant->gallivm; 1796bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 1797bf215546Sopenharmony_ci struct lp_type gs_type = bld->type; 1798bf215546Sopenharmony_ci LLVMValueRef clipmask = lp_build_const_int_vec(gallivm, 1799bf215546Sopenharmony_ci lp_int_type(gs_type), 0); 1800bf215546Sopenharmony_ci LLVMValueRef indices[LP_MAX_VECTOR_LENGTH]; 1801bf215546Sopenharmony_ci LLVMValueRef next_prim_offset = 1802bf215546Sopenharmony_ci lp_build_const_int32(gallivm, variant->shader->base.primitive_boundary); 1803bf215546Sopenharmony_ci LLVMValueRef io = variant->io_ptr; 1804bf215546Sopenharmony_ci unsigned i; 1805bf215546Sopenharmony_ci const struct tgsi_shader_info *gs_info = &variant->shader->base.info; 1806bf215546Sopenharmony_ci 1807bf215546Sopenharmony_ci LLVMValueRef cond = LLVMBuildICmp(gallivm->builder, LLVMIntNE, mask_vec, lp_build_const_int_vec(gallivm, bld->type, 0), ""); 1808bf215546Sopenharmony_ci for (i = 0; i < gs_type.length; ++i) { 1809bf215546Sopenharmony_ci LLVMValueRef ind = lp_build_const_int32(gallivm, i); 1810bf215546Sopenharmony_ci LLVMValueRef currently_emitted = 1811bf215546Sopenharmony_ci LLVMBuildExtractElement(builder, emitted_vertices_vec, ind, ""); 1812bf215546Sopenharmony_ci indices[i] = LLVMBuildMul(builder, ind, next_prim_offset, ""); 1813bf215546Sopenharmony_ci indices[i] = LLVMBuildAdd(builder, indices[i], currently_emitted, ""); 1814bf215546Sopenharmony_ci indices[i] = LLVMBuildSelect(builder, LLVMBuildExtractElement(builder, cond, ind, ""), indices[i], 1815bf215546Sopenharmony_ci lp_build_const_int32(gallivm, variant->shader->base.primitive_boundary - 1), ""); 1816bf215546Sopenharmony_ci } 1817bf215546Sopenharmony_ci 1818bf215546Sopenharmony_ci LLVMValueRef stream_idx = LLVMBuildExtractElement(builder, stream_id, lp_build_const_int32(gallivm, 0), ""); 1819bf215546Sopenharmony_ci LLVMValueRef cnd = LLVMBuildICmp(builder, LLVMIntULT, stream_idx, lp_build_const_int32(gallivm, variant->shader->base.num_vertex_streams), ""); 1820bf215546Sopenharmony_ci struct lp_build_if_state if_ctx; 1821bf215546Sopenharmony_ci lp_build_if(&if_ctx, gallivm, cnd); 1822bf215546Sopenharmony_ci io = lp_build_pointer_get(builder, io, LLVMBuildExtractElement(builder, stream_id, lp_build_const_int32(gallivm, 0), "")); 1823bf215546Sopenharmony_ci 1824bf215546Sopenharmony_ci if (variant->key.clamp_vertex_color) { 1825bf215546Sopenharmony_ci do_clamp_vertex_color(gallivm, gs_type, 1826bf215546Sopenharmony_ci gs_info, outputs); 1827bf215546Sopenharmony_ci } 1828bf215546Sopenharmony_ci convert_to_aos(gallivm, variant->vertex_header_type, 1829bf215546Sopenharmony_ci io, indices, 1830bf215546Sopenharmony_ci outputs, clipmask, 1831bf215546Sopenharmony_ci gs_info->num_outputs, gs_type, 1832bf215546Sopenharmony_ci FALSE); 1833bf215546Sopenharmony_ci lp_build_endif(&if_ctx); 1834bf215546Sopenharmony_ci} 1835bf215546Sopenharmony_ci 1836bf215546Sopenharmony_cistatic void 1837bf215546Sopenharmony_cidraw_gs_llvm_end_primitive(const struct lp_build_gs_iface *gs_base, 1838bf215546Sopenharmony_ci struct lp_build_context * bld, 1839bf215546Sopenharmony_ci LLVMValueRef total_emitted_vertices_vec_ptr, 1840bf215546Sopenharmony_ci LLVMValueRef verts_per_prim_vec, 1841bf215546Sopenharmony_ci LLVMValueRef emitted_prims_vec, 1842bf215546Sopenharmony_ci LLVMValueRef mask_vec, unsigned stream) 1843bf215546Sopenharmony_ci{ 1844bf215546Sopenharmony_ci const struct draw_gs_llvm_iface *gs_iface = draw_gs_llvm_iface(gs_base); 1845bf215546Sopenharmony_ci struct draw_gs_llvm_variant *variant = gs_iface->variant; 1846bf215546Sopenharmony_ci struct gallivm_state *gallivm = variant->gallivm; 1847bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 1848bf215546Sopenharmony_ci LLVMValueRef prim_lengts_ptr = 1849bf215546Sopenharmony_ci draw_gs_jit_prim_lengths(variant, variant->context_ptr); 1850bf215546Sopenharmony_ci unsigned i; 1851bf215546Sopenharmony_ci 1852bf215546Sopenharmony_ci LLVMValueRef cond = LLVMBuildICmp(gallivm->builder, LLVMIntNE, mask_vec, lp_build_const_int_vec(gallivm, bld->type, 0), ""); 1853bf215546Sopenharmony_ci for (i = 0; i < bld->type.length; ++i) { 1854bf215546Sopenharmony_ci LLVMValueRef ind = lp_build_const_int32(gallivm, i); 1855bf215546Sopenharmony_ci LLVMValueRef prims_emitted = 1856bf215546Sopenharmony_ci LLVMBuildExtractElement(builder, emitted_prims_vec, ind, ""); 1857bf215546Sopenharmony_ci LLVMValueRef store_ptr; 1858bf215546Sopenharmony_ci LLVMValueRef num_vertices = 1859bf215546Sopenharmony_ci LLVMBuildExtractElement(builder, verts_per_prim_vec, ind, ""); 1860bf215546Sopenharmony_ci 1861bf215546Sopenharmony_ci LLVMValueRef this_cond = LLVMBuildExtractElement(gallivm->builder, cond, ind, ""); 1862bf215546Sopenharmony_ci struct lp_build_if_state ifthen; 1863bf215546Sopenharmony_ci lp_build_if(&ifthen, gallivm, this_cond); 1864bf215546Sopenharmony_ci prims_emitted = LLVMBuildMul(gallivm->builder, prims_emitted, lp_build_const_int32(gallivm, variant->shader->base.num_vertex_streams), ""); 1865bf215546Sopenharmony_ci prims_emitted = LLVMBuildAdd(gallivm->builder, prims_emitted, lp_build_const_int32(gallivm, stream), ""); 1866bf215546Sopenharmony_ci store_ptr = LLVMBuildGEP(builder, prim_lengts_ptr, &prims_emitted, 1, ""); 1867bf215546Sopenharmony_ci store_ptr = LLVMBuildLoad(builder, store_ptr, ""); 1868bf215546Sopenharmony_ci store_ptr = LLVMBuildGEP(builder, store_ptr, &ind, 1, ""); 1869bf215546Sopenharmony_ci LLVMBuildStore(builder, num_vertices, store_ptr); 1870bf215546Sopenharmony_ci lp_build_endif(&ifthen); 1871bf215546Sopenharmony_ci } 1872bf215546Sopenharmony_ci} 1873bf215546Sopenharmony_ci 1874bf215546Sopenharmony_cistatic void 1875bf215546Sopenharmony_cidraw_gs_llvm_epilogue(const struct lp_build_gs_iface *gs_base, 1876bf215546Sopenharmony_ci LLVMValueRef total_emitted_vertices_vec, 1877bf215546Sopenharmony_ci LLVMValueRef emitted_prims_vec, unsigned stream) 1878bf215546Sopenharmony_ci{ 1879bf215546Sopenharmony_ci const struct draw_gs_llvm_iface *gs_iface = draw_gs_llvm_iface(gs_base); 1880bf215546Sopenharmony_ci struct draw_gs_llvm_variant *variant = gs_iface->variant; 1881bf215546Sopenharmony_ci struct gallivm_state *gallivm = variant->gallivm; 1882bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 1883bf215546Sopenharmony_ci LLVMValueRef emitted_verts_ptr = 1884bf215546Sopenharmony_ci draw_gs_jit_emitted_vertices(variant, variant->context_ptr); 1885bf215546Sopenharmony_ci LLVMValueRef emitted_prims_ptr = 1886bf215546Sopenharmony_ci draw_gs_jit_emitted_prims(variant, variant->context_ptr); 1887bf215546Sopenharmony_ci LLVMValueRef stream_val = lp_build_const_int32(gallivm, stream); 1888bf215546Sopenharmony_ci 1889bf215546Sopenharmony_ci emitted_verts_ptr = LLVMBuildGEP(builder, emitted_verts_ptr, &stream_val, 1, ""); 1890bf215546Sopenharmony_ci emitted_prims_ptr = LLVMBuildGEP(builder, emitted_prims_ptr, &stream_val, 1, ""); 1891bf215546Sopenharmony_ci 1892bf215546Sopenharmony_ci LLVMBuildStore(builder, total_emitted_vertices_vec, emitted_verts_ptr); 1893bf215546Sopenharmony_ci LLVMBuildStore(builder, emitted_prims_vec, emitted_prims_ptr); 1894bf215546Sopenharmony_ci} 1895bf215546Sopenharmony_ci 1896bf215546Sopenharmony_cistatic void 1897bf215546Sopenharmony_cidraw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) 1898bf215546Sopenharmony_ci{ 1899bf215546Sopenharmony_ci struct gallivm_state *gallivm = variant->gallivm; 1900bf215546Sopenharmony_ci LLVMContextRef context = gallivm->context; 1901bf215546Sopenharmony_ci LLVMTypeRef int32_type = LLVMInt32TypeInContext(context); 1902bf215546Sopenharmony_ci LLVMTypeRef arg_types[13]; 1903bf215546Sopenharmony_ci unsigned num_arg_types = ARRAY_SIZE(arg_types); 1904bf215546Sopenharmony_ci LLVMTypeRef func_type; 1905bf215546Sopenharmony_ci LLVMValueRef context_ptr; 1906bf215546Sopenharmony_ci LLVMBasicBlockRef block; 1907bf215546Sopenharmony_ci LLVMBuilderRef builder; 1908bf215546Sopenharmony_ci char func_name[64]; 1909bf215546Sopenharmony_ci struct lp_type vs_type; 1910bf215546Sopenharmony_ci LLVMValueRef count, fetch_elts, start_or_maxelt; 1911bf215546Sopenharmony_ci LLVMValueRef vertex_id_offset; 1912bf215546Sopenharmony_ci LLVMValueRef stride, step, io_itr; 1913bf215546Sopenharmony_ci LLVMValueRef ind_vec, start_vec, have_elts, fetch_max, tmp; 1914bf215546Sopenharmony_ci LLVMValueRef io_ptr, vbuffers_ptr, vb_ptr; 1915bf215546Sopenharmony_ci LLVMValueRef vb_stride[PIPE_MAX_ATTRIBS]; 1916bf215546Sopenharmony_ci LLVMValueRef map_ptr[PIPE_MAX_ATTRIBS]; 1917bf215546Sopenharmony_ci LLVMValueRef buffer_size_adj[PIPE_MAX_ATTRIBS]; 1918bf215546Sopenharmony_ci LLVMValueRef instance_index[PIPE_MAX_ATTRIBS]; 1919bf215546Sopenharmony_ci LLVMValueRef fake_buf_ptr, fake_buf; 1920bf215546Sopenharmony_ci 1921bf215546Sopenharmony_ci struct draw_context *draw = llvm->draw; 1922bf215546Sopenharmony_ci const struct tgsi_shader_info *vs_info = &draw->vs.vertex_shader->info; 1923bf215546Sopenharmony_ci unsigned i, j; 1924bf215546Sopenharmony_ci struct lp_build_context bld, blduivec; 1925bf215546Sopenharmony_ci struct lp_build_loop_state lp_loop; 1926bf215546Sopenharmony_ci struct lp_build_if_state if_ctx; 1927bf215546Sopenharmony_ci const int vector_length = lp_native_vector_width / 32; 1928bf215546Sopenharmony_ci LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS]; 1929bf215546Sopenharmony_ci struct lp_build_sampler_soa *sampler = 0; 1930bf215546Sopenharmony_ci struct lp_build_image_soa *image = NULL; 1931bf215546Sopenharmony_ci LLVMValueRef ret, clipmask_bool_ptr; 1932bf215546Sopenharmony_ci struct draw_llvm_variant_key *key = &variant->key; 1933bf215546Sopenharmony_ci /* If geometry shader is present we need to skip both the viewport 1934bf215546Sopenharmony_ci * transformation and clipping otherwise the inputs to the geometry 1935bf215546Sopenharmony_ci * shader will be incorrect. 1936bf215546Sopenharmony_ci * The code can't handle vp transform when vs writes vp index neither 1937bf215546Sopenharmony_ci * (though this would be fixable here, but couldn't just broadcast 1938bf215546Sopenharmony_ci * the values). 1939bf215546Sopenharmony_ci */ 1940bf215546Sopenharmony_ci const boolean bypass_viewport = key->has_gs_or_tes || key->bypass_viewport || 1941bf215546Sopenharmony_ci vs_info->writes_viewport_index; 1942bf215546Sopenharmony_ci const boolean enable_cliptest = !key->has_gs_or_tes && (key->clip_xy || 1943bf215546Sopenharmony_ci key->clip_z || 1944bf215546Sopenharmony_ci key->clip_user || 1945bf215546Sopenharmony_ci key->need_edgeflags); 1946bf215546Sopenharmony_ci LLVMValueRef variant_func; 1947bf215546Sopenharmony_ci const unsigned pos = draw->vs.position_output; 1948bf215546Sopenharmony_ci const unsigned cv = draw->vs.clipvertex_output; 1949bf215546Sopenharmony_ci boolean have_clipdist = FALSE; 1950bf215546Sopenharmony_ci struct lp_bld_tgsi_system_values system_values; 1951bf215546Sopenharmony_ci 1952bf215546Sopenharmony_ci memset(&system_values, 0, sizeof(system_values)); 1953bf215546Sopenharmony_ci memset(&outputs, 0, sizeof(outputs)); 1954bf215546Sopenharmony_ci snprintf(func_name, sizeof(func_name), "draw_llvm_vs_variant"); 1955bf215546Sopenharmony_ci 1956bf215546Sopenharmony_ci i = 0; 1957bf215546Sopenharmony_ci arg_types[i++] = get_context_ptr_type(variant); /* context */ 1958bf215546Sopenharmony_ci arg_types[i++] = get_vertex_header_ptr_type(variant); /* vertex_header */ 1959bf215546Sopenharmony_ci arg_types[i++] = get_buffer_ptr_type(variant); /* vbuffers */ 1960bf215546Sopenharmony_ci arg_types[i++] = int32_type; /* count */ 1961bf215546Sopenharmony_ci arg_types[i++] = int32_type; /* start/fetch_elt_max */ 1962bf215546Sopenharmony_ci arg_types[i++] = int32_type; /* stride */ 1963bf215546Sopenharmony_ci arg_types[i++] = get_vb_ptr_type(variant); /* pipe_vertex_buffer's */ 1964bf215546Sopenharmony_ci arg_types[i++] = int32_type; /* instance_id */ 1965bf215546Sopenharmony_ci arg_types[i++] = int32_type; /* vertex_id_offset */ 1966bf215546Sopenharmony_ci arg_types[i++] = int32_type; /* start_instance */ 1967bf215546Sopenharmony_ci arg_types[i++] = LLVMPointerType(int32_type, 0); /* fetch_elts */ 1968bf215546Sopenharmony_ci arg_types[i++] = int32_type; /* draw_id */ 1969bf215546Sopenharmony_ci arg_types[i++] = int32_type; /* view_id */ 1970bf215546Sopenharmony_ci 1971bf215546Sopenharmony_ci func_type = LLVMFunctionType(LLVMInt8TypeInContext(context), 1972bf215546Sopenharmony_ci arg_types, num_arg_types, 0); 1973bf215546Sopenharmony_ci 1974bf215546Sopenharmony_ci variant_func = LLVMAddFunction(gallivm->module, func_name, func_type); 1975bf215546Sopenharmony_ci variant->function = variant_func; 1976bf215546Sopenharmony_ci 1977bf215546Sopenharmony_ci LLVMSetFunctionCallConv(variant_func, LLVMCCallConv); 1978bf215546Sopenharmony_ci for (i = 0; i < num_arg_types; ++i) 1979bf215546Sopenharmony_ci if (LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind) 1980bf215546Sopenharmony_ci lp_add_function_attr(variant_func, i + 1, LP_FUNC_ATTR_NOALIAS); 1981bf215546Sopenharmony_ci 1982bf215546Sopenharmony_ci if (gallivm->cache && gallivm->cache->data_size) 1983bf215546Sopenharmony_ci return; 1984bf215546Sopenharmony_ci context_ptr = LLVMGetParam(variant_func, 0); 1985bf215546Sopenharmony_ci io_ptr = LLVMGetParam(variant_func, 1); 1986bf215546Sopenharmony_ci vbuffers_ptr = LLVMGetParam(variant_func, 2); 1987bf215546Sopenharmony_ci count = LLVMGetParam(variant_func, 3); 1988bf215546Sopenharmony_ci /* 1989bf215546Sopenharmony_ci * XXX: the maxelt part is unused. Not really useful, since we cannot 1990bf215546Sopenharmony_ci * get index buffer overflows due to vsplit (which provides its own 1991bf215546Sopenharmony_ci * elts buffer, with a different size than what's passed in here). 1992bf215546Sopenharmony_ci */ 1993bf215546Sopenharmony_ci start_or_maxelt = LLVMGetParam(variant_func, 4); 1994bf215546Sopenharmony_ci /* 1995bf215546Sopenharmony_ci * XXX: stride is actually unused. The stride we use is strictly calculated 1996bf215546Sopenharmony_ci * from the number of outputs (including the draw_extra outputs). 1997bf215546Sopenharmony_ci * Should probably fix some day (we need a new vs just because of extra 1998bf215546Sopenharmony_ci * outputs which the generated vs won't touch). 1999bf215546Sopenharmony_ci */ 2000bf215546Sopenharmony_ci stride = LLVMGetParam(variant_func, 5); 2001bf215546Sopenharmony_ci vb_ptr = LLVMGetParam(variant_func, 6); 2002bf215546Sopenharmony_ci system_values.instance_id = LLVMGetParam(variant_func, 7); 2003bf215546Sopenharmony_ci vertex_id_offset = LLVMGetParam(variant_func, 8); 2004bf215546Sopenharmony_ci system_values.base_instance = LLVMGetParam(variant_func, 9); 2005bf215546Sopenharmony_ci fetch_elts = LLVMGetParam(variant_func, 10); 2006bf215546Sopenharmony_ci system_values.draw_id = LLVMGetParam(variant_func, 11); 2007bf215546Sopenharmony_ci system_values.view_index = LLVMGetParam(variant_func, 12); 2008bf215546Sopenharmony_ci 2009bf215546Sopenharmony_ci lp_build_name(context_ptr, "context"); 2010bf215546Sopenharmony_ci lp_build_name(io_ptr, "io"); 2011bf215546Sopenharmony_ci lp_build_name(vbuffers_ptr, "vbuffers"); 2012bf215546Sopenharmony_ci lp_build_name(count, "count"); 2013bf215546Sopenharmony_ci lp_build_name(start_or_maxelt, "start_or_maxelt"); 2014bf215546Sopenharmony_ci lp_build_name(stride, "stride"); 2015bf215546Sopenharmony_ci lp_build_name(vb_ptr, "vb"); 2016bf215546Sopenharmony_ci lp_build_name(system_values.instance_id, "instance_id"); 2017bf215546Sopenharmony_ci lp_build_name(vertex_id_offset, "vertex_id_offset"); 2018bf215546Sopenharmony_ci lp_build_name(system_values.base_instance, "start_instance"); 2019bf215546Sopenharmony_ci lp_build_name(fetch_elts, "fetch_elts"); 2020bf215546Sopenharmony_ci lp_build_name(system_values.draw_id, "draw_id"); 2021bf215546Sopenharmony_ci 2022bf215546Sopenharmony_ci /* 2023bf215546Sopenharmony_ci * Function body 2024bf215546Sopenharmony_ci */ 2025bf215546Sopenharmony_ci 2026bf215546Sopenharmony_ci block = LLVMAppendBasicBlockInContext(gallivm->context, variant_func, "entry"); 2027bf215546Sopenharmony_ci builder = gallivm->builder; 2028bf215546Sopenharmony_ci LLVMPositionBuilderAtEnd(builder, block); 2029bf215546Sopenharmony_ci 2030bf215546Sopenharmony_ci memset(&vs_type, 0, sizeof vs_type); 2031bf215546Sopenharmony_ci vs_type.floating = TRUE; /* floating point values */ 2032bf215546Sopenharmony_ci vs_type.sign = TRUE; /* values are signed */ 2033bf215546Sopenharmony_ci vs_type.norm = FALSE; /* values are not limited to [0,1] or [-1,1] */ 2034bf215546Sopenharmony_ci vs_type.width = 32; /* 32-bit float */ 2035bf215546Sopenharmony_ci vs_type.length = vector_length; 2036bf215546Sopenharmony_ci 2037bf215546Sopenharmony_ci lp_build_context_init(&bld, gallivm, lp_type_uint(32)); 2038bf215546Sopenharmony_ci lp_build_context_init(&blduivec, gallivm, lp_uint_type(vs_type)); 2039bf215546Sopenharmony_ci 2040bf215546Sopenharmony_ci /* hold temporary "bool" clipmask */ 2041bf215546Sopenharmony_ci clipmask_bool_ptr = lp_build_alloca(gallivm, blduivec.vec_type, ""); 2042bf215546Sopenharmony_ci 2043bf215546Sopenharmony_ci fake_buf = lp_build_alloca_undef(gallivm, 2044bf215546Sopenharmony_ci LLVMVectorType(LLVMInt64TypeInContext(context), 4), ""); 2045bf215546Sopenharmony_ci fake_buf = LLVMBuildBitCast(builder, fake_buf, 2046bf215546Sopenharmony_ci LLVMPointerType(LLVMInt8TypeInContext(context), 0), ""); 2047bf215546Sopenharmony_ci fake_buf_ptr = LLVMBuildGEP2(builder, LLVMInt8TypeInContext(context), fake_buf, &bld.zero, 1, ""); 2048bf215546Sopenharmony_ci 2049bf215546Sopenharmony_ci /* code generated texture sampling */ 2050bf215546Sopenharmony_ci sampler = draw_llvm_sampler_soa_create(draw_llvm_variant_key_samplers(key), 2051bf215546Sopenharmony_ci MAX2(key->nr_samplers, 2052bf215546Sopenharmony_ci key->nr_sampler_views)); 2053bf215546Sopenharmony_ci image = draw_llvm_image_soa_create(draw_llvm_variant_key_images(key), 2054bf215546Sopenharmony_ci key->nr_images); 2055bf215546Sopenharmony_ci 2056bf215546Sopenharmony_ci step = lp_build_const_int32(gallivm, vector_length); 2057bf215546Sopenharmony_ci 2058bf215546Sopenharmony_ci ind_vec = blduivec.undef; 2059bf215546Sopenharmony_ci for (i = 0; i < vs_type.length; i++) { 2060bf215546Sopenharmony_ci LLVMValueRef index = lp_build_const_int32(gallivm, i); 2061bf215546Sopenharmony_ci ind_vec = LLVMBuildInsertElement(builder, ind_vec, index, index, ""); 2062bf215546Sopenharmony_ci } 2063bf215546Sopenharmony_ci 2064bf215546Sopenharmony_ci have_elts = LLVMBuildICmp(builder, LLVMIntNE, 2065bf215546Sopenharmony_ci LLVMConstPointerNull(arg_types[10]), fetch_elts, ""); 2066bf215546Sopenharmony_ci 2067bf215546Sopenharmony_ci fetch_max = LLVMBuildSub(builder, count, bld.one, "fetch_max"); 2068bf215546Sopenharmony_ci fetch_max = lp_build_broadcast_scalar(&blduivec, fetch_max); 2069bf215546Sopenharmony_ci /* 2070bf215546Sopenharmony_ci * Only needed for non-indexed path. 2071bf215546Sopenharmony_ci */ 2072bf215546Sopenharmony_ci start_vec = lp_build_broadcast_scalar(&blduivec, start_or_maxelt); 2073bf215546Sopenharmony_ci 2074bf215546Sopenharmony_ci /* 2075bf215546Sopenharmony_ci * Pre-calculate everything which is constant per shader invocation. 2076bf215546Sopenharmony_ci */ 2077bf215546Sopenharmony_ci for (j = 0; j < key->nr_vertex_elements; ++j) { 2078bf215546Sopenharmony_ci LLVMValueRef vb_buffer_offset, buffer_size, temp_ptr; 2079bf215546Sopenharmony_ci LLVMValueRef vb_info, vbuffer_ptr, buf_offset, ofbit; 2080bf215546Sopenharmony_ci struct pipe_vertex_element *velem = &key->vertex_element[j]; 2081bf215546Sopenharmony_ci LLVMValueRef vb_index = 2082bf215546Sopenharmony_ci lp_build_const_int32(gallivm, velem->vertex_buffer_index); 2083bf215546Sopenharmony_ci LLVMValueRef bsize = lp_build_const_int32(gallivm, 2084bf215546Sopenharmony_ci util_format_get_blocksize(velem->src_format)); 2085bf215546Sopenharmony_ci LLVMValueRef src_offset = lp_build_const_int32(gallivm, 2086bf215546Sopenharmony_ci velem->src_offset); 2087bf215546Sopenharmony_ci struct lp_build_if_state if_ctx; 2088bf215546Sopenharmony_ci 2089bf215546Sopenharmony_ci if (velem->src_format != PIPE_FORMAT_NONE) { 2090bf215546Sopenharmony_ci vbuffer_ptr = LLVMBuildGEP2(builder, variant->buffer_type, vbuffers_ptr, &vb_index, 1, ""); 2091bf215546Sopenharmony_ci vb_info = LLVMBuildGEP2(builder, variant->vb_type, vb_ptr, &vb_index, 1, ""); 2092bf215546Sopenharmony_ci vb_stride[j] = draw_jit_vbuffer_stride(gallivm, variant->vb_type, vb_info); 2093bf215546Sopenharmony_ci vb_stride[j] = LLVMBuildZExt(gallivm->builder, vb_stride[j], 2094bf215546Sopenharmony_ci LLVMInt32TypeInContext(context), ""); 2095bf215546Sopenharmony_ci vb_buffer_offset = draw_jit_vbuffer_offset(gallivm, variant->vb_type, vb_info); 2096bf215546Sopenharmony_ci map_ptr[j] = draw_jit_dvbuffer_map(gallivm, variant->buffer_type, vbuffer_ptr); 2097bf215546Sopenharmony_ci buffer_size = draw_jit_dvbuffer_size(gallivm, variant->buffer_type, vbuffer_ptr); 2098bf215546Sopenharmony_ci 2099bf215546Sopenharmony_ci ofbit = NULL; 2100bf215546Sopenharmony_ci /* 2101bf215546Sopenharmony_ci * We'll set buffer_size_adj to zero if we have of, so it will 2102bf215546Sopenharmony_ci * always overflow later automatically without having to keep ofbit. 2103bf215546Sopenharmony_ci * Overflows (with normal wraparound) doing the actual offset 2104bf215546Sopenharmony_ci * calculation should be ok, just not for the buffer size calc. 2105bf215546Sopenharmony_ci * It would also be possible to detect such overflows and return 2106bf215546Sopenharmony_ci * zeros if that happens, but this would be more complex. 2107bf215546Sopenharmony_ci */ 2108bf215546Sopenharmony_ci buf_offset = lp_build_add(&bld, vb_buffer_offset, src_offset); 2109bf215546Sopenharmony_ci tmp = lp_build_sub(&bld, bsize, bld.one); 2110bf215546Sopenharmony_ci buffer_size_adj[j] = lp_build_usub_overflow(gallivm, buffer_size, tmp, 2111bf215546Sopenharmony_ci &ofbit); 2112bf215546Sopenharmony_ci buffer_size_adj[j] = lp_build_usub_overflow(gallivm, buffer_size_adj[j], 2113bf215546Sopenharmony_ci buf_offset, &ofbit); 2114bf215546Sopenharmony_ci 2115bf215546Sopenharmony_ci /* 2116bf215546Sopenharmony_ci * We can't easily set fake vertex buffers outside the generated code. 2117bf215546Sopenharmony_ci * Hence, set fake vertex buffers here instead basically, so fetch 2118bf215546Sopenharmony_ci * code can always fetch using offset 0, eliminating all control flow 2119bf215546Sopenharmony_ci * inside the main loop. 2120bf215546Sopenharmony_ci * (Alternatively, could have control flow per vector skipping fetch 2121bf215546Sopenharmony_ci * if ofbit is true.) 2122bf215546Sopenharmony_ci */ 2123bf215546Sopenharmony_ci if (velem->instance_divisor) { 2124bf215546Sopenharmony_ci /* 2125bf215546Sopenharmony_ci * Index is equal to the start instance plus the number of current 2126bf215546Sopenharmony_ci * instance divided by the divisor. In this case we compute it as: 2127bf215546Sopenharmony_ci * index = start_instance + (instance_id / divisor). 2128bf215546Sopenharmony_ci * Note we could actually do the fetch here, outside the loop - 2129bf215546Sopenharmony_ci * it's all constant, hopefully llvm recognizes this. 2130bf215546Sopenharmony_ci */ 2131bf215546Sopenharmony_ci LLVMValueRef current_instance; 2132bf215546Sopenharmony_ci current_instance = LLVMBuildUDiv(builder, system_values.instance_id, 2133bf215546Sopenharmony_ci lp_build_const_int32(gallivm, 2134bf215546Sopenharmony_ci velem->instance_divisor), 2135bf215546Sopenharmony_ci "instance_divisor"); 2136bf215546Sopenharmony_ci instance_index[j] = lp_build_uadd_overflow(gallivm, system_values.base_instance, 2137bf215546Sopenharmony_ci current_instance, &ofbit); 2138bf215546Sopenharmony_ci } 2139bf215546Sopenharmony_ci 2140bf215546Sopenharmony_ci buffer_size_adj[j] = LLVMBuildSelect(builder, ofbit, bld.zero, 2141bf215546Sopenharmony_ci buffer_size_adj[j], ""); 2142bf215546Sopenharmony_ci 2143bf215546Sopenharmony_ci LLVMTypeRef byte_type = LLVMInt8TypeInContext(context); 2144bf215546Sopenharmony_ci LLVMTypeRef byte_ptr_type = LLVMPointerType(byte_type, 0); 2145bf215546Sopenharmony_ci temp_ptr = lp_build_alloca_undef(gallivm, byte_ptr_type, ""); 2146bf215546Sopenharmony_ci 2147bf215546Sopenharmony_ci lp_build_if(&if_ctx, gallivm, ofbit); 2148bf215546Sopenharmony_ci { 2149bf215546Sopenharmony_ci LLVMBuildStore(builder, fake_buf_ptr, temp_ptr); 2150bf215546Sopenharmony_ci } 2151bf215546Sopenharmony_ci lp_build_else(&if_ctx); 2152bf215546Sopenharmony_ci { 2153bf215546Sopenharmony_ci map_ptr[j] = LLVMBuildGEP2(builder, byte_type, map_ptr[j], &buf_offset, 1, ""); 2154bf215546Sopenharmony_ci LLVMBuildStore(builder, map_ptr[j], temp_ptr); 2155bf215546Sopenharmony_ci } 2156bf215546Sopenharmony_ci lp_build_endif(&if_ctx); 2157bf215546Sopenharmony_ci map_ptr[j] = LLVMBuildLoad2(builder, byte_ptr_type, temp_ptr, "map_ptr"); 2158bf215546Sopenharmony_ci 2159bf215546Sopenharmony_ci if (0) { 2160bf215546Sopenharmony_ci lp_build_printf(gallivm, "velem %d, vbuf index = %u, vb_stride = %u\n", 2161bf215546Sopenharmony_ci lp_build_const_int32(gallivm, j), 2162bf215546Sopenharmony_ci vb_index, vb_stride[j]); 2163bf215546Sopenharmony_ci lp_build_printf(gallivm, 2164bf215546Sopenharmony_ci " vb_buffer_offset = %u, src_offset = %u, buf_offset = %u\n", 2165bf215546Sopenharmony_ci vb_buffer_offset, src_offset, buf_offset); 2166bf215546Sopenharmony_ci lp_build_printf(gallivm, " buffer size = %u, blocksize = %u\n", 2167bf215546Sopenharmony_ci buffer_size, bsize); 2168bf215546Sopenharmony_ci lp_build_printf(gallivm, " instance_id = %u\n", system_values.instance_id); 2169bf215546Sopenharmony_ci } 2170bf215546Sopenharmony_ci } 2171bf215546Sopenharmony_ci } 2172bf215546Sopenharmony_ci 2173bf215546Sopenharmony_ci lp_build_loop_begin(&lp_loop, gallivm, bld.zero); 2174bf215546Sopenharmony_ci { 2175bf215546Sopenharmony_ci LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS]; 2176bf215546Sopenharmony_ci LLVMValueRef io; 2177bf215546Sopenharmony_ci LLVMValueRef clipmask; /* holds the clipmask value */ 2178bf215546Sopenharmony_ci LLVMValueRef true_index_array, index_store; 2179bf215546Sopenharmony_ci const LLVMValueRef (*ptr_aos)[TGSI_NUM_CHANNELS]; 2180bf215546Sopenharmony_ci 2181bf215546Sopenharmony_ci io_itr = lp_loop.counter; 2182bf215546Sopenharmony_ci 2183bf215546Sopenharmony_ci io = LLVMBuildGEP2(builder, variant->vertex_header_type, io_ptr, &io_itr, 1, ""); 2184bf215546Sopenharmony_ci#if DEBUG_STORE 2185bf215546Sopenharmony_ci lp_build_printf(gallivm, " --- io %d = %p, loop counter %d\n", 2186bf215546Sopenharmony_ci io_itr, io, lp_loop.counter); 2187bf215546Sopenharmony_ci#endif 2188bf215546Sopenharmony_ci 2189bf215546Sopenharmony_ci true_index_array = lp_build_broadcast_scalar(&blduivec, lp_loop.counter); 2190bf215546Sopenharmony_ci true_index_array = LLVMBuildAdd(builder, true_index_array, ind_vec, ""); 2191bf215546Sopenharmony_ci 2192bf215546Sopenharmony_ci LLVMValueRef exec_mask = lp_build_cmp(&blduivec, PIPE_FUNC_LEQUAL, true_index_array, fetch_max); 2193bf215546Sopenharmony_ci /* 2194bf215546Sopenharmony_ci * Limit indices to fetch_max, otherwise might try to access indices 2195bf215546Sopenharmony_ci * beyond index buffer (or rather vsplit elt buffer) size. 2196bf215546Sopenharmony_ci * Could probably safely (?) skip this for non-indexed draws and 2197bf215546Sopenharmony_ci * simplify things minimally (by removing it could combine the ind_vec 2198bf215546Sopenharmony_ci * and start_vec adds). I think the only effect for non-indexed draws will 2199bf215546Sopenharmony_ci * be that for the invalid elements they will be all fetched from the 2200bf215546Sopenharmony_ci * same location as the last valid one, but noone should really care. 2201bf215546Sopenharmony_ci */ 2202bf215546Sopenharmony_ci true_index_array = lp_build_min(&blduivec, true_index_array, fetch_max); 2203bf215546Sopenharmony_ci 2204bf215546Sopenharmony_ci index_store = lp_build_alloca_undef(gallivm, blduivec.vec_type, "index_store"); 2205bf215546Sopenharmony_ci 2206bf215546Sopenharmony_ci lp_build_if(&if_ctx, gallivm, have_elts); 2207bf215546Sopenharmony_ci { 2208bf215546Sopenharmony_ci /* 2209bf215546Sopenharmony_ci * Note: you'd expect some comparison/clamp against fetch_elt_max 2210bf215546Sopenharmony_ci * here. 2211bf215546Sopenharmony_ci * There used to be one here but it was incorrect: overflow was 2212bf215546Sopenharmony_ci * detected if index > fetch_elt_max - but the correct condition 2213bf215546Sopenharmony_ci * would be index >= fetch_elt_max (since this is just size of elts 2214bf215546Sopenharmony_ci * buffer / element size). 2215bf215546Sopenharmony_ci * Using the correct condition however will cause failures - due to 2216bf215546Sopenharmony_ci * vsplit/vcache code which rebases indices. So, as an example, if 2217bf215546Sopenharmony_ci * fetch_elt_max is just 1 and fetch_count 2, vsplit cache will 2218bf215546Sopenharmony_ci * replace all invalid indices with 0 - which in case of elt_bias 2219bf215546Sopenharmony_ci * not being zero will get a different fetch index than the valid 2220bf215546Sopenharmony_ci * index 0. So, just rely on vsplit code preventing out-of-bounds 2221bf215546Sopenharmony_ci * fetches. This is also why it's safe to do elts fetch even if there 2222bf215546Sopenharmony_ci * was no index buffer bound - the real buffer is never seen here, at 2223bf215546Sopenharmony_ci * least not if there are index buffer overflows... 2224bf215546Sopenharmony_ci */ 2225bf215546Sopenharmony_ci 2226bf215546Sopenharmony_ci /* 2227bf215546Sopenharmony_ci * XXX should not have to do this, as scale can be handled 2228bf215546Sopenharmony_ci * natively by loads (hits asserts though). 2229bf215546Sopenharmony_ci */ 2230bf215546Sopenharmony_ci tmp = lp_build_shl_imm(&blduivec, true_index_array, 2); 2231bf215546Sopenharmony_ci fetch_elts = LLVMBuildBitCast(builder, fetch_elts, 2232bf215546Sopenharmony_ci LLVMPointerType(LLVMInt8TypeInContext(context), 2233bf215546Sopenharmony_ci 0), ""); 2234bf215546Sopenharmony_ci tmp = lp_build_gather(gallivm, vs_type.length, 2235bf215546Sopenharmony_ci 32, bld.type, TRUE, 2236bf215546Sopenharmony_ci fetch_elts, tmp, FALSE); 2237bf215546Sopenharmony_ci LLVMBuildStore(builder, tmp, index_store); 2238bf215546Sopenharmony_ci } 2239bf215546Sopenharmony_ci lp_build_else(&if_ctx); 2240bf215546Sopenharmony_ci { 2241bf215546Sopenharmony_ci tmp = LLVMBuildAdd(builder, true_index_array, start_vec, ""); 2242bf215546Sopenharmony_ci LLVMBuildStore(builder, tmp, index_store); 2243bf215546Sopenharmony_ci } 2244bf215546Sopenharmony_ci lp_build_endif(&if_ctx); 2245bf215546Sopenharmony_ci 2246bf215546Sopenharmony_ci true_index_array = LLVMBuildLoad2(builder, blduivec.vec_type, index_store, ""); 2247bf215546Sopenharmony_ci 2248bf215546Sopenharmony_ci for (j = 0; j < key->nr_vertex_elements; ++j) { 2249bf215546Sopenharmony_ci struct pipe_vertex_element *velem = &key->vertex_element[j]; 2250bf215546Sopenharmony_ci const struct util_format_description *format_desc = 2251bf215546Sopenharmony_ci util_format_description(velem->src_format); 2252bf215546Sopenharmony_ci 2253bf215546Sopenharmony_ci if (format_desc->format == PIPE_FORMAT_NONE) { 2254bf215546Sopenharmony_ci for (i = 0; i < TGSI_NUM_CHANNELS; i++) { 2255bf215546Sopenharmony_ci inputs[j][i] = lp_build_zero(gallivm, vs_type); 2256bf215546Sopenharmony_ci } 2257bf215546Sopenharmony_ci } 2258bf215546Sopenharmony_ci else if (velem->instance_divisor) { 2259bf215546Sopenharmony_ci fetch_instanced(gallivm, format_desc, vs_type, 2260bf215546Sopenharmony_ci vb_stride[j], map_ptr[j], 2261bf215546Sopenharmony_ci buffer_size_adj[j], 2262bf215546Sopenharmony_ci inputs[j], instance_index[j]); 2263bf215546Sopenharmony_ci } 2264bf215546Sopenharmony_ci else { 2265bf215546Sopenharmony_ci fetch_vector(gallivm, format_desc, vs_type, 2266bf215546Sopenharmony_ci vb_stride[j], map_ptr[j], 2267bf215546Sopenharmony_ci buffer_size_adj[j], 2268bf215546Sopenharmony_ci inputs[j], true_index_array); 2269bf215546Sopenharmony_ci } 2270bf215546Sopenharmony_ci } 2271bf215546Sopenharmony_ci 2272bf215546Sopenharmony_ci struct lp_build_mask_context mask; 2273bf215546Sopenharmony_ci 2274bf215546Sopenharmony_ci lp_build_mask_begin(&mask, gallivm, vs_type, exec_mask); 2275bf215546Sopenharmony_ci /* In the paths with elts vertex id has to be unaffected by the 2276bf215546Sopenharmony_ci * index bias and because indices inside our elements array have 2277bf215546Sopenharmony_ci * already had index bias applied we need to subtract it here to 2278bf215546Sopenharmony_ci * get back to the original index. 2279bf215546Sopenharmony_ci * in the linear paths vertex id has to be unaffected by the 2280bf215546Sopenharmony_ci * original start index and because we abuse the 'start' variable 2281bf215546Sopenharmony_ci * to either represent the actual start index or the index at which 2282bf215546Sopenharmony_ci * the primitive was split (we split rendering into chunks of at 2283bf215546Sopenharmony_ci * most 4095-vertices) we need to back out the original start 2284bf215546Sopenharmony_ci * index out of our vertex id here. 2285bf215546Sopenharmony_ci * for ARB_shader_draw_parameters, base_vertex should be 0 for non-indexed draws. 2286bf215546Sopenharmony_ci */ 2287bf215546Sopenharmony_ci LLVMValueRef base_vertex = lp_build_select(&bld, have_elts, vertex_id_offset, lp_build_const_int32(gallivm, 0)); 2288bf215546Sopenharmony_ci system_values.basevertex = lp_build_broadcast_scalar(&blduivec, base_vertex); 2289bf215546Sopenharmony_ci /* first vertex is for Vulkan base vertex support */ 2290bf215546Sopenharmony_ci LLVMValueRef first_vertex = lp_build_select(&bld, have_elts, vertex_id_offset, start_or_maxelt); 2291bf215546Sopenharmony_ci system_values.firstvertex = lp_build_broadcast_scalar(&blduivec, first_vertex); 2292bf215546Sopenharmony_ci system_values.vertex_id = true_index_array; 2293bf215546Sopenharmony_ci system_values.vertex_id_nobase = LLVMBuildSub(builder, true_index_array, 2294bf215546Sopenharmony_ci lp_build_broadcast_scalar(&blduivec, vertex_id_offset), ""); 2295bf215546Sopenharmony_ci 2296bf215546Sopenharmony_ci ptr_aos = (const LLVMValueRef (*)[TGSI_NUM_CHANNELS]) inputs; 2297bf215546Sopenharmony_ci generate_vs(variant, 2298bf215546Sopenharmony_ci builder, 2299bf215546Sopenharmony_ci vs_type, 2300bf215546Sopenharmony_ci outputs, 2301bf215546Sopenharmony_ci ptr_aos, 2302bf215546Sopenharmony_ci &system_values, 2303bf215546Sopenharmony_ci context_ptr, 2304bf215546Sopenharmony_ci sampler, 2305bf215546Sopenharmony_ci image, 2306bf215546Sopenharmony_ci key->clamp_vertex_color, 2307bf215546Sopenharmony_ci &mask); 2308bf215546Sopenharmony_ci 2309bf215546Sopenharmony_ci lp_build_mask_end(&mask); 2310bf215546Sopenharmony_ci if (pos != -1 && cv != -1) { 2311bf215546Sopenharmony_ci /* store original positions in clip before further manipulation */ 2312bf215546Sopenharmony_ci store_clip(gallivm, vs_type, variant->vertex_header_type, io, outputs, pos); 2313bf215546Sopenharmony_ci 2314bf215546Sopenharmony_ci /* do cliptest */ 2315bf215546Sopenharmony_ci if (enable_cliptest) { 2316bf215546Sopenharmony_ci LLVMValueRef temp = LLVMBuildLoad2(builder, blduivec.vec_type, clipmask_bool_ptr, ""); 2317bf215546Sopenharmony_ci /* allocate clipmask, assign it integer type */ 2318bf215546Sopenharmony_ci clipmask = generate_clipmask(llvm, 2319bf215546Sopenharmony_ci gallivm, 2320bf215546Sopenharmony_ci vs_type, 2321bf215546Sopenharmony_ci outputs, 2322bf215546Sopenharmony_ci key, 2323bf215546Sopenharmony_ci variant->context_type, 2324bf215546Sopenharmony_ci context_ptr, &have_clipdist); 2325bf215546Sopenharmony_ci temp = LLVMBuildOr(builder, clipmask, temp, ""); 2326bf215546Sopenharmony_ci /* store temporary clipping boolean value */ 2327bf215546Sopenharmony_ci LLVMBuildStore(builder, temp, clipmask_bool_ptr); 2328bf215546Sopenharmony_ci } 2329bf215546Sopenharmony_ci else { 2330bf215546Sopenharmony_ci clipmask = blduivec.zero; 2331bf215546Sopenharmony_ci } 2332bf215546Sopenharmony_ci 2333bf215546Sopenharmony_ci /* do viewport mapping */ 2334bf215546Sopenharmony_ci if (!bypass_viewport) { 2335bf215546Sopenharmony_ci generate_viewport(variant, builder, vs_type, outputs, context_ptr); 2336bf215546Sopenharmony_ci } 2337bf215546Sopenharmony_ci } 2338bf215546Sopenharmony_ci else { 2339bf215546Sopenharmony_ci clipmask = blduivec.zero; 2340bf215546Sopenharmony_ci } 2341bf215546Sopenharmony_ci 2342bf215546Sopenharmony_ci /* store clipmask in vertex header, 2343bf215546Sopenharmony_ci * original positions in clip 2344bf215546Sopenharmony_ci * and transformed positions in data 2345bf215546Sopenharmony_ci */ 2346bf215546Sopenharmony_ci convert_to_aos(gallivm, variant->vertex_header_type, io, NULL, outputs, clipmask, 2347bf215546Sopenharmony_ci vs_info->num_outputs, vs_type, 2348bf215546Sopenharmony_ci enable_cliptest && key->need_edgeflags); 2349bf215546Sopenharmony_ci } 2350bf215546Sopenharmony_ci lp_build_loop_end_cond(&lp_loop, count, step, LLVMIntUGE); 2351bf215546Sopenharmony_ci 2352bf215546Sopenharmony_ci sampler->destroy(sampler); 2353bf215546Sopenharmony_ci image->destroy(image); 2354bf215546Sopenharmony_ci 2355bf215546Sopenharmony_ci /* return clipping boolean value for function */ 2356bf215546Sopenharmony_ci ret = clipmask_booli8(gallivm, vs_type, clipmask_bool_ptr, 2357bf215546Sopenharmony_ci enable_cliptest && key->need_edgeflags); 2358bf215546Sopenharmony_ci 2359bf215546Sopenharmony_ci LLVMBuildRet(builder, ret); 2360bf215546Sopenharmony_ci 2361bf215546Sopenharmony_ci gallivm_verify_function(gallivm, variant_func); 2362bf215546Sopenharmony_ci} 2363bf215546Sopenharmony_ci 2364bf215546Sopenharmony_ci 2365bf215546Sopenharmony_cistruct draw_llvm_variant_key * 2366bf215546Sopenharmony_cidraw_llvm_make_variant_key(struct draw_llvm *llvm, char *store) 2367bf215546Sopenharmony_ci{ 2368bf215546Sopenharmony_ci unsigned i; 2369bf215546Sopenharmony_ci struct draw_llvm_variant_key *key; 2370bf215546Sopenharmony_ci struct draw_sampler_static_state *draw_sampler; 2371bf215546Sopenharmony_ci struct draw_image_static_state *draw_image; 2372bf215546Sopenharmony_ci 2373bf215546Sopenharmony_ci key = (struct draw_llvm_variant_key *)store; 2374bf215546Sopenharmony_ci 2375bf215546Sopenharmony_ci memset(key, 0, offsetof(struct draw_llvm_variant_key, vertex_element[0])); 2376bf215546Sopenharmony_ci 2377bf215546Sopenharmony_ci 2378bf215546Sopenharmony_ci /* will have to rig this up properly later */ 2379bf215546Sopenharmony_ci key->clip_xy = llvm->draw->clip_xy; 2380bf215546Sopenharmony_ci key->clip_z = llvm->draw->clip_z; 2381bf215546Sopenharmony_ci key->clip_user = llvm->draw->clip_user; 2382bf215546Sopenharmony_ci key->bypass_viewport = llvm->draw->bypass_viewport; 2383bf215546Sopenharmony_ci key->clip_halfz = llvm->draw->rasterizer->clip_halfz; 2384bf215546Sopenharmony_ci /* XXX assumes edgeflag output not at 0 */ 2385bf215546Sopenharmony_ci key->need_edgeflags = (llvm->draw->vs.edgeflag_output ? TRUE : FALSE); 2386bf215546Sopenharmony_ci key->ucp_enable = llvm->draw->rasterizer->clip_plane_enable; 2387bf215546Sopenharmony_ci key->has_gs_or_tes = llvm->draw->gs.geometry_shader != NULL || llvm->draw->tes.tess_eval_shader != NULL; 2388bf215546Sopenharmony_ci key->num_outputs = draw_total_vs_outputs(llvm->draw); 2389bf215546Sopenharmony_ci 2390bf215546Sopenharmony_ci key->clamp_vertex_color = !key->has_gs_or_tes && 2391bf215546Sopenharmony_ci llvm->draw->rasterizer->clamp_vertex_color; 2392bf215546Sopenharmony_ci 2393bf215546Sopenharmony_ci /* All variants of this shader will have the same value for 2394bf215546Sopenharmony_ci * nr_samplers. Not yet trying to compact away holes in the 2395bf215546Sopenharmony_ci * sampler array. 2396bf215546Sopenharmony_ci */ 2397bf215546Sopenharmony_ci key->nr_samplers = llvm->draw->vs.vertex_shader->info.file_max[TGSI_FILE_SAMPLER] + 1; 2398bf215546Sopenharmony_ci if (llvm->draw->vs.vertex_shader->info.file_max[TGSI_FILE_SAMPLER_VIEW] != -1) { 2399bf215546Sopenharmony_ci key->nr_sampler_views = 2400bf215546Sopenharmony_ci llvm->draw->vs.vertex_shader->info.file_max[TGSI_FILE_SAMPLER_VIEW] + 1; 2401bf215546Sopenharmony_ci } 2402bf215546Sopenharmony_ci else { 2403bf215546Sopenharmony_ci key->nr_sampler_views = key->nr_samplers; 2404bf215546Sopenharmony_ci } 2405bf215546Sopenharmony_ci 2406bf215546Sopenharmony_ci key->nr_images = llvm->draw->vs.vertex_shader->info.file_max[TGSI_FILE_IMAGE] + 1; 2407bf215546Sopenharmony_ci 2408bf215546Sopenharmony_ci /* Presumably all variants of the shader should have the same 2409bf215546Sopenharmony_ci * number of vertex elements - ie the number of shader inputs. 2410bf215546Sopenharmony_ci * NOTE: we NEED to store the needed number of needed inputs 2411bf215546Sopenharmony_ci * here, not the number of provided elements to match keysize 2412bf215546Sopenharmony_ci * (and the offset of sampler state in the key). 2413bf215546Sopenharmony_ci * If we have excess number of vertex elements, this is valid, 2414bf215546Sopenharmony_ci * but the excess ones don't matter. 2415bf215546Sopenharmony_ci * If we don't have enough vertex elements (which looks not really 2416bf215546Sopenharmony_ci * valid but we'll handle it gracefully) fill out missing ones with 2417bf215546Sopenharmony_ci * zero (we'll recognize these later by PIPE_FORMAT_NONE). 2418bf215546Sopenharmony_ci */ 2419bf215546Sopenharmony_ci key->nr_vertex_elements = 2420bf215546Sopenharmony_ci llvm->draw->vs.vertex_shader->info.file_max[TGSI_FILE_INPUT] + 1; 2421bf215546Sopenharmony_ci 2422bf215546Sopenharmony_ci if (llvm->draw->pt.nr_vertex_elements < key->nr_vertex_elements) { 2423bf215546Sopenharmony_ci debug_printf("draw: vs with %d inputs but only have %d vertex elements\n", 2424bf215546Sopenharmony_ci key->nr_vertex_elements, llvm->draw->pt.nr_vertex_elements); 2425bf215546Sopenharmony_ci memset(key->vertex_element, 0, 2426bf215546Sopenharmony_ci sizeof(struct pipe_vertex_element) * key->nr_vertex_elements); 2427bf215546Sopenharmony_ci } 2428bf215546Sopenharmony_ci memcpy(key->vertex_element, 2429bf215546Sopenharmony_ci llvm->draw->pt.vertex_element, 2430bf215546Sopenharmony_ci sizeof(struct pipe_vertex_element) * 2431bf215546Sopenharmony_ci MIN2(key->nr_vertex_elements, llvm->draw->pt.nr_vertex_elements)); 2432bf215546Sopenharmony_ci 2433bf215546Sopenharmony_ci draw_sampler = draw_llvm_variant_key_samplers(key); 2434bf215546Sopenharmony_ci memset(draw_sampler, 0, 2435bf215546Sopenharmony_ci MAX2(key->nr_samplers, key->nr_sampler_views) * sizeof *draw_sampler); 2436bf215546Sopenharmony_ci 2437bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_samplers; i++) { 2438bf215546Sopenharmony_ci lp_sampler_static_sampler_state(&draw_sampler[i].sampler_state, 2439bf215546Sopenharmony_ci llvm->draw->samplers[PIPE_SHADER_VERTEX][i]); 2440bf215546Sopenharmony_ci } 2441bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_sampler_views; i++) { 2442bf215546Sopenharmony_ci lp_sampler_static_texture_state(&draw_sampler[i].texture_state, 2443bf215546Sopenharmony_ci llvm->draw->sampler_views[PIPE_SHADER_VERTEX][i]); 2444bf215546Sopenharmony_ci } 2445bf215546Sopenharmony_ci 2446bf215546Sopenharmony_ci draw_image = draw_llvm_variant_key_images(key); 2447bf215546Sopenharmony_ci memset(draw_image, 0, 2448bf215546Sopenharmony_ci key->nr_images * sizeof *draw_image); 2449bf215546Sopenharmony_ci for (i = 0; i < key->nr_images; i++) { 2450bf215546Sopenharmony_ci lp_sampler_static_texture_state_image(&draw_image[i].image_state, 2451bf215546Sopenharmony_ci llvm->draw->images[PIPE_SHADER_VERTEX][i]); 2452bf215546Sopenharmony_ci } 2453bf215546Sopenharmony_ci return key; 2454bf215546Sopenharmony_ci} 2455bf215546Sopenharmony_ci 2456bf215546Sopenharmony_ci 2457bf215546Sopenharmony_civoid 2458bf215546Sopenharmony_cidraw_llvm_dump_variant_key(struct draw_llvm_variant_key *key) 2459bf215546Sopenharmony_ci{ 2460bf215546Sopenharmony_ci unsigned i; 2461bf215546Sopenharmony_ci struct draw_sampler_static_state *sampler = draw_llvm_variant_key_samplers(key); 2462bf215546Sopenharmony_ci struct draw_image_static_state *image = draw_llvm_variant_key_images(key); 2463bf215546Sopenharmony_ci debug_printf("clamp_vertex_color = %u\n", key->clamp_vertex_color); 2464bf215546Sopenharmony_ci debug_printf("clip_xy = %u\n", key->clip_xy); 2465bf215546Sopenharmony_ci debug_printf("clip_z = %u\n", key->clip_z); 2466bf215546Sopenharmony_ci debug_printf("clip_user = %u\n", key->clip_user); 2467bf215546Sopenharmony_ci debug_printf("bypass_viewport = %u\n", key->bypass_viewport); 2468bf215546Sopenharmony_ci debug_printf("clip_halfz = %u\n", key->clip_halfz); 2469bf215546Sopenharmony_ci debug_printf("need_edgeflags = %u\n", key->need_edgeflags); 2470bf215546Sopenharmony_ci debug_printf("has_gs_or_tes = %u\n", key->has_gs_or_tes); 2471bf215546Sopenharmony_ci debug_printf("ucp_enable = %u\n", key->ucp_enable); 2472bf215546Sopenharmony_ci 2473bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_vertex_elements; i++) { 2474bf215546Sopenharmony_ci debug_printf("vertex_element[%i].src_offset = %u\n", i, key->vertex_element[i].src_offset); 2475bf215546Sopenharmony_ci debug_printf("vertex_element[%i].instance_divisor = %u\n", i, key->vertex_element[i].instance_divisor); 2476bf215546Sopenharmony_ci debug_printf("vertex_element[%i].vertex_buffer_index = %u\n", i, key->vertex_element[i].vertex_buffer_index); 2477bf215546Sopenharmony_ci debug_printf("vertex_element[%i].src_format = %s\n", i, util_format_name(key->vertex_element[i].src_format)); 2478bf215546Sopenharmony_ci } 2479bf215546Sopenharmony_ci 2480bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_sampler_views; i++) { 2481bf215546Sopenharmony_ci debug_printf("sampler[%i].src_format = %s\n", i, util_format_name(sampler[i].texture_state.format)); 2482bf215546Sopenharmony_ci } 2483bf215546Sopenharmony_ci 2484bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_images; i++) 2485bf215546Sopenharmony_ci debug_printf("images[%i].format = %s\n", i, util_format_name(image[i].image_state.format)); 2486bf215546Sopenharmony_ci} 2487bf215546Sopenharmony_ci 2488bf215546Sopenharmony_ci 2489bf215546Sopenharmony_civoid 2490bf215546Sopenharmony_cidraw_llvm_set_mapped_texture(struct draw_context *draw, 2491bf215546Sopenharmony_ci enum pipe_shader_type shader_stage, 2492bf215546Sopenharmony_ci unsigned sview_idx, 2493bf215546Sopenharmony_ci uint32_t width, uint32_t height, uint32_t depth, 2494bf215546Sopenharmony_ci uint32_t first_level, uint32_t last_level, 2495bf215546Sopenharmony_ci uint32_t num_samples, 2496bf215546Sopenharmony_ci uint32_t sample_stride, 2497bf215546Sopenharmony_ci const void *base_ptr, 2498bf215546Sopenharmony_ci uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS], 2499bf215546Sopenharmony_ci uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS], 2500bf215546Sopenharmony_ci uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]) 2501bf215546Sopenharmony_ci{ 2502bf215546Sopenharmony_ci unsigned j; 2503bf215546Sopenharmony_ci struct draw_jit_texture *jit_tex; 2504bf215546Sopenharmony_ci 2505bf215546Sopenharmony_ci switch (shader_stage) { 2506bf215546Sopenharmony_ci case PIPE_SHADER_VERTEX: 2507bf215546Sopenharmony_ci assert(sview_idx < ARRAY_SIZE(draw->llvm->jit_context.textures)); 2508bf215546Sopenharmony_ci jit_tex = &draw->llvm->jit_context.textures[sview_idx]; 2509bf215546Sopenharmony_ci break; 2510bf215546Sopenharmony_ci case PIPE_SHADER_GEOMETRY: 2511bf215546Sopenharmony_ci assert(sview_idx < ARRAY_SIZE(draw->llvm->gs_jit_context.textures)); 2512bf215546Sopenharmony_ci jit_tex = &draw->llvm->gs_jit_context.textures[sview_idx]; 2513bf215546Sopenharmony_ci break; 2514bf215546Sopenharmony_ci case PIPE_SHADER_TESS_CTRL: 2515bf215546Sopenharmony_ci assert(sview_idx < ARRAY_SIZE(draw->llvm->tcs_jit_context.textures)); 2516bf215546Sopenharmony_ci jit_tex = &draw->llvm->tcs_jit_context.textures[sview_idx]; 2517bf215546Sopenharmony_ci break; 2518bf215546Sopenharmony_ci case PIPE_SHADER_TESS_EVAL: 2519bf215546Sopenharmony_ci assert(sview_idx < ARRAY_SIZE(draw->llvm->tes_jit_context.textures)); 2520bf215546Sopenharmony_ci jit_tex = &draw->llvm->tes_jit_context.textures[sview_idx]; 2521bf215546Sopenharmony_ci break; 2522bf215546Sopenharmony_ci default: 2523bf215546Sopenharmony_ci assert(0); 2524bf215546Sopenharmony_ci return; 2525bf215546Sopenharmony_ci } 2526bf215546Sopenharmony_ci 2527bf215546Sopenharmony_ci jit_tex->width = width; 2528bf215546Sopenharmony_ci jit_tex->height = height; 2529bf215546Sopenharmony_ci jit_tex->depth = depth; 2530bf215546Sopenharmony_ci jit_tex->first_level = first_level; 2531bf215546Sopenharmony_ci jit_tex->last_level = last_level; 2532bf215546Sopenharmony_ci jit_tex->base = base_ptr; 2533bf215546Sopenharmony_ci jit_tex->num_samples = num_samples; 2534bf215546Sopenharmony_ci jit_tex->sample_stride = sample_stride; 2535bf215546Sopenharmony_ci 2536bf215546Sopenharmony_ci for (j = first_level; j <= last_level; j++) { 2537bf215546Sopenharmony_ci jit_tex->mip_offsets[j] = mip_offsets[j]; 2538bf215546Sopenharmony_ci jit_tex->row_stride[j] = row_stride[j]; 2539bf215546Sopenharmony_ci jit_tex->img_stride[j] = img_stride[j]; 2540bf215546Sopenharmony_ci } 2541bf215546Sopenharmony_ci} 2542bf215546Sopenharmony_ci 2543bf215546Sopenharmony_civoid 2544bf215546Sopenharmony_cidraw_llvm_set_mapped_image(struct draw_context *draw, 2545bf215546Sopenharmony_ci enum pipe_shader_type shader_stage, 2546bf215546Sopenharmony_ci unsigned idx, 2547bf215546Sopenharmony_ci uint32_t width, uint32_t height, uint32_t depth, 2548bf215546Sopenharmony_ci const void *base_ptr, 2549bf215546Sopenharmony_ci uint32_t row_stride, 2550bf215546Sopenharmony_ci uint32_t img_stride, 2551bf215546Sopenharmony_ci uint32_t num_samples, 2552bf215546Sopenharmony_ci uint32_t sample_stride) 2553bf215546Sopenharmony_ci{ 2554bf215546Sopenharmony_ci struct draw_jit_image *jit_image; 2555bf215546Sopenharmony_ci 2556bf215546Sopenharmony_ci switch (shader_stage) { 2557bf215546Sopenharmony_ci case PIPE_SHADER_VERTEX: 2558bf215546Sopenharmony_ci assert(idx < ARRAY_SIZE(draw->llvm->jit_context.images)); 2559bf215546Sopenharmony_ci jit_image = &draw->llvm->jit_context.images[idx]; 2560bf215546Sopenharmony_ci break; 2561bf215546Sopenharmony_ci case PIPE_SHADER_GEOMETRY: 2562bf215546Sopenharmony_ci assert(idx < ARRAY_SIZE(draw->llvm->gs_jit_context.images)); 2563bf215546Sopenharmony_ci jit_image = &draw->llvm->gs_jit_context.images[idx]; 2564bf215546Sopenharmony_ci break; 2565bf215546Sopenharmony_ci case PIPE_SHADER_TESS_CTRL: 2566bf215546Sopenharmony_ci assert(idx < ARRAY_SIZE(draw->llvm->tcs_jit_context.images)); 2567bf215546Sopenharmony_ci jit_image = &draw->llvm->tcs_jit_context.images[idx]; 2568bf215546Sopenharmony_ci break; 2569bf215546Sopenharmony_ci case PIPE_SHADER_TESS_EVAL: 2570bf215546Sopenharmony_ci assert(idx < ARRAY_SIZE(draw->llvm->tes_jit_context.images)); 2571bf215546Sopenharmony_ci jit_image = &draw->llvm->tes_jit_context.images[idx]; 2572bf215546Sopenharmony_ci break; 2573bf215546Sopenharmony_ci default: 2574bf215546Sopenharmony_ci assert(0); 2575bf215546Sopenharmony_ci return; 2576bf215546Sopenharmony_ci } 2577bf215546Sopenharmony_ci 2578bf215546Sopenharmony_ci jit_image->width = width; 2579bf215546Sopenharmony_ci jit_image->height = height; 2580bf215546Sopenharmony_ci jit_image->depth = depth; 2581bf215546Sopenharmony_ci jit_image->base = base_ptr; 2582bf215546Sopenharmony_ci 2583bf215546Sopenharmony_ci jit_image->row_stride = row_stride; 2584bf215546Sopenharmony_ci jit_image->img_stride = img_stride; 2585bf215546Sopenharmony_ci jit_image->num_samples = num_samples; 2586bf215546Sopenharmony_ci jit_image->sample_stride = sample_stride; 2587bf215546Sopenharmony_ci} 2588bf215546Sopenharmony_ci 2589bf215546Sopenharmony_ci 2590bf215546Sopenharmony_civoid 2591bf215546Sopenharmony_cidraw_llvm_set_sampler_state(struct draw_context *draw, 2592bf215546Sopenharmony_ci enum pipe_shader_type shader_type) 2593bf215546Sopenharmony_ci{ 2594bf215546Sopenharmony_ci unsigned i; 2595bf215546Sopenharmony_ci 2596bf215546Sopenharmony_ci switch (shader_type) { 2597bf215546Sopenharmony_ci case PIPE_SHADER_VERTEX: 2598bf215546Sopenharmony_ci for (i = 0; i < draw->num_samplers[PIPE_SHADER_VERTEX]; i++) { 2599bf215546Sopenharmony_ci struct draw_jit_sampler *jit_sam = &draw->llvm->jit_context.samplers[i]; 2600bf215546Sopenharmony_ci 2601bf215546Sopenharmony_ci if (draw->samplers[PIPE_SHADER_VERTEX][i]) { 2602bf215546Sopenharmony_ci const struct pipe_sampler_state *s 2603bf215546Sopenharmony_ci = draw->samplers[PIPE_SHADER_VERTEX][i]; 2604bf215546Sopenharmony_ci jit_sam->min_lod = s->min_lod; 2605bf215546Sopenharmony_ci jit_sam->max_lod = s->max_lod; 2606bf215546Sopenharmony_ci jit_sam->lod_bias = s->lod_bias; 2607bf215546Sopenharmony_ci jit_sam->max_aniso = s->max_anisotropy; 2608bf215546Sopenharmony_ci COPY_4V(jit_sam->border_color, s->border_color.f); 2609bf215546Sopenharmony_ci } 2610bf215546Sopenharmony_ci } 2611bf215546Sopenharmony_ci break; 2612bf215546Sopenharmony_ci case PIPE_SHADER_GEOMETRY: 2613bf215546Sopenharmony_ci for (i = 0; i < draw->num_samplers[PIPE_SHADER_GEOMETRY]; i++) { 2614bf215546Sopenharmony_ci struct draw_jit_sampler *jit_sam = &draw->llvm->gs_jit_context.samplers[i]; 2615bf215546Sopenharmony_ci 2616bf215546Sopenharmony_ci if (draw->samplers[PIPE_SHADER_GEOMETRY][i]) { 2617bf215546Sopenharmony_ci const struct pipe_sampler_state *s 2618bf215546Sopenharmony_ci = draw->samplers[PIPE_SHADER_GEOMETRY][i]; 2619bf215546Sopenharmony_ci jit_sam->min_lod = s->min_lod; 2620bf215546Sopenharmony_ci jit_sam->max_lod = s->max_lod; 2621bf215546Sopenharmony_ci jit_sam->lod_bias = s->lod_bias; 2622bf215546Sopenharmony_ci jit_sam->max_aniso = s->max_anisotropy; 2623bf215546Sopenharmony_ci COPY_4V(jit_sam->border_color, s->border_color.f); 2624bf215546Sopenharmony_ci } 2625bf215546Sopenharmony_ci } 2626bf215546Sopenharmony_ci break; 2627bf215546Sopenharmony_ci case PIPE_SHADER_TESS_CTRL: 2628bf215546Sopenharmony_ci for (i = 0; i < draw->num_samplers[PIPE_SHADER_TESS_CTRL]; i++) { 2629bf215546Sopenharmony_ci struct draw_jit_sampler *jit_sam = &draw->llvm->tcs_jit_context.samplers[i]; 2630bf215546Sopenharmony_ci 2631bf215546Sopenharmony_ci if (draw->samplers[PIPE_SHADER_TESS_CTRL][i]) { 2632bf215546Sopenharmony_ci const struct pipe_sampler_state *s 2633bf215546Sopenharmony_ci = draw->samplers[PIPE_SHADER_TESS_CTRL][i]; 2634bf215546Sopenharmony_ci jit_sam->min_lod = s->min_lod; 2635bf215546Sopenharmony_ci jit_sam->max_lod = s->max_lod; 2636bf215546Sopenharmony_ci jit_sam->lod_bias = s->lod_bias; 2637bf215546Sopenharmony_ci jit_sam->max_aniso = s->max_anisotropy; 2638bf215546Sopenharmony_ci COPY_4V(jit_sam->border_color, s->border_color.f); 2639bf215546Sopenharmony_ci } 2640bf215546Sopenharmony_ci } 2641bf215546Sopenharmony_ci break; 2642bf215546Sopenharmony_ci case PIPE_SHADER_TESS_EVAL: 2643bf215546Sopenharmony_ci for (i = 0; i < draw->num_samplers[PIPE_SHADER_TESS_EVAL]; i++) { 2644bf215546Sopenharmony_ci struct draw_jit_sampler *jit_sam = &draw->llvm->tes_jit_context.samplers[i]; 2645bf215546Sopenharmony_ci 2646bf215546Sopenharmony_ci if (draw->samplers[PIPE_SHADER_TESS_EVAL][i]) { 2647bf215546Sopenharmony_ci const struct pipe_sampler_state *s 2648bf215546Sopenharmony_ci = draw->samplers[PIPE_SHADER_TESS_EVAL][i]; 2649bf215546Sopenharmony_ci jit_sam->min_lod = s->min_lod; 2650bf215546Sopenharmony_ci jit_sam->max_lod = s->max_lod; 2651bf215546Sopenharmony_ci jit_sam->lod_bias = s->lod_bias; 2652bf215546Sopenharmony_ci jit_sam->max_aniso = s->max_anisotropy; 2653bf215546Sopenharmony_ci COPY_4V(jit_sam->border_color, s->border_color.f); 2654bf215546Sopenharmony_ci } 2655bf215546Sopenharmony_ci } 2656bf215546Sopenharmony_ci break; 2657bf215546Sopenharmony_ci default: 2658bf215546Sopenharmony_ci assert(0); 2659bf215546Sopenharmony_ci break; 2660bf215546Sopenharmony_ci } 2661bf215546Sopenharmony_ci} 2662bf215546Sopenharmony_ci 2663bf215546Sopenharmony_ci 2664bf215546Sopenharmony_civoid 2665bf215546Sopenharmony_cidraw_llvm_destroy_variant(struct draw_llvm_variant *variant) 2666bf215546Sopenharmony_ci{ 2667bf215546Sopenharmony_ci struct draw_llvm *llvm = variant->llvm; 2668bf215546Sopenharmony_ci 2669bf215546Sopenharmony_ci if (gallivm_debug & (GALLIVM_DEBUG_TGSI | GALLIVM_DEBUG_IR)) { 2670bf215546Sopenharmony_ci debug_printf("Deleting VS variant: %u vs variants,\t%u total variants\n", 2671bf215546Sopenharmony_ci variant->shader->variants_cached, llvm->nr_variants); 2672bf215546Sopenharmony_ci } 2673bf215546Sopenharmony_ci 2674bf215546Sopenharmony_ci gallivm_destroy(variant->gallivm); 2675bf215546Sopenharmony_ci 2676bf215546Sopenharmony_ci list_del(&variant->list_item_local.list); 2677bf215546Sopenharmony_ci variant->shader->variants_cached--; 2678bf215546Sopenharmony_ci list_del(&variant->list_item_global.list); 2679bf215546Sopenharmony_ci llvm->nr_variants--; 2680bf215546Sopenharmony_ci FREE(variant); 2681bf215546Sopenharmony_ci} 2682bf215546Sopenharmony_ci 2683bf215546Sopenharmony_ci 2684bf215546Sopenharmony_ci/** 2685bf215546Sopenharmony_ci * Create LLVM types for various structures. 2686bf215546Sopenharmony_ci */ 2687bf215546Sopenharmony_cistatic void 2688bf215546Sopenharmony_cicreate_gs_jit_types(struct draw_gs_llvm_variant *var) 2689bf215546Sopenharmony_ci{ 2690bf215546Sopenharmony_ci struct gallivm_state *gallivm = var->gallivm; 2691bf215546Sopenharmony_ci LLVMTypeRef texture_type, sampler_type, image_type; 2692bf215546Sopenharmony_ci 2693bf215546Sopenharmony_ci texture_type = create_jit_texture_type(gallivm, "texture"); 2694bf215546Sopenharmony_ci sampler_type = create_jit_sampler_type(gallivm, "sampler"); 2695bf215546Sopenharmony_ci image_type = create_jit_image_type(gallivm, "image"); 2696bf215546Sopenharmony_ci 2697bf215546Sopenharmony_ci var->context_type = create_gs_jit_context_type(gallivm, 2698bf215546Sopenharmony_ci var->shader->base.vector_length, 2699bf215546Sopenharmony_ci texture_type, sampler_type, 2700bf215546Sopenharmony_ci image_type, 2701bf215546Sopenharmony_ci "draw_gs_jit_context"); 2702bf215546Sopenharmony_ci var->context_ptr_type = LLVMPointerType(var->context_type, 0); 2703bf215546Sopenharmony_ci 2704bf215546Sopenharmony_ci var->input_array_type = create_gs_jit_input_type(gallivm); 2705bf215546Sopenharmony_ci} 2706bf215546Sopenharmony_ci 2707bf215546Sopenharmony_cistatic LLVMTypeRef 2708bf215546Sopenharmony_ciget_gs_context_ptr_type(struct draw_gs_llvm_variant *variant) 2709bf215546Sopenharmony_ci{ 2710bf215546Sopenharmony_ci if (!variant->context_ptr_type) 2711bf215546Sopenharmony_ci create_gs_jit_types(variant); 2712bf215546Sopenharmony_ci return variant->context_ptr_type; 2713bf215546Sopenharmony_ci} 2714bf215546Sopenharmony_ci 2715bf215546Sopenharmony_cistatic LLVMValueRef 2716bf215546Sopenharmony_cigenerate_mask_value(struct draw_gs_llvm_variant *variant, 2717bf215546Sopenharmony_ci struct lp_type gs_type) 2718bf215546Sopenharmony_ci{ 2719bf215546Sopenharmony_ci struct gallivm_state *gallivm = variant->gallivm; 2720bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 2721bf215546Sopenharmony_ci struct lp_type mask_type = lp_int_type(gs_type); 2722bf215546Sopenharmony_ci LLVMValueRef num_prims; 2723bf215546Sopenharmony_ci LLVMValueRef mask_val = lp_build_const_vec(gallivm, mask_type, 0); 2724bf215546Sopenharmony_ci unsigned i; 2725bf215546Sopenharmony_ci 2726bf215546Sopenharmony_ci num_prims = lp_build_broadcast(gallivm, lp_build_vec_type(gallivm, mask_type), 2727bf215546Sopenharmony_ci variant->num_prims); 2728bf215546Sopenharmony_ci for (i = 0; i < gs_type.length; i++) { 2729bf215546Sopenharmony_ci LLVMValueRef idx = lp_build_const_int32(gallivm, i); 2730bf215546Sopenharmony_ci mask_val = LLVMBuildInsertElement(builder, mask_val, idx, idx, ""); 2731bf215546Sopenharmony_ci } 2732bf215546Sopenharmony_ci mask_val = lp_build_compare(gallivm, mask_type, 2733bf215546Sopenharmony_ci PIPE_FUNC_GREATER, num_prims, mask_val); 2734bf215546Sopenharmony_ci 2735bf215546Sopenharmony_ci return mask_val; 2736bf215546Sopenharmony_ci} 2737bf215546Sopenharmony_ci 2738bf215546Sopenharmony_cistatic void 2739bf215546Sopenharmony_cidraw_gs_llvm_generate(struct draw_llvm *llvm, 2740bf215546Sopenharmony_ci struct draw_gs_llvm_variant *variant) 2741bf215546Sopenharmony_ci{ 2742bf215546Sopenharmony_ci struct gallivm_state *gallivm = variant->gallivm; 2743bf215546Sopenharmony_ci LLVMContextRef context = gallivm->context; 2744bf215546Sopenharmony_ci LLVMTypeRef int32_type = LLVMInt32TypeInContext(context); 2745bf215546Sopenharmony_ci LLVMTypeRef arg_types[8]; 2746bf215546Sopenharmony_ci LLVMTypeRef func_type; 2747bf215546Sopenharmony_ci LLVMValueRef variant_func; 2748bf215546Sopenharmony_ci LLVMValueRef context_ptr; 2749bf215546Sopenharmony_ci LLVMValueRef prim_id_ptr; 2750bf215546Sopenharmony_ci LLVMBasicBlockRef block; 2751bf215546Sopenharmony_ci LLVMBuilderRef builder; 2752bf215546Sopenharmony_ci LLVMValueRef io_ptr, input_array, num_prims, mask_val; 2753bf215546Sopenharmony_ci struct lp_build_sampler_soa *sampler = 0; 2754bf215546Sopenharmony_ci struct lp_build_image_soa *image = NULL; 2755bf215546Sopenharmony_ci struct lp_build_context bld; 2756bf215546Sopenharmony_ci struct lp_bld_tgsi_system_values system_values; 2757bf215546Sopenharmony_ci char func_name[64]; 2758bf215546Sopenharmony_ci struct lp_type gs_type; 2759bf215546Sopenharmony_ci unsigned i; 2760bf215546Sopenharmony_ci struct draw_gs_llvm_iface gs_iface; 2761bf215546Sopenharmony_ci const struct tgsi_token *tokens = variant->shader->base.state.tokens; 2762bf215546Sopenharmony_ci LLVMValueRef consts_ptr, num_consts_ptr; 2763bf215546Sopenharmony_ci LLVMValueRef ssbos_ptr, num_ssbos_ptr; 2764bf215546Sopenharmony_ci LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS]; 2765bf215546Sopenharmony_ci struct lp_build_mask_context mask; 2766bf215546Sopenharmony_ci const struct tgsi_shader_info *gs_info = &variant->shader->base.info; 2767bf215546Sopenharmony_ci unsigned vector_length = variant->shader->base.vector_length; 2768bf215546Sopenharmony_ci 2769bf215546Sopenharmony_ci memset(&system_values, 0, sizeof(system_values)); 2770bf215546Sopenharmony_ci memset(&outputs, 0, sizeof(outputs)); 2771bf215546Sopenharmony_ci 2772bf215546Sopenharmony_ci snprintf(func_name, sizeof(func_name), "draw_llvm_gs_variant"); 2773bf215546Sopenharmony_ci 2774bf215546Sopenharmony_ci assert(variant->vertex_header_ptr_type); 2775bf215546Sopenharmony_ci 2776bf215546Sopenharmony_ci LLVMTypeRef prim_id_type = LLVMVectorType(int32_type, vector_length); 2777bf215546Sopenharmony_ci arg_types[0] = get_gs_context_ptr_type(variant); /* context */ 2778bf215546Sopenharmony_ci arg_types[1] = variant->input_array_type; /* input */ 2779bf215546Sopenharmony_ci arg_types[2] = LLVMPointerType(variant->vertex_header_ptr_type, 0); /* vertex_header */ 2780bf215546Sopenharmony_ci arg_types[3] = int32_type; /* num_prims */ 2781bf215546Sopenharmony_ci arg_types[4] = int32_type; /* instance_id */ 2782bf215546Sopenharmony_ci arg_types[5] = LLVMPointerType(prim_id_type, 0); /* prim_id_ptr */ 2783bf215546Sopenharmony_ci arg_types[6] = int32_type; 2784bf215546Sopenharmony_ci arg_types[7] = int32_type; 2785bf215546Sopenharmony_ci 2786bf215546Sopenharmony_ci func_type = LLVMFunctionType(int32_type, arg_types, ARRAY_SIZE(arg_types), 0); 2787bf215546Sopenharmony_ci 2788bf215546Sopenharmony_ci variant_func = LLVMAddFunction(gallivm->module, func_name, func_type); 2789bf215546Sopenharmony_ci 2790bf215546Sopenharmony_ci variant->function = variant_func; 2791bf215546Sopenharmony_ci 2792bf215546Sopenharmony_ci LLVMSetFunctionCallConv(variant_func, LLVMCCallConv); 2793bf215546Sopenharmony_ci 2794bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(arg_types); ++i) 2795bf215546Sopenharmony_ci if (LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind) 2796bf215546Sopenharmony_ci lp_add_function_attr(variant_func, i + 1, LP_FUNC_ATTR_NOALIAS); 2797bf215546Sopenharmony_ci 2798bf215546Sopenharmony_ci if (gallivm->cache && gallivm->cache->data_size) 2799bf215546Sopenharmony_ci return; 2800bf215546Sopenharmony_ci context_ptr = LLVMGetParam(variant_func, 0); 2801bf215546Sopenharmony_ci input_array = LLVMGetParam(variant_func, 1); 2802bf215546Sopenharmony_ci io_ptr = LLVMGetParam(variant_func, 2); 2803bf215546Sopenharmony_ci num_prims = LLVMGetParam(variant_func, 3); 2804bf215546Sopenharmony_ci system_values.instance_id = LLVMGetParam(variant_func, 4); 2805bf215546Sopenharmony_ci prim_id_ptr = LLVMGetParam(variant_func, 5); 2806bf215546Sopenharmony_ci system_values.invocation_id = LLVMGetParam(variant_func, 6); 2807bf215546Sopenharmony_ci system_values.view_index = LLVMGetParam(variant_func, 7); 2808bf215546Sopenharmony_ci 2809bf215546Sopenharmony_ci lp_build_name(context_ptr, "context"); 2810bf215546Sopenharmony_ci lp_build_name(input_array, "input"); 2811bf215546Sopenharmony_ci lp_build_name(io_ptr, "io"); 2812bf215546Sopenharmony_ci lp_build_name(num_prims, "num_prims"); 2813bf215546Sopenharmony_ci lp_build_name(system_values.instance_id, "instance_id"); 2814bf215546Sopenharmony_ci lp_build_name(prim_id_ptr, "prim_id_ptr"); 2815bf215546Sopenharmony_ci lp_build_name(system_values.invocation_id, "invocation_id"); 2816bf215546Sopenharmony_ci lp_build_name(system_values.view_index, "view_index"); 2817bf215546Sopenharmony_ci 2818bf215546Sopenharmony_ci variant->context_ptr = context_ptr; 2819bf215546Sopenharmony_ci variant->io_ptr = io_ptr; 2820bf215546Sopenharmony_ci variant->num_prims = num_prims; 2821bf215546Sopenharmony_ci 2822bf215546Sopenharmony_ci gs_iface.base.fetch_input = draw_gs_llvm_fetch_input; 2823bf215546Sopenharmony_ci gs_iface.base.emit_vertex = draw_gs_llvm_emit_vertex; 2824bf215546Sopenharmony_ci gs_iface.base.end_primitive = draw_gs_llvm_end_primitive; 2825bf215546Sopenharmony_ci gs_iface.base.gs_epilogue = draw_gs_llvm_epilogue; 2826bf215546Sopenharmony_ci gs_iface.input = input_array; 2827bf215546Sopenharmony_ci gs_iface.variant = variant; 2828bf215546Sopenharmony_ci 2829bf215546Sopenharmony_ci /* 2830bf215546Sopenharmony_ci * Function body 2831bf215546Sopenharmony_ci */ 2832bf215546Sopenharmony_ci 2833bf215546Sopenharmony_ci block = LLVMAppendBasicBlockInContext(gallivm->context, variant_func, "entry"); 2834bf215546Sopenharmony_ci builder = gallivm->builder; 2835bf215546Sopenharmony_ci LLVMPositionBuilderAtEnd(builder, block); 2836bf215546Sopenharmony_ci 2837bf215546Sopenharmony_ci lp_build_context_init(&bld, gallivm, lp_type_int(32)); 2838bf215546Sopenharmony_ci 2839bf215546Sopenharmony_ci memset(&gs_type, 0, sizeof gs_type); 2840bf215546Sopenharmony_ci gs_type.floating = TRUE; /* floating point values */ 2841bf215546Sopenharmony_ci gs_type.sign = TRUE; /* values are signed */ 2842bf215546Sopenharmony_ci gs_type.norm = FALSE; /* values are not limited to [0,1] or [-1,1] */ 2843bf215546Sopenharmony_ci gs_type.width = 32; /* 32-bit float */ 2844bf215546Sopenharmony_ci gs_type.length = vector_length; 2845bf215546Sopenharmony_ci 2846bf215546Sopenharmony_ci consts_ptr = draw_gs_jit_context_constants(variant, context_ptr); 2847bf215546Sopenharmony_ci num_consts_ptr = 2848bf215546Sopenharmony_ci draw_gs_jit_context_num_constants(variant, context_ptr); 2849bf215546Sopenharmony_ci 2850bf215546Sopenharmony_ci ssbos_ptr = draw_gs_jit_context_ssbos(variant, context_ptr); 2851bf215546Sopenharmony_ci num_ssbos_ptr = 2852bf215546Sopenharmony_ci draw_gs_jit_context_num_ssbos(variant, context_ptr); 2853bf215546Sopenharmony_ci 2854bf215546Sopenharmony_ci /* code generated texture sampling */ 2855bf215546Sopenharmony_ci sampler = draw_llvm_sampler_soa_create(variant->key.samplers, 2856bf215546Sopenharmony_ci MAX2(variant->key.nr_samplers, 2857bf215546Sopenharmony_ci variant->key.nr_sampler_views)); 2858bf215546Sopenharmony_ci image = draw_llvm_image_soa_create(draw_gs_llvm_variant_key_images(&variant->key), 2859bf215546Sopenharmony_ci variant->key.nr_images); 2860bf215546Sopenharmony_ci mask_val = generate_mask_value(variant, gs_type); 2861bf215546Sopenharmony_ci lp_build_mask_begin(&mask, gallivm, gs_type, mask_val); 2862bf215546Sopenharmony_ci 2863bf215546Sopenharmony_ci if (gs_info->uses_primid) { 2864bf215546Sopenharmony_ci system_values.prim_id = LLVMBuildLoad2(builder, prim_id_type, prim_id_ptr, "prim_id"); 2865bf215546Sopenharmony_ci } 2866bf215546Sopenharmony_ci 2867bf215546Sopenharmony_ci if (gallivm_debug & (GALLIVM_DEBUG_TGSI | GALLIVM_DEBUG_IR)) { 2868bf215546Sopenharmony_ci if (llvm->draw->gs.geometry_shader->state.type == PIPE_SHADER_IR_TGSI) 2869bf215546Sopenharmony_ci tgsi_dump(tokens, 0); 2870bf215546Sopenharmony_ci else 2871bf215546Sopenharmony_ci nir_print_shader(llvm->draw->gs.geometry_shader->state.ir.nir, stderr); 2872bf215546Sopenharmony_ci draw_gs_llvm_dump_variant_key(&variant->key); 2873bf215546Sopenharmony_ci } 2874bf215546Sopenharmony_ci 2875bf215546Sopenharmony_ci struct lp_build_tgsi_params params; 2876bf215546Sopenharmony_ci memset(¶ms, 0, sizeof(params)); 2877bf215546Sopenharmony_ci 2878bf215546Sopenharmony_ci params.type = gs_type; 2879bf215546Sopenharmony_ci params.mask = &mask; 2880bf215546Sopenharmony_ci params.consts_ptr = consts_ptr; 2881bf215546Sopenharmony_ci params.const_sizes_ptr = num_consts_ptr; 2882bf215546Sopenharmony_ci params.system_values = &system_values; 2883bf215546Sopenharmony_ci params.context_ptr = context_ptr; 2884bf215546Sopenharmony_ci params.sampler = sampler; 2885bf215546Sopenharmony_ci params.info = &llvm->draw->gs.geometry_shader->info; 2886bf215546Sopenharmony_ci params.gs_iface = (const struct lp_build_gs_iface *)&gs_iface; 2887bf215546Sopenharmony_ci params.ssbo_ptr = ssbos_ptr; 2888bf215546Sopenharmony_ci params.ssbo_sizes_ptr = num_ssbos_ptr; 2889bf215546Sopenharmony_ci params.image = image; 2890bf215546Sopenharmony_ci params.gs_vertex_streams = variant->shader->base.num_vertex_streams; 2891bf215546Sopenharmony_ci params.aniso_filter_table = draw_gs_jit_context_aniso_filter_table(variant, context_ptr); 2892bf215546Sopenharmony_ci 2893bf215546Sopenharmony_ci if (llvm->draw->gs.geometry_shader->state.type == PIPE_SHADER_IR_TGSI) 2894bf215546Sopenharmony_ci lp_build_tgsi_soa(variant->gallivm, 2895bf215546Sopenharmony_ci tokens, 2896bf215546Sopenharmony_ci ¶ms, 2897bf215546Sopenharmony_ci outputs); 2898bf215546Sopenharmony_ci else 2899bf215546Sopenharmony_ci lp_build_nir_soa(variant->gallivm, 2900bf215546Sopenharmony_ci llvm->draw->gs.geometry_shader->state.ir.nir, 2901bf215546Sopenharmony_ci ¶ms, 2902bf215546Sopenharmony_ci outputs); 2903bf215546Sopenharmony_ci 2904bf215546Sopenharmony_ci sampler->destroy(sampler); 2905bf215546Sopenharmony_ci image->destroy(image); 2906bf215546Sopenharmony_ci 2907bf215546Sopenharmony_ci lp_build_mask_end(&mask); 2908bf215546Sopenharmony_ci 2909bf215546Sopenharmony_ci LLVMBuildRet(builder, lp_build_zero(gallivm, lp_type_uint(32))); 2910bf215546Sopenharmony_ci 2911bf215546Sopenharmony_ci gallivm_verify_function(gallivm, variant_func); 2912bf215546Sopenharmony_ci} 2913bf215546Sopenharmony_ci 2914bf215546Sopenharmony_cistruct draw_gs_llvm_variant * 2915bf215546Sopenharmony_cidraw_gs_llvm_create_variant(struct draw_llvm *llvm, 2916bf215546Sopenharmony_ci unsigned num_outputs, 2917bf215546Sopenharmony_ci const struct draw_gs_llvm_variant_key *key) 2918bf215546Sopenharmony_ci{ 2919bf215546Sopenharmony_ci struct draw_gs_llvm_variant *variant; 2920bf215546Sopenharmony_ci struct llvm_geometry_shader *shader = 2921bf215546Sopenharmony_ci llvm_geometry_shader(llvm->draw->gs.geometry_shader); 2922bf215546Sopenharmony_ci char module_name[64]; 2923bf215546Sopenharmony_ci unsigned char ir_sha1_cache_key[20]; 2924bf215546Sopenharmony_ci struct lp_cached_code cached = { 0 }; 2925bf215546Sopenharmony_ci bool needs_caching = false; 2926bf215546Sopenharmony_ci 2927bf215546Sopenharmony_ci variant = MALLOC(sizeof *variant + 2928bf215546Sopenharmony_ci shader->variant_key_size - 2929bf215546Sopenharmony_ci sizeof variant->key); 2930bf215546Sopenharmony_ci if (!variant) 2931bf215546Sopenharmony_ci return NULL; 2932bf215546Sopenharmony_ci 2933bf215546Sopenharmony_ci variant->llvm = llvm; 2934bf215546Sopenharmony_ci variant->shader = shader; 2935bf215546Sopenharmony_ci 2936bf215546Sopenharmony_ci snprintf(module_name, sizeof(module_name), "draw_llvm_gs_variant%u", 2937bf215546Sopenharmony_ci variant->shader->variants_cached); 2938bf215546Sopenharmony_ci 2939bf215546Sopenharmony_ci memcpy(&variant->key, key, shader->variant_key_size); 2940bf215546Sopenharmony_ci 2941bf215546Sopenharmony_ci if (shader->base.state.ir.nir && llvm->draw->disk_cache_cookie) { 2942bf215546Sopenharmony_ci draw_get_ir_cache_key(shader->base.state.ir.nir, 2943bf215546Sopenharmony_ci key, 2944bf215546Sopenharmony_ci shader->variant_key_size, 2945bf215546Sopenharmony_ci num_outputs, 2946bf215546Sopenharmony_ci ir_sha1_cache_key); 2947bf215546Sopenharmony_ci 2948bf215546Sopenharmony_ci llvm->draw->disk_cache_find_shader(llvm->draw->disk_cache_cookie, 2949bf215546Sopenharmony_ci &cached, 2950bf215546Sopenharmony_ci ir_sha1_cache_key); 2951bf215546Sopenharmony_ci if (!cached.data_size) 2952bf215546Sopenharmony_ci needs_caching = true; 2953bf215546Sopenharmony_ci } 2954bf215546Sopenharmony_ci variant->gallivm = gallivm_create(module_name, llvm->context, &cached); 2955bf215546Sopenharmony_ci 2956bf215546Sopenharmony_ci create_gs_jit_types(variant); 2957bf215546Sopenharmony_ci 2958bf215546Sopenharmony_ci variant->vertex_header_type = create_jit_vertex_header(variant->gallivm, num_outputs); 2959bf215546Sopenharmony_ci variant->vertex_header_ptr_type = LLVMPointerType(variant->vertex_header_type, 0); 2960bf215546Sopenharmony_ci 2961bf215546Sopenharmony_ci draw_gs_llvm_generate(llvm, variant); 2962bf215546Sopenharmony_ci 2963bf215546Sopenharmony_ci gallivm_compile_module(variant->gallivm); 2964bf215546Sopenharmony_ci 2965bf215546Sopenharmony_ci variant->jit_func = (draw_gs_jit_func) 2966bf215546Sopenharmony_ci gallivm_jit_function(variant->gallivm, variant->function); 2967bf215546Sopenharmony_ci 2968bf215546Sopenharmony_ci if (needs_caching) 2969bf215546Sopenharmony_ci llvm->draw->disk_cache_insert_shader(llvm->draw->disk_cache_cookie, 2970bf215546Sopenharmony_ci &cached, 2971bf215546Sopenharmony_ci ir_sha1_cache_key); 2972bf215546Sopenharmony_ci gallivm_free_ir(variant->gallivm); 2973bf215546Sopenharmony_ci 2974bf215546Sopenharmony_ci variant->list_item_global.base = variant; 2975bf215546Sopenharmony_ci variant->list_item_local.base = variant; 2976bf215546Sopenharmony_ci /*variant->no = */shader->variants_created++; 2977bf215546Sopenharmony_ci variant->list_item_global.base = variant; 2978bf215546Sopenharmony_ci 2979bf215546Sopenharmony_ci return variant; 2980bf215546Sopenharmony_ci} 2981bf215546Sopenharmony_ci 2982bf215546Sopenharmony_civoid 2983bf215546Sopenharmony_cidraw_gs_llvm_destroy_variant(struct draw_gs_llvm_variant *variant) 2984bf215546Sopenharmony_ci{ 2985bf215546Sopenharmony_ci struct draw_llvm *llvm = variant->llvm; 2986bf215546Sopenharmony_ci 2987bf215546Sopenharmony_ci if (gallivm_debug & (GALLIVM_DEBUG_TGSI | GALLIVM_DEBUG_IR)) { 2988bf215546Sopenharmony_ci debug_printf("Deleting GS variant: %u gs variants,\t%u total variants\n", 2989bf215546Sopenharmony_ci variant->shader->variants_cached, llvm->nr_gs_variants); 2990bf215546Sopenharmony_ci } 2991bf215546Sopenharmony_ci 2992bf215546Sopenharmony_ci gallivm_destroy(variant->gallivm); 2993bf215546Sopenharmony_ci 2994bf215546Sopenharmony_ci list_del(&variant->list_item_local.list); 2995bf215546Sopenharmony_ci variant->shader->variants_cached--; 2996bf215546Sopenharmony_ci list_del(&variant->list_item_global.list); 2997bf215546Sopenharmony_ci llvm->nr_gs_variants--; 2998bf215546Sopenharmony_ci FREE(variant); 2999bf215546Sopenharmony_ci} 3000bf215546Sopenharmony_ci 3001bf215546Sopenharmony_cistruct draw_gs_llvm_variant_key * 3002bf215546Sopenharmony_cidraw_gs_llvm_make_variant_key(struct draw_llvm *llvm, char *store) 3003bf215546Sopenharmony_ci{ 3004bf215546Sopenharmony_ci unsigned i; 3005bf215546Sopenharmony_ci struct draw_gs_llvm_variant_key *key; 3006bf215546Sopenharmony_ci struct draw_sampler_static_state *draw_sampler; 3007bf215546Sopenharmony_ci struct draw_image_static_state *draw_image; 3008bf215546Sopenharmony_ci 3009bf215546Sopenharmony_ci key = (struct draw_gs_llvm_variant_key *)store; 3010bf215546Sopenharmony_ci 3011bf215546Sopenharmony_ci memset(key, 0, offsetof(struct draw_gs_llvm_variant_key, samplers[0])); 3012bf215546Sopenharmony_ci 3013bf215546Sopenharmony_ci key->num_outputs = draw_total_gs_outputs(llvm->draw); 3014bf215546Sopenharmony_ci 3015bf215546Sopenharmony_ci key->clamp_vertex_color = llvm->draw->rasterizer->clamp_vertex_color; 3016bf215546Sopenharmony_ci 3017bf215546Sopenharmony_ci /* All variants of this shader will have the same value for 3018bf215546Sopenharmony_ci * nr_samplers. Not yet trying to compact away holes in the 3019bf215546Sopenharmony_ci * sampler array. 3020bf215546Sopenharmony_ci */ 3021bf215546Sopenharmony_ci key->nr_samplers = llvm->draw->gs.geometry_shader->info.file_max[TGSI_FILE_SAMPLER] + 1; 3022bf215546Sopenharmony_ci if (llvm->draw->gs.geometry_shader->info.file_max[TGSI_FILE_SAMPLER_VIEW] != -1) { 3023bf215546Sopenharmony_ci key->nr_sampler_views = 3024bf215546Sopenharmony_ci llvm->draw->gs.geometry_shader->info.file_max[TGSI_FILE_SAMPLER_VIEW] + 1; 3025bf215546Sopenharmony_ci } 3026bf215546Sopenharmony_ci else { 3027bf215546Sopenharmony_ci key->nr_sampler_views = key->nr_samplers; 3028bf215546Sopenharmony_ci } 3029bf215546Sopenharmony_ci 3030bf215546Sopenharmony_ci key->nr_images = llvm->draw->gs.geometry_shader->info.file_max[TGSI_FILE_IMAGE] + 1; 3031bf215546Sopenharmony_ci 3032bf215546Sopenharmony_ci draw_sampler = key->samplers; 3033bf215546Sopenharmony_ci 3034bf215546Sopenharmony_ci memset(draw_sampler, 0, MAX2(key->nr_samplers, key->nr_sampler_views) * sizeof *draw_sampler); 3035bf215546Sopenharmony_ci 3036bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_samplers; i++) { 3037bf215546Sopenharmony_ci lp_sampler_static_sampler_state(&draw_sampler[i].sampler_state, 3038bf215546Sopenharmony_ci llvm->draw->samplers[PIPE_SHADER_GEOMETRY][i]); 3039bf215546Sopenharmony_ci } 3040bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_sampler_views; i++) { 3041bf215546Sopenharmony_ci lp_sampler_static_texture_state(&draw_sampler[i].texture_state, 3042bf215546Sopenharmony_ci llvm->draw->sampler_views[PIPE_SHADER_GEOMETRY][i]); 3043bf215546Sopenharmony_ci } 3044bf215546Sopenharmony_ci 3045bf215546Sopenharmony_ci draw_image = draw_gs_llvm_variant_key_images(key); 3046bf215546Sopenharmony_ci memset(draw_image, 0, 3047bf215546Sopenharmony_ci key->nr_images * sizeof *draw_image); 3048bf215546Sopenharmony_ci for (i = 0; i < key->nr_images; i++) { 3049bf215546Sopenharmony_ci lp_sampler_static_texture_state_image(&draw_image[i].image_state, 3050bf215546Sopenharmony_ci llvm->draw->images[PIPE_SHADER_GEOMETRY][i]); 3051bf215546Sopenharmony_ci } 3052bf215546Sopenharmony_ci return key; 3053bf215546Sopenharmony_ci} 3054bf215546Sopenharmony_ci 3055bf215546Sopenharmony_civoid 3056bf215546Sopenharmony_cidraw_gs_llvm_dump_variant_key(struct draw_gs_llvm_variant_key *key) 3057bf215546Sopenharmony_ci{ 3058bf215546Sopenharmony_ci unsigned i; 3059bf215546Sopenharmony_ci struct draw_sampler_static_state *sampler = key->samplers; 3060bf215546Sopenharmony_ci struct draw_image_static_state *image = draw_gs_llvm_variant_key_images(key); 3061bf215546Sopenharmony_ci 3062bf215546Sopenharmony_ci debug_printf("clamp_vertex_color = %u\n", key->clamp_vertex_color); 3063bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_sampler_views; i++) { 3064bf215546Sopenharmony_ci debug_printf("sampler[%i].src_format = %s\n", i, 3065bf215546Sopenharmony_ci util_format_name(sampler[i].texture_state.format)); 3066bf215546Sopenharmony_ci } 3067bf215546Sopenharmony_ci 3068bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_images; i++) 3069bf215546Sopenharmony_ci debug_printf("images[%i].format = %s\n", i, util_format_name(image[i].image_state.format)); 3070bf215546Sopenharmony_ci 3071bf215546Sopenharmony_ci} 3072bf215546Sopenharmony_ci 3073bf215546Sopenharmony_cistatic void 3074bf215546Sopenharmony_cicreate_tcs_jit_types(struct draw_tcs_llvm_variant *var) 3075bf215546Sopenharmony_ci{ 3076bf215546Sopenharmony_ci struct gallivm_state *gallivm = var->gallivm; 3077bf215546Sopenharmony_ci LLVMTypeRef texture_type, sampler_type, image_type; 3078bf215546Sopenharmony_ci 3079bf215546Sopenharmony_ci texture_type = create_jit_texture_type(gallivm, "texture"); 3080bf215546Sopenharmony_ci sampler_type = create_jit_sampler_type(gallivm, "sampler"); 3081bf215546Sopenharmony_ci image_type = create_jit_image_type(gallivm, "image"); 3082bf215546Sopenharmony_ci 3083bf215546Sopenharmony_ci var->context_type = create_tcs_jit_context_type(gallivm, 3084bf215546Sopenharmony_ci 0, 3085bf215546Sopenharmony_ci texture_type, sampler_type, 3086bf215546Sopenharmony_ci image_type, 3087bf215546Sopenharmony_ci "draw_tcs_jit_context"); 3088bf215546Sopenharmony_ci var->input_array_type = create_tcs_jit_input_type(gallivm); 3089bf215546Sopenharmony_ci var->output_array_type = create_tcs_jit_output_type(gallivm); 3090bf215546Sopenharmony_ci var->context_ptr_type = LLVMPointerType(var->context_type, 0); 3091bf215546Sopenharmony_ci} 3092bf215546Sopenharmony_ci 3093bf215546Sopenharmony_cistatic LLVMTypeRef 3094bf215546Sopenharmony_ciget_tcs_context_ptr_type(struct draw_tcs_llvm_variant *variant) 3095bf215546Sopenharmony_ci{ 3096bf215546Sopenharmony_ci if (!variant->context_ptr_type) 3097bf215546Sopenharmony_ci create_tcs_jit_types(variant); 3098bf215546Sopenharmony_ci return variant->context_ptr_type; 3099bf215546Sopenharmony_ci} 3100bf215546Sopenharmony_ci 3101bf215546Sopenharmony_cistatic LLVMValueRef 3102bf215546Sopenharmony_cidraw_tcs_llvm_emit_fetch_input(const struct lp_build_tcs_iface *tes_iface, 3103bf215546Sopenharmony_ci struct lp_build_context *bld, 3104bf215546Sopenharmony_ci boolean is_vindex_indirect, 3105bf215546Sopenharmony_ci LLVMValueRef vertex_index, 3106bf215546Sopenharmony_ci boolean is_aindex_indirect, 3107bf215546Sopenharmony_ci LLVMValueRef attrib_index, 3108bf215546Sopenharmony_ci boolean is_sindex_indirect, 3109bf215546Sopenharmony_ci LLVMValueRef swizzle_index) 3110bf215546Sopenharmony_ci{ 3111bf215546Sopenharmony_ci const struct draw_tcs_llvm_iface *tcs = draw_tcs_llvm_iface(tes_iface); 3112bf215546Sopenharmony_ci struct gallivm_state *gallivm = bld->gallivm; 3113bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 3114bf215546Sopenharmony_ci LLVMValueRef indices[3]; 3115bf215546Sopenharmony_ci LLVMValueRef res; 3116bf215546Sopenharmony_ci struct lp_type type = bld->type; 3117bf215546Sopenharmony_ci 3118bf215546Sopenharmony_ci if (is_vindex_indirect || is_aindex_indirect || is_sindex_indirect) { 3119bf215546Sopenharmony_ci int i; 3120bf215546Sopenharmony_ci 3121bf215546Sopenharmony_ci res = bld->zero; 3122bf215546Sopenharmony_ci for (i = 0; i < type.length; ++i) { 3123bf215546Sopenharmony_ci LLVMValueRef idx = lp_build_const_int32(gallivm, i); 3124bf215546Sopenharmony_ci LLVMValueRef vert_chan_index = vertex_index; 3125bf215546Sopenharmony_ci LLVMValueRef attr_chan_index = attrib_index; 3126bf215546Sopenharmony_ci LLVMValueRef swiz_chan_index = swizzle_index; 3127bf215546Sopenharmony_ci LLVMValueRef channel_vec; 3128bf215546Sopenharmony_ci 3129bf215546Sopenharmony_ci if (is_vindex_indirect) { 3130bf215546Sopenharmony_ci vert_chan_index = LLVMBuildExtractElement(builder, 3131bf215546Sopenharmony_ci vertex_index, idx, ""); 3132bf215546Sopenharmony_ci } 3133bf215546Sopenharmony_ci if (is_aindex_indirect) { 3134bf215546Sopenharmony_ci attr_chan_index = LLVMBuildExtractElement(builder, 3135bf215546Sopenharmony_ci attrib_index, idx, ""); 3136bf215546Sopenharmony_ci } 3137bf215546Sopenharmony_ci if (is_sindex_indirect) { 3138bf215546Sopenharmony_ci swiz_chan_index = LLVMBuildExtractElement(builder, 3139bf215546Sopenharmony_ci swizzle_index, idx, ""); 3140bf215546Sopenharmony_ci } 3141bf215546Sopenharmony_ci 3142bf215546Sopenharmony_ci indices[0] = vert_chan_index; 3143bf215546Sopenharmony_ci indices[1] = attr_chan_index; 3144bf215546Sopenharmony_ci indices[2] = swiz_chan_index; 3145bf215546Sopenharmony_ci 3146bf215546Sopenharmony_ci channel_vec = LLVMBuildGEP(builder, tcs->input, indices, 3, ""); 3147bf215546Sopenharmony_ci channel_vec = LLVMBuildLoad(builder, channel_vec, ""); 3148bf215546Sopenharmony_ci 3149bf215546Sopenharmony_ci res = LLVMBuildInsertElement(builder, res, channel_vec, idx, ""); 3150bf215546Sopenharmony_ci } 3151bf215546Sopenharmony_ci } else { 3152bf215546Sopenharmony_ci indices[0] = vertex_index; 3153bf215546Sopenharmony_ci indices[1] = attrib_index; 3154bf215546Sopenharmony_ci indices[2] = swizzle_index; 3155bf215546Sopenharmony_ci 3156bf215546Sopenharmony_ci res = LLVMBuildGEP(builder, tcs->input, indices, 3, ""); 3157bf215546Sopenharmony_ci res = LLVMBuildLoad(builder, res, ""); 3158bf215546Sopenharmony_ci res = lp_build_broadcast_scalar(bld, res); 3159bf215546Sopenharmony_ci } 3160bf215546Sopenharmony_ci return res; 3161bf215546Sopenharmony_ci} 3162bf215546Sopenharmony_ci 3163bf215546Sopenharmony_cistatic LLVMValueRef 3164bf215546Sopenharmony_cidraw_tcs_llvm_emit_fetch_output(const struct lp_build_tcs_iface *tes_iface, 3165bf215546Sopenharmony_ci struct lp_build_context *bld, 3166bf215546Sopenharmony_ci boolean is_vindex_indirect, 3167bf215546Sopenharmony_ci LLVMValueRef vertex_index, 3168bf215546Sopenharmony_ci boolean is_aindex_indirect, 3169bf215546Sopenharmony_ci LLVMValueRef attrib_index, 3170bf215546Sopenharmony_ci boolean is_sindex_indirect, 3171bf215546Sopenharmony_ci LLVMValueRef swizzle_index, 3172bf215546Sopenharmony_ci uint32_t name) 3173bf215546Sopenharmony_ci{ 3174bf215546Sopenharmony_ci const struct draw_tcs_llvm_iface *tcs = draw_tcs_llvm_iface(tes_iface); 3175bf215546Sopenharmony_ci struct gallivm_state *gallivm = bld->gallivm; 3176bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 3177bf215546Sopenharmony_ci LLVMValueRef indices[3]; 3178bf215546Sopenharmony_ci LLVMValueRef res; 3179bf215546Sopenharmony_ci struct lp_type type = bld->type; 3180bf215546Sopenharmony_ci 3181bf215546Sopenharmony_ci if (is_vindex_indirect || is_aindex_indirect || is_sindex_indirect) { 3182bf215546Sopenharmony_ci int i; 3183bf215546Sopenharmony_ci 3184bf215546Sopenharmony_ci res = bld->zero; 3185bf215546Sopenharmony_ci for (i = 0; i < type.length; ++i) { 3186bf215546Sopenharmony_ci LLVMValueRef idx = lp_build_const_int32(gallivm, i); 3187bf215546Sopenharmony_ci LLVMValueRef vert_chan_index = vertex_index; 3188bf215546Sopenharmony_ci LLVMValueRef attr_chan_index = attrib_index; 3189bf215546Sopenharmony_ci LLVMValueRef swiz_chan_index = swizzle_index; 3190bf215546Sopenharmony_ci LLVMValueRef channel_vec; 3191bf215546Sopenharmony_ci 3192bf215546Sopenharmony_ci if (is_vindex_indirect) { 3193bf215546Sopenharmony_ci vert_chan_index = LLVMBuildExtractElement(builder, 3194bf215546Sopenharmony_ci vertex_index, idx, ""); 3195bf215546Sopenharmony_ci } 3196bf215546Sopenharmony_ci if (is_aindex_indirect) { 3197bf215546Sopenharmony_ci attr_chan_index = LLVMBuildExtractElement(builder, 3198bf215546Sopenharmony_ci attrib_index, idx, ""); 3199bf215546Sopenharmony_ci } 3200bf215546Sopenharmony_ci if (is_sindex_indirect) { 3201bf215546Sopenharmony_ci swiz_chan_index = LLVMBuildExtractElement(builder, 3202bf215546Sopenharmony_ci swizzle_index, idx, ""); 3203bf215546Sopenharmony_ci } 3204bf215546Sopenharmony_ci 3205bf215546Sopenharmony_ci indices[0] = vert_chan_index; 3206bf215546Sopenharmony_ci indices[1] = attr_chan_index; 3207bf215546Sopenharmony_ci indices[2] = swiz_chan_index; 3208bf215546Sopenharmony_ci 3209bf215546Sopenharmony_ci channel_vec = LLVMBuildGEP(builder, tcs->output, indices, 3, ""); 3210bf215546Sopenharmony_ci channel_vec = LLVMBuildLoad(builder, channel_vec, ""); 3211bf215546Sopenharmony_ci 3212bf215546Sopenharmony_ci res = LLVMBuildInsertElement(builder, res, channel_vec, idx, ""); 3213bf215546Sopenharmony_ci } 3214bf215546Sopenharmony_ci } else { 3215bf215546Sopenharmony_ci indices[0] = vertex_index ? vertex_index : lp_build_const_int32(gallivm, 0); 3216bf215546Sopenharmony_ci indices[1] = attrib_index; 3217bf215546Sopenharmony_ci indices[2] = swizzle_index; 3218bf215546Sopenharmony_ci 3219bf215546Sopenharmony_ci res = LLVMBuildGEP(builder, tcs->output, indices, 3, ""); 3220bf215546Sopenharmony_ci res = LLVMBuildLoad(builder, res, ""); 3221bf215546Sopenharmony_ci res = lp_build_broadcast_scalar(bld, res); 3222bf215546Sopenharmony_ci } 3223bf215546Sopenharmony_ci return res; 3224bf215546Sopenharmony_ci} 3225bf215546Sopenharmony_ci 3226bf215546Sopenharmony_cistatic void 3227bf215546Sopenharmony_cidraw_tcs_llvm_emit_store_output(const struct lp_build_tcs_iface *tes_iface, 3228bf215546Sopenharmony_ci struct lp_build_context *bld, 3229bf215546Sopenharmony_ci unsigned name, 3230bf215546Sopenharmony_ci boolean is_vindex_indirect, 3231bf215546Sopenharmony_ci LLVMValueRef vertex_index, 3232bf215546Sopenharmony_ci boolean is_aindex_indirect, 3233bf215546Sopenharmony_ci LLVMValueRef attrib_index, 3234bf215546Sopenharmony_ci boolean is_sindex_indirect, 3235bf215546Sopenharmony_ci LLVMValueRef swizzle_index, 3236bf215546Sopenharmony_ci LLVMValueRef value, 3237bf215546Sopenharmony_ci LLVMValueRef mask_vec) 3238bf215546Sopenharmony_ci{ 3239bf215546Sopenharmony_ci const struct draw_tcs_llvm_iface *tcs = draw_tcs_llvm_iface(tes_iface); 3240bf215546Sopenharmony_ci struct gallivm_state *gallivm = bld->gallivm; 3241bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 3242bf215546Sopenharmony_ci LLVMValueRef indices[3]; 3243bf215546Sopenharmony_ci LLVMValueRef res; 3244bf215546Sopenharmony_ci struct lp_type type = bld->type; 3245bf215546Sopenharmony_ci 3246bf215546Sopenharmony_ci if (is_vindex_indirect || is_aindex_indirect || is_sindex_indirect) { 3247bf215546Sopenharmony_ci int i; 3248bf215546Sopenharmony_ci 3249bf215546Sopenharmony_ci for (i = 0; i < type.length; ++i) { 3250bf215546Sopenharmony_ci LLVMValueRef idx = lp_build_const_int32(gallivm, i); 3251bf215546Sopenharmony_ci LLVMValueRef vert_chan_index = vertex_index ? vertex_index : lp_build_const_int32(gallivm, 0); 3252bf215546Sopenharmony_ci LLVMValueRef attr_chan_index = attrib_index; 3253bf215546Sopenharmony_ci LLVMValueRef swiz_chan_index = swizzle_index; 3254bf215546Sopenharmony_ci LLVMValueRef channel_vec; 3255bf215546Sopenharmony_ci 3256bf215546Sopenharmony_ci if (is_vindex_indirect) { 3257bf215546Sopenharmony_ci vert_chan_index = LLVMBuildExtractElement(builder, 3258bf215546Sopenharmony_ci vertex_index, idx, ""); 3259bf215546Sopenharmony_ci } 3260bf215546Sopenharmony_ci if (is_aindex_indirect) { 3261bf215546Sopenharmony_ci attr_chan_index = LLVMBuildExtractElement(builder, 3262bf215546Sopenharmony_ci attrib_index, idx, ""); 3263bf215546Sopenharmony_ci } 3264bf215546Sopenharmony_ci 3265bf215546Sopenharmony_ci if (is_sindex_indirect) { 3266bf215546Sopenharmony_ci swiz_chan_index = LLVMBuildExtractElement(builder, 3267bf215546Sopenharmony_ci swizzle_index, idx, ""); 3268bf215546Sopenharmony_ci } 3269bf215546Sopenharmony_ci 3270bf215546Sopenharmony_ci indices[0] = vert_chan_index; 3271bf215546Sopenharmony_ci indices[1] = attr_chan_index; 3272bf215546Sopenharmony_ci indices[2] = swiz_chan_index; 3273bf215546Sopenharmony_ci 3274bf215546Sopenharmony_ci channel_vec = LLVMBuildGEP(builder, tcs->output, indices, 3, ""); 3275bf215546Sopenharmony_ci 3276bf215546Sopenharmony_ci res = LLVMBuildExtractElement(builder, value, idx, ""); 3277bf215546Sopenharmony_ci 3278bf215546Sopenharmony_ci struct lp_build_if_state ifthen; 3279bf215546Sopenharmony_ci LLVMValueRef cond = LLVMBuildICmp(gallivm->builder, LLVMIntNE, mask_vec, lp_build_const_int_vec(gallivm, bld->type, 0), ""); 3280bf215546Sopenharmony_ci cond = LLVMBuildExtractElement(gallivm->builder, cond, idx, ""); 3281bf215546Sopenharmony_ci lp_build_if(&ifthen, gallivm, cond); 3282bf215546Sopenharmony_ci LLVMBuildStore(builder, res, channel_vec); 3283bf215546Sopenharmony_ci lp_build_endif(&ifthen); 3284bf215546Sopenharmony_ci } 3285bf215546Sopenharmony_ci } else { 3286bf215546Sopenharmony_ci indices[0] = vertex_index ? vertex_index : lp_build_const_int32(gallivm, 0); 3287bf215546Sopenharmony_ci indices[1] = attrib_index; 3288bf215546Sopenharmony_ci indices[2] = swizzle_index; 3289bf215546Sopenharmony_ci 3290bf215546Sopenharmony_ci res = LLVMBuildGEP(builder, tcs->output, indices, 3, ""); 3291bf215546Sopenharmony_ci for (unsigned i = 0; i < type.length; ++i) { 3292bf215546Sopenharmony_ci LLVMValueRef idx = lp_build_const_int32(gallivm, i); 3293bf215546Sopenharmony_ci LLVMValueRef val = LLVMBuildExtractElement(builder, value, idx, ""); 3294bf215546Sopenharmony_ci 3295bf215546Sopenharmony_ci struct lp_build_if_state ifthen; 3296bf215546Sopenharmony_ci LLVMValueRef cond = LLVMBuildICmp(gallivm->builder, LLVMIntNE, mask_vec, lp_build_const_int_vec(gallivm, bld->type, 0), ""); 3297bf215546Sopenharmony_ci cond = LLVMBuildExtractElement(gallivm->builder, cond, idx, ""); 3298bf215546Sopenharmony_ci lp_build_if(&ifthen, gallivm, cond); 3299bf215546Sopenharmony_ci LLVMBuildStore(builder, val, res); 3300bf215546Sopenharmony_ci lp_build_endif(&ifthen); 3301bf215546Sopenharmony_ci } 3302bf215546Sopenharmony_ci } 3303bf215546Sopenharmony_ci} 3304bf215546Sopenharmony_ci 3305bf215546Sopenharmony_ci 3306bf215546Sopenharmony_cistatic LLVMValueRef 3307bf215546Sopenharmony_cigenerate_tcs_mask_value(struct draw_tcs_llvm_variant *variant, 3308bf215546Sopenharmony_ci struct lp_type tcs_type, LLVMValueRef limit, LLVMValueRef loop_counter) 3309bf215546Sopenharmony_ci{ 3310bf215546Sopenharmony_ci struct gallivm_state *gallivm = variant->gallivm; 3311bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 3312bf215546Sopenharmony_ci struct lp_type mask_type = lp_int_type(tcs_type); 3313bf215546Sopenharmony_ci LLVMValueRef num_vecs; 3314bf215546Sopenharmony_ci LLVMValueRef mask_val = lp_build_const_vec(gallivm, mask_type, 0); 3315bf215546Sopenharmony_ci unsigned i; 3316bf215546Sopenharmony_ci 3317bf215546Sopenharmony_ci num_vecs = lp_build_broadcast(gallivm, lp_build_vec_type(gallivm, mask_type), limit); 3318bf215546Sopenharmony_ci for (i = 0; i < tcs_type.length; i++) { 3319bf215546Sopenharmony_ci LLVMValueRef idx = lp_build_const_int32(gallivm, i); 3320bf215546Sopenharmony_ci mask_val = LLVMBuildInsertElement(builder, mask_val, LLVMBuildAdd(builder, loop_counter, idx, ""), idx, ""); 3321bf215546Sopenharmony_ci } 3322bf215546Sopenharmony_ci mask_val = lp_build_compare(gallivm, mask_type, 3323bf215546Sopenharmony_ci PIPE_FUNC_GREATER, num_vecs, mask_val); 3324bf215546Sopenharmony_ci 3325bf215546Sopenharmony_ci return mask_val; 3326bf215546Sopenharmony_ci} 3327bf215546Sopenharmony_ci 3328bf215546Sopenharmony_cistatic void 3329bf215546Sopenharmony_cidraw_tcs_llvm_generate(struct draw_llvm *llvm, 3330bf215546Sopenharmony_ci struct draw_tcs_llvm_variant *variant) 3331bf215546Sopenharmony_ci{ 3332bf215546Sopenharmony_ci struct gallivm_state *gallivm = variant->gallivm; 3333bf215546Sopenharmony_ci LLVMContextRef context = gallivm->context; 3334bf215546Sopenharmony_ci LLVMTypeRef int32_type = LLVMInt32TypeInContext(context); 3335bf215546Sopenharmony_ci LLVMTypeRef arg_types[7]; 3336bf215546Sopenharmony_ci LLVMTypeRef func_type, coro_func_type; 3337bf215546Sopenharmony_ci LLVMValueRef variant_func, variant_coro; 3338bf215546Sopenharmony_ci LLVMValueRef context_ptr; 3339bf215546Sopenharmony_ci LLVMValueRef view_index; 3340bf215546Sopenharmony_ci LLVMValueRef input_array, output_array, prim_id, patch_vertices_in; 3341bf215546Sopenharmony_ci LLVMValueRef mask_val; 3342bf215546Sopenharmony_ci LLVMBasicBlockRef block; 3343bf215546Sopenharmony_ci LLVMBuilderRef builder; 3344bf215546Sopenharmony_ci struct lp_build_context bld, bldvec; 3345bf215546Sopenharmony_ci struct lp_build_sampler_soa *sampler = 0; 3346bf215546Sopenharmony_ci struct lp_build_image_soa *image = NULL; 3347bf215546Sopenharmony_ci struct lp_bld_tgsi_system_values system_values; 3348bf215546Sopenharmony_ci char func_name[64], func_name_coro[64]; 3349bf215546Sopenharmony_ci unsigned i; 3350bf215546Sopenharmony_ci struct draw_tcs_llvm_iface tcs_iface; 3351bf215546Sopenharmony_ci struct lp_build_mask_context mask; 3352bf215546Sopenharmony_ci LLVMValueRef consts_ptr, num_consts_ptr; 3353bf215546Sopenharmony_ci LLVMValueRef ssbos_ptr, num_ssbos_ptr; 3354bf215546Sopenharmony_ci struct lp_type tcs_type; 3355bf215546Sopenharmony_ci unsigned vector_length = variant->shader->base.vector_length; 3356bf215546Sopenharmony_ci 3357bf215546Sopenharmony_ci memset(&system_values, 0, sizeof(system_values)); 3358bf215546Sopenharmony_ci 3359bf215546Sopenharmony_ci snprintf(func_name, sizeof(func_name), "draw_llvm_tcs_variant"); 3360bf215546Sopenharmony_ci 3361bf215546Sopenharmony_ci snprintf(func_name_coro, sizeof(func_name_coro), "draw_llvm_tcs_coro_variant"); 3362bf215546Sopenharmony_ci 3363bf215546Sopenharmony_ci arg_types[0] = get_tcs_context_ptr_type(variant); /* context */ 3364bf215546Sopenharmony_ci arg_types[1] = variant->input_array_type; /* input */ 3365bf215546Sopenharmony_ci arg_types[2] = variant->output_array_type; 3366bf215546Sopenharmony_ci arg_types[3] = int32_type; 3367bf215546Sopenharmony_ci arg_types[4] = int32_type; 3368bf215546Sopenharmony_ci arg_types[5] = int32_type; 3369bf215546Sopenharmony_ci arg_types[6] = int32_type; /* coroutine only */ 3370bf215546Sopenharmony_ci 3371bf215546Sopenharmony_ci func_type = LLVMFunctionType(int32_type, arg_types, ARRAY_SIZE(arg_types) - 1, 0); 3372bf215546Sopenharmony_ci 3373bf215546Sopenharmony_ci coro_func_type = LLVMFunctionType(LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0), arg_types, ARRAY_SIZE(arg_types), 0); 3374bf215546Sopenharmony_ci 3375bf215546Sopenharmony_ci variant_func = LLVMAddFunction(gallivm->module, func_name, func_type); 3376bf215546Sopenharmony_ci 3377bf215546Sopenharmony_ci variant_coro = LLVMAddFunction(gallivm->module, func_name_coro, coro_func_type); 3378bf215546Sopenharmony_ci 3379bf215546Sopenharmony_ci variant->function = variant_func; 3380bf215546Sopenharmony_ci LLVMSetFunctionCallConv(variant_func, LLVMCCallConv); 3381bf215546Sopenharmony_ci 3382bf215546Sopenharmony_ci LLVMSetFunctionCallConv(variant_coro, LLVMCCallConv); 3383bf215546Sopenharmony_ci 3384bf215546Sopenharmony_ci lp_build_coro_add_presplit(variant_coro); 3385bf215546Sopenharmony_ci 3386bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(arg_types); ++i) { 3387bf215546Sopenharmony_ci if (LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind) { 3388bf215546Sopenharmony_ci lp_add_function_attr(variant_coro, i + 1, LP_FUNC_ATTR_NOALIAS); 3389bf215546Sopenharmony_ci lp_add_function_attr(variant_func, i + 1, LP_FUNC_ATTR_NOALIAS); 3390bf215546Sopenharmony_ci } 3391bf215546Sopenharmony_ci } 3392bf215546Sopenharmony_ci 3393bf215546Sopenharmony_ci if (gallivm->cache && gallivm->cache->data_size) 3394bf215546Sopenharmony_ci return; 3395bf215546Sopenharmony_ci context_ptr = LLVMGetParam(variant_func, 0); 3396bf215546Sopenharmony_ci input_array = LLVMGetParam(variant_func, 1); 3397bf215546Sopenharmony_ci output_array = LLVMGetParam(variant_func, 2); 3398bf215546Sopenharmony_ci prim_id = LLVMGetParam(variant_func, 3); 3399bf215546Sopenharmony_ci patch_vertices_in = LLVMGetParam(variant_func, 4); 3400bf215546Sopenharmony_ci view_index = LLVMGetParam(variant_func, 5); 3401bf215546Sopenharmony_ci 3402bf215546Sopenharmony_ci lp_build_name(context_ptr, "context"); 3403bf215546Sopenharmony_ci lp_build_name(input_array, "input"); 3404bf215546Sopenharmony_ci lp_build_name(output_array, "output"); 3405bf215546Sopenharmony_ci lp_build_name(prim_id, "prim_id"); 3406bf215546Sopenharmony_ci lp_build_name(patch_vertices_in, "patch_vertices_in"); 3407bf215546Sopenharmony_ci lp_build_name(view_index, "view_index"); 3408bf215546Sopenharmony_ci 3409bf215546Sopenharmony_ci block = LLVMAppendBasicBlockInContext(gallivm->context, variant_func, "entry"); 3410bf215546Sopenharmony_ci builder = gallivm->builder; 3411bf215546Sopenharmony_ci LLVMPositionBuilderAtEnd(builder, block); 3412bf215546Sopenharmony_ci 3413bf215546Sopenharmony_ci lp_build_context_init(&bld, gallivm, lp_type_int(32)); 3414bf215546Sopenharmony_ci 3415bf215546Sopenharmony_ci memset(&tcs_type, 0, sizeof tcs_type); 3416bf215546Sopenharmony_ci tcs_type.floating = TRUE; /* floating point values */ 3417bf215546Sopenharmony_ci tcs_type.sign = TRUE; /* values are signed */ 3418bf215546Sopenharmony_ci tcs_type.norm = FALSE; /* values are not limited to [0,1] or [-1,1] */ 3419bf215546Sopenharmony_ci tcs_type.width = 32; /* 32-bit float */ 3420bf215546Sopenharmony_ci tcs_type.length = vector_length; 3421bf215546Sopenharmony_ci 3422bf215546Sopenharmony_ci lp_build_context_init(&bldvec, variant->gallivm, lp_int_type(tcs_type)); 3423bf215546Sopenharmony_ci 3424bf215546Sopenharmony_ci LLVMValueRef count = lp_build_const_int32(gallivm, variant->shader->base.vertices_out); 3425bf215546Sopenharmony_ci LLVMValueRef step = lp_build_const_int32(gallivm, vector_length); 3426bf215546Sopenharmony_ci 3427bf215546Sopenharmony_ci struct lp_build_loop_state loop_state[2]; 3428bf215546Sopenharmony_ci LLVMValueRef num_inner_loop; 3429bf215546Sopenharmony_ci unsigned count_align = util_align_npot(variant->shader->base.vertices_out, tcs_type.length); 3430bf215546Sopenharmony_ci num_inner_loop = lp_build_const_int32(gallivm, count_align / tcs_type.length); 3431bf215546Sopenharmony_ci LLVMTypeRef hdl_ptr_type = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); 3432bf215546Sopenharmony_ci LLVMValueRef coro_hdls = LLVMBuildArrayAlloca(gallivm->builder, hdl_ptr_type, num_inner_loop, "coro_hdls"); 3433bf215546Sopenharmony_ci unsigned end_coroutine = INT_MAX; 3434bf215546Sopenharmony_ci lp_build_loop_begin(&loop_state[1], gallivm, 3435bf215546Sopenharmony_ci lp_build_const_int32(gallivm, 0)); /* coroutine reentry loop */ 3436bf215546Sopenharmony_ci lp_build_loop_begin(&loop_state[0], gallivm, 3437bf215546Sopenharmony_ci lp_build_const_int32(gallivm, 0)); /* inner loop */ 3438bf215546Sopenharmony_ci { 3439bf215546Sopenharmony_ci LLVMValueRef args[7]; 3440bf215546Sopenharmony_ci args[0] = context_ptr; 3441bf215546Sopenharmony_ci args[1] = input_array; 3442bf215546Sopenharmony_ci args[2] = output_array; 3443bf215546Sopenharmony_ci args[3] = prim_id; 3444bf215546Sopenharmony_ci args[4] = patch_vertices_in; 3445bf215546Sopenharmony_ci args[5] = view_index; 3446bf215546Sopenharmony_ci args[6] = loop_state[0].counter; 3447bf215546Sopenharmony_ci LLVMValueRef coro_entry = LLVMBuildGEP2(builder, hdl_ptr_type, coro_hdls, &loop_state[0].counter, 1, ""); 3448bf215546Sopenharmony_ci LLVMValueRef coro_hdl = LLVMBuildLoad2(builder, hdl_ptr_type, coro_entry, "coro_hdl"); 3449bf215546Sopenharmony_ci 3450bf215546Sopenharmony_ci struct lp_build_if_state ifstate; 3451bf215546Sopenharmony_ci LLVMValueRef cmp = LLVMBuildICmp(builder, LLVMIntEQ, loop_state[1].counter, 3452bf215546Sopenharmony_ci lp_build_const_int32(gallivm, 0), ""); 3453bf215546Sopenharmony_ci /* first time here - call the coroutine function entry point */ 3454bf215546Sopenharmony_ci lp_build_if(&ifstate, gallivm, cmp); 3455bf215546Sopenharmony_ci LLVMValueRef coro_ret = LLVMBuildCall2(builder, coro_func_type, variant_coro, args, 7, ""); 3456bf215546Sopenharmony_ci LLVMBuildStore(builder, coro_ret, coro_entry); 3457bf215546Sopenharmony_ci lp_build_else(&ifstate); 3458bf215546Sopenharmony_ci /* subsequent calls for this invocation - check if done. */ 3459bf215546Sopenharmony_ci LLVMValueRef coro_done = lp_build_coro_done(gallivm, coro_hdl); 3460bf215546Sopenharmony_ci struct lp_build_if_state ifstate2; 3461bf215546Sopenharmony_ci lp_build_if(&ifstate2, gallivm, coro_done); 3462bf215546Sopenharmony_ci /* if done destroy and force loop exit */ 3463bf215546Sopenharmony_ci lp_build_coro_destroy(gallivm, coro_hdl); 3464bf215546Sopenharmony_ci lp_build_loop_force_set_counter(&loop_state[1], lp_build_const_int32(gallivm, end_coroutine - 1)); 3465bf215546Sopenharmony_ci lp_build_else(&ifstate2); 3466bf215546Sopenharmony_ci /* otherwise resume the coroutine */ 3467bf215546Sopenharmony_ci lp_build_coro_resume(gallivm, coro_hdl); 3468bf215546Sopenharmony_ci lp_build_endif(&ifstate2); 3469bf215546Sopenharmony_ci lp_build_endif(&ifstate); 3470bf215546Sopenharmony_ci lp_build_loop_force_reload_counter(&loop_state[1]); 3471bf215546Sopenharmony_ci } 3472bf215546Sopenharmony_ci lp_build_loop_end_cond(&loop_state[0], 3473bf215546Sopenharmony_ci num_inner_loop, 3474bf215546Sopenharmony_ci NULL, LLVMIntUGE); 3475bf215546Sopenharmony_ci lp_build_loop_end_cond(&loop_state[1], 3476bf215546Sopenharmony_ci lp_build_const_int32(gallivm, end_coroutine), 3477bf215546Sopenharmony_ci NULL, LLVMIntEQ); 3478bf215546Sopenharmony_ci LLVMBuildRet(builder, lp_build_zero(gallivm, lp_type_uint(32))); 3479bf215546Sopenharmony_ci 3480bf215546Sopenharmony_ci block = LLVMAppendBasicBlockInContext(gallivm->context, variant_coro, "entry"); 3481bf215546Sopenharmony_ci LLVMPositionBuilderAtEnd(builder, block); 3482bf215546Sopenharmony_ci 3483bf215546Sopenharmony_ci context_ptr = LLVMGetParam(variant_coro, 0); 3484bf215546Sopenharmony_ci input_array = LLVMGetParam(variant_coro, 1); 3485bf215546Sopenharmony_ci output_array = LLVMGetParam(variant_coro, 2); 3486bf215546Sopenharmony_ci prim_id = LLVMGetParam(variant_coro, 3); 3487bf215546Sopenharmony_ci patch_vertices_in = LLVMGetParam(variant_coro, 4); 3488bf215546Sopenharmony_ci view_index = LLVMGetParam(variant_coro, 5); 3489bf215546Sopenharmony_ci 3490bf215546Sopenharmony_ci consts_ptr = draw_tcs_jit_context_constants(variant, context_ptr); 3491bf215546Sopenharmony_ci num_consts_ptr = 3492bf215546Sopenharmony_ci draw_tcs_jit_context_num_constants(variant, context_ptr); 3493bf215546Sopenharmony_ci 3494bf215546Sopenharmony_ci ssbos_ptr = draw_tcs_jit_context_ssbos(variant, context_ptr); 3495bf215546Sopenharmony_ci num_ssbos_ptr = 3496bf215546Sopenharmony_ci draw_tcs_jit_context_num_ssbos(variant, context_ptr); 3497bf215546Sopenharmony_ci sampler = draw_llvm_sampler_soa_create(variant->key.samplers, 3498bf215546Sopenharmony_ci MAX2(variant->key.nr_samplers, 3499bf215546Sopenharmony_ci variant->key.nr_sampler_views)); 3500bf215546Sopenharmony_ci image = draw_llvm_image_soa_create(draw_tcs_llvm_variant_key_images(&variant->key), 3501bf215546Sopenharmony_ci variant->key.nr_images); 3502bf215546Sopenharmony_ci 3503bf215546Sopenharmony_ci LLVMValueRef counter = LLVMGetParam(variant_coro, 6); 3504bf215546Sopenharmony_ci LLVMValueRef invocvec = LLVMGetUndef(LLVMVectorType(int32_type, vector_length)); 3505bf215546Sopenharmony_ci for (i = 0; i < vector_length; i++) { 3506bf215546Sopenharmony_ci LLVMValueRef loop_iter = lp_build_const_int32(gallivm, i); 3507bf215546Sopenharmony_ci LLVMValueRef idx = LLVMBuildAdd(builder, LLVMBuildMul(builder, counter, step, ""), loop_iter, ""); 3508bf215546Sopenharmony_ci invocvec = LLVMBuildInsertElement(builder, invocvec, idx, loop_iter, ""); 3509bf215546Sopenharmony_ci } 3510bf215546Sopenharmony_ci 3511bf215546Sopenharmony_ci system_values.invocation_id = invocvec; 3512bf215546Sopenharmony_ci system_values.prim_id = lp_build_broadcast_scalar(&bldvec, prim_id); 3513bf215546Sopenharmony_ci system_values.view_index = view_index; 3514bf215546Sopenharmony_ci system_values.vertices_in = lp_build_broadcast_scalar(&bldvec, patch_vertices_in); 3515bf215546Sopenharmony_ci tcs_iface.input = input_array; 3516bf215546Sopenharmony_ci tcs_iface.output = output_array; 3517bf215546Sopenharmony_ci tcs_iface.base.emit_fetch_input = draw_tcs_llvm_emit_fetch_input; 3518bf215546Sopenharmony_ci tcs_iface.base.emit_fetch_output = draw_tcs_llvm_emit_fetch_output; 3519bf215546Sopenharmony_ci tcs_iface.base.emit_store_output = draw_tcs_llvm_emit_store_output; 3520bf215546Sopenharmony_ci 3521bf215546Sopenharmony_ci 3522bf215546Sopenharmony_ci { 3523bf215546Sopenharmony_ci LLVMValueRef coro_id = lp_build_coro_id(gallivm); 3524bf215546Sopenharmony_ci LLVMValueRef coro_hdl = lp_build_coro_begin_alloc_mem(gallivm, coro_id); 3525bf215546Sopenharmony_ci 3526bf215546Sopenharmony_ci mask_val = generate_tcs_mask_value(variant, tcs_type, count, LLVMBuildMul(builder, counter, step, "")); 3527bf215546Sopenharmony_ci lp_build_mask_begin(&mask, gallivm, tcs_type, mask_val); 3528bf215546Sopenharmony_ci 3529bf215546Sopenharmony_ci struct lp_build_coro_suspend_info coro_info; 3530bf215546Sopenharmony_ci 3531bf215546Sopenharmony_ci LLVMBasicBlockRef sus_block = LLVMAppendBasicBlockInContext(gallivm->context, variant_coro, "suspend"); 3532bf215546Sopenharmony_ci LLVMBasicBlockRef clean_block = LLVMAppendBasicBlockInContext(gallivm->context, variant_coro, "cleanup"); 3533bf215546Sopenharmony_ci 3534bf215546Sopenharmony_ci coro_info.suspend = sus_block; 3535bf215546Sopenharmony_ci coro_info.cleanup = clean_block; 3536bf215546Sopenharmony_ci 3537bf215546Sopenharmony_ci struct lp_build_tgsi_params params; 3538bf215546Sopenharmony_ci memset(¶ms, 0, sizeof(params)); 3539bf215546Sopenharmony_ci 3540bf215546Sopenharmony_ci params.type = tcs_type; 3541bf215546Sopenharmony_ci params.mask = &mask; 3542bf215546Sopenharmony_ci params.consts_ptr = consts_ptr; 3543bf215546Sopenharmony_ci params.const_sizes_ptr = num_consts_ptr; 3544bf215546Sopenharmony_ci params.system_values = &system_values; 3545bf215546Sopenharmony_ci params.context_ptr = context_ptr; 3546bf215546Sopenharmony_ci params.sampler = sampler; 3547bf215546Sopenharmony_ci params.info = &llvm->draw->tcs.tess_ctrl_shader->info; 3548bf215546Sopenharmony_ci params.ssbo_ptr = ssbos_ptr; 3549bf215546Sopenharmony_ci params.ssbo_sizes_ptr = num_ssbos_ptr; 3550bf215546Sopenharmony_ci params.image = image; 3551bf215546Sopenharmony_ci params.coro = &coro_info; 3552bf215546Sopenharmony_ci params.tcs_iface = &tcs_iface.base; 3553bf215546Sopenharmony_ci params.aniso_filter_table = draw_tcs_jit_context_aniso_filter_table(variant, context_ptr); 3554bf215546Sopenharmony_ci 3555bf215546Sopenharmony_ci lp_build_nir_soa(variant->gallivm, 3556bf215546Sopenharmony_ci llvm->draw->tcs.tess_ctrl_shader->state.ir.nir, 3557bf215546Sopenharmony_ci ¶ms, NULL); 3558bf215546Sopenharmony_ci 3559bf215546Sopenharmony_ci lp_build_mask_end(&mask); 3560bf215546Sopenharmony_ci 3561bf215546Sopenharmony_ci lp_build_coro_suspend_switch(gallivm, &coro_info, NULL, true); 3562bf215546Sopenharmony_ci LLVMPositionBuilderAtEnd(builder, clean_block); 3563bf215546Sopenharmony_ci 3564bf215546Sopenharmony_ci lp_build_coro_free_mem(gallivm, coro_id, coro_hdl); 3565bf215546Sopenharmony_ci 3566bf215546Sopenharmony_ci LLVMBuildBr(builder, sus_block); 3567bf215546Sopenharmony_ci LLVMPositionBuilderAtEnd(builder, sus_block); 3568bf215546Sopenharmony_ci 3569bf215546Sopenharmony_ci lp_build_coro_end(gallivm, coro_hdl); 3570bf215546Sopenharmony_ci LLVMBuildRet(builder, coro_hdl); 3571bf215546Sopenharmony_ci } 3572bf215546Sopenharmony_ci 3573bf215546Sopenharmony_ci sampler->destroy(sampler); 3574bf215546Sopenharmony_ci image->destroy(image); 3575bf215546Sopenharmony_ci gallivm_verify_function(gallivm, variant_func); 3576bf215546Sopenharmony_ci gallivm_verify_function(gallivm, variant_coro); 3577bf215546Sopenharmony_ci} 3578bf215546Sopenharmony_ci 3579bf215546Sopenharmony_cistruct draw_tcs_llvm_variant * 3580bf215546Sopenharmony_cidraw_tcs_llvm_create_variant(struct draw_llvm *llvm, 3581bf215546Sopenharmony_ci unsigned num_outputs, 3582bf215546Sopenharmony_ci const struct draw_tcs_llvm_variant_key *key) 3583bf215546Sopenharmony_ci{ 3584bf215546Sopenharmony_ci struct draw_tcs_llvm_variant *variant; 3585bf215546Sopenharmony_ci struct llvm_tess_ctrl_shader *shader = llvm_tess_ctrl_shader(llvm->draw->tcs.tess_ctrl_shader); 3586bf215546Sopenharmony_ci char module_name[64]; 3587bf215546Sopenharmony_ci unsigned char ir_sha1_cache_key[20]; 3588bf215546Sopenharmony_ci struct lp_cached_code cached = { 0 }; 3589bf215546Sopenharmony_ci bool needs_caching = false; 3590bf215546Sopenharmony_ci 3591bf215546Sopenharmony_ci variant = MALLOC(sizeof *variant + 3592bf215546Sopenharmony_ci shader->variant_key_size - sizeof variant->key); 3593bf215546Sopenharmony_ci if (!variant) 3594bf215546Sopenharmony_ci return NULL; 3595bf215546Sopenharmony_ci 3596bf215546Sopenharmony_ci variant->llvm = llvm; 3597bf215546Sopenharmony_ci variant->shader = shader; 3598bf215546Sopenharmony_ci 3599bf215546Sopenharmony_ci snprintf(module_name, sizeof(module_name), "draw_llvm_tcs_variant%u", 3600bf215546Sopenharmony_ci variant->shader->variants_cached); 3601bf215546Sopenharmony_ci 3602bf215546Sopenharmony_ci memcpy(&variant->key, key, shader->variant_key_size); 3603bf215546Sopenharmony_ci 3604bf215546Sopenharmony_ci if (shader->base.state.ir.nir && llvm->draw->disk_cache_cookie) { 3605bf215546Sopenharmony_ci draw_get_ir_cache_key(shader->base.state.ir.nir, 3606bf215546Sopenharmony_ci key, 3607bf215546Sopenharmony_ci shader->variant_key_size, 3608bf215546Sopenharmony_ci num_outputs, 3609bf215546Sopenharmony_ci ir_sha1_cache_key); 3610bf215546Sopenharmony_ci 3611bf215546Sopenharmony_ci llvm->draw->disk_cache_find_shader(llvm->draw->disk_cache_cookie, 3612bf215546Sopenharmony_ci &cached, 3613bf215546Sopenharmony_ci ir_sha1_cache_key); 3614bf215546Sopenharmony_ci if (!cached.data_size) 3615bf215546Sopenharmony_ci needs_caching = true; 3616bf215546Sopenharmony_ci } 3617bf215546Sopenharmony_ci 3618bf215546Sopenharmony_ci variant->gallivm = gallivm_create(module_name, llvm->context, &cached); 3619bf215546Sopenharmony_ci 3620bf215546Sopenharmony_ci create_tcs_jit_types(variant); 3621bf215546Sopenharmony_ci 3622bf215546Sopenharmony_ci if (gallivm_debug & (GALLIVM_DEBUG_TGSI | GALLIVM_DEBUG_IR)) { 3623bf215546Sopenharmony_ci nir_print_shader(llvm->draw->tcs.tess_ctrl_shader->state.ir.nir, stderr); 3624bf215546Sopenharmony_ci draw_tcs_llvm_dump_variant_key(&variant->key); 3625bf215546Sopenharmony_ci } 3626bf215546Sopenharmony_ci 3627bf215546Sopenharmony_ci draw_tcs_llvm_generate(llvm, variant); 3628bf215546Sopenharmony_ci 3629bf215546Sopenharmony_ci gallivm_compile_module(variant->gallivm); 3630bf215546Sopenharmony_ci 3631bf215546Sopenharmony_ci variant->jit_func = (draw_tcs_jit_func) 3632bf215546Sopenharmony_ci gallivm_jit_function(variant->gallivm, variant->function); 3633bf215546Sopenharmony_ci 3634bf215546Sopenharmony_ci if (needs_caching) 3635bf215546Sopenharmony_ci llvm->draw->disk_cache_insert_shader(llvm->draw->disk_cache_cookie, 3636bf215546Sopenharmony_ci &cached, 3637bf215546Sopenharmony_ci ir_sha1_cache_key); 3638bf215546Sopenharmony_ci gallivm_free_ir(variant->gallivm); 3639bf215546Sopenharmony_ci 3640bf215546Sopenharmony_ci variant->list_item_global.base = variant; 3641bf215546Sopenharmony_ci variant->list_item_local.base = variant; 3642bf215546Sopenharmony_ci /*variant->no = */shader->variants_created++; 3643bf215546Sopenharmony_ci variant->list_item_global.base = variant; 3644bf215546Sopenharmony_ci 3645bf215546Sopenharmony_ci return variant; 3646bf215546Sopenharmony_ci} 3647bf215546Sopenharmony_ci 3648bf215546Sopenharmony_civoid 3649bf215546Sopenharmony_cidraw_tcs_llvm_destroy_variant(struct draw_tcs_llvm_variant *variant) 3650bf215546Sopenharmony_ci{ 3651bf215546Sopenharmony_ci struct draw_llvm *llvm = variant->llvm; 3652bf215546Sopenharmony_ci 3653bf215546Sopenharmony_ci if (gallivm_debug & (GALLIVM_DEBUG_TGSI | GALLIVM_DEBUG_IR)) { 3654bf215546Sopenharmony_ci debug_printf("Deleting TCS variant: %u tcs variants,\t%u total variants\n", 3655bf215546Sopenharmony_ci variant->shader->variants_cached, llvm->nr_tcs_variants); 3656bf215546Sopenharmony_ci } 3657bf215546Sopenharmony_ci 3658bf215546Sopenharmony_ci gallivm_destroy(variant->gallivm); 3659bf215546Sopenharmony_ci 3660bf215546Sopenharmony_ci list_del(&variant->list_item_local.list); 3661bf215546Sopenharmony_ci variant->shader->variants_cached--; 3662bf215546Sopenharmony_ci list_del(&variant->list_item_global.list); 3663bf215546Sopenharmony_ci llvm->nr_tcs_variants--; 3664bf215546Sopenharmony_ci FREE(variant); 3665bf215546Sopenharmony_ci} 3666bf215546Sopenharmony_ci 3667bf215546Sopenharmony_cistruct draw_tcs_llvm_variant_key * 3668bf215546Sopenharmony_cidraw_tcs_llvm_make_variant_key(struct draw_llvm *llvm, char *store) 3669bf215546Sopenharmony_ci{ 3670bf215546Sopenharmony_ci unsigned i; 3671bf215546Sopenharmony_ci struct draw_tcs_llvm_variant_key *key; 3672bf215546Sopenharmony_ci struct draw_sampler_static_state *draw_sampler; 3673bf215546Sopenharmony_ci struct draw_image_static_state *draw_image; 3674bf215546Sopenharmony_ci 3675bf215546Sopenharmony_ci key = (struct draw_tcs_llvm_variant_key *)store; 3676bf215546Sopenharmony_ci 3677bf215546Sopenharmony_ci memset(key, 0, offsetof(struct draw_tcs_llvm_variant_key, samplers[0])); 3678bf215546Sopenharmony_ci 3679bf215546Sopenharmony_ci /* All variants of this shader will have the same value for 3680bf215546Sopenharmony_ci * nr_samplers. Not yet trying to compact away holes in the 3681bf215546Sopenharmony_ci * sampler array. 3682bf215546Sopenharmony_ci */ 3683bf215546Sopenharmony_ci key->nr_samplers = llvm->draw->tcs.tess_ctrl_shader->info.file_max[TGSI_FILE_SAMPLER] + 1; 3684bf215546Sopenharmony_ci if (llvm->draw->tcs.tess_ctrl_shader->info.file_max[TGSI_FILE_SAMPLER_VIEW] != -1) { 3685bf215546Sopenharmony_ci key->nr_sampler_views = 3686bf215546Sopenharmony_ci llvm->draw->tcs.tess_ctrl_shader->info.file_max[TGSI_FILE_SAMPLER_VIEW] + 1; 3687bf215546Sopenharmony_ci } 3688bf215546Sopenharmony_ci else { 3689bf215546Sopenharmony_ci key->nr_sampler_views = key->nr_samplers; 3690bf215546Sopenharmony_ci } 3691bf215546Sopenharmony_ci 3692bf215546Sopenharmony_ci key->nr_images = llvm->draw->tcs.tess_ctrl_shader->info.file_max[TGSI_FILE_IMAGE] + 1; 3693bf215546Sopenharmony_ci 3694bf215546Sopenharmony_ci draw_sampler = key->samplers; 3695bf215546Sopenharmony_ci 3696bf215546Sopenharmony_ci memset(draw_sampler, 0, MAX2(key->nr_samplers, key->nr_sampler_views) * sizeof *draw_sampler); 3697bf215546Sopenharmony_ci 3698bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_samplers; i++) { 3699bf215546Sopenharmony_ci lp_sampler_static_sampler_state(&draw_sampler[i].sampler_state, 3700bf215546Sopenharmony_ci llvm->draw->samplers[PIPE_SHADER_TESS_CTRL][i]); 3701bf215546Sopenharmony_ci } 3702bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_sampler_views; i++) { 3703bf215546Sopenharmony_ci lp_sampler_static_texture_state(&draw_sampler[i].texture_state, 3704bf215546Sopenharmony_ci llvm->draw->sampler_views[PIPE_SHADER_TESS_CTRL][i]); 3705bf215546Sopenharmony_ci } 3706bf215546Sopenharmony_ci 3707bf215546Sopenharmony_ci draw_image = draw_tcs_llvm_variant_key_images(key); 3708bf215546Sopenharmony_ci memset(draw_image, 0, 3709bf215546Sopenharmony_ci key->nr_images * sizeof *draw_image); 3710bf215546Sopenharmony_ci for (i = 0; i < key->nr_images; i++) { 3711bf215546Sopenharmony_ci lp_sampler_static_texture_state_image(&draw_image[i].image_state, 3712bf215546Sopenharmony_ci llvm->draw->images[PIPE_SHADER_TESS_CTRL][i]); 3713bf215546Sopenharmony_ci } 3714bf215546Sopenharmony_ci return key; 3715bf215546Sopenharmony_ci} 3716bf215546Sopenharmony_ci 3717bf215546Sopenharmony_civoid 3718bf215546Sopenharmony_cidraw_tcs_llvm_dump_variant_key(struct draw_tcs_llvm_variant_key *key) 3719bf215546Sopenharmony_ci{ 3720bf215546Sopenharmony_ci unsigned i; 3721bf215546Sopenharmony_ci struct draw_sampler_static_state *sampler = key->samplers; 3722bf215546Sopenharmony_ci struct draw_image_static_state *image = draw_tcs_llvm_variant_key_images(key); 3723bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_sampler_views; i++) { 3724bf215546Sopenharmony_ci debug_printf("sampler[%i].src_format = %s\n", i, 3725bf215546Sopenharmony_ci util_format_name(sampler[i].texture_state.format)); 3726bf215546Sopenharmony_ci } 3727bf215546Sopenharmony_ci 3728bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_images; i++) 3729bf215546Sopenharmony_ci debug_printf("images[%i].format = %s\n", i, util_format_name(image[i].image_state.format)); 3730bf215546Sopenharmony_ci 3731bf215546Sopenharmony_ci} 3732bf215546Sopenharmony_ci 3733bf215546Sopenharmony_cistatic void 3734bf215546Sopenharmony_cicreate_tes_jit_types(struct draw_tes_llvm_variant *var) 3735bf215546Sopenharmony_ci{ 3736bf215546Sopenharmony_ci struct gallivm_state *gallivm = var->gallivm; 3737bf215546Sopenharmony_ci LLVMTypeRef texture_type, sampler_type, image_type; 3738bf215546Sopenharmony_ci 3739bf215546Sopenharmony_ci texture_type = create_jit_texture_type(gallivm, "texture"); 3740bf215546Sopenharmony_ci sampler_type = create_jit_sampler_type(gallivm, "sampler"); 3741bf215546Sopenharmony_ci image_type = create_jit_image_type(gallivm, "image"); 3742bf215546Sopenharmony_ci 3743bf215546Sopenharmony_ci var->context_type = create_tes_jit_context_type(gallivm, 3744bf215546Sopenharmony_ci 0, 3745bf215546Sopenharmony_ci texture_type, sampler_type, 3746bf215546Sopenharmony_ci image_type, 3747bf215546Sopenharmony_ci "draw_tes_jit_context"); 3748bf215546Sopenharmony_ci var->context_ptr_type = LLVMPointerType(var->context_type, 0); 3749bf215546Sopenharmony_ci 3750bf215546Sopenharmony_ci var->input_array_deref_type = create_tes_jit_input_deref_type(gallivm); 3751bf215546Sopenharmony_ci var->input_array_type = LLVMPointerType(var->input_array_deref_type, 0); /* num vertices per prim */ 3752bf215546Sopenharmony_ci} 3753bf215546Sopenharmony_ci 3754bf215546Sopenharmony_cistatic LLVMTypeRef 3755bf215546Sopenharmony_ciget_tes_context_ptr_type(struct draw_tes_llvm_variant *variant) 3756bf215546Sopenharmony_ci{ 3757bf215546Sopenharmony_ci if (!variant->context_ptr_type) 3758bf215546Sopenharmony_ci create_tes_jit_types(variant); 3759bf215546Sopenharmony_ci return variant->context_ptr_type; 3760bf215546Sopenharmony_ci} 3761bf215546Sopenharmony_ci 3762bf215546Sopenharmony_cistatic LLVMValueRef 3763bf215546Sopenharmony_cigenerate_tes_mask_value(struct draw_tes_llvm_variant *variant, 3764bf215546Sopenharmony_ci struct lp_type tes_type, LLVMValueRef limit, LLVMValueRef loop_counter) 3765bf215546Sopenharmony_ci{ 3766bf215546Sopenharmony_ci struct gallivm_state *gallivm = variant->gallivm; 3767bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 3768bf215546Sopenharmony_ci struct lp_type mask_type = lp_int_type(tes_type); 3769bf215546Sopenharmony_ci LLVMValueRef num_prims; 3770bf215546Sopenharmony_ci LLVMValueRef mask_val = lp_build_const_vec(gallivm, mask_type, 0); 3771bf215546Sopenharmony_ci unsigned i; 3772bf215546Sopenharmony_ci 3773bf215546Sopenharmony_ci num_prims = lp_build_broadcast(gallivm, lp_build_vec_type(gallivm, mask_type), limit); 3774bf215546Sopenharmony_ci for (i = 0; i < tes_type.length; i++) { 3775bf215546Sopenharmony_ci LLVMValueRef idx = lp_build_const_int32(gallivm, i); 3776bf215546Sopenharmony_ci mask_val = LLVMBuildInsertElement(builder, mask_val, LLVMBuildAdd(builder, loop_counter, idx, ""), idx, ""); 3777bf215546Sopenharmony_ci } 3778bf215546Sopenharmony_ci mask_val = lp_build_compare(gallivm, mask_type, 3779bf215546Sopenharmony_ci PIPE_FUNC_GREATER, num_prims, mask_val); 3780bf215546Sopenharmony_ci 3781bf215546Sopenharmony_ci return mask_val; 3782bf215546Sopenharmony_ci} 3783bf215546Sopenharmony_ci 3784bf215546Sopenharmony_cistatic LLVMValueRef 3785bf215546Sopenharmony_cidraw_tes_llvm_fetch_vertex_input(const struct lp_build_tes_iface *tes_iface, 3786bf215546Sopenharmony_ci struct lp_build_context *bld, 3787bf215546Sopenharmony_ci boolean is_vindex_indirect, 3788bf215546Sopenharmony_ci LLVMValueRef vertex_index, 3789bf215546Sopenharmony_ci boolean is_aindex_indirect, 3790bf215546Sopenharmony_ci LLVMValueRef attrib_index, 3791bf215546Sopenharmony_ci boolean is_sindex_indirect, 3792bf215546Sopenharmony_ci LLVMValueRef swizzle_index) 3793bf215546Sopenharmony_ci{ 3794bf215546Sopenharmony_ci const struct draw_tes_llvm_iface *tes = draw_tes_llvm_iface(tes_iface); 3795bf215546Sopenharmony_ci struct gallivm_state *gallivm = bld->gallivm; 3796bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 3797bf215546Sopenharmony_ci LLVMValueRef indices[3]; 3798bf215546Sopenharmony_ci LLVMValueRef res; 3799bf215546Sopenharmony_ci struct lp_type type = bld->type; 3800bf215546Sopenharmony_ci 3801bf215546Sopenharmony_ci if (is_vindex_indirect || is_aindex_indirect || is_sindex_indirect) { 3802bf215546Sopenharmony_ci int i; 3803bf215546Sopenharmony_ci 3804bf215546Sopenharmony_ci res = bld->zero; 3805bf215546Sopenharmony_ci 3806bf215546Sopenharmony_ci for (i = 0; i < type.length; ++i) { 3807bf215546Sopenharmony_ci LLVMValueRef idx = lp_build_const_int32(gallivm, i); 3808bf215546Sopenharmony_ci LLVMValueRef vert_chan_index = vertex_index; 3809bf215546Sopenharmony_ci LLVMValueRef attr_chan_index = attrib_index; 3810bf215546Sopenharmony_ci LLVMValueRef swiz_chan_index = swizzle_index; 3811bf215546Sopenharmony_ci LLVMValueRef channel_vec; 3812bf215546Sopenharmony_ci 3813bf215546Sopenharmony_ci if (is_vindex_indirect) { 3814bf215546Sopenharmony_ci vert_chan_index = LLVMBuildExtractElement(builder, 3815bf215546Sopenharmony_ci vertex_index, idx, ""); 3816bf215546Sopenharmony_ci } 3817bf215546Sopenharmony_ci if (is_aindex_indirect) { 3818bf215546Sopenharmony_ci attr_chan_index = LLVMBuildExtractElement(builder, 3819bf215546Sopenharmony_ci attrib_index, idx, ""); 3820bf215546Sopenharmony_ci } 3821bf215546Sopenharmony_ci if (is_sindex_indirect) { 3822bf215546Sopenharmony_ci swiz_chan_index = LLVMBuildExtractElement(builder, 3823bf215546Sopenharmony_ci swizzle_index, idx, ""); 3824bf215546Sopenharmony_ci } 3825bf215546Sopenharmony_ci 3826bf215546Sopenharmony_ci indices[0] = vert_chan_index; 3827bf215546Sopenharmony_ci indices[1] = attr_chan_index; 3828bf215546Sopenharmony_ci indices[2] = swiz_chan_index; 3829bf215546Sopenharmony_ci 3830bf215546Sopenharmony_ci channel_vec = LLVMBuildGEP2(builder, tes->variant->input_array_deref_type, tes->input, indices, 3, ""); 3831bf215546Sopenharmony_ci channel_vec = LLVMBuildLoad2(builder, LLVMFloatTypeInContext(gallivm->context), channel_vec, ""); 3832bf215546Sopenharmony_ci 3833bf215546Sopenharmony_ci res = LLVMBuildInsertElement(builder, res, channel_vec, idx, ""); 3834bf215546Sopenharmony_ci } 3835bf215546Sopenharmony_ci } else { 3836bf215546Sopenharmony_ci indices[0] = vertex_index; 3837bf215546Sopenharmony_ci indices[1] = attrib_index; 3838bf215546Sopenharmony_ci indices[2] = swizzle_index; 3839bf215546Sopenharmony_ci 3840bf215546Sopenharmony_ci res = LLVMBuildGEP2(builder, tes->variant->input_array_deref_type, tes->input, indices, 3, ""); 3841bf215546Sopenharmony_ci res = LLVMBuildLoad2(builder, LLVMFloatTypeInContext(gallivm->context), res, ""); 3842bf215546Sopenharmony_ci res = lp_build_broadcast_scalar(bld, res); 3843bf215546Sopenharmony_ci } 3844bf215546Sopenharmony_ci return res; 3845bf215546Sopenharmony_ci} 3846bf215546Sopenharmony_ci 3847bf215546Sopenharmony_cistatic LLVMValueRef 3848bf215546Sopenharmony_cidraw_tes_llvm_fetch_patch_input(const struct lp_build_tes_iface *tes_iface, 3849bf215546Sopenharmony_ci struct lp_build_context *bld, 3850bf215546Sopenharmony_ci boolean is_aindex_indirect, 3851bf215546Sopenharmony_ci LLVMValueRef attrib_index, 3852bf215546Sopenharmony_ci LLVMValueRef swizzle_index) 3853bf215546Sopenharmony_ci{ 3854bf215546Sopenharmony_ci const struct draw_tes_llvm_iface *tes = draw_tes_llvm_iface(tes_iface); 3855bf215546Sopenharmony_ci struct gallivm_state *gallivm = bld->gallivm; 3856bf215546Sopenharmony_ci LLVMBuilderRef builder = gallivm->builder; 3857bf215546Sopenharmony_ci LLVMValueRef indices[3]; 3858bf215546Sopenharmony_ci LLVMValueRef res; 3859bf215546Sopenharmony_ci struct lp_type type = bld->type; 3860bf215546Sopenharmony_ci 3861bf215546Sopenharmony_ci if (is_aindex_indirect) { 3862bf215546Sopenharmony_ci int i; 3863bf215546Sopenharmony_ci 3864bf215546Sopenharmony_ci res = bld->zero; 3865bf215546Sopenharmony_ci 3866bf215546Sopenharmony_ci for (i = 0; i < type.length; ++i) { 3867bf215546Sopenharmony_ci LLVMValueRef idx = lp_build_const_int32(gallivm, i); 3868bf215546Sopenharmony_ci LLVMValueRef attr_chan_index = attrib_index; 3869bf215546Sopenharmony_ci LLVMValueRef channel_vec; 3870bf215546Sopenharmony_ci 3871bf215546Sopenharmony_ci if (is_aindex_indirect) { 3872bf215546Sopenharmony_ci attr_chan_index = LLVMBuildExtractElement(builder, 3873bf215546Sopenharmony_ci attrib_index, idx, ""); 3874bf215546Sopenharmony_ci } 3875bf215546Sopenharmony_ci 3876bf215546Sopenharmony_ci indices[0] = lp_build_const_int32(gallivm, 0); 3877bf215546Sopenharmony_ci indices[1] = attr_chan_index; 3878bf215546Sopenharmony_ci indices[2] = swizzle_index; 3879bf215546Sopenharmony_ci 3880bf215546Sopenharmony_ci channel_vec = LLVMBuildGEP2(builder, tes->variant->input_array_deref_type, tes->input, indices, 3, ""); 3881bf215546Sopenharmony_ci channel_vec = LLVMBuildLoad2(builder, LLVMFloatTypeInContext(gallivm->context), channel_vec, ""); 3882bf215546Sopenharmony_ci 3883bf215546Sopenharmony_ci res = LLVMBuildInsertElement(builder, res, channel_vec, idx, ""); 3884bf215546Sopenharmony_ci } 3885bf215546Sopenharmony_ci } else { 3886bf215546Sopenharmony_ci indices[0] = lp_build_const_int32(gallivm, 0); 3887bf215546Sopenharmony_ci indices[1] = attrib_index; 3888bf215546Sopenharmony_ci indices[2] = swizzle_index; 3889bf215546Sopenharmony_ci 3890bf215546Sopenharmony_ci res = LLVMBuildGEP2(builder, tes->variant->input_array_deref_type, tes->input, indices, 3, ""); 3891bf215546Sopenharmony_ci res = LLVMBuildLoad2(builder, LLVMFloatTypeInContext(gallivm->context), res, ""); 3892bf215546Sopenharmony_ci res = lp_build_broadcast_scalar(bld, res); 3893bf215546Sopenharmony_ci } 3894bf215546Sopenharmony_ci return res; 3895bf215546Sopenharmony_ci} 3896bf215546Sopenharmony_ci 3897bf215546Sopenharmony_cistatic void 3898bf215546Sopenharmony_cidraw_tes_llvm_generate(struct draw_llvm *llvm, 3899bf215546Sopenharmony_ci struct draw_tes_llvm_variant *variant) 3900bf215546Sopenharmony_ci{ 3901bf215546Sopenharmony_ci struct gallivm_state *gallivm = variant->gallivm; 3902bf215546Sopenharmony_ci LLVMContextRef context = gallivm->context; 3903bf215546Sopenharmony_ci LLVMTypeRef int32_type = LLVMInt32TypeInContext(context); 3904bf215546Sopenharmony_ci LLVMTypeRef flt_type = LLVMFloatTypeInContext(context); 3905bf215546Sopenharmony_ci LLVMTypeRef arg_types[11]; 3906bf215546Sopenharmony_ci LLVMTypeRef func_type; 3907bf215546Sopenharmony_ci LLVMValueRef variant_func; 3908bf215546Sopenharmony_ci LLVMValueRef context_ptr; 3909bf215546Sopenharmony_ci LLVMValueRef tess_coord[2], io_ptr, input_array, num_tess_coord; 3910bf215546Sopenharmony_ci LLVMValueRef view_index; 3911bf215546Sopenharmony_ci LLVMValueRef tess_inner, tess_outer, prim_id, patch_vertices_in; 3912bf215546Sopenharmony_ci LLVMBasicBlockRef block; 3913bf215546Sopenharmony_ci LLVMBuilderRef builder; 3914bf215546Sopenharmony_ci LLVMValueRef mask_val; 3915bf215546Sopenharmony_ci struct lp_build_context bld, bldvec; 3916bf215546Sopenharmony_ci struct lp_build_sampler_soa *sampler = 0; 3917bf215546Sopenharmony_ci struct lp_build_image_soa *image = NULL; 3918bf215546Sopenharmony_ci struct lp_bld_tgsi_system_values system_values; 3919bf215546Sopenharmony_ci char func_name[64]; 3920bf215546Sopenharmony_ci unsigned i; 3921bf215546Sopenharmony_ci struct draw_tes_llvm_iface tes_iface; 3922bf215546Sopenharmony_ci LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS]; 3923bf215546Sopenharmony_ci struct lp_build_mask_context mask; 3924bf215546Sopenharmony_ci LLVMValueRef consts_ptr, num_consts_ptr; 3925bf215546Sopenharmony_ci LLVMValueRef ssbos_ptr, num_ssbos_ptr; 3926bf215546Sopenharmony_ci LLVMValueRef step; 3927bf215546Sopenharmony_ci struct lp_type tes_type; 3928bf215546Sopenharmony_ci unsigned vector_length = variant->shader->base.vector_length; 3929bf215546Sopenharmony_ci 3930bf215546Sopenharmony_ci memset(&system_values, 0, sizeof(system_values)); 3931bf215546Sopenharmony_ci memset(&outputs, 0, sizeof(outputs)); 3932bf215546Sopenharmony_ci 3933bf215546Sopenharmony_ci snprintf(func_name, sizeof(func_name), "draw_llvm_tes_variant"); 3934bf215546Sopenharmony_ci 3935bf215546Sopenharmony_ci LLVMTypeRef tess_outer_deref_type = LLVMArrayType(flt_type, 4); 3936bf215546Sopenharmony_ci LLVMTypeRef tess_inner_deref_type = LLVMArrayType(flt_type, 2); 3937bf215546Sopenharmony_ci 3938bf215546Sopenharmony_ci arg_types[0] = get_tes_context_ptr_type(variant); /* context */ 3939bf215546Sopenharmony_ci arg_types[1] = variant->input_array_type; /* input */ 3940bf215546Sopenharmony_ci arg_types[2] = variant->vertex_header_ptr_type; 3941bf215546Sopenharmony_ci arg_types[3] = int32_type; 3942bf215546Sopenharmony_ci arg_types[4] = int32_type; 3943bf215546Sopenharmony_ci arg_types[5] = LLVMPointerType(flt_type, 0); 3944bf215546Sopenharmony_ci arg_types[6] = LLVMPointerType(flt_type, 0); 3945bf215546Sopenharmony_ci arg_types[7] = LLVMPointerType(tess_outer_deref_type, 0); 3946bf215546Sopenharmony_ci arg_types[8] = LLVMPointerType(tess_inner_deref_type, 0); 3947bf215546Sopenharmony_ci arg_types[9] = int32_type; 3948bf215546Sopenharmony_ci arg_types[10] = int32_type; 3949bf215546Sopenharmony_ci 3950bf215546Sopenharmony_ci func_type = LLVMFunctionType(int32_type, arg_types, ARRAY_SIZE(arg_types), 0); 3951bf215546Sopenharmony_ci variant_func = LLVMAddFunction(gallivm->module, func_name, func_type); 3952bf215546Sopenharmony_ci 3953bf215546Sopenharmony_ci variant->function = variant_func; 3954bf215546Sopenharmony_ci LLVMSetFunctionCallConv(variant_func, LLVMCCallConv); 3955bf215546Sopenharmony_ci 3956bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(arg_types); ++i) 3957bf215546Sopenharmony_ci if (LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind) 3958bf215546Sopenharmony_ci lp_add_function_attr(variant_func, i + 1, LP_FUNC_ATTR_NOALIAS); 3959bf215546Sopenharmony_ci 3960bf215546Sopenharmony_ci if (gallivm->cache && gallivm->cache->data_size) 3961bf215546Sopenharmony_ci return; 3962bf215546Sopenharmony_ci context_ptr = LLVMGetParam(variant_func, 0); 3963bf215546Sopenharmony_ci input_array = LLVMGetParam(variant_func, 1); 3964bf215546Sopenharmony_ci io_ptr = LLVMGetParam(variant_func, 2); 3965bf215546Sopenharmony_ci prim_id = LLVMGetParam(variant_func, 3); 3966bf215546Sopenharmony_ci num_tess_coord = LLVMGetParam(variant_func, 4); 3967bf215546Sopenharmony_ci tess_coord[0] = LLVMGetParam(variant_func, 5); 3968bf215546Sopenharmony_ci tess_coord[1] = LLVMGetParam(variant_func, 6); 3969bf215546Sopenharmony_ci tess_outer = LLVMGetParam(variant_func, 7); 3970bf215546Sopenharmony_ci tess_inner = LLVMGetParam(variant_func, 8); 3971bf215546Sopenharmony_ci patch_vertices_in = LLVMGetParam(variant_func, 9); 3972bf215546Sopenharmony_ci view_index = LLVMGetParam(variant_func, 10); 3973bf215546Sopenharmony_ci 3974bf215546Sopenharmony_ci lp_build_name(context_ptr, "context"); 3975bf215546Sopenharmony_ci lp_build_name(input_array, "input"); 3976bf215546Sopenharmony_ci lp_build_name(io_ptr, "io"); 3977bf215546Sopenharmony_ci lp_build_name(prim_id, "prim_id"); 3978bf215546Sopenharmony_ci lp_build_name(num_tess_coord, "num_tess_coord"); 3979bf215546Sopenharmony_ci lp_build_name(tess_coord[0], "tess_coord[0]"); 3980bf215546Sopenharmony_ci lp_build_name(tess_coord[1], "tess_coord[1]"); 3981bf215546Sopenharmony_ci lp_build_name(tess_outer, "tess_outer"); 3982bf215546Sopenharmony_ci lp_build_name(tess_inner, "tess_inner"); 3983bf215546Sopenharmony_ci lp_build_name(patch_vertices_in, "patch_vertices_in"); 3984bf215546Sopenharmony_ci lp_build_name(view_index, "view_index"); 3985bf215546Sopenharmony_ci 3986bf215546Sopenharmony_ci tes_iface.base.fetch_vertex_input = draw_tes_llvm_fetch_vertex_input; 3987bf215546Sopenharmony_ci tes_iface.base.fetch_patch_input = draw_tes_llvm_fetch_patch_input; 3988bf215546Sopenharmony_ci tes_iface.input = input_array; 3989bf215546Sopenharmony_ci tes_iface.variant = variant; 3990bf215546Sopenharmony_ci 3991bf215546Sopenharmony_ci block = LLVMAppendBasicBlockInContext(gallivm->context, variant_func, "entry"); 3992bf215546Sopenharmony_ci builder = gallivm->builder; 3993bf215546Sopenharmony_ci LLVMPositionBuilderAtEnd(builder, block); 3994bf215546Sopenharmony_ci 3995bf215546Sopenharmony_ci lp_build_context_init(&bld, gallivm, lp_type_int(32)); 3996bf215546Sopenharmony_ci 3997bf215546Sopenharmony_ci memset(&tes_type, 0, sizeof tes_type); 3998bf215546Sopenharmony_ci tes_type.floating = TRUE; /* floating point values */ 3999bf215546Sopenharmony_ci tes_type.sign = TRUE; /* values are signed */ 4000bf215546Sopenharmony_ci tes_type.norm = FALSE; /* values are not limited to [0,1] or [-1,1] */ 4001bf215546Sopenharmony_ci tes_type.width = 32; /* 32-bit float */ 4002bf215546Sopenharmony_ci tes_type.length = vector_length; 4003bf215546Sopenharmony_ci 4004bf215546Sopenharmony_ci lp_build_context_init(&bldvec, variant->gallivm, lp_int_type(tes_type)); 4005bf215546Sopenharmony_ci consts_ptr = draw_tes_jit_context_constants(variant, context_ptr); 4006bf215546Sopenharmony_ci num_consts_ptr = 4007bf215546Sopenharmony_ci draw_tes_jit_context_num_constants(variant, context_ptr); 4008bf215546Sopenharmony_ci 4009bf215546Sopenharmony_ci ssbos_ptr = draw_tes_jit_context_ssbos(variant, context_ptr); 4010bf215546Sopenharmony_ci num_ssbos_ptr = 4011bf215546Sopenharmony_ci draw_tes_jit_context_num_ssbos(variant, context_ptr); 4012bf215546Sopenharmony_ci sampler = draw_llvm_sampler_soa_create(variant->key.samplers, 4013bf215546Sopenharmony_ci MAX2(variant->key.nr_samplers, 4014bf215546Sopenharmony_ci variant->key.nr_sampler_views)); 4015bf215546Sopenharmony_ci image = draw_llvm_image_soa_create(draw_tes_llvm_variant_key_images(&variant->key), 4016bf215546Sopenharmony_ci variant->key.nr_images); 4017bf215546Sopenharmony_ci step = lp_build_const_int32(gallivm, vector_length); 4018bf215546Sopenharmony_ci 4019bf215546Sopenharmony_ci system_values.tess_outer = LLVMBuildLoad2(builder, tess_outer_deref_type, tess_outer, ""); 4020bf215546Sopenharmony_ci system_values.tess_inner = LLVMBuildLoad2(builder, tess_inner_deref_type, tess_inner, ""); 4021bf215546Sopenharmony_ci 4022bf215546Sopenharmony_ci system_values.prim_id = lp_build_broadcast_scalar(&bldvec, prim_id); 4023bf215546Sopenharmony_ci 4024bf215546Sopenharmony_ci system_values.view_index = view_index; 4025bf215546Sopenharmony_ci 4026bf215546Sopenharmony_ci system_values.vertices_in = lp_build_broadcast_scalar(&bldvec, patch_vertices_in); 4027bf215546Sopenharmony_ci 4028bf215546Sopenharmony_ci if (variant->key.primid_needed) { 4029bf215546Sopenharmony_ci int slot = variant->key.primid_output; 4030bf215546Sopenharmony_ci for (unsigned i = 0; i < 4; i++) { 4031bf215546Sopenharmony_ci outputs[slot][i] = lp_build_alloca(gallivm, lp_build_int_vec_type(gallivm, tes_type), "primid"); 4032bf215546Sopenharmony_ci LLVMBuildStore(builder, system_values.prim_id, outputs[slot][i]); 4033bf215546Sopenharmony_ci } 4034bf215546Sopenharmony_ci } 4035bf215546Sopenharmony_ci struct lp_build_loop_state lp_loop; 4036bf215546Sopenharmony_ci lp_build_loop_begin(&lp_loop, gallivm, bld.zero); 4037bf215546Sopenharmony_ci { 4038bf215546Sopenharmony_ci LLVMValueRef io; 4039bf215546Sopenharmony_ci 4040bf215546Sopenharmony_ci io = LLVMBuildGEP2(builder, variant->vertex_header_type, io_ptr, &lp_loop.counter, 1, ""); 4041bf215546Sopenharmony_ci mask_val = generate_tes_mask_value(variant, tes_type, num_tess_coord, lp_loop.counter); 4042bf215546Sopenharmony_ci lp_build_mask_begin(&mask, gallivm, tes_type, mask_val); 4043bf215546Sopenharmony_ci 4044bf215546Sopenharmony_ci system_values.tess_coord = LLVMGetUndef(LLVMArrayType(LLVMVectorType(flt_type, vector_length), 3)); 4045bf215546Sopenharmony_ci for (i = 0; i < 3; i++) { 4046bf215546Sopenharmony_ci LLVMValueRef tess_coord_chan = LLVMGetUndef(LLVMVectorType(flt_type, vector_length)); 4047bf215546Sopenharmony_ci for (unsigned j = 0; j < vector_length; j++) { 4048bf215546Sopenharmony_ci LLVMValueRef idx = LLVMBuildAdd(builder, lp_loop.counter, lp_build_const_int32(gallivm, j), ""); 4049bf215546Sopenharmony_ci LLVMValueRef tc_val; 4050bf215546Sopenharmony_ci if (i == 2) { 4051bf215546Sopenharmony_ci if (variant->shader->base.prim_mode == PIPE_PRIM_TRIANGLES) { 4052bf215546Sopenharmony_ci tc_val = lp_build_const_float(gallivm, 1.0); 4053bf215546Sopenharmony_ci tc_val = LLVMBuildFSub(builder, tc_val, lp_build_pointer_get(builder, tess_coord[0], idx), ""); 4054bf215546Sopenharmony_ci tc_val = LLVMBuildFSub(builder, tc_val, lp_build_pointer_get(builder, tess_coord[1], idx), ""); 4055bf215546Sopenharmony_ci } else 4056bf215546Sopenharmony_ci tc_val = lp_build_const_float(gallivm, 0.0); 4057bf215546Sopenharmony_ci } else 4058bf215546Sopenharmony_ci tc_val = lp_build_pointer_get(builder, tess_coord[i], idx); 4059bf215546Sopenharmony_ci 4060bf215546Sopenharmony_ci tess_coord_chan = LLVMBuildInsertElement(builder, tess_coord_chan, tc_val, lp_build_const_int32(gallivm, j), ""); 4061bf215546Sopenharmony_ci } 4062bf215546Sopenharmony_ci system_values.tess_coord = LLVMBuildInsertValue(builder, system_values.tess_coord, tess_coord_chan, i, ""); 4063bf215546Sopenharmony_ci } 4064bf215546Sopenharmony_ci 4065bf215546Sopenharmony_ci struct lp_build_tgsi_params params; 4066bf215546Sopenharmony_ci memset(¶ms, 0, sizeof(params)); 4067bf215546Sopenharmony_ci 4068bf215546Sopenharmony_ci params.type = tes_type; 4069bf215546Sopenharmony_ci params.mask = &mask; 4070bf215546Sopenharmony_ci params.consts_ptr = consts_ptr; 4071bf215546Sopenharmony_ci params.const_sizes_ptr = num_consts_ptr; 4072bf215546Sopenharmony_ci params.system_values = &system_values; 4073bf215546Sopenharmony_ci params.context_ptr = context_ptr; 4074bf215546Sopenharmony_ci params.sampler = sampler; 4075bf215546Sopenharmony_ci params.info = &llvm->draw->tes.tess_eval_shader->info; 4076bf215546Sopenharmony_ci params.ssbo_ptr = ssbos_ptr; 4077bf215546Sopenharmony_ci params.ssbo_sizes_ptr = num_ssbos_ptr; 4078bf215546Sopenharmony_ci params.image = image; 4079bf215546Sopenharmony_ci params.tes_iface = &tes_iface.base; 4080bf215546Sopenharmony_ci params.aniso_filter_table = draw_tes_jit_context_aniso_filter_table(variant, context_ptr); 4081bf215546Sopenharmony_ci 4082bf215546Sopenharmony_ci lp_build_nir_soa(variant->gallivm, 4083bf215546Sopenharmony_ci llvm->draw->tes.tess_eval_shader->state.ir.nir, 4084bf215546Sopenharmony_ci ¶ms, 4085bf215546Sopenharmony_ci outputs); 4086bf215546Sopenharmony_ci 4087bf215546Sopenharmony_ci lp_build_mask_end(&mask); 4088bf215546Sopenharmony_ci 4089bf215546Sopenharmony_ci if (variant->key.clamp_vertex_color) { 4090bf215546Sopenharmony_ci const struct tgsi_shader_info *info = &llvm->draw->tes.tess_eval_shader->info; 4091bf215546Sopenharmony_ci do_clamp_vertex_color(variant->gallivm, 4092bf215546Sopenharmony_ci tes_type, info, 4093bf215546Sopenharmony_ci outputs); 4094bf215546Sopenharmony_ci } 4095bf215546Sopenharmony_ci LLVMValueRef clipmask = lp_build_const_int_vec(gallivm, 4096bf215546Sopenharmony_ci lp_int_type(tes_type), 0); 4097bf215546Sopenharmony_ci 4098bf215546Sopenharmony_ci convert_to_aos(gallivm, variant->vertex_header_type, io, NULL, outputs, clipmask, 4099bf215546Sopenharmony_ci draw_total_tes_outputs(llvm->draw), tes_type, FALSE); 4100bf215546Sopenharmony_ci } 4101bf215546Sopenharmony_ci lp_build_loop_end_cond(&lp_loop, num_tess_coord, step, LLVMIntUGE); 4102bf215546Sopenharmony_ci sampler->destroy(sampler); 4103bf215546Sopenharmony_ci image->destroy(image); 4104bf215546Sopenharmony_ci 4105bf215546Sopenharmony_ci LLVMBuildRet(builder, lp_build_zero(gallivm, lp_type_uint(32))); 4106bf215546Sopenharmony_ci gallivm_verify_function(gallivm, variant_func); 4107bf215546Sopenharmony_ci} 4108bf215546Sopenharmony_ci 4109bf215546Sopenharmony_cistruct draw_tes_llvm_variant * 4110bf215546Sopenharmony_cidraw_tes_llvm_create_variant(struct draw_llvm *llvm, 4111bf215546Sopenharmony_ci unsigned num_outputs, 4112bf215546Sopenharmony_ci const struct draw_tes_llvm_variant_key *key) 4113bf215546Sopenharmony_ci{ 4114bf215546Sopenharmony_ci struct draw_tes_llvm_variant *variant; 4115bf215546Sopenharmony_ci struct llvm_tess_eval_shader *shader = llvm_tess_eval_shader(llvm->draw->tes.tess_eval_shader); 4116bf215546Sopenharmony_ci char module_name[64]; 4117bf215546Sopenharmony_ci unsigned char ir_sha1_cache_key[20]; 4118bf215546Sopenharmony_ci struct lp_cached_code cached = { 0 }; 4119bf215546Sopenharmony_ci bool needs_caching = false; 4120bf215546Sopenharmony_ci 4121bf215546Sopenharmony_ci variant = MALLOC(sizeof *variant + 4122bf215546Sopenharmony_ci shader->variant_key_size - sizeof variant->key); 4123bf215546Sopenharmony_ci if (!variant) 4124bf215546Sopenharmony_ci return NULL; 4125bf215546Sopenharmony_ci 4126bf215546Sopenharmony_ci variant->llvm = llvm; 4127bf215546Sopenharmony_ci variant->shader = shader; 4128bf215546Sopenharmony_ci 4129bf215546Sopenharmony_ci snprintf(module_name, sizeof(module_name), "draw_llvm_tes_variant%u", 4130bf215546Sopenharmony_ci variant->shader->variants_cached); 4131bf215546Sopenharmony_ci 4132bf215546Sopenharmony_ci memcpy(&variant->key, key, shader->variant_key_size); 4133bf215546Sopenharmony_ci if (shader->base.state.ir.nir && llvm->draw->disk_cache_cookie) { 4134bf215546Sopenharmony_ci draw_get_ir_cache_key(shader->base.state.ir.nir, 4135bf215546Sopenharmony_ci key, 4136bf215546Sopenharmony_ci shader->variant_key_size, 4137bf215546Sopenharmony_ci num_outputs, 4138bf215546Sopenharmony_ci ir_sha1_cache_key); 4139bf215546Sopenharmony_ci 4140bf215546Sopenharmony_ci llvm->draw->disk_cache_find_shader(llvm->draw->disk_cache_cookie, 4141bf215546Sopenharmony_ci &cached, 4142bf215546Sopenharmony_ci ir_sha1_cache_key); 4143bf215546Sopenharmony_ci if (!cached.data_size) 4144bf215546Sopenharmony_ci needs_caching = true; 4145bf215546Sopenharmony_ci } 4146bf215546Sopenharmony_ci variant->gallivm = gallivm_create(module_name, llvm->context, &cached); 4147bf215546Sopenharmony_ci 4148bf215546Sopenharmony_ci create_tes_jit_types(variant); 4149bf215546Sopenharmony_ci 4150bf215546Sopenharmony_ci variant->vertex_header_type = create_jit_vertex_header(variant->gallivm, num_outputs); 4151bf215546Sopenharmony_ci variant->vertex_header_ptr_type = LLVMPointerType(variant->vertex_header_type, 0); 4152bf215546Sopenharmony_ci 4153bf215546Sopenharmony_ci if (gallivm_debug & (GALLIVM_DEBUG_TGSI | GALLIVM_DEBUG_IR)) { 4154bf215546Sopenharmony_ci nir_print_shader(llvm->draw->tes.tess_eval_shader->state.ir.nir, stderr); 4155bf215546Sopenharmony_ci draw_tes_llvm_dump_variant_key(&variant->key); 4156bf215546Sopenharmony_ci } 4157bf215546Sopenharmony_ci 4158bf215546Sopenharmony_ci draw_tes_llvm_generate(llvm, variant); 4159bf215546Sopenharmony_ci 4160bf215546Sopenharmony_ci gallivm_compile_module(variant->gallivm); 4161bf215546Sopenharmony_ci 4162bf215546Sopenharmony_ci variant->jit_func = (draw_tes_jit_func) 4163bf215546Sopenharmony_ci gallivm_jit_function(variant->gallivm, variant->function); 4164bf215546Sopenharmony_ci 4165bf215546Sopenharmony_ci if (needs_caching) 4166bf215546Sopenharmony_ci llvm->draw->disk_cache_insert_shader(llvm->draw->disk_cache_cookie, 4167bf215546Sopenharmony_ci &cached, 4168bf215546Sopenharmony_ci ir_sha1_cache_key); 4169bf215546Sopenharmony_ci gallivm_free_ir(variant->gallivm); 4170bf215546Sopenharmony_ci 4171bf215546Sopenharmony_ci variant->list_item_global.base = variant; 4172bf215546Sopenharmony_ci variant->list_item_local.base = variant; 4173bf215546Sopenharmony_ci /*variant->no = */shader->variants_created++; 4174bf215546Sopenharmony_ci variant->list_item_global.base = variant; 4175bf215546Sopenharmony_ci 4176bf215546Sopenharmony_ci return variant; 4177bf215546Sopenharmony_ci} 4178bf215546Sopenharmony_ci 4179bf215546Sopenharmony_civoid 4180bf215546Sopenharmony_cidraw_tes_llvm_destroy_variant(struct draw_tes_llvm_variant *variant) 4181bf215546Sopenharmony_ci{ 4182bf215546Sopenharmony_ci struct draw_llvm *llvm = variant->llvm; 4183bf215546Sopenharmony_ci 4184bf215546Sopenharmony_ci if (gallivm_debug & (GALLIVM_DEBUG_TGSI | GALLIVM_DEBUG_IR)) { 4185bf215546Sopenharmony_ci debug_printf("Deleting TES variant: %u tes variants,\t%u total variants\n", 4186bf215546Sopenharmony_ci variant->shader->variants_cached, llvm->nr_tes_variants); 4187bf215546Sopenharmony_ci } 4188bf215546Sopenharmony_ci 4189bf215546Sopenharmony_ci gallivm_destroy(variant->gallivm); 4190bf215546Sopenharmony_ci 4191bf215546Sopenharmony_ci list_del(&variant->list_item_local.list); 4192bf215546Sopenharmony_ci variant->shader->variants_cached--; 4193bf215546Sopenharmony_ci list_del(&variant->list_item_global.list); 4194bf215546Sopenharmony_ci llvm->nr_tes_variants--; 4195bf215546Sopenharmony_ci FREE(variant); 4196bf215546Sopenharmony_ci} 4197bf215546Sopenharmony_ci 4198bf215546Sopenharmony_cistruct draw_tes_llvm_variant_key * 4199bf215546Sopenharmony_cidraw_tes_llvm_make_variant_key(struct draw_llvm *llvm, char *store) 4200bf215546Sopenharmony_ci{ 4201bf215546Sopenharmony_ci unsigned i; 4202bf215546Sopenharmony_ci struct draw_tes_llvm_variant_key *key; 4203bf215546Sopenharmony_ci struct draw_sampler_static_state *draw_sampler; 4204bf215546Sopenharmony_ci struct draw_image_static_state *draw_image; 4205bf215546Sopenharmony_ci 4206bf215546Sopenharmony_ci key = (struct draw_tes_llvm_variant_key *)store; 4207bf215546Sopenharmony_ci 4208bf215546Sopenharmony_ci memset(key, 0, offsetof(struct draw_tes_llvm_variant_key, samplers[0])); 4209bf215546Sopenharmony_ci 4210bf215546Sopenharmony_ci int primid_output = draw_find_shader_output(llvm->draw, TGSI_SEMANTIC_PRIMID, 0); 4211bf215546Sopenharmony_ci if (primid_output >= 0) { 4212bf215546Sopenharmony_ci key->primid_output = primid_output; 4213bf215546Sopenharmony_ci key->primid_needed = true; 4214bf215546Sopenharmony_ci } 4215bf215546Sopenharmony_ci 4216bf215546Sopenharmony_ci key->clamp_vertex_color = llvm->draw->rasterizer->clamp_vertex_color && 4217bf215546Sopenharmony_ci llvm->draw->gs.geometry_shader == NULL; 4218bf215546Sopenharmony_ci 4219bf215546Sopenharmony_ci /* All variants of this shader will have the same value for 4220bf215546Sopenharmony_ci * nr_samplers. Not yet trying to compact away holes in the 4221bf215546Sopenharmony_ci * sampler array. 4222bf215546Sopenharmony_ci */ 4223bf215546Sopenharmony_ci key->nr_samplers = llvm->draw->tes.tess_eval_shader->info.file_max[TGSI_FILE_SAMPLER] + 1; 4224bf215546Sopenharmony_ci if (llvm->draw->tes.tess_eval_shader->info.file_max[TGSI_FILE_SAMPLER_VIEW] != -1) { 4225bf215546Sopenharmony_ci key->nr_sampler_views = 4226bf215546Sopenharmony_ci llvm->draw->tes.tess_eval_shader->info.file_max[TGSI_FILE_SAMPLER_VIEW] + 1; 4227bf215546Sopenharmony_ci } 4228bf215546Sopenharmony_ci else { 4229bf215546Sopenharmony_ci key->nr_sampler_views = key->nr_samplers; 4230bf215546Sopenharmony_ci } 4231bf215546Sopenharmony_ci 4232bf215546Sopenharmony_ci key->nr_images = llvm->draw->tes.tess_eval_shader->info.file_max[TGSI_FILE_IMAGE] + 1; 4233bf215546Sopenharmony_ci 4234bf215546Sopenharmony_ci draw_sampler = key->samplers; 4235bf215546Sopenharmony_ci 4236bf215546Sopenharmony_ci memset(draw_sampler, 0, MAX2(key->nr_samplers, key->nr_sampler_views) * sizeof *draw_sampler); 4237bf215546Sopenharmony_ci 4238bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_samplers; i++) { 4239bf215546Sopenharmony_ci lp_sampler_static_sampler_state(&draw_sampler[i].sampler_state, 4240bf215546Sopenharmony_ci llvm->draw->samplers[PIPE_SHADER_TESS_EVAL][i]); 4241bf215546Sopenharmony_ci } 4242bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_sampler_views; i++) { 4243bf215546Sopenharmony_ci lp_sampler_static_texture_state(&draw_sampler[i].texture_state, 4244bf215546Sopenharmony_ci llvm->draw->sampler_views[PIPE_SHADER_TESS_EVAL][i]); 4245bf215546Sopenharmony_ci } 4246bf215546Sopenharmony_ci 4247bf215546Sopenharmony_ci draw_image = draw_tes_llvm_variant_key_images(key); 4248bf215546Sopenharmony_ci memset(draw_image, 0, 4249bf215546Sopenharmony_ci key->nr_images * sizeof *draw_image); 4250bf215546Sopenharmony_ci for (i = 0; i < key->nr_images; i++) { 4251bf215546Sopenharmony_ci lp_sampler_static_texture_state_image(&draw_image[i].image_state, 4252bf215546Sopenharmony_ci llvm->draw->images[PIPE_SHADER_TESS_EVAL][i]); 4253bf215546Sopenharmony_ci } 4254bf215546Sopenharmony_ci return key; 4255bf215546Sopenharmony_ci} 4256bf215546Sopenharmony_ci 4257bf215546Sopenharmony_civoid 4258bf215546Sopenharmony_cidraw_tes_llvm_dump_variant_key(struct draw_tes_llvm_variant_key *key) 4259bf215546Sopenharmony_ci{ 4260bf215546Sopenharmony_ci unsigned i; 4261bf215546Sopenharmony_ci struct draw_sampler_static_state *sampler = key->samplers; 4262bf215546Sopenharmony_ci struct draw_image_static_state *image = draw_tes_llvm_variant_key_images(key); 4263bf215546Sopenharmony_ci 4264bf215546Sopenharmony_ci if (key->primid_needed) 4265bf215546Sopenharmony_ci debug_printf("prim id output %d\n", key->primid_output); 4266bf215546Sopenharmony_ci debug_printf("clamp_vertex_color = %u\n", key->clamp_vertex_color); 4267bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_sampler_views; i++) { 4268bf215546Sopenharmony_ci debug_printf("sampler[%i].src_format = %s\n", i, 4269bf215546Sopenharmony_ci util_format_name(sampler[i].texture_state.format)); 4270bf215546Sopenharmony_ci } 4271bf215546Sopenharmony_ci 4272bf215546Sopenharmony_ci for (i = 0 ; i < key->nr_images; i++) 4273bf215546Sopenharmony_ci debug_printf("images[%i].format = %s\n", i, util_format_name(image[i].image_state.format)); 4274bf215546Sopenharmony_ci 4275bf215546Sopenharmony_ci} 4276