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