summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/state_trackers/nine/device9.c60
-rw-r--r--src/gallium/state_trackers/nine/nine_ff.c114
-rw-r--r--src/gallium/state_trackers/nine/nine_ff.h8
-rw-r--r--src/gallium/state_trackers/nine/nine_state.c160
-rw-r--r--src/gallium/state_trackers/nine/nine_state.h29
-rw-r--r--src/gallium/state_trackers/nine/pixelshader9.h3
6 files changed, 267 insertions, 107 deletions
diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c
index 3fd1cdffab9..bfbbd02a8dc 100644
--- a/src/gallium/state_trackers/nine/device9.c
+++ b/src/gallium/state_trackers/nine/device9.c
@@ -1982,8 +1982,11 @@ NineDevice9_SetTransform( struct NineDevice9 *This,
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;
}
@@ -2053,7 +2056,10 @@ NineDevice9_SetMaterial( struct NineDevice9 *This,
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;
}
@@ -2095,7 +2101,10 @@ NineDevice9_SetLight( struct NineDevice9 *This,
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;
}
@@ -2140,6 +2149,8 @@ NineDevice9_LightEnable( struct NineDevice9 *This,
}
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;
}
@@ -2492,8 +2503,6 @@ NineDevice9_SetTextureStageState( struct NineDevice9 *This,
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);
@@ -2502,39 +2511,14 @@ NineDevice9_SetTextureStageState( struct NineDevice9 *This,
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;
}
diff --git a/src/gallium/state_trackers/nine/nine_ff.c b/src/gallium/state_trackers/nine/nine_ff.c
index 0c92bd13e8b..65f09ead006 100644
--- a/src/gallium/state_trackers/nine/nine_ff.c
+++ b/src/gallium/state_trackers/nine/nine_ff.c
@@ -1558,7 +1558,6 @@ nine_ff_build_ps(struct NineDevice9 *device, struct nine_ff_ps_key *key)
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;
@@ -1619,8 +1618,8 @@ nine_ff_get_vs(struct NineDevice9 *device)
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;
@@ -1659,8 +1658,8 @@ nine_ff_get_vs(struct NineDevice9 *device)
}
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)
@@ -1673,7 +1672,7 @@ nine_ff_get_vs(struct NineDevice9 *device)
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 */
@@ -1708,13 +1707,12 @@ nine_ff_get_vs(struct NineDevice9 *device)
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;
@@ -1727,8 +1725,8 @@ nine_ff_get_ps(struct NineDevice9 *device)
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.
@@ -1740,11 +1738,11 @@ nine_ff_get_ps(struct NineDevice9 *device)
}
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,
@@ -1755,34 +1753,34 @@ nine_ff_get_ps(struct NineDevice9 *device)
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) {
@@ -1818,7 +1816,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, context);
+ key.projected = nine_ff_get_projected_key(context);
key.specular = !!context->rs[D3DRS_SPECULARENABLE];
for (; s < 8; ++s)
@@ -1860,7 +1858,6 @@ nine_ff_get_ps(struct NineDevice9 *device)
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;
@@ -1869,9 +1866,9 @@ nine_ff_load_vs_transforms(struct NineDevice9 *device)
/* 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));
@@ -1907,7 +1904,7 @@ nine_ff_load_lights(struct NineDevice9 *device)
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));
@@ -1923,8 +1920,8 @@ nine_ff_load_lights(struct NineDevice9 *device)
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;
@@ -1940,7 +1937,7 @@ nine_ff_load_lights(struct NineDevice9 *device)
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;
}
}
@@ -1969,15 +1966,15 @@ nine_ff_load_point_and_fog_params(struct NineDevice9 *device)
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));
}
}
@@ -1993,19 +1990,19 @@ nine_ff_load_ps_params(struct NineDevice9 *device)
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]);
}
}
@@ -2038,7 +2035,6 @@ nine_ff_load_viewport_info(struct NineDevice9 *device)
void
nine_ff_update(struct NineDevice9 *device)
{
- struct nine_state *state = &device->state;
struct nine_context *context = &device->context;
struct pipe_constant_buffer cb;
@@ -2061,7 +2057,7 @@ nine_ff_update(struct NineDevice9 *device)
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;
diff --git a/src/gallium/state_trackers/nine/nine_ff.h b/src/gallium/state_trackers/nine/nine_ff.h
index ec79959211f..4d51c3d6ecb 100644
--- a/src/gallium/state_trackers/nine/nine_ff.h
+++ b/src/gallium/state_trackers/nine/nine_ff.h
@@ -62,7 +62,7 @@ nine_decltype_get_dim(BYTE type)
}
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;
@@ -81,9 +81,9 @@ nine_ff_get_projected_key(struct nine_state *state, struct nine_context *context
}
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)
diff --git a/src/gallium/state_trackers/nine/nine_state.c b/src/gallium/state_trackers/nine/nine_state.c
index 7737027ffd5..603fb894866 100644
--- a/src/gallium/state_trackers/nine/nine_state.c
+++ b/src/gallium/state_trackers/nine/nine_state.c
@@ -390,7 +390,7 @@ prepare_ps(struct NineDevice9 *device, uint8_t shader_changed)
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;
@@ -1490,6 +1490,100 @@ nine_context_set_scissor(struct NineDevice9 *device,
}
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)
{
@@ -1646,6 +1740,61 @@ nine_context_apply_stateblock(struct NineDevice9 *device,
/* 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
@@ -2101,6 +2250,11 @@ nine_state_set_defaults(struct NineDevice9 *device, const D3DCAPS9 *caps,
}
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) {
@@ -2137,8 +2291,8 @@ nine_state_set_defaults(struct NineDevice9 *device, const D3DCAPS9 *caps,
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;
diff --git a/src/gallium/state_trackers/nine/nine_state.h b/src/gallium/state_trackers/nine/nine_state.h
index 4d1e8a48337..754a3de7eb0 100644
--- a/src/gallium/state_trackers/nine/nine_state.h
+++ b/src/gallium/state_trackers/nine/nine_state.h
@@ -139,7 +139,7 @@
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;
@@ -280,6 +280,8 @@ struct nine_context {
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;
@@ -397,6 +399,31 @@ 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,
struct NineSurface9 *rt);
diff --git a/src/gallium/state_trackers/nine/pixelshader9.h b/src/gallium/state_trackers/nine/pixelshader9.h
index 38874dcfba7..67a18f20c42 100644
--- a/src/gallium/state_trackers/nine/pixelshader9.h
+++ b/src/gallium/state_trackers/nine/pixelshader9.h
@@ -65,7 +65,6 @@ NinePixelShader9( void *data )
static inline BOOL
NinePixelShader9_UpdateKey( struct NinePixelShader9 *ps,
- struct nine_state *state,
struct nine_context *context )
{
uint16_t samplers_shadow;
@@ -99,7 +98,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, context);
+ projected = nine_ff_get_projected_key(context);
key |= ((uint64_t) projected) << 48;
}