From dc9ecf58c0c5c8a97cd41362e78c2fcd9f6e3b80 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 18 Mar 2016 09:55:57 -0600 Subject: [PATCH] svga: use shader sampler view declarations Previously, we looked at the bound textures (via the pipe_sampler_views) to determine texture dimensions (1D/2D/3D/etc) and datatype (float vs. int). But this could fail in out of memory conditions. If we failed to allocate a texture and didn't create a pipe_sampler_view, we'd default to using 0 (PIPE_BUFFER) as the texture type. This led to device errors because of inconsistent shader code. This change relies on all TGSI shaders having an SVIEW declaration for each SAMP declaration. The previous patch series does that. Reviewed-by: Charmaine Lee --- src/gallium/drivers/svga/svga_shader.c | 16 ++-- src/gallium/drivers/svga/svga_shader.h | 3 +- .../drivers/svga/svga_tgsi_decl_sm30.c | 20 +++-- src/gallium/drivers/svga/svga_tgsi_emit.h | 2 + src/gallium/drivers/svga/svga_tgsi_insn.c | 2 +- src/gallium/drivers/svga/svga_tgsi_vgpu10.c | 78 ++++++++++++------- 6 files changed, 74 insertions(+), 47 deletions(-) diff --git a/src/gallium/drivers/svga/svga_shader.c b/src/gallium/drivers/svga/svga_shader.c index 5c99e16d976..78eb3f65b61 100644 --- a/src/gallium/drivers/svga/svga_shader.c +++ b/src/gallium/drivers/svga/svga_shader.c @@ -180,18 +180,18 @@ svga_init_shader_key_common(const struct svga_context *svga, unsigned shader, assert(view->texture); assert(view->texture->target < (1 << 4)); /* texture_target:4 */ - key->tex[i].texture_target = view->texture->target; - /* 1D/2D array textures with one slice are treated as non-arrays * by the SVGA3D device. Convert the texture type here so that * we emit the right TEX/SAMPLE instruction in the shader. */ - if (view->texture->array_size == 1) { - if (view->texture->target == PIPE_TEXTURE_1D_ARRAY) { - key->tex[i].texture_target = PIPE_TEXTURE_1D; + if (view->texture->target == PIPE_TEXTURE_1D_ARRAY || + view->texture->target == PIPE_TEXTURE_2D_ARRAY) { + if (view->texture->array_size == 1) { + key->tex[i].is_array = 0; } - else if (view->texture->target == PIPE_TEXTURE_2D_ARRAY) { - key->tex[i].texture_target = PIPE_TEXTURE_2D; + else { + assert(view->texture->array_size > 1); + key->tex[i].is_array = 1; } } @@ -207,8 +207,6 @@ svga_init_shader_key_common(const struct svga_context *svga, unsigned shader, key->tex[i].swizzle_g = view->swizzle_g; key->tex[i].swizzle_b = view->swizzle_b; key->tex[i].swizzle_a = view->swizzle_a; - - key->tex[i].return_type = svga_get_texture_datatype(view->format); } } key->num_textures = svga->curr.num_sampler_views[shader]; diff --git a/src/gallium/drivers/svga/svga_shader.h b/src/gallium/drivers/svga/svga_shader.h index f49fdb46d0e..3f915740b1f 100644 --- a/src/gallium/drivers/svga/svga_shader.h +++ b/src/gallium/drivers/svga/svga_shader.h @@ -98,14 +98,13 @@ struct svga_compile_key unsigned compare_func:3; unsigned unnormalized:1; unsigned width_height_idx:5; /**< texture unit */ - unsigned texture_target:4; /**< PIPE_TEXTURE_x */ + unsigned is_array:1; unsigned texture_msaa:1; /**< A multisample texture? */ unsigned sprite_texgen:1; unsigned swizzle_r:3; unsigned swizzle_g:3; unsigned swizzle_b:3; unsigned swizzle_a:3; - unsigned return_type:3; /**< TGSI_RETURN_TYPE_x */ } tex[PIPE_MAX_SAMPLERS]; /* Note: svga_compile_keys_equal() depends on the variable-size * tex[] array being at the end of this structure. diff --git a/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c b/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c index ca4009b9e38..204b814a964 100644 --- a/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c +++ b/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c @@ -517,15 +517,15 @@ vs30_output(struct svga_shader_emitter *emit, static ubyte svga_tgsi_sampler_type(const struct svga_shader_emitter *emit, int idx) { - switch (emit->key.tex[idx].texture_target) { - case PIPE_TEXTURE_1D: + switch (emit->sampler_target[idx]) { + case TGSI_TEXTURE_1D: return SVGA3DSAMP_2D; - case PIPE_TEXTURE_2D: - case PIPE_TEXTURE_RECT: + case TGSI_TEXTURE_2D: + case TGSI_TEXTURE_RECT: return SVGA3DSAMP_2D; - case PIPE_TEXTURE_3D: + case TGSI_TEXTURE_3D: return SVGA3DSAMP_VOLUME; - case PIPE_TEXTURE_CUBE: + case TGSI_TEXTURE_CUBE: return SVGA3DSAMP_CUBE; } @@ -585,6 +585,14 @@ svga_translate_decl_sm30( struct svga_shader_emitter *emit, ok = ps30_output( emit, decl->Semantic, idx ); break; + case TGSI_FILE_SAMPLER_VIEW: + { + unsigned unit = decl->Range.First; + assert(decl->Range.First == decl->Range.Last); + emit->sampler_target[unit] = decl->SamplerView.Resource; + } + break; + default: /* don't need to declare other vars */ ok = TRUE; diff --git a/src/gallium/drivers/svga/svga_tgsi_emit.h b/src/gallium/drivers/svga/svga_tgsi_emit.h index 83f0c8bd4d0..7a593ba6e9d 100644 --- a/src/gallium/drivers/svga/svga_tgsi_emit.h +++ b/src/gallium/drivers/svga/svga_tgsi_emit.h @@ -136,6 +136,8 @@ struct svga_shader_emitter int current_arl; unsigned pstipple_sampler_unit; + + uint8_t sampler_target[PIPE_MAX_SAMPLERS]; }; diff --git a/src/gallium/drivers/svga/svga_tgsi_insn.c b/src/gallium/drivers/svga/svga_tgsi_insn.c index 489e68f88e8..3188c411863 100644 --- a/src/gallium/drivers/svga/svga_tgsi_insn.c +++ b/src/gallium/drivers/svga/svga_tgsi_insn.c @@ -3849,7 +3849,7 @@ svga_shader_emit_instructions(struct svga_shader_emitter *emit, if (new_tokens) { /* Setup texture state for stipple */ - emit->key.tex[unit].texture_target = PIPE_TEXTURE_2D; + emit->sampler_target[unit] = TGSI_TEXTURE_2D; emit->key.tex[unit].swizzle_r = TGSI_SWIZZLE_X; emit->key.tex[unit].swizzle_g = TGSI_SWIZZLE_Y; emit->key.tex[unit].swizzle_b = TGSI_SWIZZLE_Z; diff --git a/src/gallium/drivers/svga/svga_tgsi_vgpu10.c b/src/gallium/drivers/svga/svga_tgsi_vgpu10.c index 0c5afeb4cf9..0d5628251df 100644 --- a/src/gallium/drivers/svga/svga_tgsi_vgpu10.c +++ b/src/gallium/drivers/svga/svga_tgsi_vgpu10.c @@ -134,6 +134,8 @@ struct svga_shader_emitter_v10 /* Samplers */ unsigned num_samplers; + ubyte sampler_target[PIPE_MAX_SAMPLERS]; /**< TGSI_TEXTURE_x */ + ubyte sampler_return_type[PIPE_MAX_SAMPLERS]; /**< TGSI_RETURN_TYPE_x */ /* Address regs (really implemented with temps) */ unsigned num_address_regs; @@ -2312,9 +2314,13 @@ emit_vgpu10_declaration(struct svga_shader_emitter_v10 *emit, return TRUE; case TGSI_FILE_SAMPLER_VIEW: - /* Not used at this time, but maybe in the future. - * See emit_resource_declarations(). - */ + { + unsigned unit = decl->Range.First; + assert(decl->Range.First == decl->Range.Last); + emit->sampler_target[unit] = decl->SamplerView.Resource; + /* Note: we can ignore YZW return types for now */ + emit->sampler_return_type[unit] = decl->SamplerView.ReturnTypeX; + } return TRUE; default: @@ -2854,7 +2860,7 @@ emit_constant_declaration(struct svga_shader_emitter_v10 *emit) /* Texture buffer sizes */ for (i = 0; i < emit->num_samplers; i++) { - if (emit->key.tex[i].texture_target == PIPE_BUFFER) { + if (emit->sampler_target[i] == TGSI_TEXTURE_BUFFER) { emit->texture_buffer_size_index[i] = total_consts++; } } @@ -2918,30 +2924,44 @@ emit_sampler_declarations(struct svga_shader_emitter_v10 *emit) /** - * Translate PIPE_TEXTURE_x to VGAPU10_RESOURCE_DIMENSION_x. + * Translate TGSI_TEXTURE_x to VGAPU10_RESOURCE_DIMENSION_x. */ static unsigned -pipe_texture_to_resource_dimension(unsigned target, bool msaa) +tgsi_texture_to_resource_dimension(unsigned target, boolean is_array) { switch (target) { - case PIPE_BUFFER: + case TGSI_TEXTURE_BUFFER: return VGPU10_RESOURCE_DIMENSION_BUFFER; - case PIPE_TEXTURE_1D: + case TGSI_TEXTURE_1D: return VGPU10_RESOURCE_DIMENSION_TEXTURE1D; - case PIPE_TEXTURE_2D: - case PIPE_TEXTURE_RECT: - return msaa ? VGPU10_RESOURCE_DIMENSION_TEXTURE2DMS - : VGPU10_RESOURCE_DIMENSION_TEXTURE2D; - case PIPE_TEXTURE_3D: + case TGSI_TEXTURE_2D: + case TGSI_TEXTURE_RECT: + return VGPU10_RESOURCE_DIMENSION_TEXTURE2D; + case TGSI_TEXTURE_3D: return VGPU10_RESOURCE_DIMENSION_TEXTURE3D; - case PIPE_TEXTURE_CUBE: + case TGSI_TEXTURE_CUBE: + return VGPU10_RESOURCE_DIMENSION_TEXTURECUBE; + case TGSI_TEXTURE_SHADOW1D: + return VGPU10_RESOURCE_DIMENSION_TEXTURE1D; + case TGSI_TEXTURE_SHADOW2D: + case TGSI_TEXTURE_SHADOWRECT: + return VGPU10_RESOURCE_DIMENSION_TEXTURE2D; + case TGSI_TEXTURE_1D_ARRAY: + case TGSI_TEXTURE_SHADOW1D_ARRAY: + return is_array ? VGPU10_RESOURCE_DIMENSION_TEXTURE1DARRAY + : VGPU10_RESOURCE_DIMENSION_TEXTURE1D; + case TGSI_TEXTURE_2D_ARRAY: + case TGSI_TEXTURE_SHADOW2D_ARRAY: + return is_array ? VGPU10_RESOURCE_DIMENSION_TEXTURE2DARRAY + : VGPU10_RESOURCE_DIMENSION_TEXTURE2D; + case TGSI_TEXTURE_SHADOWCUBE: return VGPU10_RESOURCE_DIMENSION_TEXTURECUBE; - case PIPE_TEXTURE_1D_ARRAY: - return VGPU10_RESOURCE_DIMENSION_TEXTURE1DARRAY; - case PIPE_TEXTURE_2D_ARRAY: - return msaa ? VGPU10_RESOURCE_DIMENSION_TEXTURE2DMSARRAY - : VGPU10_RESOURCE_DIMENSION_TEXTURE2DARRAY; - case PIPE_TEXTURE_CUBE_ARRAY: + case TGSI_TEXTURE_2D_MSAA: + return VGPU10_RESOURCE_DIMENSION_TEXTURE2DMS; + case TGSI_TEXTURE_2D_ARRAY_MSAA: + return is_array ? VGPU10_RESOURCE_DIMENSION_TEXTURE2DMSARRAY + : VGPU10_RESOURCE_DIMENSION_TEXTURE2DMS; + case TGSI_TEXTURE_CUBE_ARRAY: return VGPU10_RESOURCE_DIMENSION_TEXTURECUBEARRAY; default: assert(!"Unexpected resource type"); @@ -2993,8 +3013,8 @@ emit_resource_declarations(struct svga_shader_emitter_v10 *emit) opcode0.value = 0; opcode0.opcodeType = VGPU10_OPCODE_DCL_RESOURCE; opcode0.resourceDimension = - pipe_texture_to_resource_dimension(emit->key.tex[i].texture_target, - emit->key.tex[i].texture_msaa); + tgsi_texture_to_resource_dimension(emit->sampler_target[i], + emit->key.tex[i].is_array); operand0.value = 0; operand0.numComponents = VGPU10_OPERAND_0_COMPONENT; operand0.operandType = VGPU10_OPERAND_TYPE_RESOURCE; @@ -3008,10 +3028,10 @@ emit_resource_declarations(struct svga_shader_emitter_v10 *emit) STATIC_ASSERT(VGPU10_RETURN_TYPE_SINT == TGSI_RETURN_TYPE_SINT + 1); STATIC_ASSERT(VGPU10_RETURN_TYPE_UINT == TGSI_RETURN_TYPE_UINT + 1); STATIC_ASSERT(VGPU10_RETURN_TYPE_FLOAT == TGSI_RETURN_TYPE_FLOAT + 1); - assert(emit->key.tex[i].return_type <= TGSI_RETURN_TYPE_FLOAT); - rt = emit->key.tex[i].return_type + 1; + assert(emit->sampler_return_type[i] <= TGSI_RETURN_TYPE_FLOAT); + rt = emit->sampler_return_type[i] + 1; #else - switch (emit->key.tex[i].return_type) { + switch (emit->sampler_return_type[i]) { case TGSI_RETURN_TYPE_UNORM: rt = VGPU10_RETURN_TYPE_UNORM; break; case TGSI_RETURN_TYPE_SNORM: rt = VGPU10_RETURN_TYPE_SNORM; break; case TGSI_RETURN_TYPE_SINT: rt = VGPU10_RETURN_TYPE_SINT; break; @@ -5024,7 +5044,7 @@ end_tex_swizzle(struct svga_shader_emitter_v10 *emit, unsigned swz_b = emit->key.tex[swz->unit].swizzle_b; unsigned swz_a = emit->key.tex[swz->unit].swizzle_a; unsigned writemask_0 = 0, writemask_1 = 0; - boolean int_tex = is_integer_type(emit->key.tex[swz->unit].return_type); + boolean int_tex = is_integer_type(emit->sampler_return_type[swz->unit]); /* Swizzle w/out zero/one terms */ struct tgsi_full_src_register src_swizzled = @@ -5131,7 +5151,7 @@ is_valid_tex_instruction(struct svga_shader_emitter_v10 *emit, boolean valid = TRUE; if (tgsi_is_shadow_target(target) && - is_integer_type(emit->key.tex[unit].return_type)) { + is_integer_type(emit->sampler_return_type[unit])) { debug_printf("Invalid SAMPLE_C with an integer texture!\n"); valid = FALSE; } @@ -5528,7 +5548,7 @@ emit_txq(struct svga_shader_emitter_v10 *emit, { const uint unit = inst->Src[1].Register.Index; - if (emit->key.tex[unit].texture_target == PIPE_BUFFER) { + if (emit->sampler_target[unit] == TGSI_TEXTURE_BUFFER) { /* RESINFO does not support querying texture buffers, so we instead * store texture buffer sizes in shader constants, then copy them to * implement TXQ instead of emitting RESINFO. @@ -6617,7 +6637,7 @@ transform_fs_pstipple(struct svga_shader_emitter_v10 *emit, emit->fs.pstipple_sampler_unit = unit; /* Setup texture state for stipple */ - emit->key.tex[unit].texture_target = PIPE_TEXTURE_2D; + emit->sampler_target[unit] = TGSI_TEXTURE_2D; emit->key.tex[unit].swizzle_r = TGSI_SWIZZLE_X; emit->key.tex[unit].swizzle_g = TGSI_SWIZZLE_Y; emit->key.tex[unit].swizzle_b = TGSI_SWIZZLE_Z; -- 2.30.2