diff options
-rw-r--r-- | src/gallium/state_trackers/nine/device9.c | 33 | ||||
-rw-r--r-- | src/gallium/state_trackers/nine/nine_limits.h | 211 | ||||
-rw-r--r-- | src/gallium/state_trackers/nine/nine_state.c | 2 | ||||
-rw-r--r-- | src/gallium/state_trackers/nine/nine_state.h | 1 | ||||
-rw-r--r-- | src/gallium/state_trackers/nine/stateblock9.c | 2 |
5 files changed, 236 insertions, 13 deletions
diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c index 5fbb4357c2f..1c0e2114612 100644 --- a/src/gallium/state_trackers/nine/device9.c +++ b/src/gallium/state_trackers/nine/device9.c @@ -38,6 +38,7 @@ #include "nine_pipe.h" #include "nine_ff.h" #include "nine_dump.h" +#include "nine_limits.h" #include "pipe/p_screen.h" #include "pipe/p_context.h" @@ -112,8 +113,10 @@ NineDevice9_SetDefaultState( struct NineDevice9 *This, boolean is_reset ) This->state.scissor.maxy = refSurf->desc.Height; } - if (This->nswapchains && This->swapchains[0]->params.EnableAutoDepthStencil) + if (This->nswapchains && This->swapchains[0]->params.EnableAutoDepthStencil) { This->state.rs[D3DRS_ZENABLE] = TRUE; + This->state.rs_advertised[D3DRS_ZENABLE] = TRUE; + } if (This->state.rs[D3DRS_ZENABLE]) NineDevice9_SetDepthStencilSurface( This, (IDirect3DSurface9 *)This->swapchains[0]->zsbuf); @@ -2380,8 +2383,15 @@ NineDevice9_SetRenderState( struct NineDevice9 *This, DBG("This=%p State=%u(%s) Value=%08x\n", This, State, nine_d3drs_to_string(State), Value); + user_assert(State < D3DRS_COUNT, D3DERR_INVALIDCALL); + + if (state->rs_advertised[State] == Value && likely(!This->is_recording)) + return D3D_OK; + + state->rs_advertised[State] = Value; + /* Amd hacks (equivalent to GL extensions) */ - if (State == D3DRS_POINTSIZE) { + if (unlikely(State == D3DRS_POINTSIZE)) { if (Value == RESZ_CODE) return NineDevice9_ResolveZ(This); @@ -2394,20 +2404,17 @@ NineDevice9_SetRenderState( struct NineDevice9 *This, } /* NV hack */ - if (State == D3DRS_ADAPTIVETESS_Y && - (Value == D3DFMT_ATOC || (Value == D3DFMT_UNKNOWN && state->rs[NINED3DRS_ALPHACOVERAGE]))) { + if (unlikely(State == D3DRS_ADAPTIVETESS_Y)) { + if (Value == D3DFMT_ATOC || (Value == D3DFMT_UNKNOWN && state->rs[NINED3DRS_ALPHACOVERAGE])) { state->rs[NINED3DRS_ALPHACOVERAGE] = (Value == D3DFMT_ATOC); state->changed.group |= NINE_STATE_BLEND; return D3D_OK; + } } - user_assert(State < Elements(state->rs), D3DERR_INVALIDCALL); - - if (likely(state->rs[State] != Value) || unlikely(This->is_recording)) { - state->rs[State] = Value; - state->changed.rs[State / 32] |= 1 << (State % 32); - state->changed.group |= nine_render_state_group[State]; - } + state->rs[State] = nine_fix_render_state_value(State, Value); + state->changed.rs[State / 32] |= 1 << (State % 32); + state->changed.group |= nine_render_state_group[State]; return D3D_OK; } @@ -2417,9 +2424,9 @@ NineDevice9_GetRenderState( struct NineDevice9 *This, D3DRENDERSTATETYPE State, DWORD *pValue ) { - user_assert(State < Elements(This->state.rs), D3DERR_INVALIDCALL); + user_assert(State < D3DRS_COUNT, D3DERR_INVALIDCALL); - *pValue = This->state.rs[State]; + *pValue = This->state.rs_advertised[State]; return D3D_OK; } diff --git a/src/gallium/state_trackers/nine/nine_limits.h b/src/gallium/state_trackers/nine/nine_limits.h new file mode 100644 index 00000000000..ef1ed2566ba --- /dev/null +++ b/src/gallium/state_trackers/nine/nine_limits.h @@ -0,0 +1,211 @@ +/* + * Copyright 2015 Axel Davy <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef _NINE_LIMITS_H_ +#define _NINE_LIMITS_H_ + +#include "assert.h" +#include "d3d9types.h" + +// state can be any value +#define NINE_STATE_NO_LIMIT 0 +// value is clamped if below min or max +#define NINE_STATE_CLAMP 1 +// boolean: 0 -> false; any other value -> true +#define NINE_STATE_BOOL 2 +// a mask is applied on the value +#define NINE_STATE_MASK 3 +// if outside a range, state value is changed to a default value +#define NINE_STATE_RANGE_DEF_VAL 4 + +struct nine_state_behaviour { + unsigned state_value_behaviour; + union { + struct { + unsigned min; + unsigned max; + } clamp; + unsigned mask; + struct { + unsigned min; + unsigned max; + unsigned default_val; + } range_def_val; + } u; +}; + +#define __NO_LIMIT_RS(o) \ + [D3DRS_##o] = {NINE_STATE_NO_LIMIT} + +#define __CLAMP_RS(o, m, M) \ + [D3DRS_##o] = {NINE_STATE_CLAMP, {.clamp = {m, M}}} + +#define __BOOLEAN_RS(o) \ + [D3DRS_##o] = {NINE_STATE_BOOL} + +#define __MASK_RS(o, m) \ + [D3DRS_##o] = {NINE_STATE_MASK, {.mask = m}} + +#define __RANGE_DEF_VAL_RS(o, m, M, d) \ + [D3DRS_##o] = {NINE_STATE_RANGE_DEF_VAL, {.range_def_val = {m, M, d}}} + +#define __TO_DETERMINE_RS(o, m, M) \ + [D3DRS_##o] = {NINE_STATE_NO_LIMIT} + +static const struct nine_state_behaviour +render_state_limits_table[D3DRS_BLENDOPALPHA + 1] = { + __TO_DETERMINE_RS(ZENABLE, 0, 3), + __TO_DETERMINE_RS(FILLMODE, 1, 3), + __CLAMP_RS(SHADEMODE, 1, 3), + __BOOLEAN_RS(ZWRITEENABLE), + __BOOLEAN_RS(ALPHATESTENABLE), + __BOOLEAN_RS(LASTPIXEL), + __RANGE_DEF_VAL_RS(SRCBLEND, 1, 17, D3DBLEND_ZERO), + __RANGE_DEF_VAL_RS(DESTBLEND, 1, 17, D3DBLEND_ZERO), + __CLAMP_RS(CULLMODE, 1, 3), + __CLAMP_RS(ZFUNC, 1, 8), + __MASK_RS(ALPHAREF, 0x000000FF), + __CLAMP_RS(ALPHAFUNC, 1, 8), + __BOOLEAN_RS(DITHERENABLE), + __BOOLEAN_RS(ALPHABLENDENABLE), + __BOOLEAN_RS(FOGENABLE), + __BOOLEAN_RS(SPECULARENABLE), + __NO_LIMIT_RS(FOGCOLOR), + __MASK_RS(FOGTABLEMODE, 0x00000007), + __NO_LIMIT_RS(FOGSTART), /* a bit more complex than that, lets ignore */ + __NO_LIMIT_RS(FOGEND), + __NO_LIMIT_RS(FOGDENSITY), /* actually should be between 0.0 and 1.0 */ + __BOOLEAN_RS(RANGEFOGENABLE), + __BOOLEAN_RS(STENCILENABLE), + __CLAMP_RS(STENCILFAIL, 1, 8), + __CLAMP_RS(STENCILZFAIL, 1, 8), + __CLAMP_RS(STENCILPASS, 1, 8), + __CLAMP_RS(STENCILFUNC, 1, 8), + __NO_LIMIT_RS(STENCILREF), + __NO_LIMIT_RS(STENCILMASK), + __NO_LIMIT_RS(STENCILWRITEMASK), + __NO_LIMIT_RS(TEXTUREFACTOR), + __TO_DETERMINE_RS(WRAP0, 0, 15), + __TO_DETERMINE_RS(WRAP1, 0, 15), + __TO_DETERMINE_RS(WRAP2, 0, 15), + __TO_DETERMINE_RS(WRAP3, 0, 15), + __TO_DETERMINE_RS(WRAP4, 0, 15), + __TO_DETERMINE_RS(WRAP5, 0, 15), + __TO_DETERMINE_RS(WRAP6, 0, 15), + __TO_DETERMINE_RS(WRAP7, 0, 15), + __BOOLEAN_RS(CLIPPING), + __BOOLEAN_RS(LIGHTING), + __NO_LIMIT_RS(AMBIENT), + __MASK_RS(FOGVERTEXMODE, 0x00000007), + __BOOLEAN_RS(COLORVERTEX), + __BOOLEAN_RS(LOCALVIEWER), + __BOOLEAN_RS(NORMALIZENORMALS), + __TO_DETERMINE_RS(DIFFUSEMATERIALSOURCE, 0, 2), + __TO_DETERMINE_RS(SPECULARMATERIALSOURCE, 0, 2), + __TO_DETERMINE_RS(AMBIENTMATERIALSOURCE, 0, 2), + __TO_DETERMINE_RS(EMISSIVEMATERIALSOURCE, 0, 2), + __TO_DETERMINE_RS(VERTEXBLEND, 0, 256), /* values between 4 and 254 -both included- are forbidden too */ + __NO_LIMIT_RS(CLIPPLANEENABLE), /* expected check seems complex */ + __TO_DETERMINE_RS(POINTSIZE, 0, 0xFFFFFFFF), + __TO_DETERMINE_RS(POINTSIZE_MIN, 0, 0x7FFFFFFF), /* float >= 0.0 */ + __BOOLEAN_RS(POINTSPRITEENABLE), + __BOOLEAN_RS(POINTSCALEENABLE), + __TO_DETERMINE_RS(POINTSCALE_A, 0, 0x7FFFFFFF), /* float >= 0.0 */ + __TO_DETERMINE_RS(POINTSCALE_B, 0, 0x7FFFFFFF), /* float >= 0.0 */ + __TO_DETERMINE_RS(POINTSCALE_C, 0, 0x7FFFFFFF), /* float >= 0.0 */ + __BOOLEAN_RS(MULTISAMPLEANTIALIAS), + __NO_LIMIT_RS(MULTISAMPLEMASK), + __TO_DETERMINE_RS(PATCHEDGESTYLE, 0, 1), + __TO_DETERMINE_RS(DEBUGMONITORTOKEN, 0, 1), + __TO_DETERMINE_RS(POINTSIZE_MAX, 0, 0x7FFFFFFF), /* check more complex than that */ + __BOOLEAN_RS(INDEXEDVERTEXBLENDENABLE), + __TO_DETERMINE_RS(COLORWRITEENABLE, 0, 15), + __NO_LIMIT_RS(TWEENFACTOR), + __CLAMP_RS(BLENDOP, 1, 5), + __TO_DETERMINE_RS(POSITIONDEGREE, 1, 5), /* can actually be only 1 or 5 */ + __TO_DETERMINE_RS(NORMALDEGREE, 1, 2), + __BOOLEAN_RS(SCISSORTESTENABLE), + __NO_LIMIT_RS(SLOPESCALEDEPTHBIAS), + __BOOLEAN_RS(ANTIALIASEDLINEENABLE), + __NO_LIMIT_RS(MINTESSELLATIONLEVEL), + __NO_LIMIT_RS(MAXTESSELLATIONLEVEL), + __NO_LIMIT_RS(ADAPTIVETESS_X), + __NO_LIMIT_RS(ADAPTIVETESS_Y), + __NO_LIMIT_RS(ADAPTIVETESS_Z), + __NO_LIMIT_RS(ADAPTIVETESS_W), + __BOOLEAN_RS(ENABLEADAPTIVETESSELLATION), + __BOOLEAN_RS(TWOSIDEDSTENCILMODE), + __CLAMP_RS(CCW_STENCILFAIL, 1, 8), + __CLAMP_RS(CCW_STENCILZFAIL, 1, 8), + __CLAMP_RS(CCW_STENCILPASS, 1, 8), + __CLAMP_RS(CCW_STENCILFUNC, 1, 8), + __TO_DETERMINE_RS(COLORWRITEENABLE1, 0, 15), + __TO_DETERMINE_RS(COLORWRITEENABLE2, 0, 15), + __TO_DETERMINE_RS(COLORWRITEENABLE3, 0, 15), + __NO_LIMIT_RS(BLENDFACTOR), + __BOOLEAN_RS(SRGBWRITEENABLE), + __NO_LIMIT_RS(DEPTHBIAS), + __TO_DETERMINE_RS(WRAP8, 0, 15), + __TO_DETERMINE_RS(WRAP9, 0, 15), + __TO_DETERMINE_RS(WRAP10, 0, 15), + __TO_DETERMINE_RS(WRAP11, 0, 15), + __TO_DETERMINE_RS(WRAP12, 0, 15), + __TO_DETERMINE_RS(WRAP13, 0, 15), + __TO_DETERMINE_RS(WRAP14, 0, 15), + __TO_DETERMINE_RS(WRAP15, 0, 15), + __BOOLEAN_RS(SEPARATEALPHABLENDENABLE), + __RANGE_DEF_VAL_RS(SRCBLENDALPHA, 1, 17, D3DBLEND_ZERO), + __RANGE_DEF_VAL_RS(DESTBLENDALPHA, 1, 17, D3DBLEND_ZERO), + __CLAMP_RS(BLENDOPALPHA, 1, 5) +}; + +static DWORD inline +nine_fix_render_state_value(D3DRENDERSTATETYPE State, + DWORD Value) +{ + struct nine_state_behaviour behaviour = render_state_limits_table[State]; + + switch (behaviour.state_value_behaviour) { + case NINE_STATE_NO_LIMIT: + break; + case NINE_STATE_CLAMP: + if (Value < behaviour.u.clamp.min) + Value = behaviour.u.clamp.min; + else if (Value > behaviour.u.clamp.max) + Value = behaviour.u.clamp.max; + break; + case NINE_STATE_BOOL: + Value = Value ? 1 : 0; + break; + case NINE_STATE_MASK: + Value = Value & behaviour.u.mask; + break; + case NINE_STATE_RANGE_DEF_VAL: + if (Value < behaviour.u.range_def_val.min || Value > behaviour.u.range_def_val.max) + Value = behaviour.u.range_def_val.default_val; + break; + } + + return Value; +} + +#endif /* _NINE_HELPERS_H_ */ diff --git a/src/gallium/state_trackers/nine/nine_state.c b/src/gallium/state_trackers/nine/nine_state.c index f835d298014..3a62f434565 100644 --- a/src/gallium/state_trackers/nine/nine_state.c +++ b/src/gallium/state_trackers/nine/nine_state.c @@ -1261,6 +1261,8 @@ nine_state_set_defaults(struct NineDevice9 *device, const D3DCAPS9 *caps, */ state->rs[D3DRS_POINTSIZE_MAX] = fui(caps->MaxPointSize); + memcpy(state->rs_advertised, state->rs, sizeof(state->rs)); + /* Set changed flags to initialize driver. */ state->changed.group = NINE_STATE_ALL; diff --git a/src/gallium/state_trackers/nine/nine_state.h b/src/gallium/state_trackers/nine/nine_state.h index 19bf02b0419..34bdd2231aa 100644 --- a/src/gallium/state_trackers/nine/nine_state.h +++ b/src/gallium/state_trackers/nine/nine_state.h @@ -181,6 +181,7 @@ struct nine_state uint8_t rt_mask; DWORD rs[NINED3DRS_COUNT]; + DWORD rs_advertised[NINED3DRS_COUNT]; /* the ones apps get with GetRenderState */ struct NineBaseTexture9 *texture[NINE_MAX_SAMPLERS]; /* PS, DMAP, VS */ diff --git a/src/gallium/state_trackers/nine/stateblock9.c b/src/gallium/state_trackers/nine/stateblock9.c index 397b560460c..0d1a04b657a 100644 --- a/src/gallium/state_trackers/nine/stateblock9.c +++ b/src/gallium/state_trackers/nine/stateblock9.c @@ -180,6 +180,7 @@ nine_state_copy_common(struct nine_state *dst, const int r = ffs(m) - 1; m &= ~(1 << r); dst->rs[i * 32 + r] = src->rs[i * 32 + r]; + dst->rs_advertised[i * 32 + r] = src->rs_advertised[i * 32 + r]; } } @@ -358,6 +359,7 @@ nine_state_copy_common_all(struct nine_state *dst, /* Render states. */ memcpy(dst->rs, src->rs, sizeof(dst->rs)); + memcpy(dst->rs_advertised, src->rs_advertised, sizeof(dst->rs_advertised)); if (apply) memcpy(dst->changed.rs, src->changed.rs, sizeof(dst->changed.rs)); |