1
/**************************************************************************
3
* Copyright 2009 VMware, Inc.
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the
8
* "Software"), to deal in the Software without restriction, including
9
* without limitation the rights to use, copy, modify, merge, publish,
10
* distribute, sub license, and/or sell copies of the Software, and to
11
* permit persons to whom the Software is furnished to do so, subject to
12
* the following conditions:
14
* The above copyright notice and this permission notice (including the
15
* next paragraph) shall be included in all copies or substantial portions
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
**************************************************************************/
29
* Texture sampling code generation
31
* This file is nothing more than ugly glue between three largely independent
33
* - TGSI -> LLVM translation (i.e., lp_build_tgsi_soa)
34
* - texture sampling code generation (i.e., lp_build_sample_soa)
37
* All interesting code is in the functions mentioned above. There is really
38
* nothing to see here.
40
* @author Jose Fonseca <jfonseca@vmware.com>
43
#include "pipe/p_defines.h"
44
#include "pipe/p_shader_tokens.h"
45
#include "gallivm/lp_bld_debug.h"
46
#include "gallivm/lp_bld_const.h"
47
#include "gallivm/lp_bld_type.h"
48
#include "gallivm/lp_bld_sample.h"
49
#include "gallivm/lp_bld_tgsi.h"
51
#include "lp_tex_sample.h"
52
#include "lp_state_fs.h"
57
* This provides the bridge between the sampler state store in
58
* lp_jit_context and lp_jit_texture and the sampler code
59
* generator. It provides the texture layout information required by
60
* the texture sampler code generator in terms of the state stored in
61
* lp_jit_context and lp_jit_texture in runtime.
63
struct llvmpipe_sampler_dynamic_state
65
struct lp_sampler_dynamic_state base;
67
const struct lp_sampler_static_state *static_state;
72
* This is the bridge between our sampler and the TGSI translator.
74
struct lp_llvm_sampler_soa
76
struct lp_build_sampler_soa base;
78
struct llvmpipe_sampler_dynamic_state dynamic_state;
82
struct llvmpipe_image_dynamic_state
84
struct lp_sampler_dynamic_state base;
86
const struct lp_image_static_state *static_state;
90
* This is the bridge between our sampler and the TGSI translator.
92
struct lp_llvm_image_soa
94
struct lp_build_image_soa base;
96
struct llvmpipe_image_dynamic_state dynamic_state;
102
* Fetch the specified member of the lp_jit_texture structure.
103
* \param emit_load if TRUE, emit the LLVM load instruction to actually
104
* fetch the field's value. Otherwise, just emit the
105
* GEP code to address the field.
107
* @sa http://llvm.org/docs/GetElementPtr.html
110
lp_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
111
struct gallivm_state *gallivm,
112
LLVMValueRef context_ptr,
113
unsigned texture_unit,
114
LLVMValueRef texture_unit_offset,
115
unsigned member_index,
116
const char *member_name,
119
LLVMBuilderRef builder = gallivm->builder;
120
LLVMValueRef indices[4];
124
assert(texture_unit < PIPE_MAX_SHADER_SAMPLER_VIEWS);
127
indices[0] = lp_build_const_int32(gallivm, 0);
128
/* context[0].textures */
129
indices[1] = lp_build_const_int32(gallivm, LP_JIT_CTX_TEXTURES);
130
/* context[0].textures[unit] */
131
indices[2] = lp_build_const_int32(gallivm, texture_unit);
132
if (texture_unit_offset) {
133
indices[2] = LLVMBuildAdd(gallivm->builder, indices[2], texture_unit_offset, "");
134
LLVMValueRef cond = LLVMBuildICmp(gallivm->builder, LLVMIntULT, indices[2], lp_build_const_int32(gallivm, PIPE_MAX_SHADER_SAMPLER_VIEWS), "");
135
indices[2] = LLVMBuildSelect(gallivm->builder, cond, indices[2], lp_build_const_int32(gallivm, texture_unit), "");
137
/* context[0].textures[unit].member */
138
indices[3] = lp_build_const_int32(gallivm, member_index);
140
ptr = LLVMBuildGEP(builder, context_ptr, indices, ARRAY_SIZE(indices), "");
143
res = LLVMBuildLoad(builder, ptr, "");
147
lp_build_name(res, "context.texture%u.%s", texture_unit, member_name);
154
* Helper macro to instantiate the functions that generate the code to
155
* fetch the members of lp_jit_texture to fulfill the sampler code
156
* generator requests.
158
* This complexity is the price we have to pay to keep the texture
159
* sampler code generator a reusable module without dependencies to
160
* llvmpipe internals.
162
#define LP_LLVM_TEXTURE_MEMBER(_name, _index, _emit_load) \
163
static LLVMValueRef \
164
lp_llvm_texture_##_name( const struct lp_sampler_dynamic_state *base, \
165
struct gallivm_state *gallivm, \
166
LLVMValueRef context_ptr, \
167
unsigned texture_unit, \
168
LLVMValueRef texture_unit_offset) \
170
return lp_llvm_texture_member(base, gallivm, context_ptr, \
171
texture_unit, texture_unit_offset, \
172
_index, #_name, _emit_load ); \
176
LP_LLVM_TEXTURE_MEMBER(width, LP_JIT_TEXTURE_WIDTH, TRUE)
177
LP_LLVM_TEXTURE_MEMBER(height, LP_JIT_TEXTURE_HEIGHT, TRUE)
178
LP_LLVM_TEXTURE_MEMBER(depth, LP_JIT_TEXTURE_DEPTH, TRUE)
179
LP_LLVM_TEXTURE_MEMBER(first_level, LP_JIT_TEXTURE_FIRST_LEVEL, TRUE)
180
LP_LLVM_TEXTURE_MEMBER(last_level, LP_JIT_TEXTURE_LAST_LEVEL, TRUE)
181
LP_LLVM_TEXTURE_MEMBER(base_ptr, LP_JIT_TEXTURE_BASE, TRUE)
182
LP_LLVM_TEXTURE_MEMBER(row_stride, LP_JIT_TEXTURE_ROW_STRIDE, FALSE)
183
LP_LLVM_TEXTURE_MEMBER(img_stride, LP_JIT_TEXTURE_IMG_STRIDE, FALSE)
184
LP_LLVM_TEXTURE_MEMBER(mip_offsets, LP_JIT_TEXTURE_MIP_OFFSETS, FALSE)
185
LP_LLVM_TEXTURE_MEMBER(num_samples, LP_JIT_TEXTURE_NUM_SAMPLES, TRUE)
186
LP_LLVM_TEXTURE_MEMBER(sample_stride, LP_JIT_TEXTURE_SAMPLE_STRIDE, TRUE)
190
* Fetch the specified member of the lp_jit_sampler structure.
191
* \param emit_load if TRUE, emit the LLVM load instruction to actually
192
* fetch the field's value. Otherwise, just emit the
193
* GEP code to address the field.
195
* @sa http://llvm.org/docs/GetElementPtr.html
198
lp_llvm_sampler_member(const struct lp_sampler_dynamic_state *base,
199
struct gallivm_state *gallivm,
200
LLVMValueRef context_ptr,
201
unsigned sampler_unit,
202
unsigned member_index,
203
const char *member_name,
206
LLVMBuilderRef builder = gallivm->builder;
207
LLVMValueRef indices[4];
211
assert(sampler_unit < PIPE_MAX_SAMPLERS);
214
indices[0] = lp_build_const_int32(gallivm, 0);
215
/* context[0].samplers */
216
indices[1] = lp_build_const_int32(gallivm, LP_JIT_CTX_SAMPLERS);
217
/* context[0].samplers[unit] */
218
indices[2] = lp_build_const_int32(gallivm, sampler_unit);
219
/* context[0].samplers[unit].member */
220
indices[3] = lp_build_const_int32(gallivm, member_index);
222
ptr = LLVMBuildGEP(builder, context_ptr, indices, ARRAY_SIZE(indices), "");
225
res = LLVMBuildLoad(builder, ptr, "");
229
lp_build_name(res, "context.sampler%u.%s", sampler_unit, member_name);
235
#define LP_LLVM_SAMPLER_MEMBER(_name, _index, _emit_load) \
236
static LLVMValueRef \
237
lp_llvm_sampler_##_name( const struct lp_sampler_dynamic_state *base, \
238
struct gallivm_state *gallivm, \
239
LLVMValueRef context_ptr, \
240
unsigned sampler_unit) \
242
return lp_llvm_sampler_member(base, gallivm, context_ptr, \
243
sampler_unit, _index, #_name, _emit_load ); \
247
LP_LLVM_SAMPLER_MEMBER(min_lod, LP_JIT_SAMPLER_MIN_LOD, TRUE)
248
LP_LLVM_SAMPLER_MEMBER(max_lod, LP_JIT_SAMPLER_MAX_LOD, TRUE)
249
LP_LLVM_SAMPLER_MEMBER(lod_bias, LP_JIT_SAMPLER_LOD_BIAS, TRUE)
250
LP_LLVM_SAMPLER_MEMBER(border_color, LP_JIT_SAMPLER_BORDER_COLOR, FALSE)
251
LP_LLVM_SAMPLER_MEMBER(max_aniso, LP_JIT_SAMPLER_MAX_ANISO, TRUE)
255
* Fetch the specified member of the lp_jit_image structure.
256
* \param emit_load if TRUE, emit the LLVM load instruction to actually
257
* fetch the field's value. Otherwise, just emit the
258
* GEP code to address the field.
260
* @sa http://llvm.org/docs/GetElementPtr.html
263
lp_llvm_image_member(const struct lp_sampler_dynamic_state *base,
264
struct gallivm_state *gallivm,
265
LLVMValueRef context_ptr,
267
LLVMValueRef image_unit_offset,
268
unsigned member_index,
269
const char *member_name,
272
LLVMBuilderRef builder = gallivm->builder;
273
LLVMValueRef indices[4];
277
assert(image_unit < PIPE_MAX_SHADER_IMAGES);
280
indices[0] = lp_build_const_int32(gallivm, 0);
281
/* context[0].images */
282
indices[1] = lp_build_const_int32(gallivm, LP_JIT_CTX_IMAGES);
283
/* context[0].images[unit] */
284
indices[2] = lp_build_const_int32(gallivm, image_unit);
285
if (image_unit_offset) {
286
indices[2] = LLVMBuildAdd(gallivm->builder, indices[2], image_unit_offset, "");
287
LLVMValueRef cond = LLVMBuildICmp(gallivm->builder, LLVMIntULT, indices[2], lp_build_const_int32(gallivm, PIPE_MAX_SHADER_IMAGES), "");
288
indices[2] = LLVMBuildSelect(gallivm->builder, cond, indices[2], lp_build_const_int32(gallivm, image_unit), "");
290
/* context[0].images[unit].member */
291
indices[3] = lp_build_const_int32(gallivm, member_index);
293
ptr = LLVMBuildGEP(builder, context_ptr, indices, ARRAY_SIZE(indices), "");
296
res = LLVMBuildLoad(builder, ptr, "");
300
lp_build_name(res, "context.image%u.%s", image_unit, member_name);
307
* Helper macro to instantiate the functions that generate the code to
308
* fetch the members of lp_jit_image to fulfill the sampler code
309
* generator requests.
311
* This complexity is the price we have to pay to keep the image
312
* sampler code generator a reusable module without dependencies to
313
* llvmpipe internals.
315
#define LP_LLVM_IMAGE_MEMBER(_name, _index, _emit_load) \
316
static LLVMValueRef \
317
lp_llvm_image_##_name( const struct lp_sampler_dynamic_state *base, \
318
struct gallivm_state *gallivm, \
319
LLVMValueRef context_ptr, \
320
unsigned image_unit, LLVMValueRef image_unit_offset) \
322
return lp_llvm_image_member(base, gallivm, context_ptr, \
323
image_unit, image_unit_offset, \
324
_index, #_name, _emit_load ); \
328
LP_LLVM_IMAGE_MEMBER(width, LP_JIT_IMAGE_WIDTH, TRUE)
329
LP_LLVM_IMAGE_MEMBER(height, LP_JIT_IMAGE_HEIGHT, TRUE)
330
LP_LLVM_IMAGE_MEMBER(depth, LP_JIT_IMAGE_DEPTH, TRUE)
331
LP_LLVM_IMAGE_MEMBER(base_ptr, LP_JIT_IMAGE_BASE, TRUE)
332
LP_LLVM_IMAGE_MEMBER(row_stride, LP_JIT_IMAGE_ROW_STRIDE, TRUE)
333
LP_LLVM_IMAGE_MEMBER(img_stride, LP_JIT_IMAGE_IMG_STRIDE, TRUE)
334
LP_LLVM_IMAGE_MEMBER(num_samples, LP_JIT_IMAGE_NUM_SAMPLES, TRUE)
335
LP_LLVM_IMAGE_MEMBER(sample_stride, LP_JIT_IMAGE_SAMPLE_STRIDE, TRUE)
337
#if LP_USE_TEXTURE_CACHE
339
lp_llvm_texture_cache_ptr(const struct lp_sampler_dynamic_state *base,
340
struct gallivm_state *gallivm,
341
LLVMValueRef thread_data_ptr,
344
/* We use the same cache for all units */
347
return lp_jit_thread_data_cache(gallivm, thread_data_ptr);
353
lp_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
360
* Fetch filtered values from texture.
361
* The 'texel' parameter returns four vectors corresponding to R, G, B, A.
364
lp_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
365
struct gallivm_state *gallivm,
366
const struct lp_sampler_params *params)
368
struct lp_llvm_sampler_soa *sampler = (struct lp_llvm_sampler_soa *)base;
369
unsigned texture_index = params->texture_index;
370
unsigned sampler_index = params->sampler_index;
372
assert(sampler_index < PIPE_MAX_SAMPLERS);
373
assert(texture_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
375
if (LP_PERF & PERF_NO_TEX) {
376
lp_build_sample_nop(gallivm, params->type, params->coords, params->texel);
380
if (params->texture_index_offset) {
381
struct lp_build_sample_array_switch switch_info;
382
memset(&switch_info, 0, sizeof(switch_info));
383
LLVMValueRef unit = LLVMBuildAdd(gallivm->builder, params->texture_index_offset,
384
lp_build_const_int32(gallivm, texture_index), "");
385
lp_build_sample_array_init_soa(&switch_info, gallivm, params, unit,
386
0, sampler->nr_samplers);
388
for (unsigned i = 0; i < sampler->nr_samplers; i++) {
389
lp_build_sample_array_case_soa(&switch_info, i,
390
&sampler->dynamic_state.static_state[i].texture_state,
391
&sampler->dynamic_state.static_state[i].sampler_state,
392
&sampler->dynamic_state.base);
394
lp_build_sample_array_fini_soa(&switch_info);
396
lp_build_sample_soa(&sampler->dynamic_state.static_state[texture_index].texture_state,
397
&sampler->dynamic_state.static_state[sampler_index].sampler_state,
398
&sampler->dynamic_state.base,
404
* Fetch the texture size.
407
lp_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa *base,
408
struct gallivm_state *gallivm,
409
const struct lp_sampler_size_query_params *params)
411
struct lp_llvm_sampler_soa *sampler = (struct lp_llvm_sampler_soa *)base;
413
assert(params->texture_unit < PIPE_MAX_SHADER_SAMPLER_VIEWS);
415
lp_build_size_query_soa(gallivm,
416
&sampler->dynamic_state.static_state[params->texture_unit].texture_state,
417
&sampler->dynamic_state.base,
422
struct lp_build_sampler_soa *
423
lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
424
unsigned nr_samplers)
426
struct lp_llvm_sampler_soa *sampler;
428
sampler = CALLOC_STRUCT(lp_llvm_sampler_soa);
432
sampler->base.destroy = lp_llvm_sampler_soa_destroy;
433
sampler->base.emit_tex_sample = lp_llvm_sampler_soa_emit_fetch_texel;
434
sampler->base.emit_size_query = lp_llvm_sampler_soa_emit_size_query;
435
sampler->dynamic_state.base.width = lp_llvm_texture_width;
436
sampler->dynamic_state.base.height = lp_llvm_texture_height;
437
sampler->dynamic_state.base.depth = lp_llvm_texture_depth;
438
sampler->dynamic_state.base.first_level = lp_llvm_texture_first_level;
439
sampler->dynamic_state.base.last_level = lp_llvm_texture_last_level;
440
sampler->dynamic_state.base.base_ptr = lp_llvm_texture_base_ptr;
441
sampler->dynamic_state.base.row_stride = lp_llvm_texture_row_stride;
442
sampler->dynamic_state.base.img_stride = lp_llvm_texture_img_stride;
443
sampler->dynamic_state.base.mip_offsets = lp_llvm_texture_mip_offsets;
444
sampler->dynamic_state.base.num_samples = lp_llvm_texture_num_samples;
445
sampler->dynamic_state.base.sample_stride = lp_llvm_texture_sample_stride;
446
sampler->dynamic_state.base.min_lod = lp_llvm_sampler_min_lod;
447
sampler->dynamic_state.base.max_lod = lp_llvm_sampler_max_lod;
448
sampler->dynamic_state.base.lod_bias = lp_llvm_sampler_lod_bias;
449
sampler->dynamic_state.base.border_color = lp_llvm_sampler_border_color;
450
sampler->dynamic_state.base.max_aniso = lp_llvm_sampler_max_aniso;
452
#if LP_USE_TEXTURE_CACHE
453
sampler->dynamic_state.base.cache_ptr = lp_llvm_texture_cache_ptr;
456
sampler->dynamic_state.static_state = static_state;
458
sampler->nr_samplers = nr_samplers;
459
return &sampler->base;
463
lp_llvm_image_soa_destroy(struct lp_build_image_soa *image)
469
lp_llvm_image_soa_emit_op(const struct lp_build_image_soa *base,
470
struct gallivm_state *gallivm,
471
const struct lp_img_params *params)
473
struct lp_llvm_image_soa *image = (struct lp_llvm_image_soa *)base;
474
unsigned image_index = params->image_index;
475
assert(image_index < PIPE_MAX_SHADER_IMAGES);
477
if (params->image_index_offset) {
478
struct lp_build_img_op_array_switch switch_info;
479
memset(&switch_info, 0, sizeof(switch_info));
480
LLVMValueRef unit = LLVMBuildAdd(gallivm->builder, params->image_index_offset,
481
lp_build_const_int32(gallivm, image_index), "");
483
lp_build_image_op_switch_soa(&switch_info, gallivm, params,
484
unit, 0, image->nr_images);
486
for (unsigned i = 0; i < image->nr_images; i++) {
487
lp_build_image_op_array_case(&switch_info, i,
488
&image->dynamic_state.static_state[i].image_state,
489
&image->dynamic_state.base);
491
lp_build_image_op_array_fini_soa(&switch_info);
493
lp_build_img_op_soa(&image->dynamic_state.static_state[image_index].image_state,
494
&image->dynamic_state.base,
495
gallivm, params, params->outdata);
500
* Fetch the texture size.
503
lp_llvm_image_soa_emit_size_query(const struct lp_build_image_soa *base,
504
struct gallivm_state *gallivm,
505
const struct lp_sampler_size_query_params *params)
507
struct lp_llvm_image_soa *image = (struct lp_llvm_image_soa *)base;
509
assert(params->texture_unit < PIPE_MAX_SHADER_IMAGES);
511
lp_build_size_query_soa(gallivm,
512
&image->dynamic_state.static_state[params->texture_unit].image_state,
513
&image->dynamic_state.base,
517
struct lp_build_image_soa *
518
lp_llvm_image_soa_create(const struct lp_image_static_state *static_state,
521
struct lp_llvm_image_soa *image;
523
image = CALLOC_STRUCT(lp_llvm_image_soa);
527
image->base.destroy = lp_llvm_image_soa_destroy;
528
image->base.emit_op = lp_llvm_image_soa_emit_op;
529
image->base.emit_size_query = lp_llvm_image_soa_emit_size_query;
531
image->dynamic_state.base.width = lp_llvm_image_width;
532
image->dynamic_state.base.height = lp_llvm_image_height;
534
image->dynamic_state.base.depth = lp_llvm_image_depth;
535
image->dynamic_state.base.base_ptr = lp_llvm_image_base_ptr;
536
image->dynamic_state.base.row_stride = lp_llvm_image_row_stride;
537
image->dynamic_state.base.img_stride = lp_llvm_image_img_stride;
538
image->dynamic_state.base.num_samples = lp_llvm_image_num_samples;
539
image->dynamic_state.base.sample_stride = lp_llvm_image_sample_stride;
541
image->dynamic_state.static_state = static_state;
543
image->nr_images = nr_images;