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 <charmainel@vmware.com>
This commit is contained in:
Brian Paul 2016-03-18 09:55:57 -06:00
parent b56b853ab3
commit dc9ecf58c0
6 changed files with 74 additions and 47 deletions

View File

@ -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];

View File

@ -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.

View File

@ -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;

View File

@ -136,6 +136,8 @@ struct svga_shader_emitter
int current_arl;
unsigned pstipple_sampler_unit;
uint8_t sampler_target[PIPE_MAX_SAMPLERS];
};

View File

@ -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;

View File

@ -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 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_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 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;