diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c index d11f3d1903c..8b47d3eaf84 100644 --- a/src/gallium/state_trackers/nine/device9.c +++ b/src/gallium/state_trackers/nine/device9.c @@ -3068,23 +3068,22 @@ NineDevice9_SetVertexDeclaration( struct NineDevice9 *This, IDirect3DVertexDeclaration9 *pDecl ) { struct nine_state *state = This->update; - struct nine_context *context = &This->context; - BOOL was_programmable_vs = This->state.programmable_vs; + struct NineVertexDeclaration9 *vdecl = NineVertexDeclaration9(pDecl); DBG("This=%p pDecl=%p\n", This, pDecl); - if (likely(!This->is_recording) && state->vdecl == NineVertexDeclaration9(pDecl)) + if (unlikely(This->is_recording)) { + nine_bind(&state->vdecl, vdecl); + state->changed.group |= NINE_STATE_VDECL; return D3D_OK; - - nine_bind(&state->vdecl, pDecl); - - This->state.programmable_vs = This->state.vs && !(This->state.vdecl && This->state.vdecl->position_t); - if (likely(!This->is_recording) && was_programmable_vs != This->state.programmable_vs) { - context->commit |= NINE_STATE_COMMIT_CONST_VS; - state->changed.group |= NINE_STATE_VS; } - state->changed.group |= NINE_STATE_VDECL; + if (state->vdecl == vdecl) + return D3D_OK; + + nine_bind(&state->vdecl, vdecl); + + nine_context_set_vertex_declaration(This, vdecl); return D3D_OK; } @@ -3165,7 +3164,7 @@ NineDevice9_SetVertexShader( struct NineDevice9 *This, nine_bind(&state->vs, pShader); - This->state.programmable_vs = This->state.vs && !(This->state.vdecl && This->state.vdecl->position_t); + This->state.programmable_vs = This->state.vs && !(This->context.vdecl && This->context.vdecl->position_t); /* ff -> non-ff: commit back non-ff constants */ if (!was_programmable_vs && This->state.programmable_vs) diff --git a/src/gallium/state_trackers/nine/nine_ff.c b/src/gallium/state_trackers/nine/nine_ff.c index c0f15d84c8f..2c459636e84 100644 --- a/src/gallium/state_trackers/nine/nine_ff.c +++ b/src/gallium/state_trackers/nine/nine_ff.c @@ -1578,11 +1578,11 @@ nine_ff_get_vs(struct NineDevice9 *device) bld.key = &key; /* FIXME: this shouldn't be NULL, but it is on init */ - if (state->vdecl) { + if (context->vdecl) { key.color0in_one = 1; key.color1in_zero = 1; - for (i = 0; i < state->vdecl->nelems; i++) { - uint16_t usage = state->vdecl->usage_map[i]; + for (i = 0; i < context->vdecl->nelems; i++) { + uint16_t usage = context->vdecl->usage_map[i]; if (usage == NINE_DECLUSAGE_POSITIONT) key.position_t = 1; else if (usage == NINE_DECLUSAGE_i(COLOR, 0)) @@ -1603,7 +1603,7 @@ nine_ff_get_vs(struct NineDevice9 *device) else if (usage % NINE_DECLUSAGE_COUNT == NINE_DECLUSAGE_TEXCOORD) { s = usage / NINE_DECLUSAGE_COUNT; if (s < 8) - input_texture_coord[s] = nine_decltype_get_dim(state->vdecl->decls[i].Type); + input_texture_coord[s] = nine_decltype_get_dim(context->vdecl->decls[i].Type); else DBG("FF given texture coordinate >= 8. Ignoring\n"); } else if (usage < NINE_DECLUSAGE_NONE) @@ -1818,7 +1818,7 @@ nine_ff_get_ps(struct NineDevice9 *device) if (s >= 1) key.ts[s-1].resultarg = 0; - key.projected = nine_ff_get_projected_key(state); + key.projected = nine_ff_get_projected_key(state, context); key.specular = !!context->rs[D3DRS_SPECULARENABLE]; for (; s < 8; ++s) diff --git a/src/gallium/state_trackers/nine/nine_ff.h b/src/gallium/state_trackers/nine/nine_ff.h index 6c32dba5902..b1e3b9ac4a9 100644 --- a/src/gallium/state_trackers/nine/nine_ff.h +++ b/src/gallium/state_trackers/nine/nine_ff.h @@ -62,20 +62,20 @@ nine_decltype_get_dim(BYTE type) } static inline uint16_t -nine_ff_get_projected_key(struct nine_state *state) +nine_ff_get_projected_key(struct nine_state *state, struct nine_context *context) { unsigned s, i; uint16_t projected = 0; char input_texture_coord[8]; memset(&input_texture_coord, 0, sizeof(input_texture_coord)); - if (state->vdecl) { - for (i = 0; i < state->vdecl->nelems; i++) { - uint16_t usage = state->vdecl->usage_map[i]; + if (context->vdecl) { + for (i = 0; i < context->vdecl->nelems; i++) { + uint16_t usage = context->vdecl->usage_map[i]; if (usage % NINE_DECLUSAGE_COUNT == NINE_DECLUSAGE_TEXCOORD) { s = usage / NINE_DECLUSAGE_COUNT; if (s < 8) - input_texture_coord[s] = nine_decltype_get_dim(state->vdecl->decls[i].Type); + input_texture_coord[s] = nine_decltype_get_dim(context->vdecl->decls[i].Type); } } } diff --git a/src/gallium/state_trackers/nine/nine_state.c b/src/gallium/state_trackers/nine/nine_state.c index cde38ee6622..07a57ba8f94 100644 --- a/src/gallium/state_trackers/nine/nine_state.c +++ b/src/gallium/state_trackers/nine/nine_state.c @@ -597,7 +597,7 @@ update_vertex_elements(struct NineDevice9 *device) { struct nine_state *state = &device->state; struct nine_context *context = &device->context; - const struct NineVertexDeclaration9 *vdecl = device->state.vdecl; + const struct NineVertexDeclaration9 *vdecl = device->context.vdecl; const struct NineVertexShader9 *vs; unsigned n, b, i; int index; @@ -1276,6 +1276,25 @@ nine_context_set_stream_source_freq(struct NineDevice9 *device, state->changed.group |= NINE_STATE_STREAMFREQ; } +void +nine_context_set_vertex_declaration(struct NineDevice9 *device, + struct NineVertexDeclaration9 *vdecl) +{ + struct nine_state *state = &device->state; + struct nine_context *context = &device->context; + BOOL was_programmable_vs = device->state.programmable_vs; + + nine_bind(&context->vdecl, vdecl); + + device->state.programmable_vs = device->state.vs && !(device->context.vdecl && device->context.vdecl->position_t); + if (was_programmable_vs != device->state.programmable_vs) { + context->commit |= NINE_STATE_COMMIT_CONST_VS; + state->changed.group |= NINE_STATE_VS; + } + + state->changed.group |= NINE_STATE_VDECL; +} + void nine_context_apply_stateblock(struct NineDevice9 *device, const struct nine_state *src) @@ -1331,6 +1350,12 @@ nine_context_apply_stateblock(struct NineDevice9 *device, } context->changed.vtxbuf |= src->changed.vtxbuf; } + + /* Vertex declaration */ + if ((src->changed.group & NINE_STATE_VDECL) && src->vdecl) + nine_context_set_vertex_declaration(device, src->vdecl); + + device->state.programmable_vs = device->state.vs && !(context->vdecl && context->vdecl->position_t); } static void @@ -1857,6 +1882,7 @@ nine_context_clear(struct nine_context *context) { unsigned i; + nine_bind(&context->vdecl, NULL); for (i = 0; i < PIPE_MAX_ATTRIBS; ++i) pipe_resource_reference(&context->vtxbuf[i].buffer, NULL); diff --git a/src/gallium/state_trackers/nine/nine_state.h b/src/gallium/state_trackers/nine/nine_state.h index 5bc9f707023..523c93d68e9 100644 --- a/src/gallium/state_trackers/nine/nine_state.h +++ b/src/gallium/state_trackers/nine/nine_state.h @@ -227,6 +227,8 @@ struct nine_context { uint8_t rt_mask; + struct NineVertexDeclaration9 *vdecl; + struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; UINT stream_freq[PIPE_MAX_ATTRIBS]; uint32_t stream_instancedata_mask; /* derived from stream_freq */ @@ -298,6 +300,10 @@ nine_context_set_stream_source_freq(struct NineDevice9 *device, UINT StreamNumber, UINT Setting); +void +nine_context_set_vertex_declaration(struct NineDevice9 *device, + struct NineVertexDeclaration9 *vdecl); + void nine_context_apply_stateblock(struct NineDevice9 *device, const struct nine_state *src); diff --git a/src/gallium/state_trackers/nine/pixelshader9.h b/src/gallium/state_trackers/nine/pixelshader9.h index 4c0b537b1bd..d9f55b4e5fa 100644 --- a/src/gallium/state_trackers/nine/pixelshader9.h +++ b/src/gallium/state_trackers/nine/pixelshader9.h @@ -99,7 +99,7 @@ NinePixelShader9_UpdateKey( struct NinePixelShader9 *ps, key |= ((uint64_t)1) << 34; if (unlikely(ps->byte_code.version < 0x14)) { - projected = nine_ff_get_projected_key(state); + projected = nine_ff_get_projected_key(state, context); key |= ((uint64_t) projected) << 48; } diff --git a/src/gallium/state_trackers/nine/stateblock9.c b/src/gallium/state_trackers/nine/stateblock9.c index 4af370ec94d..1ed251af623 100644 --- a/src/gallium/state_trackers/nine/stateblock9.c +++ b/src/gallium/state_trackers/nine/stateblock9.c @@ -567,10 +567,7 @@ NineStateBlock9_Apply( struct NineStateBlock9 *This ) nine_context_apply_stateblock(device, src); if ((src->changed.group & NINE_STATE_VDECL) && src->vdecl) - NineDevice9_SetVertexDeclaration(This->base.device, (IDirect3DVertexDeclaration9 *)src->vdecl); - - /* Recomputing it is needed if we changed vs but not vdecl */ - dst->programmable_vs = dst->vs && !(dst->vdecl && dst->vdecl->position_t); + nine_bind(&dst->vdecl, src->vdecl); /* Textures */ if (src->changed.texture) {