• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2023 Valve Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "lp_context.h"
25 #include "lp_texture_handle.h"
26 #include "lp_screen.h"
27 
28 #include "gallivm/lp_bld_const.h"
29 #include "gallivm/lp_bld_debug.h"
30 #include "gallivm/lp_bld_nir.h"
31 
32 #include "nir.h"
33 #include "nir_builder.h"
34 
35 #include "pipe/p_context.h"
36 #include "pipe/p_screen.h"
37 #include "util/mesa-sha1.h"
38 
39 static const char *image_function_base_hash = "8ca89d7a4ab5830be6a1ba1140844081235b01164a8fce8316ca6a2f81f1a899";
40 static const char *sample_function_base_hash = "0789b032c4a1ddba086e07496fe2a992b1ee08f78c0884a2923564b1ed52b9cc";
41 static const char *size_function_base_hash = "6d249ab9c1106c68b87ec9fdb5ade28368171d27f221c687f32ae1544231d2fe";
42 static const char *jit_sample_function_base_hash = "21de75bb5dbcfea1f90d03b8b688f19bdb0d96f95681cbe8b26853e1723846e4";
43 
44 static void
45 llvmpipe_register_texture(struct llvmpipe_context *ctx, struct lp_static_texture_state *state, bool sampled);
46 
47 static void
48 llvmpipe_register_sampler(struct llvmpipe_context *ctx, struct lp_static_sampler_state *state);
49 
50 static uint64_t
llvmpipe_create_texture_handle(struct pipe_context * pctx,struct pipe_sampler_view * view,const struct pipe_sampler_state * sampler)51 llvmpipe_create_texture_handle(struct pipe_context *pctx, struct pipe_sampler_view *view, const struct pipe_sampler_state *sampler)
52 {
53    struct llvmpipe_context *ctx = llvmpipe_context(pctx);
54    struct lp_sampler_matrix *matrix = &ctx->sampler_matrix;
55 
56    struct lp_texture_handle *handle = calloc(1, sizeof(struct lp_texture_handle));
57 
58    if (view) {
59       struct lp_static_texture_state state;
60       lp_sampler_static_texture_state(&state, view);
61 
62       /* Trade a bit of performance for potentially less sampler/texture combinations. */
63       state.pot_width = false;
64       state.pot_height = false;
65       state.pot_depth = false;
66 
67       llvmpipe_register_texture(ctx, &state, true);
68 
69       bool found = false;
70       for (uint32_t i = 0; i < matrix->texture_count; i++) {
71          if (!memcmp(&matrix->textures[i]->state, &state, sizeof(struct lp_static_texture_state))) {
72             handle->functions = matrix->textures[i];
73             found = true;
74             break;
75          }
76       }
77       assert(found);
78    }
79 
80    if (sampler) {
81       struct lp_static_sampler_state state;
82       lp_sampler_static_sampler_state(&state, sampler);
83 
84       llvmpipe_register_sampler(ctx, &state);
85 
86       bool found = false;
87       for (uint32_t i = 0; i < matrix->sampler_count; i++) {
88          if (!memcmp(matrix->samplers + i, &state, sizeof(struct lp_static_sampler_state))) {
89             handle->sampler_index = i;
90             found = true;
91             break;
92          }
93       }
94       assert(found);
95    }
96 
97    return (uint64_t)(uintptr_t)handle;
98 }
99 
100 static void
llvmpipe_delete_texture_handle(struct pipe_context * pctx,uint64_t handle)101 llvmpipe_delete_texture_handle(struct pipe_context *pctx, uint64_t handle)
102 {
103    free((void *)(uintptr_t)handle);
104 }
105 
106 static uint64_t
llvmpipe_create_image_handle(struct pipe_context * pctx,const struct pipe_image_view * view)107 llvmpipe_create_image_handle(struct pipe_context *pctx, const struct pipe_image_view *view)
108 {
109    struct llvmpipe_context *ctx = llvmpipe_context(pctx);
110    struct lp_sampler_matrix *matrix = &ctx->sampler_matrix;
111 
112    struct lp_texture_handle *handle = calloc(1, sizeof(struct lp_texture_handle));
113 
114    struct lp_static_texture_state state;
115    lp_sampler_static_texture_state_image(&state, view);
116 
117    /* Trade a bit of performance for potentially less sampler/texture combinations. */
118    state.pot_width = false;
119    state.pot_height = false;
120    state.pot_depth = false;
121 
122    if (view->u.tex.first_layer == view->u.tex.last_layer) {
123       if (state.target == PIPE_TEXTURE_1D_ARRAY)
124          state.target = PIPE_TEXTURE_1D;
125       else if (state.target == PIPE_TEXTURE_2D_ARRAY || state.target == PIPE_TEXTURE_3D)
126          state.target = PIPE_TEXTURE_2D;
127       else if (state.target == PIPE_TEXTURE_CUBE_ARRAY)
128          state.target = PIPE_TEXTURE_CUBE;
129    }
130 
131    llvmpipe_register_texture(ctx, &state, false);
132 
133    bool found = false;
134    for (uint32_t i = 0; i < matrix->texture_count; i++) {
135       if (!memcmp(&matrix->textures[i]->state, &state, sizeof(struct lp_static_texture_state))) {
136          handle->functions = matrix->textures[i];
137          found = true;
138          break;
139       }
140    }
141    assert(found);
142 
143    return (uint64_t)(uintptr_t)handle;
144 }
145 
146 static void
llvmpipe_delete_image_handle(struct pipe_context * pctx,uint64_t handle)147 llvmpipe_delete_image_handle(struct pipe_context *pctx, uint64_t handle)
148 {
149    free((void *)(uintptr_t)handle);
150 }
151 
152 static uint64_t
153 get_sample_function(uint64_t _matrix, uint64_t _texture_functions, uint64_t _sampler_desc, uint32_t sample_key);
154 
155 void
llvmpipe_init_sampler_matrix(struct llvmpipe_context * ctx)156 llvmpipe_init_sampler_matrix(struct llvmpipe_context *ctx)
157 {
158    ctx->pipe.create_texture_handle = llvmpipe_create_texture_handle;
159    ctx->pipe.delete_texture_handle = llvmpipe_delete_texture_handle;
160    ctx->pipe.create_image_handle = llvmpipe_create_image_handle;
161    ctx->pipe.delete_image_handle = llvmpipe_delete_image_handle;
162 
163    util_dynarray_init(&ctx->sampler_matrix.gallivms, NULL);
164 
165    ctx->sampler_matrix.ctx = ctx;
166 
167    ctx->sampler_matrix.compile_function = get_sample_function;
168    ctx->sampler_matrix.cache = _mesa_pointer_hash_table_create(NULL);
169    simple_mtx_init(&ctx->sampler_matrix.lock, mtx_plain);
170 }
171 
172 void
llvmpipe_sampler_matrix_destroy(struct llvmpipe_context * ctx)173 llvmpipe_sampler_matrix_destroy(struct llvmpipe_context *ctx)
174 {
175    struct lp_sampler_matrix *matrix = &ctx->sampler_matrix;
176 
177    simple_mtx_destroy(&matrix->lock);
178    _mesa_hash_table_destroy(matrix->cache, NULL);
179 
180    free(matrix->samplers);
181 
182    for (uint32_t texture_index = 0; texture_index < matrix->texture_count; texture_index++) {
183       struct lp_texture_functions *texture = matrix->textures[texture_index];
184 
185       uint32_t sampler_count = texture->sampler_count;
186       if (texture->state.format == PIPE_FORMAT_NONE)
187          sampler_count = MIN2(sampler_count, 1);
188 
189       for (uint32_t sampler_index = 0; sampler_index < sampler_count; sampler_index++)
190          free(texture->sample_functions[sampler_index]);
191 
192       free(texture->sample_functions);
193       free(texture->fetch_functions);
194       free(texture->image_functions);
195       free(texture);
196    }
197    free(matrix->textures);
198 
199    util_dynarray_foreach (&ctx->sampler_matrix.gallivms, struct gallivm_state *, gallivm)
200       gallivm_destroy(*gallivm);
201 
202    util_dynarray_fini(&ctx->sampler_matrix.gallivms);
203 }
204 
205 static void *
compile_function(struct llvmpipe_context * ctx,struct gallivm_state * gallivm,LLVMValueRef function,bool needs_caching,uint8_t cache_key[SHA1_DIGEST_LENGTH])206 compile_function(struct llvmpipe_context *ctx, struct gallivm_state *gallivm, LLVMValueRef function,
207                  bool needs_caching,
208                  uint8_t cache_key[SHA1_DIGEST_LENGTH])
209 {
210    gallivm_verify_function(gallivm, function);
211    gallivm_compile_module(gallivm);
212 
213    void *function_ptr = func_to_pointer(gallivm_jit_function(gallivm, function));
214 
215    if (needs_caching)
216       lp_disk_cache_insert_shader(llvmpipe_screen(ctx->pipe.screen), gallivm->cache, cache_key);
217 
218    gallivm_free_ir(gallivm);
219 
220    util_dynarray_append(&ctx->sampler_matrix.gallivms, struct gallivm_state *, gallivm);
221 
222    return function_ptr;
223 }
224 
225 static void *
compile_image_function(struct llvmpipe_context * ctx,struct lp_static_texture_state * texture,uint32_t op)226 compile_image_function(struct llvmpipe_context *ctx, struct lp_static_texture_state *texture, uint32_t op)
227 {
228    const struct util_format_description *desc = util_format_description(texture->format);
229    if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && !lp_storage_render_image_format_supported(texture->format))
230       return NULL;
231 
232    bool ms = op >= LP_TOTAL_IMAGE_OP_COUNT / 2;
233    if (ms)
234       op -= LP_TOTAL_IMAGE_OP_COUNT / 2;
235 
236    struct lp_img_params params = { 0 };
237 
238    params.img_op = op;
239    if (op >= LP_IMG_OP_COUNT - 1) {
240       params.img_op = LP_IMG_ATOMIC;
241       params.op = op - (LP_IMG_OP_COUNT - 1);
242    } else if (op != LP_IMG_LOAD && op != LP_IMG_STORE) {
243       params.img_op = LP_IMG_ATOMIC_CAS;
244    }
245 
246    /* Loads need to support a wider range of formats for input attachments. */
247    if (params.img_op != LP_IMG_LOAD)
248       if (texture->format != PIPE_FORMAT_NONE && !lp_storage_image_format_supported(texture->format))
249          return NULL;
250 
251    uint8_t cache_key[SHA1_DIGEST_LENGTH];
252    struct mesa_sha1 hash_ctx;
253    _mesa_sha1_init(&hash_ctx);
254    _mesa_sha1_update(&hash_ctx, image_function_base_hash, strlen(image_function_base_hash));
255    _mesa_sha1_update(&hash_ctx, texture, sizeof(*texture));
256    _mesa_sha1_update(&hash_ctx, &op, sizeof(op));
257    _mesa_sha1_update(&hash_ctx, &ms, sizeof(ms));
258    _mesa_sha1_final(&hash_ctx, cache_key);
259 
260    struct lp_cached_code cached = { 0 };
261    lp_disk_cache_find_shader(llvmpipe_screen(ctx->pipe.screen), &cached, cache_key);
262    bool needs_caching = !cached.data_size;
263 
264    struct gallivm_state *gallivm = gallivm_create("sample_function", ctx->context, &cached);
265 
266    struct lp_image_static_state state = {
267       .image_state = *texture,
268    };
269    struct lp_build_image_soa *image_soa = lp_bld_llvm_image_soa_create(&state, 1);
270 
271    struct lp_type type;
272    memset(&type, 0, sizeof type);
273    type.floating = true;      /* floating point values */
274    type.sign = true;          /* values are signed */
275    type.norm = false;         /* values are not limited to [0,1] or [-1,1] */
276    type.width = 32;           /* 32-bit float */
277    type.length = MIN2(lp_native_vector_width / 32, 16); /* n*4 elements per vector */
278 
279    struct lp_compute_shader_variant cs = { .gallivm = gallivm };
280    lp_jit_init_cs_types(&cs);
281 
282    params.type = type;
283    params.target = texture->target;
284    params.resources_type = cs.jit_resources_type;
285    params.format = texture->format;
286 
287    LLVMTypeRef function_type = lp_build_image_function_type(gallivm, &params, ms);
288    if (!function_type) {
289       free(image_soa);
290       gallivm_destroy(gallivm);
291       return NULL;
292    }
293 
294    LLVMValueRef function = LLVMAddFunction(gallivm->module, "image", function_type);
295 
296    uint32_t arg_index = 0;
297 
298    gallivm->texture_descriptor = LLVMGetParam(function, arg_index++);
299 
300    if (params.img_op != LP_IMG_LOAD)
301       params.exec_mask = LLVMGetParam(function, arg_index++);
302 
303    LLVMValueRef coords[3];
304    params.coords = coords;
305    for (uint32_t i = 0; i < 3; i++)
306       coords[i] = LLVMGetParam(function, arg_index++);
307 
308    if (ms)
309       params.ms_index = LLVMGetParam(function, arg_index++);
310 
311    if (params.img_op != LP_IMG_LOAD)
312       for (uint32_t i = 0; i < 4; i++)
313          params.indata[i] = LLVMGetParam(function, arg_index++);
314 
315    if (params.img_op == LP_IMG_ATOMIC_CAS)
316       for (uint32_t i = 0; i < 4; i++)
317          params.indata2[i] = LLVMGetParam(function, arg_index++);
318 
319    LLVMBuilderRef old_builder = gallivm->builder;
320    LLVMBasicBlockRef block = LLVMAppendBasicBlockInContext(gallivm->context, function, "entry");
321    gallivm->builder = LLVMCreateBuilderInContext(gallivm->context);
322    LLVMPositionBuilderAtEnd(gallivm->builder, block);
323 
324    LLVMValueRef outdata[4] = { 0 };
325    lp_build_img_op_soa(texture, lp_build_image_soa_dynamic_state(image_soa), gallivm, &params, outdata);
326 
327    for (uint32_t i = 1; i < 4; i++)
328       if (!outdata[i])
329          outdata[i] = outdata[0];
330 
331    if (params.img_op != LP_IMG_STORE)
332       LLVMBuildAggregateRet(gallivm->builder, outdata, 4);
333    else
334       LLVMBuildRetVoid(gallivm->builder);
335 
336    LLVMDisposeBuilder(gallivm->builder);
337    gallivm->builder = old_builder;
338 
339    free(image_soa);
340 
341    return compile_function(ctx, gallivm, function, needs_caching, cache_key);
342 }
343 
344 static void *
compile_sample_function(struct llvmpipe_context * ctx,struct lp_static_texture_state * texture,struct lp_static_sampler_state * sampler,uint32_t sample_key)345 compile_sample_function(struct llvmpipe_context *ctx, struct lp_static_texture_state *texture,
346                         struct lp_static_sampler_state *sampler, uint32_t sample_key)
347 {
348    enum lp_sampler_lod_control lod_control = (sample_key & LP_SAMPLER_LOD_CONTROL_MASK) >> LP_SAMPLER_LOD_CONTROL_SHIFT;
349 
350    bool supported = true;
351    if (texture->format != PIPE_FORMAT_NONE) {
352       enum lp_sampler_op_type op_type = (sample_key & LP_SAMPLER_OP_TYPE_MASK) >> LP_SAMPLER_OP_TYPE_SHIFT;
353       if (op_type != LP_SAMPLER_OP_LODQ)
354          if ((sampler->compare_mode == PIPE_TEX_COMPARE_NONE) == !!(sample_key & LP_SAMPLER_SHADOW))
355             supported = false;
356 
357       /* Skip integer formats which would cause a type mismatch in the compare function. */
358       const struct util_format_description *desc = util_format_description(texture->format);
359       struct lp_type texel_type = {
360          .floating = true,
361          .width = 32,
362          .length = 1,
363       };
364       texel_type = lp_build_texel_type(texel_type, desc);
365       if ((sample_key & LP_SAMPLER_SHADOW) && !texel_type.floating)
366          supported = false;
367 
368       if (texture_dims(texture->target) != 2 && op_type == LP_SAMPLER_OP_GATHER)
369          supported = false;
370 
371       if (op_type != LP_SAMPLER_OP_FETCH) {
372          if (!sampler->normalized_coords) {
373             if (texture->target != PIPE_TEXTURE_1D && texture->target != PIPE_TEXTURE_2D &&
374                 texture->target != PIPE_TEXTURE_1D_ARRAY && texture->target != PIPE_TEXTURE_2D_ARRAY)
375                supported = false;
376 
377             if (!texture->level_zero_only)
378                supported = false;
379          }
380       }
381 
382       if (util_format_is_pure_integer(texture->format) &&
383           (sampler->min_img_filter == PIPE_TEX_FILTER_LINEAR ||
384            sampler->min_mip_filter == PIPE_TEX_MIPFILTER_LINEAR ||
385            sampler->mag_img_filter == PIPE_TEX_FILTER_LINEAR))
386          supported = false;
387 
388       if (sampler->aniso) {
389          if (texture_dims(texture->target) != 2)
390             supported = false;
391 
392          if (util_format_is_pure_integer(texture->format))
393             supported = false;
394       }
395 
396       if (util_format_get_num_planes(texture->format) > 1)
397          return NULL;
398 
399       uint32_t bind = op_type == LP_SAMPLER_OP_FETCH ? PIPE_BIND_CONSTANT_BUFFER : PIPE_BIND_SAMPLER_VIEW;
400       if (!ctx->pipe.screen->is_format_supported(ctx->pipe.screen, texture->format, texture->target, 0, 0, bind))
401          supported = false;
402    }
403 
404    uint8_t cache_key[SHA1_DIGEST_LENGTH];
405    struct mesa_sha1 hash_ctx;
406    _mesa_sha1_init(&hash_ctx);
407    _mesa_sha1_update(&hash_ctx, sample_function_base_hash, strlen(sample_function_base_hash));
408    _mesa_sha1_update(&hash_ctx, texture, sizeof(*texture));
409    _mesa_sha1_update(&hash_ctx, sampler, sizeof(*sampler));
410    _mesa_sha1_update(&hash_ctx, &sample_key, sizeof(sample_key));
411    _mesa_sha1_final(&hash_ctx, cache_key);
412 
413    struct lp_cached_code cached = { 0 };
414    lp_disk_cache_find_shader(llvmpipe_screen(ctx->pipe.screen), &cached, cache_key);
415    bool needs_caching = !cached.data_size;
416 
417    struct gallivm_state *gallivm = gallivm_create("sample_function", ctx->context, &cached);
418 
419    struct lp_sampler_static_state state = {
420       .texture_state = *texture,
421       .sampler_state = *sampler,
422    };
423    struct lp_build_sampler_soa *sampler_soa = lp_llvm_sampler_soa_create(&state, 1);
424 
425    struct lp_type type;
426    memset(&type, 0, sizeof type);
427    type.floating = true;      /* floating point values */
428    type.sign = true;          /* values are signed */
429    type.norm = false;         /* values are not limited to [0,1] or [-1,1] */
430    type.width = 32;           /* 32-bit float */
431    type.length = MIN2(lp_native_vector_width / 32, 16); /* n*4 elements per vector */
432 
433    struct lp_compute_shader_variant cs = { .gallivm = gallivm };
434    lp_jit_init_cs_types(&cs);
435 
436    LLVMTypeRef function_type = lp_build_sample_function_type(gallivm, sample_key);
437    LLVMValueRef function = LLVMAddFunction(gallivm->module, "sample", function_type);
438 
439    uint32_t arg_index = 0;
440 
441    gallivm->texture_descriptor = LLVMGetParam(function, arg_index++);
442    gallivm->sampler_descriptor = LLVMGetParam(function, arg_index++);
443 
444    LLVMValueRef aniso_filter_table = LLVMGetParam(function, arg_index++);
445 
446    LLVMValueRef coords[5];
447    for (unsigned i = 0; i < 4; i++)
448       coords[i] = LLVMGetParam(function, arg_index++);
449 
450    if (sample_key & LP_SAMPLER_SHADOW)
451       coords[4] = LLVMGetParam(function, arg_index++);
452    else
453       coords[4] = lp_build_undef(gallivm, type);
454 
455    LLVMValueRef ms_index = NULL;
456    if (sample_key & LP_SAMPLER_FETCH_MS)
457       ms_index = LLVMGetParam(function, arg_index++);
458 
459    LLVMValueRef offsets[3] = { 0 };
460    if (sample_key & LP_SAMPLER_OFFSETS)
461       for (unsigned i = 0; i < 3; i++)
462          offsets[i] = LLVMGetParam(function, arg_index++);
463 
464    LLVMValueRef lod = NULL;
465    if (lod_control == LP_SAMPLER_LOD_BIAS || lod_control == LP_SAMPLER_LOD_EXPLICIT)
466       lod = LLVMGetParam(function, arg_index++);
467 
468    LLVMBuilderRef old_builder = gallivm->builder;
469    LLVMBasicBlockRef block = LLVMAppendBasicBlockInContext(gallivm->context, function, "entry");
470    gallivm->builder = LLVMCreateBuilderInContext(gallivm->context);
471    LLVMPositionBuilderAtEnd(gallivm->builder, block);
472 
473    LLVMValueRef texel_out[4] = { 0 };
474    if (supported) {
475       lp_build_sample_soa_code(gallivm, texture, sampler, lp_build_sampler_soa_dynamic_state(sampler_soa),
476                                type, sample_key, 0, 0, cs.jit_resources_type, NULL, cs.jit_cs_thread_data_type,
477                                NULL, coords, offsets, NULL, lod, ms_index, aniso_filter_table, texel_out);
478    } else {
479       lp_build_sample_nop(gallivm, lp_build_texel_type(type, util_format_description(texture->format)), coords, texel_out);
480    }
481 
482    LLVMBuildAggregateRet(gallivm->builder, texel_out, 4);
483 
484    LLVMDisposeBuilder(gallivm->builder);
485    gallivm->builder = old_builder;
486 
487    free(sampler_soa);
488 
489    return compile_function(ctx, gallivm, function, needs_caching, cache_key);
490 }
491 
492 static uint64_t
get_sample_function(uint64_t _matrix,uint64_t _texture_functions,uint64_t _sampler_desc,uint32_t sample_key)493 get_sample_function(uint64_t _matrix, uint64_t _texture_functions, uint64_t _sampler_desc, uint32_t sample_key)
494 {
495    struct lp_sampler_matrix *matrix = (void *)(uintptr_t)_matrix;
496    struct lp_texture_functions *texture_functions = (void *)(uintptr_t)_texture_functions;
497    struct lp_descriptor *sampler_desc = (void *)(uintptr_t)_sampler_desc;
498 
499    uint32_t sampler_index = sampler_desc->texture.sampler_index;
500    void *key = &texture_functions->sample_functions[sampler_index][sample_key];
501 
502    simple_mtx_lock(&matrix->lock);
503 
504    void *result;
505    struct hash_entry *entry = _mesa_hash_table_search(matrix->cache, key);
506    if (entry) {
507       result = entry->data;
508    } else {
509       result = compile_sample_function(matrix->ctx, &texture_functions->state, matrix->samplers + sampler_index, sample_key);
510       _mesa_hash_table_insert(matrix->cache, key, result);
511    }
512 
513    simple_mtx_unlock(&matrix->lock);
514 
515    return (uint64_t)(uintptr_t)result;
516 }
517 
518 static LLVMTypeRef
lp_build_compile_function_type(struct gallivm_state * gallivm)519 lp_build_compile_function_type(struct gallivm_state *gallivm)
520 {
521    LLVMTypeRef param_types[4] = {
522       LLVMInt64TypeInContext(gallivm->context),
523       LLVMInt64TypeInContext(gallivm->context),
524       LLVMInt64TypeInContext(gallivm->context),
525       LLVMInt32TypeInContext(gallivm->context),
526    };
527    LLVMTypeRef ret_type = LLVMInt64TypeInContext(gallivm->context);
528 
529    return LLVMFunctionType(ret_type, param_types, ARRAY_SIZE(param_types), false);
530 }
531 
532 static void *
compile_jit_sample_function(struct llvmpipe_context * ctx,uint32_t sample_key)533 compile_jit_sample_function(struct llvmpipe_context *ctx, uint32_t sample_key)
534 {
535    uint8_t cache_key[SHA1_DIGEST_LENGTH];
536    struct mesa_sha1 hash_ctx;
537    _mesa_sha1_init(&hash_ctx);
538    _mesa_sha1_update(&hash_ctx, jit_sample_function_base_hash, strlen(jit_sample_function_base_hash));
539    _mesa_sha1_update(&hash_ctx, &sample_key, sizeof(sample_key));
540    _mesa_sha1_final(&hash_ctx, cache_key);
541 
542    struct lp_cached_code cached = { 0 };
543    lp_disk_cache_find_shader(llvmpipe_screen(ctx->pipe.screen), &cached, cache_key);
544    bool needs_caching = !cached.data_size;
545 
546    struct gallivm_state *gallivm = gallivm_create("jit_sample_function", ctx->context, &cached);
547 
548    struct lp_type type;
549    memset(&type, 0, sizeof type);
550    type.floating = true;      /* floating point values */
551    type.sign = true;          /* values are signed */
552    type.norm = false;         /* values are not limited to [0,1] or [-1,1] */
553    type.width = 32;           /* 32-bit float */
554    type.length = MIN2(lp_native_vector_width / 32, 16); /* n*4 elements per vector */
555 
556    struct lp_compute_shader_variant cs = { .gallivm = gallivm };
557    lp_jit_init_cs_types(&cs);
558 
559    LLVMTypeRef function_type = lp_build_sample_function_type(gallivm, sample_key);
560    LLVMValueRef function = LLVMAddFunction(gallivm->module, "sample", function_type);
561 
562    uint32_t arg_index = 0;
563    LLVMValueRef texture_descriptor = LLVMGetParam(function, arg_index++);
564    LLVMValueRef sampler_descriptor = LLVMGetParam(function, arg_index++);
565 
566    LLVMBuilderRef old_builder = gallivm->builder;
567    LLVMBasicBlockRef block = LLVMAppendBasicBlockInContext(gallivm->context, function, "entry");
568    gallivm->builder = LLVMCreateBuilderInContext(gallivm->context);
569    LLVMBuilderRef builder = gallivm->builder;
570    LLVMPositionBuilderAtEnd(gallivm->builder, block);
571 
572    LLVMValueRef functions_offset =
573       lp_build_const_int64(gallivm, offsetof(struct lp_descriptor, functions));
574    LLVMValueRef functions_ptr =
575       LLVMBuildAdd(builder, texture_descriptor, functions_offset, "");
576 
577    LLVMTypeRef functions_ptr_type = LLVMInt64TypeInContext(gallivm->context);
578    LLVMTypeRef functions_ptr_ptr_type = LLVMPointerType(functions_ptr_type, 0);
579 
580    functions_ptr = LLVMBuildIntToPtr(builder, functions_ptr, functions_ptr_ptr_type, "");
581    /* struct lp_texture_functions * */
582    functions_ptr = LLVMBuildLoad2(builder, functions_ptr_type, functions_ptr, "");
583 
584    LLVMValueRef matrix_offset =
585       lp_build_const_int64(gallivm, offsetof(struct lp_texture_functions, matrix));
586    LLVMValueRef matrix_ptr = LLVMBuildAdd(builder, functions_ptr, matrix_offset, "");
587 
588    matrix_ptr = LLVMBuildIntToPtr(builder, matrix_ptr, functions_ptr_ptr_type, "");
589    /* struct lp_sampler_matrix * */
590    matrix_ptr = LLVMBuildLoad2(builder, functions_ptr_type, matrix_ptr, "");
591 
592    LLVMTypeRef compile_function_type = lp_build_compile_function_type(gallivm);
593    LLVMTypeRef compile_function_ptr_type = LLVMPointerType(compile_function_type, 0);
594    LLVMTypeRef compile_function_ptr_ptr_type = LLVMPointerType(compile_function_ptr_type, 0);
595 
596    LLVMValueRef compile_function_offset =
597       lp_build_const_int64(gallivm, offsetof(struct lp_sampler_matrix, compile_function));
598    LLVMValueRef compile_function_ptr =
599       LLVMBuildAdd(builder, matrix_ptr, compile_function_offset, "");
600 
601    compile_function_ptr =
602       LLVMBuildIntToPtr(builder, compile_function_ptr, compile_function_ptr_ptr_type, "");
603    /* struct lp_texture_functions * */
604    compile_function_ptr =
605       LLVMBuildLoad2(builder, compile_function_ptr_type, compile_function_ptr, "");
606 
607    LLVMValueRef compile_args[4] = {
608       matrix_ptr, functions_ptr, sampler_descriptor, lp_build_const_int32(gallivm, sample_key)
609    };
610 
611    LLVMValueRef sample_function =
612       LLVMBuildCall2(builder, compile_function_type, compile_function_ptr,
613                      compile_args, ARRAY_SIZE(compile_args), "");
614 
615    sample_function = LLVMBuildIntToPtr(builder, sample_function, LLVMPointerType(function_type, 0), "");
616 
617    LLVMValueRef args[LP_MAX_TEX_FUNC_ARGS];
618    uint32_t num_args = 0;
619 
620    LLVMValueRef arg = LLVMGetFirstParam(function);
621    while (true) {
622       args[num_args++] = arg;
623       if (arg == LLVMGetLastParam(function))
624          break;
625 
626       arg = LLVMGetNextParam(arg);
627    }
628 
629    LLVMValueRef result = LLVMBuildCall2(builder, function_type, sample_function, args, num_args, "");
630    LLVMBuildRet(gallivm->builder, result);
631 
632    LLVMDisposeBuilder(gallivm->builder);
633    gallivm->builder = old_builder;
634 
635    return compile_function(ctx, gallivm, function, needs_caching, cache_key);
636 }
637 
638 static void *
compile_size_function(struct llvmpipe_context * ctx,struct lp_static_texture_state * texture,bool samples)639 compile_size_function(struct llvmpipe_context *ctx, struct lp_static_texture_state *texture, bool samples)
640 {
641    uint8_t cache_key[SHA1_DIGEST_LENGTH];
642    struct mesa_sha1 hash_ctx;
643    _mesa_sha1_init(&hash_ctx);
644    _mesa_sha1_update(&hash_ctx, size_function_base_hash, strlen(size_function_base_hash));
645    _mesa_sha1_update(&hash_ctx, texture, sizeof(*texture));
646    _mesa_sha1_update(&hash_ctx, &samples, sizeof(samples));
647    _mesa_sha1_final(&hash_ctx, cache_key);
648 
649    struct lp_cached_code cached = { 0 };
650    lp_disk_cache_find_shader(llvmpipe_screen(ctx->pipe.screen), &cached, cache_key);
651    bool needs_caching = !cached.data_size;
652 
653    struct gallivm_state *gallivm = gallivm_create("sample_function", ctx->context, &cached);
654 
655    struct lp_sampler_static_state state = {
656       .texture_state = *texture,
657    };
658    struct lp_build_sampler_soa *sampler_soa = lp_llvm_sampler_soa_create(&state, 1);
659 
660    struct lp_type type;
661    memset(&type, 0, sizeof type);
662    type.floating = true;      /* floating point values */
663    type.sign = true;          /* values are signed */
664    type.norm = false;         /* values are not limited to [0,1] or [-1,1] */
665    type.width = 32;           /* 32-bit float */
666    type.length = MIN2(lp_native_vector_width / 32, 16); /* n*4 elements per vector */
667 
668    struct lp_compute_shader_variant cs = { .gallivm = gallivm };
669    lp_jit_init_cs_types(&cs);
670 
671    struct lp_sampler_size_query_params params = {
672       .int_type = lp_int_type(type),
673       .target = texture->target,
674       .resources_type = cs.jit_resources_type,
675       .is_sviewinfo = true,
676       .samples_only = samples,
677       .ms = samples,
678    };
679 
680    if (params.target == PIPE_TEXTURE_1D)
681       params.target = PIPE_TEXTURE_1D_ARRAY;
682    else if (params.target == PIPE_TEXTURE_2D)
683       params.target = PIPE_TEXTURE_2D_ARRAY;
684    else if (params.target == PIPE_TEXTURE_CUBE)
685       params.target = PIPE_TEXTURE_CUBE_ARRAY;
686 
687    LLVMTypeRef function_type = lp_build_size_function_type(gallivm, &params);
688    LLVMValueRef function = LLVMAddFunction(gallivm->module, "size", function_type);
689 
690    uint32_t arg_index = 0;
691 
692    gallivm->texture_descriptor = LLVMGetParam(function, arg_index++);
693 
694    if (!samples)
695       params.explicit_lod = LLVMGetParam(function, arg_index++);
696 
697    LLVMBuilderRef old_builder = gallivm->builder;
698    LLVMBasicBlockRef block = LLVMAppendBasicBlockInContext(gallivm->context, function, "entry");
699    gallivm->builder = LLVMCreateBuilderInContext(gallivm->context);
700    LLVMPositionBuilderAtEnd(gallivm->builder, block);
701 
702    LLVMValueRef out_sizes[4] = { 0 };
703    params.sizes_out = out_sizes;
704    lp_build_size_query_soa(gallivm, texture, lp_build_sampler_soa_dynamic_state(sampler_soa), &params);
705 
706    for (uint32_t i = 0; i < 4; i++)
707       if (!out_sizes[i])
708          out_sizes[i] = lp_build_const_int_vec(gallivm, params.int_type, 0);
709 
710    LLVMBuildAggregateRet(gallivm->builder, out_sizes, 4);
711 
712    LLVMDisposeBuilder(gallivm->builder);
713    gallivm->builder = old_builder;
714 
715    free(sampler_soa);
716 
717    return compile_function(ctx, gallivm, function, needs_caching, cache_key);
718 }
719 
720 static void
compile_sample_functions(struct llvmpipe_context * ctx,struct lp_static_texture_state * texture,struct lp_static_sampler_state * sampler,void *** dst)721 compile_sample_functions(struct llvmpipe_context *ctx, struct lp_static_texture_state *texture,
722                         struct lp_static_sampler_state *sampler, void ***dst)
723 {
724    void **functions;
725    if (*dst) {
726       functions = *dst;
727    } else {
728       functions = calloc(LP_SAMPLE_KEY_COUNT, sizeof(void *));
729       *dst = functions;
730    }
731 
732    bool has_sampler = !!sampler;
733 
734    struct lp_static_sampler_state dummy_sampler = { 0 };
735    if (!sampler)
736       sampler = &dummy_sampler;
737 
738    struct lp_sampler_matrix *matrix = &ctx->sampler_matrix;
739    for (uint32_t sample_key = 0; sample_key < LP_SAMPLE_KEY_COUNT; sample_key++) {
740       if (!BITSET_TEST(matrix->sample_keys, sample_key))
741          continue;
742 
743       enum lp_sampler_op_type op_type = (sample_key & LP_SAMPLER_OP_TYPE_MASK) >> LP_SAMPLER_OP_TYPE_SHIFT;
744       if (has_sampler && op_type == LP_SAMPLER_OP_FETCH)
745          continue;
746 
747       if (!functions[sample_key]) {
748          if (has_sampler)
749             functions[sample_key] = matrix->jit_sample_functions[sample_key];
750          else
751             functions[sample_key] = compile_sample_function(ctx, texture, sampler, sample_key);
752       }
753    }
754 }
755 
756 static void
llvmpipe_register_texture(struct llvmpipe_context * ctx,struct lp_static_texture_state * state,bool sampled)757 llvmpipe_register_texture(struct llvmpipe_context *ctx, struct lp_static_texture_state *state, bool sampled)
758 {
759    struct lp_sampler_matrix *matrix = &ctx->sampler_matrix;
760 
761    bool packed = true;
762    uint32_t dst_index = matrix->texture_count;
763    for (uint32_t i = 0; i < matrix->texture_count; i++) {
764       if (memcmp(&matrix->textures[i]->state, state, sizeof(struct lp_static_texture_state)))
765          continue;
766 
767       bool has_functions = sampled ? matrix->textures[i]->sampled : matrix->textures[i]->storage;
768       if (has_functions)
769          return;
770 
771       packed = false;
772       dst_index = i;
773       break;
774    }
775 
776    struct lp_texture_functions *entry;
777    if (packed) {
778       matrix->texture_count++;
779       matrix->textures = realloc(matrix->textures, matrix->texture_count * sizeof(struct lp_texture_functions *));
780 
781       entry = calloc(1, sizeof(struct lp_texture_functions));
782       matrix->textures[dst_index] = entry;
783 
784       entry->state = *state;
785       entry->image_functions = calloc(LP_TOTAL_IMAGE_OP_COUNT, sizeof(void **));
786       entry->matrix = matrix;
787    } else {
788       entry = matrix->textures[dst_index];
789    }
790 
791    if (sampled)
792       entry->sampled = true;
793    else
794       entry->storage = true;
795 
796    if (entry->sampled) {
797       if (entry->sample_functions) {
798          entry->sample_functions = realloc(entry->sample_functions, matrix->sampler_count * sizeof(void **));
799          memset(entry->sample_functions + entry->sampler_count, 0, (matrix->sampler_count - entry->sampler_count) * sizeof(void **));
800       } else {
801          entry->sample_functions = calloc(matrix->sampler_count, sizeof(void **));
802       }
803       entry->sampler_count = matrix->sampler_count;
804 
805       if (state->format == PIPE_FORMAT_NONE) {
806          if (matrix->sampler_count)
807             compile_sample_functions(ctx, state, NULL, entry->sample_functions);
808          for (uint32_t i = 1; i < matrix->sampler_count; i++)
809             entry->sample_functions[i] = entry->sample_functions[0];
810       } else {
811          for (uint32_t i = 0; i < matrix->sampler_count; i++)
812             compile_sample_functions(ctx, state, matrix->samplers + i, entry->sample_functions + i);
813       }
814 
815       compile_sample_functions(ctx, state, NULL, &entry->fetch_functions);
816 
817       if (!entry->size_function)
818          entry->size_function = compile_size_function(ctx, state, false);
819 
820       if (!entry->samples_function)
821          entry->samples_function = compile_size_function(ctx, state, true);
822    }
823 
824    if (entry->storage) {
825       uint32_t image_op;
826       BITSET_FOREACH_SET (image_op, matrix->image_ops, LP_TOTAL_IMAGE_OP_COUNT)
827          if (!entry->image_functions[image_op])
828             entry->image_functions[image_op] = compile_image_function(ctx, state, image_op);
829    }
830 }
831 
832 static void
llvmpipe_register_sampler(struct llvmpipe_context * ctx,struct lp_static_sampler_state * state)833 llvmpipe_register_sampler(struct llvmpipe_context *ctx, struct lp_static_sampler_state *state)
834 {
835    struct lp_sampler_matrix *matrix = &ctx->sampler_matrix;
836    for (uint32_t i = 0; i < matrix->sampler_count; i++)
837       if (!memcmp(matrix->samplers + i, state, sizeof(struct lp_static_sampler_state)))
838          return;
839 
840    matrix->sampler_count++;
841    matrix->samplers = realloc(matrix->samplers, matrix->sampler_count * sizeof(struct lp_static_sampler_state));
842 
843    matrix->samplers[matrix->sampler_count - 1] = *state;
844 
845    for (uint32_t i = 0; i < matrix->texture_count; i++) {
846       struct lp_texture_functions *texture = matrix->textures[i];
847       if (!texture->sampled)
848          continue;
849 
850       texture->sampler_count = matrix->sampler_count;
851       texture->sample_functions = realloc(texture->sample_functions, matrix->sampler_count * sizeof(void **));
852 
853       void ***dst = texture->sample_functions + (matrix->sampler_count - 1);
854 
855       if (texture->state.format == PIPE_FORMAT_NONE)  {
856          if (matrix->sampler_count == 1) {
857             *dst = NULL;
858             compile_sample_functions(ctx, &texture->state, NULL, dst);
859          } else {
860             *dst = texture->sample_functions[0];
861          }
862 
863          continue;
864       }
865 
866       *dst = NULL;
867       compile_sample_functions(ctx, &texture->state, state, dst);
868    }
869 }
870 
871 static void
register_sample_key(struct llvmpipe_context * ctx,uint32_t sample_key)872 register_sample_key(struct llvmpipe_context *ctx, uint32_t sample_key)
873 {
874    struct lp_sampler_matrix *matrix = &ctx->sampler_matrix;
875    if (BITSET_TEST(matrix->sample_keys, sample_key))
876       return;
877 
878    BITSET_SET(matrix->sample_keys, sample_key);
879 
880    matrix->jit_sample_functions[sample_key] = compile_jit_sample_function(ctx, sample_key);
881 
882    for (uint32_t texture_index = 0; texture_index < matrix->texture_count; texture_index++) {
883       struct lp_texture_functions *texture = matrix->textures[texture_index];
884       if (!texture->sampled)
885          continue;
886 
887       enum lp_sampler_op_type op_type = (sample_key & LP_SAMPLER_OP_TYPE_MASK) >> LP_SAMPLER_OP_TYPE_SHIFT;
888       if (op_type == LP_SAMPLER_OP_FETCH) {
889          struct lp_static_sampler_state dummy_sampler = { 0 };
890          texture->fetch_functions[sample_key] = compile_sample_function(ctx, &texture->state, &dummy_sampler, sample_key);
891          continue;
892       }
893 
894       if (texture->state.format == PIPE_FORMAT_NONE) {
895          if (matrix->sampler_count) {
896             struct lp_static_sampler_state dummy_sampler = { 0 };
897             texture->sample_functions[0][sample_key] = compile_sample_function(ctx, &texture->state, &dummy_sampler, sample_key);
898          }
899          continue;
900       }
901 
902       for (uint32_t sampler_index = 0; sampler_index < matrix->sampler_count; sampler_index++)
903          texture->sample_functions[sampler_index][sample_key] = matrix->jit_sample_functions[sample_key];
904    }
905 }
906 
907 static void
register_image_op(struct llvmpipe_context * ctx,uint32_t op)908 register_image_op(struct llvmpipe_context *ctx, uint32_t op)
909 {
910    struct lp_sampler_matrix *matrix = &ctx->sampler_matrix;
911    if (BITSET_TEST(matrix->image_ops, op))
912       return;
913 
914    BITSET_SET(matrix->image_ops, op);
915 
916    for (uint32_t texture_index = 0; texture_index < matrix->texture_count; texture_index++) {
917       struct lp_texture_functions *texture = matrix->textures[texture_index];
918       if (texture->storage)
919          texture->image_functions[op] = compile_image_function(ctx, &texture->state, op);
920    }
921 }
922 
923 static bool
register_instr(nir_builder * b,nir_instr * instr,void * data)924 register_instr(nir_builder *b, nir_instr *instr, void *data)
925 {
926    struct llvmpipe_context *ctx = data;
927 
928    if (instr->type == nir_instr_type_tex) {
929       nir_tex_instr *tex = nir_instr_as_tex(instr);
930       uint32_t sample_key = lp_build_nir_sample_key(b->shader->info.stage, tex);
931 
932       register_sample_key(ctx, sample_key);
933    } else if (instr->type == nir_instr_type_intrinsic) {
934       nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
935 
936       struct lp_img_params params;
937       lp_img_op_from_intrinsic(&params, intrin);
938 
939       if (params.img_op == -1)
940          return false;
941 
942       uint32_t op = params.img_op;
943       if (op == LP_IMG_ATOMIC_CAS)
944          op--;
945       else if (op == LP_IMG_ATOMIC)
946          op = params.op + (LP_IMG_OP_COUNT - 1);
947 
948       if (nir_intrinsic_image_dim(intrin) == GLSL_SAMPLER_DIM_MS ||
949           nir_intrinsic_image_dim(intrin) == GLSL_SAMPLER_DIM_SUBPASS_MS)
950          op += LP_TOTAL_IMAGE_OP_COUNT / 2;
951 
952       register_image_op(ctx, op);
953    }
954 
955    return false;
956 }
957 
958 void
llvmpipe_register_shader(struct pipe_context * ctx,const struct pipe_shader_state * shader)959 llvmpipe_register_shader(struct pipe_context *ctx, const struct pipe_shader_state *shader)
960 {
961    if (shader->type == PIPE_SHADER_IR_NIR)
962       nir_shader_instructions_pass(shader->ir.nir, register_instr, nir_metadata_all, ctx);
963 }
964 
965 void
llvmpipe_clear_sample_functions_cache(struct llvmpipe_context * ctx,struct pipe_fence_handle ** fence)966 llvmpipe_clear_sample_functions_cache(struct llvmpipe_context *ctx, struct pipe_fence_handle **fence)
967 {
968    struct lp_sampler_matrix *matrix = &ctx->sampler_matrix;
969 
970    simple_mtx_lock(&matrix->lock);
971 
972    /* If the cache is empty, there is nothing to do. */
973    if (!_mesa_hash_table_num_entries(matrix->cache)) {
974       simple_mtx_unlock(&matrix->lock);
975       return;
976    }
977 
978    simple_mtx_unlock(&matrix->lock);
979 
980    if (fence)
981       ctx->pipe.screen->fence_finish(ctx->pipe.screen, NULL, *fence, OS_TIMEOUT_INFINITE);
982 
983    /* All work is finished, it's safe to move cache entries into the table.
984     * The key is the intended address of the sample function.
985     */
986    hash_table_foreach_remove(matrix->cache, entry)
987       *(void **)entry->key = entry->data;
988 }
989