st/nine: Back all ff states in nine_context

Part of the refactor to move all gallium calls to
nine_state.c, and have all internal states required
for those calls in nine_context.

Signed-off-by: Axel Davy <axel.davy@ens.fr>
This commit is contained in:
Axel Davy 2016-10-19 23:40:27 +02:00
parent bb62ea925a
commit 1a735a99d0
6 changed files with 267 additions and 107 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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)

View File

@ -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;
@ -1489,6 +1489,100 @@ nine_context_set_scissor(struct NineDevice9 *device,
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)
@ -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;

View File

@ -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;
@ -396,6 +398,31 @@ void
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,

View File

@ -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;
}