Module: Mesa
Branch: main
Commit: f2ae21758fcfc70afcd566660b49e9a60f4f96c8
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=f2ae21758fcfc70afcd566660b49e9a60f4f96c8

Author: Konstantin Seurer <[email protected]>
Date:   Mon Oct  9 16:16:22 2023 +0200

llvmpipe: Compile a nop texture function for unsupported configurations

Fixes a crash in Quake II RTX. Maybe the texture sample codegen will be
more robust in the future so we do not need to work around its
limitations here.

Reviewed-By: Mike Blumenkrantz <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25617>

---

 src/gallium/drivers/llvmpipe/lp_texture_handle.c | 32 ++++++++++++++----------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_texture_handle.c 
b/src/gallium/drivers/llvmpipe/lp_texture_handle.c
index 18014f5fca1..ff69fa024a5 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture_handle.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture_handle.c
@@ -342,11 +342,12 @@ compile_sample_function(struct llvmpipe_context *ctx, 
struct lp_static_texture_s
 {
    enum lp_sampler_lod_control lod_control = (sample_key & 
LP_SAMPLER_LOD_CONTROL_MASK) >> LP_SAMPLER_LOD_CONTROL_SHIFT;
 
+   bool supported = true;
    if (texture->format != PIPE_FORMAT_NONE) {
       enum lp_sampler_op_type op_type = (sample_key & LP_SAMPLER_OP_TYPE_MASK) 
>> LP_SAMPLER_OP_TYPE_SHIFT;
       if (op_type != LP_SAMPLER_OP_LODQ)
          if ((sampler->compare_mode == PIPE_TEX_COMPARE_NONE) == !!(sample_key 
& LP_SAMPLER_SHADOW))
-            return NULL;
+            supported = false;
 
       /* Skip integer formats which would cause a type mismatch in the compare 
function. */
       const struct util_format_description *desc = 
util_format_description(texture->format);
@@ -357,18 +358,19 @@ compile_sample_function(struct llvmpipe_context *ctx, 
struct lp_static_texture_s
       };
       texel_type = lp_build_texel_type(texel_type, desc);
       if ((sample_key & LP_SAMPLER_SHADOW) && !texel_type.floating)
-         return NULL;
+         supported = false;
 
       if (texture_dims(texture->target) != 2 && op_type == 
LP_SAMPLER_OP_GATHER)
-         return NULL;
+         supported = false;
 
       if (op_type != LP_SAMPLER_OP_FETCH) {
          if (!sampler->normalized_coords) {
-            if (texture->target != PIPE_TEXTURE_1D && texture->target != 
PIPE_TEXTURE_2D)
-               return NULL;
+            if (texture->target != PIPE_TEXTURE_1D && texture->target != 
PIPE_TEXTURE_2D &&
+                texture->target != PIPE_TEXTURE_1D_ARRAY && texture->target != 
PIPE_TEXTURE_2D_ARRAY)
+               supported = false;
 
             if (!texture->level_zero_only)
-               return NULL;
+               supported = false;
          }
       }
 
@@ -376,14 +378,14 @@ compile_sample_function(struct llvmpipe_context *ctx, 
struct lp_static_texture_s
           (sampler->min_img_filter == PIPE_TEX_FILTER_LINEAR ||
            sampler->min_mip_filter == PIPE_TEX_MIPFILTER_LINEAR ||
            sampler->mag_img_filter == PIPE_TEX_FILTER_LINEAR))
-         return NULL;
+         supported = false;
 
       if (sampler->aniso) {
          if (texture_dims(texture->target) != 2)
-            return NULL;
+            supported = false;
 
          if (util_format_is_pure_integer(texture->format))
-            return NULL;
+            supported = false;
       }
 
       if (util_format_get_num_planes(texture->format) > 1)
@@ -391,7 +393,7 @@ compile_sample_function(struct llvmpipe_context *ctx, 
struct lp_static_texture_s
 
       uint32_t bind = op_type == LP_SAMPLER_OP_FETCH ? 
PIPE_BIND_CONSTANT_BUFFER : PIPE_BIND_SAMPLER_VIEW;
       if (!ctx->pipe.screen->is_format_supported(ctx->pipe.screen, 
texture->format, texture->target, 0, 0, bind))
-         return NULL;
+         supported = false;
    }
 
    uint8_t cache_key[SHA1_DIGEST_LENGTH];
@@ -463,9 +465,13 @@ compile_sample_function(struct llvmpipe_context *ctx, 
struct lp_static_texture_s
    LLVMPositionBuilderAtEnd(gallivm->builder, block);
 
    LLVMValueRef texel_out[4] = { 0 };
-   lp_build_sample_soa_code(gallivm, texture, sampler, 
lp_build_sampler_soa_dynamic_state(sampler_soa),
-                            type, sample_key, 0, 0, cs.jit_resources_type, 
NULL, cs.jit_cs_thread_data_type,
-                            NULL, coords, offsets, NULL, lod, ms_index, 
aniso_filter_table, texel_out);
+   if (supported) {
+      lp_build_sample_soa_code(gallivm, texture, sampler, 
lp_build_sampler_soa_dynamic_state(sampler_soa),
+                               type, sample_key, 0, 0, cs.jit_resources_type, 
NULL, cs.jit_cs_thread_data_type,
+                               NULL, coords, offsets, NULL, lod, ms_index, 
aniso_filter_table, texel_out);
+   } else {
+      lp_build_sample_nop(gallivm, lp_build_texel_type(type, 
util_format_description(texture->format)), coords, texel_out);
+   }
 
    LLVMBuildAggregateRet(gallivm->builder, texel_out, 4);
 

Reply via email to