xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/llvmpipe/lp_jit.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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  * @file
30  * C - JIT interfaces
31  *
32  * @author Jose Fonseca <[email protected]>
33  */
34 
35 #include <llvm/Config/llvm-config.h>
36 
37 #include "util/u_memory.h"
38 #include "gallivm/lp_bld_init.h"
39 #include "gallivm/lp_bld_debug.h"
40 #include "gallivm/lp_bld_format.h"
41 #include "lp_context.h"
42 #include "lp_debug.h"
43 #include "lp_memory.h"
44 #include "lp_screen.h"
45 #include "lp_jit.h"
46 
47 static void
lp_jit_create_types(struct lp_fragment_shader_variant * lp)48 lp_jit_create_types(struct lp_fragment_shader_variant *lp)
49 {
50    struct gallivm_state *gallivm = lp->gallivm;
51    LLVMContextRef lc = gallivm->context;
52    LLVMTypeRef viewport_type;
53    LLVMTypeRef linear_elem_type;
54 
55    /* struct lp_jit_viewport */
56    {
57       LLVMTypeRef elem_types[LP_JIT_VIEWPORT_NUM_FIELDS];
58 
59       elem_types[LP_JIT_VIEWPORT_MIN_DEPTH] =
60       elem_types[LP_JIT_VIEWPORT_MAX_DEPTH] = LLVMFloatTypeInContext(lc);
61 
62       viewport_type = LLVMStructTypeInContext(lc, elem_types,
63                                               ARRAY_SIZE(elem_types), 0);
64 
65       LP_CHECK_MEMBER_OFFSET(struct lp_jit_viewport, min_depth,
66                              gallivm->target, viewport_type,
67                              LP_JIT_VIEWPORT_MIN_DEPTH);
68       LP_CHECK_MEMBER_OFFSET(struct lp_jit_viewport, max_depth,
69                              gallivm->target, viewport_type,
70                              LP_JIT_VIEWPORT_MAX_DEPTH);
71       LP_CHECK_STRUCT_SIZE(struct lp_jit_viewport,
72                            gallivm->target, viewport_type);
73    }
74 
75 
76    /* struct lp_jit_context */
77    {
78       LLVMTypeRef elem_types[LP_JIT_CTX_COUNT];
79       LLVMTypeRef context_type;
80 
81       elem_types[LP_JIT_CTX_ALPHA_REF] = LLVMFloatTypeInContext(lc);
82       elem_types[LP_JIT_CTX_SAMPLE_MASK] =
83       elem_types[LP_JIT_CTX_STENCIL_REF_FRONT] =
84       elem_types[LP_JIT_CTX_STENCIL_REF_BACK] = LLVMInt32TypeInContext(lc);
85       elem_types[LP_JIT_CTX_U8_BLEND_COLOR] = LLVMPointerType(LLVMInt8TypeInContext(lc), 0);
86       elem_types[LP_JIT_CTX_F_BLEND_COLOR] = LLVMPointerType(LLVMFloatTypeInContext(lc), 0);
87       elem_types[LP_JIT_CTX_VIEWPORTS] = LLVMPointerType(viewport_type, 0);
88 
89       context_type = LLVMStructTypeInContext(lc, elem_types,
90                                              ARRAY_SIZE(elem_types), 0);
91 
92       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, alpha_ref_value,
93                              gallivm->target, context_type,
94                              LP_JIT_CTX_ALPHA_REF);
95       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, stencil_ref_front,
96                              gallivm->target, context_type,
97                              LP_JIT_CTX_STENCIL_REF_FRONT);
98       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, stencil_ref_back,
99                              gallivm->target, context_type,
100                              LP_JIT_CTX_STENCIL_REF_BACK);
101       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, u8_blend_color,
102                              gallivm->target, context_type,
103                              LP_JIT_CTX_U8_BLEND_COLOR);
104       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, f_blend_color,
105                              gallivm->target, context_type,
106                              LP_JIT_CTX_F_BLEND_COLOR);
107       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, viewports,
108                              gallivm->target, context_type,
109                              LP_JIT_CTX_VIEWPORTS);
110       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, sample_mask,
111                              gallivm->target, context_type,
112                              LP_JIT_CTX_SAMPLE_MASK);
113       LP_CHECK_STRUCT_SIZE(struct lp_jit_context,
114                            gallivm->target, context_type);
115 
116       lp->jit_context_type = context_type;
117       lp->jit_context_ptr_type = LLVMPointerType(context_type, 0);
118       lp->jit_resources_type = lp_build_jit_resources_type(gallivm);
119       lp->jit_resources_ptr_type = LLVMPointerType(lp->jit_resources_type, 0);
120    }
121 
122    /* struct lp_jit_thread_data */
123    {
124       LLVMTypeRef elem_types[LP_JIT_THREAD_DATA_COUNT];
125       LLVMTypeRef thread_data_type;
126 
127       elem_types[LP_JIT_THREAD_DATA_CACHE] =
128             LLVMPointerType(lp_build_format_cache_type(gallivm), 0);
129       elem_types[LP_JIT_THREAD_DATA_VIS_COUNTER] = LLVMInt64TypeInContext(lc);
130       elem_types[LP_JIT_THREAD_DATA_PS_INVOCATIONS] = LLVMInt64TypeInContext(lc);
131       elem_types[LP_JIT_THREAD_DATA_RASTER_STATE_VIEWPORT_INDEX] =
132       elem_types[LP_JIT_THREAD_DATA_RASTER_STATE_VIEW_INDEX] =
133             LLVMInt32TypeInContext(lc);
134 
135       thread_data_type = LLVMStructTypeInContext(lc, elem_types,
136                                                  ARRAY_SIZE(elem_types), 0);
137 
138       lp->jit_thread_data_type = thread_data_type;
139       lp->jit_thread_data_ptr_type = LLVMPointerType(thread_data_type, 0);
140    }
141 
142    /*
143     * lp_linear_elem
144     *
145     * XXX: it can be instanced only once due to the use of opaque types, and
146     * the fact that screen->module is also a global.
147     */
148    {
149       LLVMTypeRef ret_type;
150       LLVMTypeRef arg_types[1];
151       LLVMTypeRef func_type;
152 
153       ret_type = LLVMPointerType(LLVMVectorType(LLVMInt8TypeInContext(lc), 16), 0);
154 
155       arg_types[0] = LLVMPointerType(LLVMInt8TypeInContext(lc), 0);
156 
157       /* lp_linear_func */
158       func_type = LLVMFunctionType(ret_type, arg_types, ARRAY_SIZE(arg_types), 0);
159 
160       /*
161        * We actually define lp_linear_elem not as a structure but simply as a
162        * lp_linear_func pointer
163        */
164       lp->jit_linear_func_type = func_type;
165       linear_elem_type = LLVMPointerType(func_type, 0);
166    }
167 
168    /* struct lp_jit_linear_context */
169    {
170       LLVMTypeRef linear_elem_ptr_type = LLVMPointerType(linear_elem_type, 0);
171       LLVMTypeRef elem_types[LP_JIT_LINEAR_CTX_COUNT];
172       LLVMTypeRef linear_context_type;
173 
174 
175       elem_types[LP_JIT_LINEAR_CTX_CONSTANTS] = LLVMPointerType(LLVMInt8TypeInContext(lc), 0);
176       elem_types[LP_JIT_LINEAR_CTX_TEX] =
177       lp->jit_linear_textures_type =
178             LLVMArrayType(linear_elem_ptr_type, LP_MAX_LINEAR_TEXTURES);
179 
180       elem_types[LP_JIT_LINEAR_CTX_INPUTS] =
181       lp->jit_linear_inputs_type =
182             LLVMArrayType(linear_elem_ptr_type, LP_MAX_LINEAR_INPUTS);
183       elem_types[LP_JIT_LINEAR_CTX_COLOR0] = LLVMPointerType(LLVMInt8TypeInContext(lc), 0);
184       elem_types[LP_JIT_LINEAR_CTX_BLEND_COLOR] = LLVMInt32TypeInContext(lc);
185       elem_types[LP_JIT_LINEAR_CTX_ALPHA_REF] = LLVMInt8TypeInContext(lc);
186 
187       linear_context_type = LLVMStructTypeInContext(lc, elem_types,
188                                                     ARRAY_SIZE(elem_types), 0);
189 
190       LP_CHECK_MEMBER_OFFSET(struct lp_jit_linear_context, constants,
191                              gallivm->target, linear_context_type,
192                              LP_JIT_LINEAR_CTX_CONSTANTS);
193       LP_CHECK_MEMBER_OFFSET(struct lp_jit_linear_context, tex,
194                              gallivm->target, linear_context_type,
195                              LP_JIT_LINEAR_CTX_TEX);
196       LP_CHECK_MEMBER_OFFSET(struct lp_jit_linear_context, inputs,
197                              gallivm->target, linear_context_type,
198                              LP_JIT_LINEAR_CTX_INPUTS);
199       LP_CHECK_MEMBER_OFFSET(struct lp_jit_linear_context, color0,
200                              gallivm->target, linear_context_type,
201                              LP_JIT_LINEAR_CTX_COLOR0);
202       LP_CHECK_MEMBER_OFFSET(struct lp_jit_linear_context, blend_color,
203                              gallivm->target, linear_context_type,
204                              LP_JIT_LINEAR_CTX_BLEND_COLOR);
205       LP_CHECK_MEMBER_OFFSET(struct lp_jit_linear_context, alpha_ref_value,
206                              gallivm->target, linear_context_type,
207                              LP_JIT_LINEAR_CTX_ALPHA_REF);
208       LP_CHECK_STRUCT_SIZE(struct lp_jit_linear_context,
209                            gallivm->target, linear_context_type);
210 
211       lp->jit_linear_context_type = linear_context_type;
212       lp->jit_linear_context_ptr_type = LLVMPointerType(linear_context_type, 0);
213    }
214 
215    if (gallivm_debug & GALLIVM_DEBUG_IR) {
216       char *str = LLVMPrintModuleToString(gallivm->module);
217       fprintf(stderr, "%s", str);
218       LLVMDisposeMessage(str);
219    }
220 }
221 
222 
223 void
lp_jit_screen_cleanup(struct llvmpipe_screen * screen)224 lp_jit_screen_cleanup(struct llvmpipe_screen *screen)
225 {
226    /* nothing */
227 }
228 
229 
230 bool
lp_jit_screen_init(struct llvmpipe_screen * screen)231 lp_jit_screen_init(struct llvmpipe_screen *screen)
232 {
233    return lp_build_init();
234 }
235 
236 
237 void
lp_jit_init_types(struct lp_fragment_shader_variant * lp)238 lp_jit_init_types(struct lp_fragment_shader_variant *lp)
239 {
240    if (!lp->jit_context_ptr_type)
241       lp_jit_create_types(lp);
242 }
243 
244 static void
lp_jit_create_cs_types(struct lp_compute_shader_variant * lp)245 lp_jit_create_cs_types(struct lp_compute_shader_variant *lp)
246 {
247    struct gallivm_state *gallivm = lp->gallivm;
248    LLVMContextRef lc = gallivm->context;
249 
250    /* struct lp_jit_cs_thread_data */
251    {
252       LLVMTypeRef elem_types[LP_JIT_CS_THREAD_DATA_COUNT];
253       LLVMTypeRef thread_data_type;
254 
255       elem_types[LP_JIT_CS_THREAD_DATA_CACHE] =
256             LLVMPointerType(lp_build_format_cache_type(gallivm), 0);
257 
258       elem_types[LP_JIT_CS_THREAD_DATA_SHARED] = LLVMPointerType(LLVMInt32TypeInContext(lc), 0);
259 
260       elem_types[LP_JIT_CS_THREAD_DATA_PAYLOAD] = LLVMPointerType(LLVMInt8TypeInContext(lc), 0);
261       thread_data_type = LLVMStructTypeInContext(lc, elem_types,
262                                                  ARRAY_SIZE(elem_types), 0);
263 
264       lp->jit_cs_thread_data_type = thread_data_type;
265       lp->jit_cs_thread_data_ptr_type = LLVMPointerType(thread_data_type, 0);
266    }
267 
268    /* struct lp_jit_cs_context */
269    {
270       LLVMTypeRef elem_types[LP_JIT_CS_CTX_COUNT];
271       LLVMTypeRef cs_context_type;
272 
273       elem_types[LP_JIT_CS_CTX_KERNEL_ARGS] = LLVMPointerType(LLVMInt8TypeInContext(lc), 0);
274       elem_types[LP_JIT_CS_CTX_SHARED_SIZE] = LLVMInt32TypeInContext(lc);
275 
276       cs_context_type = LLVMStructTypeInContext(lc, elem_types,
277                                              ARRAY_SIZE(elem_types), 0);
278 
279       LP_CHECK_MEMBER_OFFSET(struct lp_jit_cs_context, kernel_args,
280                              gallivm->target, cs_context_type,
281                              LP_JIT_CS_CTX_KERNEL_ARGS);
282       LP_CHECK_MEMBER_OFFSET(struct lp_jit_cs_context, shared_size,
283                              gallivm->target, cs_context_type,
284                              LP_JIT_CS_CTX_SHARED_SIZE);
285       LP_CHECK_STRUCT_SIZE(struct lp_jit_cs_context,
286                            gallivm->target, cs_context_type);
287 
288       lp->jit_cs_context_type = cs_context_type;
289       lp->jit_cs_context_ptr_type = LLVMPointerType(cs_context_type, 0);
290       lp->jit_resources_type = lp_build_jit_resources_type(gallivm);
291       lp->jit_resources_ptr_type = LLVMPointerType(lp->jit_resources_type, 0);
292    }
293 
294    if (gallivm_debug & GALLIVM_DEBUG_IR) {
295       char *str = LLVMPrintModuleToString(gallivm->module);
296       fprintf(stderr, "%s", str);
297       LLVMDisposeMessage(str);
298    }
299 }
300 
301 void
lp_jit_init_cs_types(struct lp_compute_shader_variant * lp)302 lp_jit_init_cs_types(struct lp_compute_shader_variant *lp)
303 {
304    if (!lp->jit_cs_context_ptr_type)
305       lp_jit_create_cs_types(lp);
306 }
307 
308 void
lp_jit_buffer_from_pipe(struct lp_jit_buffer * jit,const struct pipe_shader_buffer * buffer)309 lp_jit_buffer_from_pipe(struct lp_jit_buffer *jit, const struct pipe_shader_buffer *buffer)
310 {
311    const uint8_t *current_data = NULL;
312 
313    /* resource buffer */
314    if (buffer->buffer)
315       current_data = (uint8_t *)llvmpipe_resource_data(buffer->buffer);
316 
317    if (current_data) {
318       current_data += buffer->buffer_offset;
319       jit->u = (const uint32_t *)current_data;
320       jit->num_elements = buffer->buffer_size;
321    } else {
322       jit->u = NULL;
323       jit->num_elements = 0;
324    }
325 }
326 
327 void
lp_jit_buffer_from_bda(struct lp_jit_buffer * jit,void * mem,size_t size)328 lp_jit_buffer_from_bda(struct lp_jit_buffer *jit, void *mem, size_t size)
329 {
330    const uint8_t *current_data = mem;
331 
332    if (current_data) {
333       jit->u = (const uint32_t *)current_data;
334       jit->num_elements = size;
335    } else {
336       jit->u = NULL;
337       jit->num_elements = 0;
338    }
339 }
340 
341 void
lp_jit_buffer_from_pipe_const(struct lp_jit_buffer * jit,const struct pipe_constant_buffer * buffer,struct pipe_screen * screen)342 lp_jit_buffer_from_pipe_const(struct lp_jit_buffer *jit, const struct pipe_constant_buffer *buffer, struct pipe_screen *screen)
343 {
344    uint64_t current_size = buffer->buffer_size;
345 
346    const uint8_t *current_data = NULL;
347    if (buffer->buffer) {
348       /* resource buffer */
349       current_data = (uint8_t *)llvmpipe_resource_data(buffer->buffer);
350    } else if (buffer->user_buffer) {
351       /* user-space buffer */
352       current_data = (uint8_t *)buffer->user_buffer;
353    }
354 
355    if (current_data && current_size >= sizeof(float)) {
356       current_data += buffer->buffer_offset;
357       jit->f = (const float *)current_data;
358       jit->num_elements = DIV_ROUND_UP(current_size, lp_get_constant_buffer_stride(screen));
359    } else {
360       static const float fake_const_buf[4];
361       jit->f = fake_const_buf;
362       jit->num_elements = 0;
363    }
364 }
365 
366 void
lp_jit_texture_from_pipe(struct lp_jit_texture * jit,const struct pipe_sampler_view * view)367 lp_jit_texture_from_pipe(struct lp_jit_texture *jit, const struct pipe_sampler_view *view)
368 {
369    struct pipe_resource *res = view->texture;
370    struct llvmpipe_resource *lp_tex = llvmpipe_resource(res);
371 
372    if (!lp_tex->dt) {
373       /* regular texture - setup array of mipmap level offsets */
374       unsigned first_level = 0;
375       unsigned last_level = 0;
376 
377       if (llvmpipe_resource_is_texture(res)) {
378          first_level = view->u.tex.first_level;
379          last_level = view->u.tex.last_level;
380          assert(first_level <= last_level);
381          assert(last_level <= res->last_level);
382          jit->base = lp_tex->tex_data;
383       } else {
384          jit->base = lp_tex->data;
385       }
386 
387       if (LP_PERF & PERF_TEX_MEM) {
388          /* use dummy tile memory */
389          jit->base = lp_dummy_tile;
390          jit->width = TILE_SIZE/8;
391          jit->height = TILE_SIZE/8;
392          jit->depth = 1;
393          jit->first_level = 0;
394          jit->last_level = 0;
395          jit->mip_offsets[0] = 0;
396          jit->mip_offsets[LP_JIT_TEXTURE_SAMPLE_STRIDE] = 0;
397          jit->row_stride[0] = 0;
398          jit->img_stride[0] = 0;
399       } else {
400          jit->width = res->width0;
401          jit->height = res->height0;
402          jit->depth = res->depth0;
403          jit->first_level = first_level;
404          jit->last_level = last_level;
405          jit->mip_offsets[0] = 0;
406 
407          if (llvmpipe_resource_is_texture(res)) {
408             if (res->nr_samples > 1) {
409                jit->last_level = res->nr_samples;
410                jit->mip_offsets[LP_JIT_TEXTURE_SAMPLE_STRIDE] = lp_tex->sample_stride;
411                jit->row_stride[0] = lp_tex->row_stride[0];
412                jit->img_stride[0] = lp_tex->img_stride[0];
413             } else {
414                for (unsigned j = first_level; j <= last_level; j++) {
415                   jit->mip_offsets[j] = lp_tex->mip_offsets[j];
416                   jit->row_stride[j] = lp_tex->row_stride[j];
417                   jit->img_stride[j] = lp_tex->img_stride[j];
418                }
419             }
420 
421             bool is_2d_view_of_3d = res->target == PIPE_TEXTURE_3D && view->target == PIPE_TEXTURE_2D;
422 
423             if (res->target == PIPE_TEXTURE_1D_ARRAY ||
424                 res->target == PIPE_TEXTURE_2D_ARRAY ||
425                 res->target == PIPE_TEXTURE_CUBE ||
426                 res->target == PIPE_TEXTURE_CUBE_ARRAY ||
427                 is_2d_view_of_3d) {
428                /*
429                 * For array textures, we don't have first_layer, instead
430                 * adjust last_layer (stored as depth) plus the mip level
431                 * offsets (as we have mip-first layout can't just adjust
432                 * base ptr).  XXX For mip levels, could do something
433                 * similar.
434                 */
435                jit->depth = view->u.tex.last_layer - view->u.tex.first_layer + 1;
436                for (unsigned j = first_level; j <= last_level; j++) {
437                   if (is_2d_view_of_3d && (res->flags & PIPE_RESOURCE_FLAG_SPARSE)) {
438                      jit->mip_offsets[j] = llvmpipe_get_texel_offset(
439                         view->texture, j, 0, 0, view->u.tex.first_layer);
440                   } else {
441                      jit->mip_offsets[j] += view->u.tex.first_layer *
442                                                 lp_tex->img_stride[j];
443                   }
444                }
445                if (view->target == PIPE_TEXTURE_CUBE ||
446                    view->target == PIPE_TEXTURE_CUBE_ARRAY) {
447                   assert(jit->depth % 6 == 0);
448                }
449                assert(view->u.tex.first_layer <= view->u.tex.last_layer);
450                if (res->target == PIPE_TEXTURE_3D)
451                   assert(view->u.tex.last_layer < res->depth0);
452                else
453                   assert(view->u.tex.last_layer < res->array_size);
454             }
455 
456             if (res->flags & PIPE_RESOURCE_FLAG_SPARSE)
457                jit->residency = lp_tex->residency;
458          } else {
459             /*
460              * For tex2d_from_buf, adjust width and height with application
461              * values. If is_tex2d_from_buf is false (1D images),
462              * adjust using size value (stored as width).
463              */
464             unsigned view_blocksize = util_format_get_blocksize(view->format);
465 
466             jit->mip_offsets[0] = 0;
467             jit->img_stride[0] = 0;
468 
469             /* If it's not a 2D texture view of a buffer, adjust using size. */
470             if (!view->is_tex2d_from_buf) {
471                /* everything specified in number of elements here. */
472                jit->width = view->u.buf.size / view_blocksize;
473                jit->row_stride[0] = 0;
474 
475                /* Adjust base pointer with offset. */
476                jit->base = (uint8_t *)jit->base + view->u.buf.offset;
477 
478                /* XXX Unsure if we need to sanitize parameters? */
479                assert(view->u.buf.offset + view->u.buf.size <= res->width0);
480             } else {
481                jit->width = view->u.tex2d_from_buf.width;
482                jit->height = view->u.tex2d_from_buf.height;
483                jit->row_stride[0] = view->u.tex2d_from_buf.row_stride * view_blocksize;
484 
485                jit->base = (uint8_t *)jit->base +
486                   view->u.tex2d_from_buf.offset * view_blocksize;
487             }
488          }
489       }
490    } else {
491       /* display target texture/surface */
492       jit->base = llvmpipe_resource_map(res, 0, 0, LP_TEX_USAGE_READ);
493       jit->row_stride[0] = lp_tex->row_stride[0];
494       jit->img_stride[0] = lp_tex->img_stride[0];
495       jit->mip_offsets[0] = 0;
496       jit->width = res->width0;
497       jit->height = res->height0;
498       jit->depth = res->depth0;
499       jit->first_level = jit->last_level = 0;
500       if (res->nr_samples > 1)
501          jit->last_level = res->nr_samples;
502       assert(jit->base);
503    }
504 }
505 
506 void
lp_jit_texture_buffer_from_bda(struct lp_jit_texture * jit,void * mem,size_t size,enum pipe_format format)507 lp_jit_texture_buffer_from_bda(struct lp_jit_texture *jit, void *mem, size_t size, enum pipe_format format)
508 {
509    jit->base = mem;
510 
511    if (LP_PERF & PERF_TEX_MEM) {
512       /* use dummy tile memory */
513       jit->base = lp_dummy_tile;
514       jit->width = TILE_SIZE/8;
515       jit->height = TILE_SIZE/8;
516       jit->depth = 1;
517       jit->first_level = 0;
518       jit->last_level = 0;
519       jit->mip_offsets[0] = 0;
520       jit->row_stride[0] = 0;
521       jit->img_stride[0] = 0;
522    } else {
523       jit->height = 1;
524       jit->depth = 1;
525       jit->first_level = 0;
526       jit->last_level = 0;
527 
528       /*
529        * For buffers, we don't have "offset", instead adjust
530        * the size (stored as width) plus the base pointer.
531        */
532       const unsigned view_blocksize = util_format_get_blocksize(format);
533       /* probably don't really need to fill that out */
534       jit->mip_offsets[0] = 0;
535       jit->row_stride[0] = 0;
536       jit->img_stride[0] = 0;
537 
538       /* everything specified in number of elements here. */
539       jit->width = size / view_blocksize;
540    }
541 }
542 
543 void
lp_jit_sampler_from_pipe(struct lp_jit_sampler * jit,const struct pipe_sampler_state * sampler)544 lp_jit_sampler_from_pipe(struct lp_jit_sampler *jit, const struct pipe_sampler_state *sampler)
545 {
546    jit->min_lod = sampler->min_lod;
547    jit->max_lod = sampler->max_lod;
548    jit->lod_bias = sampler->lod_bias;
549    jit->max_aniso = sampler->max_anisotropy;
550    COPY_4V(jit->border_color, sampler->border_color.f);
551 }
552 
553 void
lp_jit_image_from_pipe(struct lp_jit_image * jit,const struct pipe_image_view * view)554 lp_jit_image_from_pipe(struct lp_jit_image *jit, const struct pipe_image_view *view)
555 {
556    struct pipe_resource *res = view->resource;
557    struct llvmpipe_resource *lp_res = llvmpipe_resource(res);
558 
559    if (!lp_res->dt) {
560       /* regular texture - setup array of mipmap level offsets */
561       if (llvmpipe_resource_is_texture(res)) {
562          jit->base = lp_res->tex_data;
563       } else {
564          jit->base = lp_res->data;
565       }
566 
567       jit->width = res->width0;
568       jit->height = res->height0;
569       jit->depth = res->depth0;
570       jit->num_samples = res->nr_samples;
571 
572       if (llvmpipe_resource_is_texture(res)) {
573          uint32_t mip_offset = lp_res->mip_offsets[view->u.tex.level];
574 
575          jit->width = u_minify(jit->width, view->u.tex.level);
576          jit->height = u_minify(jit->height, view->u.tex.level);
577 
578          if (res->target == PIPE_TEXTURE_1D_ARRAY ||
579              res->target == PIPE_TEXTURE_2D_ARRAY ||
580              res->target == PIPE_TEXTURE_3D ||
581              res->target == PIPE_TEXTURE_CUBE ||
582              res->target == PIPE_TEXTURE_CUBE_ARRAY) {
583             /*
584              * For array textures, we don't have first_layer, instead
585              * adjust last_layer (stored as depth) plus the mip level offsets
586              * (as we have mip-first layout can't just adjust base ptr).
587              * XXX For mip levels, could do something similar.
588              */
589             jit->depth = view->u.tex.last_layer - view->u.tex.first_layer + 1;
590 
591             if (res->target == PIPE_TEXTURE_3D && view->u.tex.first_layer != 0 &&
592                 (res->flags & PIPE_RESOURCE_FLAG_SPARSE)) {
593                mip_offset = llvmpipe_get_texel_offset(
594                   res, view->u.tex.level, 0, 0, view->u.tex.first_layer);
595             } else {
596                mip_offset += view->u.tex.first_layer * lp_res->img_stride[view->u.tex.level];
597             }
598          } else
599             jit->depth = u_minify(jit->depth, view->u.tex.level);
600 
601          jit->row_stride = lp_res->row_stride[view->u.tex.level];
602          jit->img_stride = lp_res->img_stride[view->u.tex.level];
603          jit->sample_stride = lp_res->sample_stride;
604          jit->base = (uint8_t *)jit->base + mip_offset;
605       } else {
606          unsigned image_blocksize = util_format_get_blocksize(view->format);
607 
608          jit->img_stride = 0;
609 
610          /* If it's not a 2D image view of a buffer, adjust using size. */
611          if (!(view->access & PIPE_IMAGE_ACCESS_TEX2D_FROM_BUFFER)) {
612             /* everything specified in number of elements here. */
613             jit->width = view->u.buf.size / image_blocksize;
614             jit->row_stride = 0;
615 
616             /* Adjust base pointer with offset. */
617             jit->base = (uint8_t *)jit->base + view->u.buf.offset;
618 
619             /* XXX Unsure if we need to sanitize parameters? */
620             assert(view->u.buf.offset + view->u.buf.size <= res->width0);
621          } else {
622             jit->width = view->u.tex2d_from_buf.width;
623             jit->height = view->u.tex2d_from_buf.height;
624             jit->row_stride = view->u.tex2d_from_buf.row_stride * image_blocksize;
625 
626             jit->base = (uint8_t *)jit->base +
627                view->u.tex2d_from_buf.offset * image_blocksize;
628          }
629       }
630 
631       if (res->flags & PIPE_RESOURCE_FLAG_SPARSE) {
632          jit->residency = lp_res->residency;
633          jit->base_offset = (uint32_t)((uintptr_t)jit->base - (uintptr_t)lp_res->tex_data);
634       }
635    }
636 }
637 
638 void
lp_jit_image_buffer_from_bda(struct lp_jit_image * jit,void * mem,size_t size,enum pipe_format format)639 lp_jit_image_buffer_from_bda(struct lp_jit_image *jit, void *mem, size_t size, enum pipe_format format)
640 {
641    jit->base = mem;
642 
643    jit->height = 1;
644    jit->depth = 1;
645    jit->num_samples = 1;
646 
647    unsigned view_blocksize = util_format_get_blocksize(format);
648    jit->width = size / view_blocksize;
649 }
650