• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <jfonseca@vmware.com>
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             if (res->target == PIPE_TEXTURE_1D_ARRAY ||
422                 res->target == PIPE_TEXTURE_2D_ARRAY ||
423                 res->target == PIPE_TEXTURE_CUBE ||
424                 res->target == PIPE_TEXTURE_CUBE_ARRAY ||
425                 (res->target == PIPE_TEXTURE_3D && view->target == PIPE_TEXTURE_2D)) {
426                /*
427                 * For array textures, we don't have first_layer, instead
428                 * adjust last_layer (stored as depth) plus the mip level
429                 * offsets (as we have mip-first layout can't just adjust
430                 * base ptr).  XXX For mip levels, could do something
431                 * similar.
432                 */
433                jit->depth = view->u.tex.last_layer - view->u.tex.first_layer + 1;
434                for (unsigned j = first_level; j <= last_level; j++) {
435                   jit->mip_offsets[j] += view->u.tex.first_layer *
436                                              lp_tex->img_stride[j];
437                }
438                if (view->target == PIPE_TEXTURE_CUBE ||
439                    view->target == PIPE_TEXTURE_CUBE_ARRAY) {
440                   assert(jit->depth % 6 == 0);
441                }
442                assert(view->u.tex.first_layer <= view->u.tex.last_layer);
443                if (res->target == PIPE_TEXTURE_3D)
444                   assert(view->u.tex.last_layer < res->depth0);
445                else
446                   assert(view->u.tex.last_layer < res->array_size);
447             }
448          } else {
449             /*
450              * For tex2d_from_buf, adjust width and height with application
451              * values. If is_tex2d_from_buf is false (1D images),
452              * adjust using size value (stored as width).
453              */
454             unsigned view_blocksize = util_format_get_blocksize(view->format);
455 
456             jit->mip_offsets[0] = 0;
457             jit->img_stride[0] = 0;
458 
459             /* If it's not a 2D texture view of a buffer, adjust using size. */
460             if (!view->is_tex2d_from_buf) {
461                /* everything specified in number of elements here. */
462                jit->width = view->u.buf.size / view_blocksize;
463                jit->row_stride[0] = 0;
464 
465                /* Adjust base pointer with offset. */
466                jit->base = (uint8_t *)jit->base + view->u.buf.offset;
467 
468                /* XXX Unsure if we need to sanitize parameters? */
469                assert(view->u.buf.offset + view->u.buf.size <= res->width0);
470             } else {
471                jit->width = view->u.tex2d_from_buf.width;
472                jit->height = view->u.tex2d_from_buf.height;
473                jit->row_stride[0] = view->u.tex2d_from_buf.row_stride * view_blocksize;
474 
475                jit->base = (uint8_t *)jit->base +
476                   view->u.tex2d_from_buf.offset * view_blocksize;
477             }
478          }
479       }
480    } else {
481       /* display target texture/surface */
482       jit->base = llvmpipe_resource_map(res, 0, 0, LP_TEX_USAGE_READ);
483       jit->row_stride[0] = lp_tex->row_stride[0];
484       jit->img_stride[0] = lp_tex->img_stride[0];
485       jit->mip_offsets[0] = 0;
486       jit->width = res->width0;
487       jit->height = res->height0;
488       jit->depth = res->depth0;
489       jit->first_level = jit->last_level = 0;
490       if (res->nr_samples > 1)
491          jit->last_level = res->nr_samples;
492       assert(jit->base);
493    }
494 }
495 
496 void
lp_jit_texture_buffer_from_bda(struct lp_jit_texture * jit,void * mem,size_t size,enum pipe_format format)497 lp_jit_texture_buffer_from_bda(struct lp_jit_texture *jit, void *mem, size_t size, enum pipe_format format)
498 {
499    jit->base = mem;
500 
501    if (LP_PERF & PERF_TEX_MEM) {
502       /* use dummy tile memory */
503       jit->base = lp_dummy_tile;
504       jit->width = TILE_SIZE/8;
505       jit->height = TILE_SIZE/8;
506       jit->depth = 1;
507       jit->first_level = 0;
508       jit->last_level = 0;
509       jit->mip_offsets[0] = 0;
510       jit->row_stride[0] = 0;
511       jit->img_stride[0] = 0;
512    } else {
513       jit->height = 1;
514       jit->depth = 1;
515       jit->first_level = 0;
516       jit->last_level = 0;
517 
518       /*
519        * For buffers, we don't have "offset", instead adjust
520        * the size (stored as width) plus the base pointer.
521        */
522       const unsigned view_blocksize = util_format_get_blocksize(format);
523       /* probably don't really need to fill that out */
524       jit->mip_offsets[0] = 0;
525       jit->row_stride[0] = 0;
526       jit->img_stride[0] = 0;
527 
528       /* everything specified in number of elements here. */
529       jit->width = size / view_blocksize;
530    }
531 }
532 
533 void
lp_jit_sampler_from_pipe(struct lp_jit_sampler * jit,const struct pipe_sampler_state * sampler)534 lp_jit_sampler_from_pipe(struct lp_jit_sampler *jit, const struct pipe_sampler_state *sampler)
535 {
536    jit->min_lod = sampler->min_lod;
537    jit->max_lod = sampler->max_lod;
538    jit->lod_bias = sampler->lod_bias;
539    jit->max_aniso = sampler->max_anisotropy;
540    COPY_4V(jit->border_color, sampler->border_color.f);
541 }
542 
543 void
lp_jit_image_from_pipe(struct lp_jit_image * jit,const struct pipe_image_view * view)544 lp_jit_image_from_pipe(struct lp_jit_image *jit, const struct pipe_image_view *view)
545 {
546    struct pipe_resource *res = view->resource;
547    struct llvmpipe_resource *lp_res = llvmpipe_resource(res);
548 
549    if (!lp_res->dt) {
550       /* regular texture - setup array of mipmap level offsets */
551       if (llvmpipe_resource_is_texture(res)) {
552          jit->base = lp_res->tex_data;
553       } else {
554          jit->base = lp_res->data;
555       }
556 
557       jit->width = res->width0;
558       jit->height = res->height0;
559       jit->depth = res->depth0;
560       jit->num_samples = res->nr_samples;
561 
562       if (llvmpipe_resource_is_texture(res)) {
563          uint32_t mip_offset = lp_res->mip_offsets[view->u.tex.level];
564 
565          jit->width = u_minify(jit->width, view->u.tex.level);
566          jit->height = u_minify(jit->height, view->u.tex.level);
567 
568          if (res->target == PIPE_TEXTURE_1D_ARRAY ||
569              res->target == PIPE_TEXTURE_2D_ARRAY ||
570              res->target == PIPE_TEXTURE_3D ||
571              res->target == PIPE_TEXTURE_CUBE ||
572              res->target == PIPE_TEXTURE_CUBE_ARRAY) {
573             /*
574              * For array textures, we don't have first_layer, instead
575              * adjust last_layer (stored as depth) plus the mip level offsets
576              * (as we have mip-first layout can't just adjust base ptr).
577              * XXX For mip levels, could do something similar.
578              */
579             jit->depth = view->u.tex.last_layer - view->u.tex.first_layer + 1;
580             mip_offset += view->u.tex.first_layer * lp_res->img_stride[view->u.tex.level];
581          } else
582             jit->depth = u_minify(jit->depth, view->u.tex.level);
583 
584          jit->row_stride = lp_res->row_stride[view->u.tex.level];
585          jit->img_stride = lp_res->img_stride[view->u.tex.level];
586          jit->sample_stride = lp_res->sample_stride;
587          jit->base = (uint8_t *)jit->base + mip_offset;
588       } else {
589          unsigned image_blocksize = util_format_get_blocksize(view->format);
590 
591          jit->img_stride = 0;
592 
593          /* If it's not a 2D image view of a buffer, adjust using size. */
594          if (!(view->access & PIPE_IMAGE_ACCESS_TEX2D_FROM_BUFFER)) {
595             /* everything specified in number of elements here. */
596             jit->width = view->u.buf.size / image_blocksize;
597             jit->row_stride = 0;
598 
599             /* Adjust base pointer with offset. */
600             jit->base = (uint8_t *)jit->base + view->u.buf.offset;
601 
602             /* XXX Unsure if we need to sanitize parameters? */
603             assert(view->u.buf.offset + view->u.buf.size <= res->width0);
604          } else {
605             jit->width = view->u.tex2d_from_buf.width;
606             jit->height = view->u.tex2d_from_buf.height;
607             jit->row_stride = view->u.tex2d_from_buf.row_stride * image_blocksize;
608 
609             jit->base = (uint8_t *)jit->base +
610                view->u.tex2d_from_buf.offset * image_blocksize;
611          }
612       }
613    }
614 }
615 
616 void
lp_jit_image_buffer_from_bda(struct lp_jit_image * jit,void * mem,size_t size,enum pipe_format format)617 lp_jit_image_buffer_from_bda(struct lp_jit_image *jit, void *mem, size_t size, enum pipe_format format)
618 {
619    jit->base = mem;
620 
621    jit->height = 1;
622    jit->depth = 1;
623    jit->num_samples = 1;
624 
625    unsigned view_blocksize = util_format_get_blocksize(format);
626    jit->width = size / view_blocksize;
627 }
628