~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/drivers/llvmpipe/lp_tex_sample.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**************************************************************************
2
 
 * 
3
 
 * Copyright 2009 VMware, Inc.
4
 
 * All rights reserved.
5
 
 *
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:
13
 
 * 
14
 
 * The above copyright notice and this permission notice (including the
15
 
 * next paragraph) shall be included in all copies or substantial portions
16
 
 * of the Software.
17
 
 * 
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.
25
 
 * 
26
 
 **************************************************************************/
27
 
 
28
 
/**
29
 
 * Texture sampling code generation
30
 
 *
31
 
 * This file is nothing more than ugly glue between three largely independent
32
 
 * entities:
33
 
 * - TGSI -> LLVM translation (i.e., lp_build_tgsi_soa)
34
 
 * - texture sampling code generation (i.e., lp_build_sample_soa)
35
 
 * - LLVM pipe driver
36
 
 *
37
 
 * All interesting code is in the functions mentioned above. There is really
38
 
 * nothing to see here.
39
 
 *
40
 
 * @author Jose Fonseca <jfonseca@vmware.com>
41
 
 */
42
 
 
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"
50
 
#include "lp_jit.h"
51
 
#include "lp_tex_sample.h"
52
 
#include "lp_state_fs.h"
53
 
#include "lp_debug.h"
54
 
 
55
 
 
56
 
/**
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.
62
 
 */
63
 
struct llvmpipe_sampler_dynamic_state
64
 
{
65
 
   struct lp_sampler_dynamic_state base;
66
 
 
67
 
   const struct lp_sampler_static_state *static_state;
68
 
};
69
 
 
70
 
 
71
 
/**
72
 
 * This is the bridge between our sampler and the TGSI translator.
73
 
 */
74
 
struct lp_llvm_sampler_soa
75
 
{
76
 
   struct lp_build_sampler_soa base;
77
 
 
78
 
   struct llvmpipe_sampler_dynamic_state dynamic_state;
79
 
   unsigned nr_samplers;
80
 
};
81
 
 
82
 
struct llvmpipe_image_dynamic_state
83
 
{
84
 
   struct lp_sampler_dynamic_state base;
85
 
 
86
 
   const struct lp_image_static_state *static_state;
87
 
};
88
 
 
89
 
/**
90
 
 * This is the bridge between our sampler and the TGSI translator.
91
 
 */
92
 
struct lp_llvm_image_soa
93
 
{
94
 
   struct lp_build_image_soa base;
95
 
 
96
 
   struct llvmpipe_image_dynamic_state dynamic_state;
97
 
   unsigned nr_images;
98
 
};
99
 
 
100
 
 
101
 
/**
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.
106
 
 *
107
 
 * @sa http://llvm.org/docs/GetElementPtr.html
108
 
 */
109
 
static LLVMValueRef
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,
117
 
                       boolean emit_load)
118
 
{
119
 
   LLVMBuilderRef builder = gallivm->builder;
120
 
   LLVMValueRef indices[4];
121
 
   LLVMValueRef ptr;
122
 
   LLVMValueRef res;
123
 
 
124
 
   assert(texture_unit < PIPE_MAX_SHADER_SAMPLER_VIEWS);
125
 
 
126
 
   /* context[0] */
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), "");
136
 
   }
137
 
   /* context[0].textures[unit].member */
138
 
   indices[3] = lp_build_const_int32(gallivm, member_index);
139
 
 
140
 
   ptr = LLVMBuildGEP(builder, context_ptr, indices, ARRAY_SIZE(indices), "");
141
 
 
142
 
   if (emit_load)
143
 
      res = LLVMBuildLoad(builder, ptr, "");
144
 
   else
145
 
      res = ptr;
146
 
 
147
 
   lp_build_name(res, "context.texture%u.%s", texture_unit, member_name);
148
 
 
149
 
   return res;
150
 
}
151
 
 
152
 
 
153
 
/**
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.
157
 
 *
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.
161
 
 */
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) \
169
 
   { \
170
 
      return lp_llvm_texture_member(base, gallivm, context_ptr, \
171
 
                                    texture_unit, texture_unit_offset,  \
172
 
                                    _index, #_name, _emit_load );       \
173
 
   }
174
 
 
175
 
 
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)
187
 
 
188
 
 
189
 
