IDirect3DVertexDeclaration9 *pDecl )
{
struct nine_state *state = This->update;
+ BOOL was_programmable_vs = This->state.programmable_vs;
DBG("This=%p pDecl=%p\n", This, pDecl);
if (likely(!This->is_recording) && state->vdecl == NineVertexDeclaration9(pDecl))
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) {
+ state->commit |= NINE_STATE_COMMIT_CONST_VS;
+ state->changed.group |= NINE_STATE_VS;
+ }
+
state->changed.group |= NINE_STATE_VDECL;
return D3D_OK;
IDirect3DVertexShader9 *pShader )
{
struct nine_state *state = This->update;
+ BOOL was_programmable_vs = This->state.programmable_vs;
DBG("This=%p pShader=%p\n", This, pShader);
if (!This->is_recording && state->vs == (struct NineVertexShader9*)pShader)
return D3D_OK;
+ nine_bind(&state->vs, pShader);
+
+ This->state.programmable_vs = This->state.vs && !(This->state.vdecl && This->state.vdecl->position_t);
+
/* ff -> non-ff: commit back non-ff constants */
- if (!state->vs && pShader)
+ if (!was_programmable_vs && This->state.programmable_vs)
state->commit |= NINE_STATE_COMMIT_CONST_VS;
- nine_bind(&state->vs, pShader);
-
state->changed.group |= NINE_STATE_VS;
return D3D_OK;
DBG("vs=%p ps=%p\n", device->state.vs, device->state.ps);
/* NOTE: the only reference belongs to the hash table */
- if (!device->state.vs) {
+ if (!state->programmable_vs) {
device->ff.vs = nine_ff_get_vs(device);
device->state.changed.group |= NINE_STATE_VS;
}
device->state.changed.group |= NINE_STATE_PS;
}
- if (!device->state.vs) {
+ if (!state->programmable_vs) {
nine_ff_load_vs_transforms(device);
nine_ff_load_tex_matrices(device);
nine_ff_load_lights(device);
uint32_t changed_group = 0;
int has_key_changed = 0;
- if (likely(vs))
+ if (likely(state->programmable_vs))
has_key_changed = NineVertexShader9_UpdateKey(vs, state);
if (!shader_changed && !has_key_changed)
return 0;
/* likely because we dislike FF */
- if (likely(vs)) {
+ if (likely(state->programmable_vs)) {
state->cso.vs = NineVertexShader9_GetVariant(vs);
} else {
vs = device->ff.vs;
state->stream_usage_mask = 0;
memset(vdecl_index_map, -1, 16);
memset(used_streams, 0, device->caps.MaxStreams);
- vs = device->state.vs ? device->state.vs : device->ff.vs;
+ vs = state->programmable_vs ? device->state.vs : device->ff.vs;
if (vdecl) {
for (n = 0; n < vs->num_inputs; ++n) {
cso_single_sampler_done(device->cso, PIPE_SHADER_FRAGMENT);
commit_samplers = FALSE;
- sampler_mask = state->vs ? state->vs->sampler_mask : 0;
+ sampler_mask = state->programmable_vs ? state->vs->sampler_mask : 0;
state->bound_samplers_mask_vs = 0;
for (num_textures = 0, i = 0; i < NINE_MAX_SAMPLERS_VS; ++i) {
const unsigned s = NINE_SAMPLER_VS(i);
{
struct pipe_context *pipe = device->pipe;
- if (unlikely(!device->state.vs))
+ if (unlikely(!device->state.programmable_vs))
pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &device->state.pipe.cb_vs_ff);
else
pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &device->state.pipe.cb_vs);
validate_textures(device); /* may clobber state */
/* ff_update may change VS/PS dirty bits */
- if (unlikely(!state->vs || !state->ps))
+ if (unlikely(!state->programmable_vs || !state->ps))
nine_ff_update(device);
group = state->changed.group;
if (group & (NINE_STATE_TEXTURE | NINE_STATE_SAMPLER))
update_textures_and_samplers(device);
if (device->prefer_user_constbuf) {
- if ((group & (NINE_STATE_VS_CONST | NINE_STATE_VS)) && state->vs)
+ if ((group & (NINE_STATE_VS_CONST | NINE_STATE_VS)) && state->programmable_vs)
prepare_vs_constants_userbuf(device);
if ((group & (NINE_STATE_PS_CONST | NINE_STATE_PS)) && state->ps)
prepare_ps_constants_userbuf(device);
} else {
- if ((group & NINE_STATE_VS_CONST) && state->vs)
+ if ((group & NINE_STATE_VS_CONST) && state->programmable_vs)
upload_constants(device, PIPE_SHADER_VERTEX);
if ((group & NINE_STATE_PS_CONST) && state->ps)
upload_constants(device, PIPE_SHADER_FRAGMENT);
int vs_const_i[NINE_MAX_CONST_I][4];
BOOL vs_const_b[NINE_MAX_CONST_B];
float *vs_lconstf_temp;
+ BOOL programmable_vs;
struct NinePixelShader9 *ps;
float *ps_const_f;
#include "device9.h"
#include "basetexture9.h"
#include "nine_helpers.h"
+#include "vertexdeclaration9.h"
#define DBG_CHANNEL DBG_STATEBLOCK
nine_state_copy_common(dst, src, src, TRUE, pool);
if ((src->changed.group & NINE_STATE_VDECL) && src->vdecl)
- nine_bind(&dst->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);
/* Textures */
if (src->changed.texture) {
This->decls[i].UsageIndex);
This->usage_map[i] = usage;
+ if (This->decls[i].Usage == D3DDECLUSAGE_POSITIONT)
+ This->position_t = TRUE;
+
This->elems[i].src_offset = This->decls[i].Offset;
This->elems[i].instance_divisor = 0;
This->elems[i].vertex_buffer_index = This->decls[i].Stream;
D3DVERTEXELEMENT9 *decls;
DWORD fvf;
+
+ BOOL position_t;
};
static inline struct NineVertexDeclaration9 *
NineVertexDeclaration9( void *data )