user_assert(M, D3DERR_INVALIDCALL);
*M = *pMatrix;
- state->ff.changed.transform[State / 32] |= 1 << (State % 32);
- state->changed.group |= NINE_STATE_FF;
+ if (unlikely(This->is_recording)) {
+ state->ff.changed.transform[State / 32] |= 1 << (State % 32);
+ state->changed.group |= NINE_STATE_FF;
+ } else
+ nine_context_set_transform(This, State, pMatrix);
return D3D_OK;
}
user_assert(pMaterial, E_POINTER);
state->ff.material = *pMaterial;
- state->changed.group |= NINE_STATE_FF_MATERIAL;
+ if (unlikely(This->is_recording))
+ state->changed.group |= NINE_STATE_FF_MATERIAL;
+ else
+ nine_context_set_material(This, pMaterial);
return D3D_OK;
}
DBG("Warning: all D3DLIGHT9.Attenuation[i] are 0\n");
}
- state->changed.group |= NINE_STATE_FF_LIGHTING;
+ if (unlikely(This->is_recording))
+ state->changed.group |= NINE_STATE_FF_LIGHTING;
+ else
+ nine_context_set_light(This, Index, pLight);
return D3D_OK;
}
}
nine_state_light_enable(&state->ff, &state->changed.group, Index, Enable);
+ if (likely(!This->is_recording))
+ nine_context_light_enable(This, Index, Enable);
return D3D_OK;
}
DWORD Value )
{
struct nine_state *state = This->update;
- struct nine_context *context = &This->context;
- int bumpmap_index = -1;
DBG("Stage=%u Type=%u Value=%08x\n", Stage, Type, Value);
nine_dump_D3DTSS_value(DBG_FF, Type, Value);
user_assert(Type < ARRAY_SIZE(state->ff.tex_stage[0]), D3DERR_INVALIDCALL);
state->ff.tex_stage[Stage][Type] = Value;
- switch (Type) {
- case D3DTSS_BUMPENVMAT00:
- bumpmap_index = 4 * Stage;
- break;
- case D3DTSS_BUMPENVMAT01:
- bumpmap_index = 4 * Stage + 1;
- break;
- case D3DTSS_BUMPENVMAT10:
- bumpmap_index = 4 * Stage + 2;
- break;
- case D3DTSS_BUMPENVMAT11:
- bumpmap_index = 4 * Stage + 3;
- break;
- case D3DTSS_BUMPENVLSCALE:
- bumpmap_index = 4 * 8 + 2 * Stage;
- break;
- case D3DTSS_BUMPENVLOFFSET:
- bumpmap_index = 4 * 8 + 2 * Stage + 1;
- break;
- case D3DTSS_TEXTURETRANSFORMFLAGS:
- state->changed.group |= NINE_STATE_PS1X_SHADER;
- break;
- default:
- break;
- }
- if (bumpmap_index >= 0 && !This->is_recording) {
- context->bumpmap_vars[bumpmap_index] = Value;
- state->changed.group |= NINE_STATE_PS_CONST;
- }
-
- state->changed.group |= NINE_STATE_FF_PSSTAGES;
- state->ff.changed.tex_stage[Stage][Type / 32] |= 1 << (Type % 32);
+ if (unlikely(This->is_recording)) {
+ if (Type == D3DTSS_TEXTURETRANSFORMFLAGS)
+ state->changed.group |= NINE_STATE_PS1X_SHADER;
+ state->changed.group |= NINE_STATE_FF_PSSTAGES;
+ state->ff.changed.tex_stage[Stage][Type / 32] |= 1 << (Type % 32);
+ } else
+ nine_context_set_texture_stage_state(This, Stage, Type, Value);
return D3D_OK;
}
static struct NineVertexShader9 *
nine_ff_get_vs(struct NineDevice9 *device)
{
- const struct nine_state *state = &device->state;
const struct nine_context *context = &device->context;
struct NineVertexShader9 *vs;
enum pipe_error err;
key.passthrough = 0;
key.pointscale = !!context->rs[D3DRS_POINTSCALEENABLE];
- key.lighting = !!context->rs[D3DRS_LIGHTING] && state->ff.num_lights_active;
- key.darkness = !!context->rs[D3DRS_LIGHTING] && !state->ff.num_lights_active;
+ key.lighting = !!context->rs[D3DRS_LIGHTING] && context->ff.num_lights_active;
+ key.darkness = !!context->rs[D3DRS_LIGHTING] && !context->ff.num_lights_active;
if (key.position_t) {
key.darkness = 0; /* |= key.lighting; */ /* XXX ? */
key.lighting = 0;
}
for (s = 0; s < 8; ++s) {
- unsigned gen = (state->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] >> 16) + 1;
- unsigned idx = state->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] & 7;
+ unsigned gen = (context->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] >> 16) + 1;
+ unsigned idx = context->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] & 7;
unsigned dim;
if (key.position_t && gen > NINED3DTSS_TCI_PASSTHRU)
key.tc_idx |= idx << (s * 3);
key.tc_dim_input |= ((input_texture_coord[idx]-1) & 0x3) << (s * 2);
- dim = state->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & 0x7;
+ dim = context->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & 0x7;
if (dim > 4)
dim = input_texture_coord[idx];
if (dim == 1) /* NV behaviour */
return vs;
}
-#define GET_D3DTS(n) nine_state_access_transform(&state->ff, D3DTS_##n, FALSE)
+#define GET_D3DTS(n) nine_state_access_transform(&context->ff, D3DTS_##n, FALSE)
#define IS_D3DTS_DIRTY(s,n) ((s)->ff.changed.transform[(D3DTS_##n) / 32] & (1 << ((D3DTS_##n) % 32)))
static struct NinePixelShader9 *
nine_ff_get_ps(struct NineDevice9 *device)
{
- struct nine_state *state = &device->state;
struct nine_context *context = &device->context;
D3DMATRIX *projection_matrix = GET_D3DTS(PROJECTION);
struct NinePixelShader9 *ps;
memset(&key, 0, sizeof(key));
for (s = 0; s < 8; ++s) {
- key.ts[s].colorop = state->ff.tex_stage[s][D3DTSS_COLOROP];
- key.ts[s].alphaop = state->ff.tex_stage[s][D3DTSS_ALPHAOP];
+ key.ts[s].colorop = context->ff.tex_stage[s][D3DTSS_COLOROP];
+ key.ts[s].alphaop = context->ff.tex_stage[s][D3DTSS_ALPHAOP];
const uint8_t used_c = ps_d3dtop_args_mask(key.ts[s].colorop);
const uint8_t used_a = ps_d3dtop_args_mask(key.ts[s].alphaop);
/* MSDN says D3DTOP_DISABLE disables this and all subsequent stages.
}
if (!context->texture[s] &&
- ((state->ff.tex_stage[s][D3DTSS_COLORARG0] == D3DTA_TEXTURE &&
+ ((context->ff.tex_stage[s][D3DTSS_COLORARG0] == D3DTA_TEXTURE &&
used_c & 0x1) ||
- (state->ff.tex_stage[s][D3DTSS_COLORARG1] == D3DTA_TEXTURE &&
+ (context->ff.tex_stage[s][D3DTSS_COLORARG1] == D3DTA_TEXTURE &&
used_c & 0x2) ||
- (state->ff.tex_stage[s][D3DTSS_COLORARG2] == D3DTA_TEXTURE &&
+ (context->ff.tex_stage[s][D3DTSS_COLORARG2] == D3DTA_TEXTURE &&
used_c & 0x4))) {
/* Tested on Windows: Invalid texture read disables the stage
* and the subsequent ones, but only for colorop. For alpha,
break;
}
- if (state->ff.tex_stage[s][D3DTSS_COLORARG0] == D3DTA_TEXTURE ||
- state->ff.tex_stage[s][D3DTSS_COLORARG1] == D3DTA_TEXTURE ||
- state->ff.tex_stage[s][D3DTSS_COLORARG2] == D3DTA_TEXTURE ||
- state->ff.tex_stage[s][D3DTSS_ALPHAARG0] == D3DTA_TEXTURE ||
- state->ff.tex_stage[s][D3DTSS_ALPHAARG1] == D3DTA_TEXTURE ||
- state->ff.tex_stage[s][D3DTSS_ALPHAARG2] == D3DTA_TEXTURE)
+ if (context->ff.tex_stage[s][D3DTSS_COLORARG0] == D3DTA_TEXTURE ||
+ context->ff.tex_stage[s][D3DTSS_COLORARG1] == D3DTA_TEXTURE ||
+ context->ff.tex_stage[s][D3DTSS_COLORARG2] == D3DTA_TEXTURE ||
+ context->ff.tex_stage[s][D3DTSS_ALPHAARG0] == D3DTA_TEXTURE ||
+ context->ff.tex_stage[s][D3DTSS_ALPHAARG1] == D3DTA_TEXTURE ||
+ context->ff.tex_stage[s][D3DTSS_ALPHAARG2] == D3DTA_TEXTURE)
sampler_mask |= (1 << s);
if (key.ts[s].colorop != D3DTOP_DISABLE) {
- if (used_c & 0x1) key.ts[s].colorarg0 = state->ff.tex_stage[s][D3DTSS_COLORARG0];
- if (used_c & 0x2) key.ts[s].colorarg1 = state->ff.tex_stage[s][D3DTSS_COLORARG1];
- if (used_c & 0x4) key.ts[s].colorarg2 = state->ff.tex_stage[s][D3DTSS_COLORARG2];
- if (used_c & 0x1) key.colorarg_b4[0] |= (state->ff.tex_stage[s][D3DTSS_COLORARG0] >> 4) << s;
- if (used_c & 0x1) key.colorarg_b5[0] |= (state->ff.tex_stage[s][D3DTSS_COLORARG0] >> 5) << s;
- if (used_c & 0x2) key.colorarg_b4[1] |= (state->ff.tex_stage[s][D3DTSS_COLORARG1] >> 4) << s;
- if (used_c & 0x2) key.colorarg_b5[1] |= (state->ff.tex_stage[s][D3DTSS_COLORARG1] >> 5) << s;
- if (used_c & 0x4) key.colorarg_b4[2] |= (state->ff.tex_stage[s][D3DTSS_COLORARG2] >> 4) << s;
- if (used_c & 0x4) key.colorarg_b5[2] |= (state->ff.tex_stage[s][D3DTSS_COLORARG2] >> 5) << s;
+ if (used_c & 0x1) key.ts[s].colorarg0 = context->ff.tex_stage[s][D3DTSS_COLORARG0];
+ if (used_c & 0x2) key.ts[s].colorarg1 = context->ff.tex_stage[s][D3DTSS_COLORARG1];
+ if (used_c & 0x4) key.ts[s].colorarg2 = context->ff.tex_stage[s][D3DTSS_COLORARG2];
+ if (used_c & 0x1) key.colorarg_b4[0] |= (context->ff.tex_stage[s][D3DTSS_COLORARG0] >> 4) << s;
+ if (used_c & 0x1) key.colorarg_b5[0] |= (context->ff.tex_stage[s][D3DTSS_COLORARG0] >> 5) << s;
+ if (used_c & 0x2) key.colorarg_b4[1] |= (context->ff.tex_stage[s][D3DTSS_COLORARG1] >> 4) << s;
+ if (used_c & 0x2) key.colorarg_b5[1] |= (context->ff.tex_stage[s][D3DTSS_COLORARG1] >> 5) << s;
+ if (used_c & 0x4) key.colorarg_b4[2] |= (context->ff.tex_stage[s][D3DTSS_COLORARG2] >> 4) << s;
+ if (used_c & 0x4) key.colorarg_b5[2] |= (context->ff.tex_stage[s][D3DTSS_COLORARG2] >> 5) << s;
}
if (key.ts[s].alphaop != D3DTOP_DISABLE) {
- if (used_a & 0x1) key.ts[s].alphaarg0 = state->ff.tex_stage[s][D3DTSS_ALPHAARG0];
- if (used_a & 0x2) key.ts[s].alphaarg1 = state->ff.tex_stage[s][D3DTSS_ALPHAARG1];
- if (used_a & 0x4) key.ts[s].alphaarg2 = state->ff.tex_stage[s][D3DTSS_ALPHAARG2];
- if (used_a & 0x1) key.alphaarg_b4[0] |= (state->ff.tex_stage[s][D3DTSS_ALPHAARG0] >> 4) << s;
- if (used_a & 0x2) key.alphaarg_b4[1] |= (state->ff.tex_stage[s][D3DTSS_ALPHAARG1] >> 4) << s;
- if (used_a & 0x4) key.alphaarg_b4[2] |= (state->ff.tex_stage[s][D3DTSS_ALPHAARG2] >> 4) << s;
+ if (used_a & 0x1) key.ts[s].alphaarg0 = context->ff.tex_stage[s][D3DTSS_ALPHAARG0];
+ if (used_a & 0x2) key.ts[s].alphaarg1 = context->ff.tex_stage[s][D3DTSS_ALPHAARG1];
+ if (used_a & 0x4) key.ts[s].alphaarg2 = context->ff.tex_stage[s][D3DTSS_ALPHAARG2];
+ if (used_a & 0x1) key.alphaarg_b4[0] |= (context->ff.tex_stage[s][D3DTSS_ALPHAARG0] >> 4) << s;
+ if (used_a & 0x2) key.alphaarg_b4[1] |= (context->ff.tex_stage[s][D3DTSS_ALPHAARG1] >> 4) << s;
+ if (used_a & 0x4) key.alphaarg_b4[2] |= (context->ff.tex_stage[s][D3DTSS_ALPHAARG2] >> 4) << s;
}
- key.ts[s].resultarg = state->ff.tex_stage[s][D3DTSS_RESULTARG] == D3DTA_TEMP;
+ key.ts[s].resultarg = context->ff.tex_stage[s][D3DTSS_RESULTARG] == D3DTA_TEMP;
if (context->texture[s]) {
switch (context->texture[s]->base.type) {
if (s >= 1)
key.ts[s-1].resultarg = 0;
- key.projected = nine_ff_get_projected_key(state, context);
+ key.projected = nine_ff_get_projected_key(context);
key.specular = !!context->rs[D3DRS_SPECULARENABLE];
for (; s < 8; ++s)
static void
nine_ff_load_vs_transforms(struct NineDevice9 *device)
{
- struct nine_state *state = &device->state;
struct nine_context *context = &device->context;
D3DMATRIX T;
D3DMATRIX *M = (D3DMATRIX *)device->ff.vs_const;
/* TODO: make this nicer, and only upload the ones we need */
/* TODO: use ff.vs_const as storage of W, V, P matrices */
- if (IS_D3DTS_DIRTY(state, WORLD) ||
- IS_D3DTS_DIRTY(state, VIEW) ||
- IS_D3DTS_DIRTY(state, PROJECTION)) {
+ if (IS_D3DTS_DIRTY(context, WORLD) ||
+ IS_D3DTS_DIRTY(context, VIEW) ||
+ IS_D3DTS_DIRTY(context, PROJECTION)) {
/* WVP, WV matrices */
nine_d3d_matrix_matrix_mul(&M[1], GET_D3DTS(WORLD), GET_D3DTS(VIEW));
nine_d3d_matrix_matrix_mul(&M[0], &M[1], GET_D3DTS(PROJECTION));
unsigned l;
if (state->changed.group & NINE_STATE_FF_MATERIAL) {
- const D3DMATERIAL9 *mtl = &state->ff.material;
+ const D3DMATERIAL9 *mtl = &context->ff.material;
memcpy(&dst[20], &mtl->Diffuse, 4 * sizeof(float));
memcpy(&dst[21], &mtl->Ambient, 4 * sizeof(float));
if (!(state->changed.group & NINE_STATE_FF_LIGHTING))
return;
- for (l = 0; l < state->ff.num_lights_active; ++l) {
- const D3DLIGHT9 *light = &state->ff.light[state->ff.active_light[l]];
+ for (l = 0; l < context->ff.num_lights_active; ++l) {
+ const D3DLIGHT9 *light = &context->ff.light[context->ff.active_light[l]];
dst[32 + l * 8].x = light->Type;
dst[32 + l * 8].y = light->Attenuation0;
dst[38 + l * 8].x = cosf(light->Theta * 0.5f);
dst[38 + l * 8].y = cosf(light->Phi * 0.5f);
dst[38 + l * 8].z = 1.0f / (dst[38 + l * 8].x - dst[38 + l * 8].y);
- dst[39 + l * 8].w = (l + 1) == state->ff.num_lights_active;
+ dst[39 + l * 8].w = (l + 1) == context->ff.num_lights_active;
}
}
static void
nine_ff_load_tex_matrices(struct NineDevice9 *device)
{
- struct nine_state *state = &device->state;
+ struct nine_context *context = &device->context;
D3DMATRIX *M = (D3DMATRIX *)device->ff.vs_const;
unsigned s;
- if (!(state->ff.changed.transform[0] & 0xff0000))
+ if (!(context->ff.changed.transform[0] & 0xff0000))
return;
for (s = 0; s < 8; ++s) {
- if (IS_D3DTS_DIRTY(state, TEXTURE0 + s))
- nine_d3d_matrix_transpose(&M[32 + s], nine_state_access_transform(&state->ff, D3DTS_TEXTURE0 + s, FALSE));
+ if (IS_D3DTS_DIRTY(context, TEXTURE0 + s))
+ nine_d3d_matrix_transpose(&M[32 + s], nine_state_access_transform(&context->ff, D3DTS_TEXTURE0 + s, FALSE));
}
}
return;
for (s = 0; s < 8; ++s)
- d3dcolor_to_rgba(&dst[s].x, state->ff.tex_stage[s][D3DTSS_CONSTANT]);
+ d3dcolor_to_rgba(&dst[s].x, context->ff.tex_stage[s][D3DTSS_CONSTANT]);
for (s = 0; s < 8; ++s) {
- dst[8 + s].x = asfloat(state->ff.tex_stage[s][D3DTSS_BUMPENVMAT00]);
- dst[8 + s].y = asfloat(state->ff.tex_stage[s][D3DTSS_BUMPENVMAT01]);
- dst[8 + s].z = asfloat(state->ff.tex_stage[s][D3DTSS_BUMPENVMAT10]);
- dst[8 + s].w = asfloat(state->ff.tex_stage[s][D3DTSS_BUMPENVMAT11]);
+ dst[8 + s].x = asfloat(context->ff.tex_stage[s][D3DTSS_BUMPENVMAT00]);
+ dst[8 + s].y = asfloat(context->ff.tex_stage[s][D3DTSS_BUMPENVMAT01]);
+ dst[8 + s].z = asfloat(context->ff.tex_stage[s][D3DTSS_BUMPENVMAT10]);
+ dst[8 + s].w = asfloat(context->ff.tex_stage[s][D3DTSS_BUMPENVMAT11]);
if (s & 1) {
- dst[16 + s / 2].z = asfloat(state->ff.tex_stage[s][D3DTSS_BUMPENVLSCALE]);
- dst[16 + s / 2].w = asfloat(state->ff.tex_stage[s][D3DTSS_BUMPENVLOFFSET]);
+ dst[16 + s / 2].z = asfloat(context->ff.tex_stage[s][D3DTSS_BUMPENVLSCALE]);
+ dst[16 + s / 2].w = asfloat(context->ff.tex_stage[s][D3DTSS_BUMPENVLOFFSET]);
} else {
- dst[16 + s / 2].x = asfloat(state->ff.tex_stage[s][D3DTSS_BUMPENVLSCALE]);
- dst[16 + s / 2].y = asfloat(state->ff.tex_stage[s][D3DTSS_BUMPENVLOFFSET]);
+ dst[16 + s / 2].x = asfloat(context->ff.tex_stage[s][D3DTSS_BUMPENVLSCALE]);
+ dst[16 + s / 2].y = asfloat(context->ff.tex_stage[s][D3DTSS_BUMPENVLOFFSET]);
}
}
void
nine_ff_update(struct NineDevice9 *device)
{
- struct nine_state *state = &device->state;
struct nine_context *context = &device->context;
struct pipe_constant_buffer cb;
nine_ff_load_point_and_fog_params(device);
nine_ff_load_viewport_info(device);
- memset(state->ff.changed.transform, 0, sizeof(state->ff.changed.transform));
+ memset(context->ff.changed.transform, 0, sizeof(context->ff.changed.transform));
cb.buffer_offset = 0;
cb.buffer = NULL;
}
static inline uint16_t
-nine_ff_get_projected_key(struct nine_state *state, struct nine_context *context)
+nine_ff_get_projected_key(struct nine_context *context)
{
unsigned s, i;
uint16_t projected = 0;
}
for (s = 0; s < 8; ++s) {
- unsigned gen = (state->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] >> 16) + 1;
- unsigned dim = state->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & 0x7;
- unsigned proj = !!(state->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED);
+ unsigned gen = (context->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] >> 16) + 1;
+ unsigned dim = context->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & 0x7;
+ unsigned proj = !!(context->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED);
if (!context->vs) {
if (dim > 4)
int has_key_changed = 0;
if (likely(ps))
- has_key_changed = NinePixelShader9_UpdateKey(ps, state, context);
+ has_key_changed = NinePixelShader9_UpdateKey(ps, context);
if (!shader_changed && !has_key_changed)
return 0;
state->changed.group |= NINE_STATE_SCISSOR;
}
+void
+nine_context_set_transform(struct NineDevice9 *device,
+ D3DTRANSFORMSTATETYPE State,
+ const D3DMATRIX *pMatrix)
+{
+ struct nine_state *state = &device->state;
+ struct nine_context *context = &device->context;
+ D3DMATRIX *M = nine_state_access_transform(&context->ff, State, TRUE);
+
+ *M = *pMatrix;
+ context->ff.changed.transform[State / 32] |= 1 << (State % 32);
+ state->changed.group |= NINE_STATE_FF;
+}
+
+void
+nine_context_set_material(struct NineDevice9 *device,
+ const D3DMATERIAL9 *pMaterial)
+{
+ struct nine_state *state = &device->state;
+ struct nine_context *context = &device->context;
+
+ context->ff.material = *pMaterial;
+ state->changed.group |= NINE_STATE_FF_MATERIAL;
+}
+
+void
+nine_context_set_light(struct NineDevice9 *device,
+ DWORD Index,
+ const D3DLIGHT9 *pLight)
+{
+ struct nine_state *state = &device->state;
+ struct nine_context *context = &device->context;
+
+ (void)nine_state_set_light(&context->ff, Index, pLight);
+ state->changed.group |= NINE_STATE_FF_LIGHTING;
+}
+
+void
+nine_context_light_enable(struct NineDevice9 *device,
+ DWORD Index,
+ BOOL Enable)
+{
+ struct nine_state *state = &device->state;
+ struct nine_context *context = &device->context;
+
+ nine_state_light_enable(&context->ff, &state->changed.group, Index, Enable);
+}
+
+void
+nine_context_set_texture_stage_state(struct NineDevice9 *device,
+ DWORD Stage,
+ D3DTEXTURESTAGESTATETYPE Type,
+ DWORD Value)
+{
+ struct nine_state *state = &device->state;
+ struct nine_context *context = &device->context;
+ int bumpmap_index = -1;
+
+ context->ff.tex_stage[Stage][Type] = Value;
+ switch (Type) {
+ case D3DTSS_BUMPENVMAT00:
+ bumpmap_index = 4 * Stage;
+ break;
+ case D3DTSS_BUMPENVMAT01:
+ bumpmap_index = 4 * Stage + 1;
+ break;
+ case D3DTSS_BUMPENVMAT10:
+ bumpmap_index = 4 * Stage + 2;
+ break;
+ case D3DTSS_BUMPENVMAT11:
+ bumpmap_index = 4 * Stage + 3;
+ break;
+ case D3DTSS_BUMPENVLSCALE:
+ bumpmap_index = 4 * 8 + 2 * Stage;
+ break;
+ case D3DTSS_BUMPENVLOFFSET:
+ bumpmap_index = 4 * 8 + 2 * Stage + 1;
+ break;
+ case D3DTSS_TEXTURETRANSFORMFLAGS:
+ state->changed.group |= NINE_STATE_PS1X_SHADER;
+ break;
+ default:
+ break;
+ }
+
+ if (bumpmap_index >= 0) {
+ context->bumpmap_vars[bumpmap_index] = Value;
+ state->changed.group |= NINE_STATE_PS_CONST;
+ }
+
+ state->changed.group |= NINE_STATE_FF_PSSTAGES;
+ context->ff.changed.tex_stage[Stage][Type / 32] |= 1 << (Type % 32);
+}
+
void
nine_context_apply_stateblock(struct NineDevice9 *device,
const struct nine_state *src)
/* Scissor */
if (src->changed.group & NINE_STATE_SCISSOR)
context->scissor = src->scissor;
+
+ if (!(src->changed.group & NINE_STATE_FF))
+ return;
+
+ /* Fixed function state. */
+
+ if (src->changed.group & NINE_STATE_FF_MATERIAL)
+ context->ff.material = src->ff.material;
+
+ if (src->changed.group & NINE_STATE_FF_PSSTAGES) {
+ unsigned s;
+ for (s = 0; s < NINE_MAX_TEXTURE_STAGES; ++s) {
+ for (i = 0; i < NINED3DTSS_COUNT; ++i)
+ if (src->ff.changed.tex_stage[s][i / 32] & (1 << (i % 32)))
+ context->ff.tex_stage[s][i] = src->ff.tex_stage[s][i];
+ }
+ }
+ if (src->changed.group & NINE_STATE_FF_LIGHTING) {
+ unsigned num_lights = MAX2(context->ff.num_lights, src->ff.num_lights);
+ /* Can happen if the stateblock had recorded the creation of
+ * new lights. */
+ if (context->ff.num_lights < num_lights) {
+ context->ff.light = REALLOC(context->ff.light,
+ context->ff.num_lights * sizeof(D3DLIGHT9),
+ num_lights * sizeof(D3DLIGHT9));
+ memset(&context->ff.light[context->ff.num_lights], 0, (num_lights - context->ff.num_lights) * sizeof(D3DLIGHT9));
+ for (i = context->ff.num_lights; i < num_lights; ++i)
+ context->ff.light[i].Type = (D3DLIGHTTYPE)NINED3DLIGHT_INVALID;
+ context->ff.num_lights = num_lights;
+ }
+ /* src->ff.num_lights < num_lights has been handled before */
+ assert (src->ff.num_lights == num_lights);
+
+ for (i = 0; i < num_lights; ++i)
+ if (src->ff.light[i].Type != NINED3DLIGHT_INVALID)
+ context->ff.light[i] = src->ff.light[i];
+
+ memcpy(context->ff.active_light, src->ff.active_light, sizeof(src->ff.active_light) );
+ context->ff.num_lights_active = src->ff.num_lights_active;
+ }
+ if (src->changed.group & NINE_STATE_FF_VSTRANSF) {
+ for (i = 0; i < ARRAY_SIZE(src->ff.changed.transform); ++i) {
+ unsigned s;
+ if (!src->ff.changed.transform[i])
+ continue;
+ for (s = i * 32; s < (i * 32 + 32); ++s) {
+ if (!(src->ff.changed.transform[i] & (1 << (s % 32))))
+ continue;
+ *nine_state_access_transform(&context->ff, s, TRUE) =
+ *nine_state_access_transform( /* const because !alloc */
+ (struct nine_ff_state *)&src->ff, s, FALSE);
+ }
+ context->ff.changed.transform[i] |= src->ff.changed.transform[i];
+ }
+ }
}
static void
}
state->ff.tex_stage[0][D3DTSS_COLOROP] = D3DTOP_MODULATE;
state->ff.tex_stage[0][D3DTSS_ALPHAOP] = D3DTOP_SELECTARG1;
+
+ for (s = 0; s < ARRAY_SIZE(state->ff.tex_stage); ++s)
+ memcpy(&context->ff.tex_stage[s], state->ff.tex_stage[s],
+ sizeof(state->ff.tex_stage[s]));
+
memset(&context->bumpmap_vars, 0, sizeof(context->bumpmap_vars));
for (s = 0; s < NINE_MAX_SAMPLERS; ++s) {
context->changed.vtxbuf = (1ULL << device->caps.MaxStreams) - 1;
state->changed.ucp = (1 << PIPE_MAX_CLIP_PLANES) - 1;
- state->ff.changed.transform[0] = ~0;
- state->ff.changed.transform[D3DTS_WORLD / 32] |= 1 << (D3DTS_WORLD % 32);
+ context->ff.changed.transform[0] = ~0;
+ context->ff.changed.transform[D3DTS_WORLD / 32] |= 1 << (D3DTS_WORLD % 32);
if (!is_reset) {
state->viewport.MinZ = context->viewport.MinZ = 0.0f;
struct nine_ff_state {
struct {
- uint32_t tex_stage[NINE_MAX_TEXTURE_STAGES][(NINED3DTSS_COUNT + 31) / 32];
+ uint32_t tex_stage[NINE_MAX_TEXTURE_STAGES][(NINED3DTSS_COUNT + 31) / 32]; /* stateblocks only */
uint32_t transform[(NINED3DTS_COUNT + 31) / 32];
} changed;
int dummy_vbo_bound_at; /* -1 = not bound , >= 0 = bound index */
boolean vbo_bound_done;
+ struct nine_ff_state ff;
+
uint32_t commit;
struct {
struct pipe_framebuffer_state fb;
nine_context_set_scissor(struct NineDevice9 *device,
const struct pipe_scissor_state *scissor);
+void
+nine_context_set_transform(struct NineDevice9 *device,
+ D3DTRANSFORMSTATETYPE State,
+ const D3DMATRIX *pMatrix);
+
+void
+nine_context_set_material(struct NineDevice9 *device,
+ const D3DMATERIAL9 *pMaterial);
+
+void
+nine_context_set_light(struct NineDevice9 *device,
+ DWORD Index,
+ const D3DLIGHT9 *pLight);
+
+void
+nine_context_light_enable(struct NineDevice9 *device,
+ DWORD Index,
+ BOOL Enable);
+
+void
+nine_context_set_texture_stage_state(struct NineDevice9 *device,
+ DWORD Stage,
+ D3DTEXTURESTAGESTATETYPE Type,
+ DWORD Value);
+
void
nine_context_set_render_target(struct NineDevice9 *device,
DWORD RenderTargetIndex,
static inline BOOL
NinePixelShader9_UpdateKey( struct NinePixelShader9 *ps,
- struct nine_state *state,
struct nine_context *context )
{
uint16_t samplers_shadow;
key |= ((uint64_t)1) << 34;
if (unlikely(ps->byte_code.version < 0x14)) {
- projected = nine_ff_get_projected_key(state, context);
+ projected = nine_ff_get_projected_key(context);
key |= ((uint64_t) projected) << 48;
}