From eea4c98f6d8251060fd36ac5c0aa31547364186c Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Thu, 3 Jun 2021 16:51:09 +0200 Subject: [PATCH] st/pbo: use correct type for images and textures MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Not all hardware can treat float, uint and sint samplers and images the same way, so we need to respect the format-types here. This has the added benefit of making sure sint and uint data doesn't get copied through a float, which might mess with signaling nan encodings. Reviewed-by: Marek Olšák Reviewed-By: Mike Blumenkrantz Part-of: --- src/mesa/state_tracker/st_context.h | 4 ++-- src/mesa/state_tracker/st_pbo.c | 38 ++++++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index ae260bb..303b4d3 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -326,8 +326,8 @@ struct st_context struct pipe_blend_state upload_blend; void *vs; void *gs; - void *upload_fs[3][2]; - void *download_fs[3][PIPE_MAX_TEXTURE_TYPES][2]; + void *upload_fs[5][2]; + void *download_fs[5][PIPE_MAX_TEXTURE_TYPES][2]; bool upload_enabled; bool download_enabled; bool rgba_only; diff --git a/src/mesa/state_tracker/st_pbo.c b/src/mesa/state_tracker/st_pbo.c index ddd3a19..31d5fd8 100644 --- a/src/mesa/state_tracker/st_pbo.c +++ b/src/mesa/state_tracker/st_pbo.c @@ -46,7 +46,9 @@ /* Conversion to apply in the fragment shader. */ enum st_pbo_conversion { - ST_PBO_CONVERT_NONE = 0, + ST_PBO_CONVERT_FLOAT = 0, + ST_PBO_CONVERT_UINT, + ST_PBO_CONVERT_SINT, ST_PBO_CONVERT_UINT_TO_SINT, ST_PBO_CONVERT_SINT_TO_UINT, @@ -383,7 +385,8 @@ st_pbo_create_gs(struct st_context *st) } static const struct glsl_type * -sampler_type_for_target(enum pipe_texture_target target) +sampler_type_for_target(enum pipe_texture_target target, + enum st_pbo_conversion conv) { bool is_array = target >= PIPE_TEXTURE_1D_ARRAY; static const enum glsl_sampler_dim dim[] = { @@ -398,7 +401,15 @@ sampler_type_for_target(enum pipe_texture_target target) [PIPE_TEXTURE_CUBE_ARRAY] = GLSL_SAMPLER_DIM_CUBE, }; - return glsl_sampler_type(dim[target], false, is_array, GLSL_TYPE_FLOAT); + static const enum glsl_base_type type[] = { + [ST_PBO_CONVERT_FLOAT] = GLSL_TYPE_FLOAT, + [ST_PBO_CONVERT_UINT] = GLSL_TYPE_UINT, + [ST_PBO_CONVERT_UINT_TO_SINT] = GLSL_TYPE_UINT, + [ST_PBO_CONVERT_SINT] = GLSL_TYPE_INT, + [ST_PBO_CONVERT_SINT_TO_UINT] = GLSL_TYPE_INT, + }; + + return glsl_sampler_type(dim[target], false, is_array, type[conv]); } @@ -501,7 +512,8 @@ create_fs(struct st_context *st, bool download, nir_variable *tex_var = nir_variable_create(b.shader, nir_var_uniform, - sampler_type_for_target(target), "tex"); + sampler_type_for_target(target, conversion), + "tex"); tex_var->data.explicit_binding = true; tex_var->data.binding = 0; @@ -512,7 +524,8 @@ create_fs(struct st_context *st, bool download, tex->sampler_dim = glsl_get_sampler_dim(tex_var->type); tex->coord_components = glsl_get_sampler_coordinate_components(tex_var->type); - tex->dest_type = nir_type_float32; + + tex->dest_type = nir_get_nir_type_for_glsl_base_type(glsl_get_sampler_result_type(tex_var->type)); tex->src[0].src_type = nir_tex_src_texture_deref; tex->src[0].src = nir_src_for_ssa(&tex_deref->dest.ssa); tex->src[1].src_type = nir_tex_src_sampler_deref; @@ -529,10 +542,17 @@ create_fs(struct st_context *st, bool download, result = nir_umin(&b, result, nir_imm_int(&b, (1u << 31) - 1)); if (download) { + static const enum glsl_base_type type[] = { + [ST_PBO_CONVERT_FLOAT] = GLSL_TYPE_FLOAT, + [ST_PBO_CONVERT_UINT] = GLSL_TYPE_UINT, + [ST_PBO_CONVERT_UINT_TO_SINT] = GLSL_TYPE_INT, + [ST_PBO_CONVERT_SINT] = GLSL_TYPE_INT, + [ST_PBO_CONVERT_SINT_TO_UINT] = GLSL_TYPE_UINT, + }; nir_variable *img_var = nir_variable_create(b.shader, nir_var_uniform, glsl_image_type(GLSL_SAMPLER_DIM_BUF, false, - GLSL_TYPE_FLOAT), "img"); + type[conversion]), "img"); img_var->data.access = ACCESS_NON_READABLE; img_var->data.explicit_binding = true; img_var->data.binding = 0; @@ -559,14 +579,18 @@ static enum st_pbo_conversion get_pbo_conversion(enum pipe_format src_format, enum pipe_format dst_format) { if (util_format_is_pure_uint(src_format)) { + if (util_format_is_pure_uint(dst_format)) + return ST_PBO_CONVERT_UINT; if (util_format_is_pure_sint(dst_format)) return ST_PBO_CONVERT_UINT_TO_SINT; } else if (util_format_is_pure_sint(src_format)) { + if (util_format_is_pure_sint(dst_format)) + return ST_PBO_CONVERT_SINT; if (util_format_is_pure_uint(dst_format)) return ST_PBO_CONVERT_SINT_TO_UINT; } - return ST_PBO_CONVERT_NONE; + return ST_PBO_CONVERT_FLOAT; } void * -- 2.7.4