/**
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.
194
 
 *
195
 
 * @sa http://llvm.org/docs/GetElementPtr.html
196
 
 */
197
 
static LLVMValueRef
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,
204
 
                       boolean emit_load)
205
 
{
206
 
   LLVMBuilderRef builder = gallivm->builder;
207
 
   LLVMValueRef indices[4];
208
 
   LLVMValueRef ptr;
209
 
   LLVMValueRef res;
210
 
 
211
 
   assert(sampler_unit < PIPE_MAX_SAMPLERS);
212
 
 
213
 
   /* context[0] */
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);
221
 
 
222
 
   ptr = LLVMBuildGEP(builder, context_ptr, indices, ARRAY_SIZE(indices), "");
223
 
 
224
 
   if (emit_load)
225
 
      res = LLVMBuildLoad(builder, ptr, "");
226
 
   else
227
 
      res = ptr;
228
 
 
229
 
   lp_build_name(res, "context.sampler%u.%s", sampler_unit, member_name);
230
 
 
231
 
   return res;
232
 
}
233
 
 
234
 
 
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) \
241
 
   { \
242
 
      return lp_llvm_sampler_member(base, gallivm, context_ptr, \
243
 
                                    sampler_unit, _index, #_name, _emit_load ); \
244
 
   }
245
 
 
246
 
 
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)
252
 
 
253
 
 
254
 
/**
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.
259
 
 *
260
 
 * @sa http://llvm.org/docs/GetElementPtr.html
261
 
 */
262
 
static LLVMValueRef
263
 
lp_llvm_image_member(const struct lp_sampler_dynamic_state *base,
264
 
                     struct gallivm_state *gallivm,
265
 
                     LLVMValueRef context_ptr,
266
 
                     unsigned image_unit,
267
 
                     LLVMValueRef image_unit_offset,
268
 
                     unsigned member_index,
269
 
                     const char *member_name,
270
 
                     boolean emit_load)
271
 
{
272
 
   LLVMBuilderRef builder = gallivm->builder;
273
 
   LLVMValueRef indices[4];
274
 
   LLVMValueRef ptr;
275
 
   LLVMValueRef res;
276
 
 
277
 
   assert(image_unit < PIPE_MAX_SHADER_IMAGES);
278
 
 
279
 
   /* context[0] */
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), "");
289
 
   }
290
 
   /* context[0].images[unit].member */
291
 
   indices[3] = lp_build_const_int32(gallivm, member_index);
292
 
 
293
 
   ptr = LLVMBuildGEP(builder, context_ptr, indices, ARRAY_SIZE(indices), "");
294
 
 
295
 
   if (emit_load)
296
 
      res = LLVMBuildLoad(builder, ptr, "");
297
 
   else
298
 
      res = ptr;
299
 
 
300
 
   lp_build_name(res, "context.image%u.%s", image_unit, member_name);
301
 
 
302
 
   return res;
303
 
}
304
 
 
305
 
 
306
 
/**
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.
310
 
 *
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.
314
 
 */
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) \
321
 
   { \
322
 
      return lp_llvm_image_member(base, gallivm, context_ptr, \
323
 
                                  image_unit, image_unit_offset, \
324
 
                                  _index, #_name, _emit_load );  \
325
 
   }
326
 
 
327
 
 
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)
336
 
 
337
 
#if LP_USE_TEXTURE_CACHE
338
 
static LLVMValueRef
339
 
lp_llvm_texture_cache_ptr(const struct lp_sampler_dynamic_state *base,
340
 
                          struct gallivm_state *gallivm,
341
 
                          LLVMValueRef thread_data_ptr,
342
 
                          unsigned unit)
343
 
{
344
 
   /* We use the same cache for all units */
345
 
   (void)unit;
346
 
 
347
 
   return lp_jit_thread_data_cache(gallivm, thread_data_ptr);
348
 
}
349
 
#endif
350
 
 
351
 
 
352
 
static void
353
 
lp_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
354
 
{
355
 
   FREE(sampler);
356
 
}
357
 
 
358
 
 
359
 
