From f2ae21758fcfc70afcd566660b49e9a60f4f96c8 Mon Sep 17 00:00:00 2001 From: Konstantin Seurer Date: Mon, 9 Oct 2023 16:16:22 +0200 Subject: [PATCH] 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 Part-of: --- .../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);