From 1a735a99d0ab4d618802e4044f068f926aaf4513 Mon Sep 17 00:00:00 2001 From: Axel Davy Date: Wed, 19 Oct 2016 23:40:27 +0200 Subject: [PATCH] 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 --- src/gallium/state_trackers/nine/device9.c | 60 +++---- src/gallium/state_trackers/nine/nine_ff.c | 114 ++++++------- src/gallium/state_trackers/nine/nine_ff.h | 8 +- src/gallium/state_trackers/nine/nine_state.c | 160 +++++++++++++++++- src/gallium/state_trackers/nine/nine_state.h | 29 +++- .../state_trackers/nine/pixelshader9.h | 3 +- 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; @@ -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; 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; @@ -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, 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; }