From: Axel Davy Date: Wed, 26 Nov 2014 21:32:57 +0000 (+0100) Subject: st/nine: Fix vertex declarations for non-standard (usage/index) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=712a4c5438d0ce257344b5196c20ad7929b54a0e;p=mesa.git st/nine: Fix vertex declarations for non-standard (usage/index) Nine code to match vertex declaration to vs inputs was limiting the number of possible combinations. Some sm3 games have issues with that, because arbitrary (usage/index) can be used. This patch does the following changes to fix the problem: . Change the numbers given to (usage/index) combinations to uint16 . Do not put limits on the indices when it doesn't make sense . change the conversion rule (usage/index) -> number to fit all combinations . Instead of having a table usage_map mapping a (usage/index) number to an input index, usage_map maps input indices to their (usage/index) Cc: "10.4" Tested-by: Yaroslav Andrusyak Acked-by: Ilia Mirkin Signed-off-by: Axel Davy --- diff --git a/src/gallium/state_trackers/nine/nine_defines.h b/src/gallium/state_trackers/nine/nine_defines.h index aa3b257de09..4f61982a724 100644 --- a/src/gallium/state_trackers/nine/nine_defines.h +++ b/src/gallium/state_trackers/nine/nine_defines.h @@ -30,25 +30,27 @@ #define NINE_RESOURCE_FLAG_DUMMY (PIPE_RESOURCE_FLAG_ST_PRIV << 2) /* vertexdeclaration9.c */ -unsigned nine_d3d9_to_nine_declusage(unsigned usage, unsigned index); - -#define NINE_DECLUSAGE_POSITION(i) ( 0 + (i)) -#define NINE_DECLUSAGE_BLENDWEIGHT(i) ( 5 + (i)) -#define NINE_DECLUSAGE_BLENDINDICES(i) ( 9 + (i)) -#define NINE_DECLUSAGE_NORMAL(i) (13 + (i)) -#define NINE_DECLUSAGE_PSIZE 15 -#define NINE_DECLUSAGE_TEXCOORD(i) (16 + (i)) -#define NINE_DECLUSAGE_TANGENT(i) (32 + (i)) -#define NINE_DECLUSAGE_BINORMAL(i) (34 + (i)) -#define NINE_DECLUSAGE_TESSFACTOR 36 -#define NINE_DECLUSAGE_POSITIONT 37 -#define NINE_DECLUSAGE_COLOR(i) (38 + (i)) -#define NINE_DECLUSAGE_DEPTH 43 -#define NINE_DECLUSAGE_FOG 44 -#define NINE_DECLUSAGE_SAMPLE 45 -#define NINE_DECLUSAGE_NONE 46 -#define NINE_DECLUSAGE_LAST NINE_DECLUSAGE_NONE -#define NINE_DECLUSAGE_COUNT (NINE_DECLUSAGE_LAST + 1) +uint16_t nine_d3d9_to_nine_declusage(unsigned usage, unsigned index); + +#define NINE_DECLUSAGE_POSITION 0 +#define NINE_DECLUSAGE_BLENDWEIGHT 1 +#define NINE_DECLUSAGE_BLENDINDICES 2 +#define NINE_DECLUSAGE_NORMAL 3 +#define NINE_DECLUSAGE_TEXCOORD 4 +#define NINE_DECLUSAGE_TANGENT 5 +#define NINE_DECLUSAGE_BINORMAL 6 +#define NINE_DECLUSAGE_COLOR 7 +#define NINE_DECLUSAGE_POSITIONT 8 + +#define NINE_DECLUSAGE_PSIZE 9 +#define NINE_DECLUSAGE_TESSFACTOR 10 +#define NINE_DECLUSAGE_DEPTH 11 +#define NINE_DECLUSAGE_FOG 12 +#define NINE_DECLUSAGE_SAMPLE 13 +#define NINE_DECLUSAGE_NONE 14 +#define NINE_DECLUSAGE_COUNT (NINE_DECLUSAGE_NONE + 1) + +#define NINE_DECLUSAGE_i(declusage, n) NINE_DECLUSAGE_##declusage + n * NINE_DECLUSAGE_COUNT #define NINED3DCLEAR_DEPTHSTENCIL (D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL) diff --git a/src/gallium/state_trackers/nine/nine_ff.c b/src/gallium/state_trackers/nine/nine_ff.c index 184c4113026..a6bd360cf33 100644 --- a/src/gallium/state_trackers/nine/nine_ff.c +++ b/src/gallium/state_trackers/nine/nine_ff.c @@ -275,7 +275,7 @@ struct vs_build_ctx struct ureg_program *ureg; const struct nine_ff_vs_key *key; - unsigned input[PIPE_MAX_ATTRIBS]; + uint16_t input[PIPE_MAX_ATTRIBS]; unsigned num_inputs; struct ureg_src aVtx; @@ -304,7 +304,7 @@ get_texcoord_sn(struct pipe_screen *screen) } static INLINE struct ureg_src -build_vs_add_input(struct vs_build_ctx *vs, unsigned ndecl) +build_vs_add_input(struct vs_build_ctx *vs, uint16_t ndecl) { const unsigned i = vs->num_inputs++; assert(i < PIPE_MAX_ATTRIBS); @@ -370,10 +370,10 @@ nine_ff_build_vs(struct NineDevice9 *device, struct vs_build_ctx *vs) * (texture coordinates handled later) */ vs->aVtx = build_vs_add_input(vs, - key->position_t ? NINE_DECLUSAGE_POSITIONT : NINE_DECLUSAGE_POSITION(0)); + key->position_t ? NINE_DECLUSAGE_POSITIONT : NINE_DECLUSAGE_POSITION); if (need_rNrm) - vs->aNrm = build_vs_add_input(vs, NINE_DECLUSAGE_NORMAL(0)); + vs->aNrm = build_vs_add_input(vs, NINE_DECLUSAGE_NORMAL); vs->aCol[0] = ureg_imm1f(ureg, 1.0f); vs->aCol[1] = ureg_imm1f(ureg, 1.0f); @@ -382,9 +382,9 @@ nine_ff_build_vs(struct NineDevice9 *device, struct vs_build_ctx *vs) const unsigned mask = key->mtl_diffuse | key->mtl_specular | key->mtl_ambient | key->mtl_emissive; if ((mask & 0x1) && !key->color0in_one) - vs->aCol[0] = build_vs_add_input(vs, NINE_DECLUSAGE_COLOR(0)); + vs->aCol[0] = build_vs_add_input(vs, NINE_DECLUSAGE_i(COLOR, 0)); if ((mask & 0x2) && !key->color1in_one) - vs->aCol[1] = build_vs_add_input(vs, NINE_DECLUSAGE_COLOR(1)); + vs->aCol[1] = build_vs_add_input(vs, NINE_DECLUSAGE_i(COLOR, 1)); vs->mtlD = MATERIAL_CONST(1); vs->mtlA = MATERIAL_CONST(2); @@ -399,20 +399,20 @@ nine_ff_build_vs(struct NineDevice9 *device, struct vs_build_ctx *vs) if (key->mtl_emissive == 1) vs->mtlE = vs->aCol[0]; else if (key->mtl_emissive == 2) vs->mtlE = vs->aCol[1]; } else { - if (!key->color0in_one) vs->aCol[0] = build_vs_add_input(vs, NINE_DECLUSAGE_COLOR(0)); - if (!key->color1in_one) vs->aCol[1] = build_vs_add_input(vs, NINE_DECLUSAGE_COLOR(1)); + if (!key->color0in_one) vs->aCol[0] = build_vs_add_input(vs, NINE_DECLUSAGE_i(COLOR, 0)); + if (!key->color1in_one) vs->aCol[1] = build_vs_add_input(vs, NINE_DECLUSAGE_i(COLOR, 1)); } if (key->vertexpointsize) vs->aPsz = build_vs_add_input(vs, NINE_DECLUSAGE_PSIZE); if (key->vertexblend_indexed) - vs->aInd = build_vs_add_input(vs, NINE_DECLUSAGE_BLENDINDICES(0)); + vs->aInd = build_vs_add_input(vs, NINE_DECLUSAGE_BLENDINDICES); if (key->vertexblend) - vs->aWgt = build_vs_add_input(vs, NINE_DECLUSAGE_BLENDWEIGHT(0)); + vs->aWgt = build_vs_add_input(vs, NINE_DECLUSAGE_BLENDWEIGHT); if (key->vertextween) { - vs->aVtx1 = build_vs_add_input(vs, NINE_DECLUSAGE_POSITION(1)); - vs->aNrm1 = build_vs_add_input(vs, NINE_DECLUSAGE_NORMAL(1)); + vs->aVtx1 = build_vs_add_input(vs, NINE_DECLUSAGE_i(POSITION,1)); + vs->aNrm1 = build_vs_add_input(vs, NINE_DECLUSAGE_i(NORMAL,1)); } /* Declare outputs: @@ -596,7 +596,7 @@ nine_ff_build_vs(struct NineDevice9 *device, struct vs_build_ctx *vs) oTex[i] = ureg_DECL_output(ureg, texcoord_sn, i); if (tci == NINED3DTSS_TCI_PASSTHRU) - vs->aTex[idx] = build_vs_add_input(vs, NINE_DECLUSAGE_TEXCOORD(idx)); + vs->aTex[idx] = build_vs_add_input(vs, NINE_DECLUSAGE_i(TEXCOORD,idx)); if (!dim) { dst[c = 4] = oTex[i]; @@ -1374,7 +1374,7 @@ nine_ff_get_vs(struct NineDevice9 *device) enum pipe_error err; struct vs_build_ctx bld; struct nine_ff_vs_key key; - unsigned s; + unsigned s, i; assert(sizeof(key) <= sizeof(key.value32)); @@ -1385,14 +1385,19 @@ nine_ff_get_vs(struct NineDevice9 *device) /* FIXME: this shouldn't be NULL, but it is on init */ if (state->vdecl) { - if (state->vdecl->usage_map[NINE_DECLUSAGE_POSITIONT] != 0xff) - key.position_t = 1; - if (state->vdecl->usage_map[NINE_DECLUSAGE_COLOR(0)] == 0xff) - key.color0in_one = 1; - if (state->vdecl->usage_map[NINE_DECLUSAGE_COLOR(1)] == 0xff) - key.color1in_one = 1; - if (state->vdecl->usage_map[NINE_DECLUSAGE_PSIZE] != 0xff) - key.vertexpointsize = 1; + key.color0in_one = 1; + key.color1in_one = 1; + for (i = 0; i < state->vdecl->nelems; i++) { + uint16_t usage = state->vdecl->usage_map[i]; + if (usage == NINE_DECLUSAGE_POSITIONT) + key.position_t = 1; + else if (usage == NINE_DECLUSAGE_i(COLOR, 0)) + key.color0in_one = 0; + else if (usage == NINE_DECLUSAGE_i(COLOR, 1)) + key.color1in_one = 0; + else if (usage == NINE_DECLUSAGE_PSIZE) + key.vertexpointsize = 1; + } } if (!key.vertexpointsize) key.pointscale = !!state->rs[D3DRS_POINTSCALEENABLE]; diff --git a/src/gallium/state_trackers/nine/nine_shader.h b/src/gallium/state_trackers/nine/nine_shader.h index 21824086490..ddee3724079 100644 --- a/src/gallium/state_trackers/nine/nine_shader.h +++ b/src/gallium/state_trackers/nine/nine_shader.h @@ -48,7 +48,7 @@ struct nine_shader_info void *cso; /* out, pipe cso for bind_vs,fs_state */ - uint8_t input_map[PIPE_MAX_ATTRIBS]; /* VS input -> NINE_DECLUSAGE_x */ + uint16_t input_map[PIPE_MAX_ATTRIBS]; /* VS input -> NINE_DECLUSAGE_x */ uint8_t num_inputs; /* there may be unused inputs (NINE_DECLUSAGE_NONE) */ boolean position_t; /* out, true if VP writes pre-transformed position */ diff --git a/src/gallium/state_trackers/nine/nine_state.c b/src/gallium/state_trackers/nine/nine_state.c index 37de6a30492..41758036bc2 100644 --- a/src/gallium/state_trackers/nine/nine_state.c +++ b/src/gallium/state_trackers/nine/nine_state.c @@ -184,7 +184,8 @@ update_vertex_elements(struct NineDevice9 *device) struct nine_state *state = &device->state; const struct NineVertexDeclaration9 *vdecl = device->state.vdecl; const struct NineVertexShader9 *vs; - unsigned n, l, b; + unsigned n, b, i; + int index; struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS]; state->stream_usage_mask = 0; @@ -197,11 +198,16 @@ update_vertex_elements(struct NineDevice9 *device) DBG("looking up input %u (usage %u) from vdecl(%p)\n", n, vs->input_map[n].ndecl, vdecl); - assert(vs->input_map[n].ndecl < Elements(vdecl->usage_map)); - l = vdecl->usage_map[vs->input_map[n].ndecl]; + index = -1; + for (i = 0; i < vdecl->nelems; i++) { + if (vdecl->usage_map[i] == vs->input_map[n].ndecl) { + index = i; + break; + } + } - if (likely(l < vdecl->nelems)) { - ve[n] = vdecl->elems[l]; + if (index >= 0) { + ve[n] = vdecl->elems[index]; b = ve[n].vertex_buffer_index; state->stream_usage_mask |= 1 << b; /* XXX wine just uses 1 here: */ diff --git a/src/gallium/state_trackers/nine/vertexdeclaration9.c b/src/gallium/state_trackers/nine/vertexdeclaration9.c index 60b1fe37ac5..49a60e35b1e 100644 --- a/src/gallium/state_trackers/nine/vertexdeclaration9.c +++ b/src/gallium/state_trackers/nine/vertexdeclaration9.c @@ -95,21 +95,20 @@ nine_d3ddeclusage_check(unsigned usage, unsigned usage_idx) { switch (usage) { case D3DDECLUSAGE_POSITIONT: - case D3DDECLUSAGE_PSIZE: case D3DDECLUSAGE_TESSFACTOR: case D3DDECLUSAGE_DEPTH: - case D3DDECLUSAGE_FOG: - case D3DDECLUSAGE_SAMPLE: - return usage_idx <= 0; case D3DDECLUSAGE_NORMAL: case D3DDECLUSAGE_TANGENT: case D3DDECLUSAGE_BINORMAL: - return usage_idx <= 1; case D3DDECLUSAGE_POSITION: case D3DDECLUSAGE_BLENDWEIGHT: case D3DDECLUSAGE_BLENDINDICES: case D3DDECLUSAGE_COLOR: - return usage_idx <= 4; + return TRUE; + case D3DDECLUSAGE_PSIZE: + case D3DDECLUSAGE_FOG: + case D3DDECLUSAGE_SAMPLE: + return usage_idx <= 0; case D3DDECLUSAGE_TEXCOORD: return usage_idx <= 15; default: @@ -118,8 +117,8 @@ nine_d3ddeclusage_check(unsigned usage, unsigned usage_idx) } #define NINE_DECLUSAGE_CASE0(n) case D3DDECLUSAGE_##n: return NINE_DECLUSAGE_##n -#define NINE_DECLUSAGE_CASEi(n) case D3DDECLUSAGE_##n: return NINE_DECLUSAGE_##n(usage_idx) -INLINE unsigned +#define NINE_DECLUSAGE_CASEi(n) case D3DDECLUSAGE_##n: return NINE_DECLUSAGE_i(n, usage_idx) +uint16_t nine_d3d9_to_nine_declusage(unsigned usage, unsigned usage_idx) { if (!nine_d3ddeclusage_check(usage, usage_idx)) @@ -135,7 +134,7 @@ nine_d3d9_to_nine_declusage(unsigned usage, unsigned usage_idx) NINE_DECLUSAGE_CASEi(TANGENT); NINE_DECLUSAGE_CASEi(BINORMAL); NINE_DECLUSAGE_CASE0(TESSFACTOR); - NINE_DECLUSAGE_CASE0(POSITIONT); + NINE_DECLUSAGE_CASEi(POSITIONT); NINE_DECLUSAGE_CASEi(COLOR); NINE_DECLUSAGE_CASE0(DEPTH); NINE_DECLUSAGE_CASE0(FOG); @@ -148,58 +147,25 @@ nine_d3d9_to_nine_declusage(unsigned usage, unsigned usage_idx) static const char *nine_declusage_names[] = { - [NINE_DECLUSAGE_POSITION(0)] = "POSITION", - [NINE_DECLUSAGE_POSITION(1)] = "POSITION1", - [NINE_DECLUSAGE_POSITION(2)] = "POSITION2", - [NINE_DECLUSAGE_POSITION(3)] = "POSITION3", - [NINE_DECLUSAGE_POSITION(4)] = "POSITION4", - [NINE_DECLUSAGE_BLENDWEIGHT(0)] = "BLENDWEIGHT", - [NINE_DECLUSAGE_BLENDWEIGHT(1)] = "BLENDWEIGHT1", - [NINE_DECLUSAGE_BLENDWEIGHT(2)] = "BLENDWEIGHT2", - [NINE_DECLUSAGE_BLENDWEIGHT(3)] = "BLENDWEIGHT3", - [NINE_DECLUSAGE_BLENDINDICES(0)] = "BLENDINDICES", - [NINE_DECLUSAGE_BLENDINDICES(1)] = "BLENDINDICES1", - [NINE_DECLUSAGE_BLENDINDICES(2)] = "BLENDINDICES2", - [NINE_DECLUSAGE_BLENDINDICES(3)] = "BLENDINDICES3", - [NINE_DECLUSAGE_NORMAL(0)] = "NORMAL", - [NINE_DECLUSAGE_NORMAL(1)] = "NORMAL1", + [NINE_DECLUSAGE_POSITION] = "POSITION", + [NINE_DECLUSAGE_BLENDWEIGHT] = "BLENDWEIGHT", + [NINE_DECLUSAGE_BLENDINDICES] = "BLENDINDICES", + [NINE_DECLUSAGE_NORMAL] = "NORMAL", [NINE_DECLUSAGE_PSIZE] = "PSIZE", - [NINE_DECLUSAGE_TEXCOORD(0)] = "TEXCOORD0", - [NINE_DECLUSAGE_TEXCOORD(1)] = "TEXCOORD1", - [NINE_DECLUSAGE_TEXCOORD(2)] = "TEXCOORD2", - [NINE_DECLUSAGE_TEXCOORD(3)] = "TEXCOORD3", - [NINE_DECLUSAGE_TEXCOORD(4)] = "TEXCOORD4", - [NINE_DECLUSAGE_TEXCOORD(5)] = "TEXCOORD5", - [NINE_DECLUSAGE_TEXCOORD(6)] = "TEXCOORD6", - [NINE_DECLUSAGE_TEXCOORD(7)] = "TEXCOORD7", - [NINE_DECLUSAGE_TEXCOORD(8)] = "TEXCOORD8", - [NINE_DECLUSAGE_TEXCOORD(9)] = "TEXCOORD9", - [NINE_DECLUSAGE_TEXCOORD(10)] = "TEXCOORD10", - [NINE_DECLUSAGE_TEXCOORD(11)] = "TEXCOORD11", - [NINE_DECLUSAGE_TEXCOORD(12)] = "TEXCOORD12", - [NINE_DECLUSAGE_TEXCOORD(13)] = "TEXCOORD13", - [NINE_DECLUSAGE_TEXCOORD(14)] = "TEXCOORD14", - [NINE_DECLUSAGE_TEXCOORD(15)] = "TEXCOORD15", - [NINE_DECLUSAGE_TANGENT(0)] = "TANGENT", - [NINE_DECLUSAGE_TANGENT(1)] = "TANGENT1", - [NINE_DECLUSAGE_BINORMAL(0)] = "BINORMAL", - [NINE_DECLUSAGE_BINORMAL(1)] = "BINORMAL1", + [NINE_DECLUSAGE_TEXCOORD] = "TEXCOORD", + [NINE_DECLUSAGE_TANGENT] = "TANGENT", + [NINE_DECLUSAGE_BINORMAL] = "BINORMAL", [NINE_DECLUSAGE_TESSFACTOR] = "TESSFACTOR", [NINE_DECLUSAGE_POSITIONT] = "POSITIONT", - [NINE_DECLUSAGE_COLOR(0)] = "DIFFUSE", - [NINE_DECLUSAGE_COLOR(1)] = "SPECULAR", - [NINE_DECLUSAGE_COLOR(2)] = "COLOR2", - [NINE_DECLUSAGE_COLOR(3)] = "COLOR3", - [NINE_DECLUSAGE_COLOR(4)] = "COLOR4", + [NINE_DECLUSAGE_COLOR] = "DIFFUSE", [NINE_DECLUSAGE_DEPTH] = "DEPTH", [NINE_DECLUSAGE_FOG] = "FOG", [NINE_DECLUSAGE_NONE] = "(NONE)", - [NINE_DECLUSAGE_COUNT] = "(OOB)" }; static INLINE const char * nine_declusage_name(unsigned ndcl) { - return nine_declusage_names[MIN2(ndcl, Elements(nine_declusage_names) - 1)]; + return nine_declusage_names[ndcl % NINE_DECLUSAGE_COUNT]; } HRESULT @@ -225,15 +191,14 @@ NineVertexDeclaration9_ctor( struct NineVertexDeclaration9 *This, This->decls = CALLOC(This->nelems+1, sizeof(D3DVERTEXELEMENT9)); This->elems = CALLOC(This->nelems, sizeof(struct pipe_vertex_element)); + This->usage_map = CALLOC(This->nelems, sizeof(uint16_t)); if (!This->decls || !This->elems) { return E_OUTOFMEMORY; } memcpy(This->decls, pElements, sizeof(D3DVERTEXELEMENT9)*(This->nelems+1)); - memset(This->usage_map, 0xff, sizeof(This->usage_map)); - for (i = 0; i < This->nelems; ++i) { - uint8_t usage = nine_d3d9_to_nine_declusage(This->decls[i].Usage, - This->decls[i].UsageIndex); - This->usage_map[usage] = i; + uint16_t usage = nine_d3d9_to_nine_declusage(This->decls[i].Usage, + This->decls[i].UsageIndex); + This->usage_map[i] = usage; This->elems[i].src_offset = This->decls[i].Offset; This->elems[i].instance_divisor = 0; @@ -241,11 +206,12 @@ NineVertexDeclaration9_ctor( struct NineVertexDeclaration9 *This, This->elems[i].src_format = decltype_format(This->decls[i].Type); /* XXX Remember Method (tesselation), Usage, UsageIndex */ - DBG("VERTEXELEMENT[%u]: Stream=%u Offset=%u Type=%s DeclUsage=%s\n", i, + DBG("VERTEXELEMENT[%u]: Stream=%u Offset=%u Type=%s DeclUsage=%s%d\n", i, This->decls[i].Stream, This->decls[i].Offset, util_format_name(This->elems[i].src_format), - nine_declusage_name(usage)); + nine_declusage_name(usage), + usage / NINE_DECLUSAGE_COUNT); } return D3D_OK; @@ -258,6 +224,8 @@ NineVertexDeclaration9_dtor( struct NineVertexDeclaration9 *This ) FREE(This->decls); if (This->elems) FREE(This->elems); + if (This->usage_map) + FREE(This->usage_map); NineUnknown_dtor(&This->base); } diff --git a/src/gallium/state_trackers/nine/vertexdeclaration9.h b/src/gallium/state_trackers/nine/vertexdeclaration9.h index 6590f460f67..a4d4a0445d5 100644 --- a/src/gallium/state_trackers/nine/vertexdeclaration9.h +++ b/src/gallium/state_trackers/nine/vertexdeclaration9.h @@ -40,9 +40,9 @@ struct NineVertexDeclaration9 struct pipe_vertex_element *elems; unsigned nelems; - /* DECLUSAGE -> element index, for selecting the vertex element + /* index -> DECLUSAGE, for selecting the vertex element * for each VS input */ - uint8_t usage_map[NINE_DECLUSAGE_COUNT]; + uint16_t *usage_map; D3DVERTEXELEMENT9 *decls; DWORD fvf; diff --git a/src/gallium/state_trackers/nine/vertexshader9.h b/src/gallium/state_trackers/nine/vertexshader9.h index a7d750d3efb..3495c9f9c55 100644 --- a/src/gallium/state_trackers/nine/vertexshader9.h +++ b/src/gallium/state_trackers/nine/vertexshader9.h @@ -32,7 +32,7 @@ struct NineVertexShader9 struct nine_shader_variant variant; struct { - uint8_t ndecl; /* NINE_DECLUSAGE_x */ + uint16_t ndecl; /* NINE_DECLUSAGE_x */ } input_map[PIPE_MAX_ATTRIBS]; unsigned num_inputs;