/**
360
 
 * Fetch filtered values from texture.
361
 
 * The 'texel' parameter returns four vectors corresponding to R, G, B, A.
362
 
 */
363
 
static void
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)
367
 
{
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;
371
 
 
372
 
   assert(sampler_index < PIPE_MAX_SAMPLERS);
373
 
   assert(texture_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
374
 
   
375
 
   if (LP_PERF & PERF_NO_TEX) {
376
 
      lp_build_sample_nop(gallivm, params->type, params->coords, params->texel);
377
 
      return;
378
 
   }
379
 
 
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);
387
 
 
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);
393
 
      }
394
 
      lp_build_sample_array_fini_soa(&switch_info);
395
 
   } else {
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,
399
 
                          gallivm, params);
400
 
   }
401
 
}
402
 
 
403
 
/**
404
 
 * Fetch the texture size.
405
 
 */
406
 
static void
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)
410
 
{
411
 
   struct lp_llvm_sampler_soa *sampler = (struct lp_llvm_sampler_soa *)base;
412
 
 
413
 
   assert(params->texture_unit < PIPE_MAX_SHADER_SAMPLER_VIEWS);
414
 
 
415
 
   lp_build_size_query_soa(gallivm,
416
 
                           &sampler->dynamic_state.static_state[params->texture_unit].texture_state,
417
 
                           &sampler->dynamic_state.base,
418
 
                           params);
419
 
}
420
 
 
421
 
 
422
 
struct lp_build_sampler_soa *
423
 
lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
424
 
                           unsigned nr_samplers)
425
 
{
426
 
   struct lp_llvm_sampler_soa *sampler;
427
 
 
428
 
   sampler = CALLOC_STRUCT(lp_llvm_sampler_soa);
429
 
   if (!sampler)
430
 
      return NULL;
431
 
 
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;
451
 
 
452
 
#if LP_USE_TEXTURE_CACHE
453
 
   sampler->dynamic_state.base.cache_ptr = lp_llvm_texture_cache_ptr;
454
 
#endif
455
 
 
456
 
   sampler->dynamic_state.static_state = static_state;
457
 
 
458
 
   sampler->nr_samplers = nr_samplers;
459
 
   return &sampler->base;
460
 
}
461
 
 
462
 
static void
463
 
lp_llvm_image_soa_destroy(struct lp_build_image_soa *image)
464
 
{
465
 
   FREE(image);
466
 
}
467
 
 
468
 
static void
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)
472
 
{
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);
476
 
 
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), "");
482
 
 
483
 
      lp_build_image_op_switch_soa(&switch_info, gallivm, params,
484
 
                                   unit, 0, image->nr_images);
485
 
 
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);
490
 
      }
491
 
      lp_build_image_op_array_fini_soa(&switch_info);
492
 
   } else {
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);
496
 
   }
497
 
}
498
 
 
499
 
/**
500
 
 * Fetch the texture size.
501
 
 */
502
 
static void
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)
506
 
{
507
 
   struct lp_llvm_image_soa *image = (struct lp_llvm_image_soa *)base;
508
 
 
509
 
   assert(params->texture_unit < PIPE_MAX_SHADER_IMAGES);
510
 
 
511
 
   lp_build_size_query_soa(gallivm,
512
 
                           &image->dynamic_state.static_state[params->texture_unit].image_state,
513
 
                           &image->dynamic_state.base,
514
 
                           params);
515
 
}
516
 
 
517
 
struct lp_build_image_soa *
518
 
lp_llvm_image_soa_create(const struct lp_image_static_state *static_state,
519
 
                         unsigned nr_images)
520
 
{
521
 
   struct lp_llvm_image_soa *image;
522
 
 
523
 
   image = CALLOC_STRUCT(lp_llvm_image_soa);
524
 
   if (!image)
525
 
      return NULL;
526
 
 
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;
530
 
 
531
 
   image->dynamic_state.base.width = lp_llvm_image_width;
532
 
   image->dynamic_state.base.height = lp_llvm_image_height;
533
 
 
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;
540
 
 
541
 
   image->dynamic_state.static_state = static_state;
542
 
 
543
 
   image->nr_images = nr_images;
544
 
   return &image->base;
545
 
}