17ec681f3Smrg/* 27ec681f3Smrg * Copyright 2015 Axel Davy <axel.davy@ens.fr> 37ec681f3Smrg * 47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 57ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 67ec681f3Smrg * to deal in the Software without restriction, including without limitation 77ec681f3Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 87ec681f3Smrg * license, and/or sell copies of the Software, and to permit persons to whom 97ec681f3Smrg * the Software is furnished to do so, subject to the following conditions: 107ec681f3Smrg * 117ec681f3Smrg * The above copyright notice and this permission notice (including the next 127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 137ec681f3Smrg * Software. 147ec681f3Smrg * 157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 187ec681f3Smrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 197ec681f3Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 207ec681f3Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 217ec681f3Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 227ec681f3Smrg 237ec681f3Smrg#ifndef _NINE_LIMITS_H_ 247ec681f3Smrg#define _NINE_LIMITS_H_ 257ec681f3Smrg 267ec681f3Smrg#include "assert.h" 277ec681f3Smrg#include "d3d9types.h" 287ec681f3Smrg 297ec681f3Smrg// state can be any value 307ec681f3Smrg#define NINE_STATE_NO_LIMIT 0 317ec681f3Smrg// value is clamped if below min or max 327ec681f3Smrg#define NINE_STATE_CLAMP 1 337ec681f3Smrg// boolean: 0 -> false; any other value -> true 347ec681f3Smrg#define NINE_STATE_BOOL 2 357ec681f3Smrg// a mask is applied on the value 367ec681f3Smrg#define NINE_STATE_MASK 3 377ec681f3Smrg// if outside a range, state value is changed to a default value 387ec681f3Smrg#define NINE_STATE_RANGE_DEF_VAL 4 397ec681f3Smrg 407ec681f3Smrgstruct nine_state_behaviour { 417ec681f3Smrg unsigned state_value_behaviour; 427ec681f3Smrg union { 437ec681f3Smrg struct { 447ec681f3Smrg unsigned min; 457ec681f3Smrg unsigned max; 467ec681f3Smrg } clamp; 477ec681f3Smrg unsigned mask; 487ec681f3Smrg struct { 497ec681f3Smrg unsigned min; 507ec681f3Smrg unsigned max; 517ec681f3Smrg unsigned default_val; 527ec681f3Smrg } range_def_val; 537ec681f3Smrg } u; 547ec681f3Smrg}; 557ec681f3Smrg 567ec681f3Smrg#define __NO_LIMIT_RS(o) \ 577ec681f3Smrg [D3DRS_##o] = {NINE_STATE_NO_LIMIT} 587ec681f3Smrg 597ec681f3Smrg#define __CLAMP_RS(o, m, M) \ 607ec681f3Smrg [D3DRS_##o] = {NINE_STATE_CLAMP, {.clamp = {m, M}}} 617ec681f3Smrg 627ec681f3Smrg#define __BOOLEAN_RS(o) \ 637ec681f3Smrg [D3DRS_##o] = {NINE_STATE_BOOL} 647ec681f3Smrg 657ec681f3Smrg#define __MASK_RS(o, m) \ 667ec681f3Smrg [D3DRS_##o] = {NINE_STATE_MASK, {.mask = m}} 677ec681f3Smrg 687ec681f3Smrg#define __RANGE_DEF_VAL_RS(o, m, M, d) \ 697ec681f3Smrg [D3DRS_##o] = {NINE_STATE_RANGE_DEF_VAL, {.range_def_val = {m, M, d}}} 707ec681f3Smrg 717ec681f3Smrg#define __TO_DETERMINE_RS(o, m, M) \ 727ec681f3Smrg [D3DRS_##o] = {NINE_STATE_NO_LIMIT} 737ec681f3Smrg 747ec681f3Smrgstatic const struct nine_state_behaviour 757ec681f3Smrgrender_state_limits_table[D3DRS_BLENDOPALPHA + 1] = { 767ec681f3Smrg __TO_DETERMINE_RS(ZENABLE, 0, 3), 777ec681f3Smrg __TO_DETERMINE_RS(FILLMODE, 1, 3), 787ec681f3Smrg __CLAMP_RS(SHADEMODE, 1, 3), 797ec681f3Smrg __BOOLEAN_RS(ZWRITEENABLE), 807ec681f3Smrg __BOOLEAN_RS(ALPHATESTENABLE), 817ec681f3Smrg __BOOLEAN_RS(LASTPIXEL), 827ec681f3Smrg __RANGE_DEF_VAL_RS(SRCBLEND, 1, 17, D3DBLEND_ZERO), 837ec681f3Smrg __RANGE_DEF_VAL_RS(DESTBLEND, 1, 17, D3DBLEND_ZERO), 847ec681f3Smrg __CLAMP_RS(CULLMODE, 1, 3), 857ec681f3Smrg __CLAMP_RS(ZFUNC, 1, 8), 867ec681f3Smrg __MASK_RS(ALPHAREF, 0x000000FF), 877ec681f3Smrg __CLAMP_RS(ALPHAFUNC, 1, 8), 887ec681f3Smrg __BOOLEAN_RS(DITHERENABLE), 897ec681f3Smrg __BOOLEAN_RS(ALPHABLENDENABLE), 907ec681f3Smrg __BOOLEAN_RS(FOGENABLE), 917ec681f3Smrg __BOOLEAN_RS(SPECULARENABLE), 927ec681f3Smrg __NO_LIMIT_RS(FOGCOLOR), 937ec681f3Smrg __MASK_RS(FOGTABLEMODE, 0x00000007), 947ec681f3Smrg __NO_LIMIT_RS(FOGSTART), /* a bit more complex than that, lets ignore */ 957ec681f3Smrg __NO_LIMIT_RS(FOGEND), 967ec681f3Smrg __NO_LIMIT_RS(FOGDENSITY), /* actually should be between 0.0 and 1.0 */ 977ec681f3Smrg __BOOLEAN_RS(RANGEFOGENABLE), 987ec681f3Smrg __BOOLEAN_RS(STENCILENABLE), 997ec681f3Smrg __CLAMP_RS(STENCILFAIL, 1, 8), 1007ec681f3Smrg __CLAMP_RS(STENCILZFAIL, 1, 8), 1017ec681f3Smrg __CLAMP_RS(STENCILPASS, 1, 8), 1027ec681f3Smrg __CLAMP_RS(STENCILFUNC, 1, 8), 1037ec681f3Smrg __NO_LIMIT_RS(STENCILREF), 1047ec681f3Smrg __NO_LIMIT_RS(STENCILMASK), 1057ec681f3Smrg __NO_LIMIT_RS(STENCILWRITEMASK), 1067ec681f3Smrg __NO_LIMIT_RS(TEXTUREFACTOR), 1077ec681f3Smrg __TO_DETERMINE_RS(WRAP0, 0, 15), 1087ec681f3Smrg __TO_DETERMINE_RS(WRAP1, 0, 15), 1097ec681f3Smrg __TO_DETERMINE_RS(WRAP2, 0, 15), 1107ec681f3Smrg __TO_DETERMINE_RS(WRAP3, 0, 15), 1117ec681f3Smrg __TO_DETERMINE_RS(WRAP4, 0, 15), 1127ec681f3Smrg __TO_DETERMINE_RS(WRAP5, 0, 15), 1137ec681f3Smrg __TO_DETERMINE_RS(WRAP6, 0, 15), 1147ec681f3Smrg __TO_DETERMINE_RS(WRAP7, 0, 15), 1157ec681f3Smrg __BOOLEAN_RS(CLIPPING), 1167ec681f3Smrg __BOOLEAN_RS(LIGHTING), 1177ec681f3Smrg __NO_LIMIT_RS(AMBIENT), 1187ec681f3Smrg __MASK_RS(FOGVERTEXMODE, 0x00000007), 1197ec681f3Smrg __BOOLEAN_RS(COLORVERTEX), 1207ec681f3Smrg __BOOLEAN_RS(LOCALVIEWER), 1217ec681f3Smrg __BOOLEAN_RS(NORMALIZENORMALS), 1227ec681f3Smrg __TO_DETERMINE_RS(DIFFUSEMATERIALSOURCE, 0, 2), 1237ec681f3Smrg __TO_DETERMINE_RS(SPECULARMATERIALSOURCE, 0, 2), 1247ec681f3Smrg __TO_DETERMINE_RS(AMBIENTMATERIALSOURCE, 0, 2), 1257ec681f3Smrg __TO_DETERMINE_RS(EMISSIVEMATERIALSOURCE, 0, 2), 1267ec681f3Smrg __TO_DETERMINE_RS(VERTEXBLEND, 0, 256), /* values between 4 and 254 -both included- are forbidden too */ 1277ec681f3Smrg __NO_LIMIT_RS(CLIPPLANEENABLE), /* expected check seems complex */ 1287ec681f3Smrg __TO_DETERMINE_RS(POINTSIZE, 0, 0xFFFFFFFF), 1297ec681f3Smrg __TO_DETERMINE_RS(POINTSIZE_MIN, 0, 0x7FFFFFFF), /* float >= 0.0 */ 1307ec681f3Smrg __BOOLEAN_RS(POINTSPRITEENABLE), 1317ec681f3Smrg __BOOLEAN_RS(POINTSCALEENABLE), 1327ec681f3Smrg __TO_DETERMINE_RS(POINTSCALE_A, 0, 0x7FFFFFFF), /* float >= 0.0 */ 1337ec681f3Smrg __TO_DETERMINE_RS(POINTSCALE_B, 0, 0x7FFFFFFF), /* float >= 0.0 */ 1347ec681f3Smrg __TO_DETERMINE_RS(POINTSCALE_C, 0, 0x7FFFFFFF), /* float >= 0.0 */ 1357ec681f3Smrg __BOOLEAN_RS(MULTISAMPLEANTIALIAS), 1367ec681f3Smrg __NO_LIMIT_RS(MULTISAMPLEMASK), 1377ec681f3Smrg __TO_DETERMINE_RS(PATCHEDGESTYLE, 0, 1), 1387ec681f3Smrg __TO_DETERMINE_RS(DEBUGMONITORTOKEN, 0, 1), 1397ec681f3Smrg __TO_DETERMINE_RS(POINTSIZE_MAX, 0, 0x7FFFFFFF), /* check more complex than that */ 1407ec681f3Smrg __BOOLEAN_RS(INDEXEDVERTEXBLENDENABLE), 1417ec681f3Smrg __TO_DETERMINE_RS(COLORWRITEENABLE, 0, 15), 1427ec681f3Smrg __NO_LIMIT_RS(TWEENFACTOR), 1437ec681f3Smrg __CLAMP_RS(BLENDOP, 1, 5), 1447ec681f3Smrg __TO_DETERMINE_RS(POSITIONDEGREE, 1, 5), /* can actually be only 1 or 5 */ 1457ec681f3Smrg __TO_DETERMINE_RS(NORMALDEGREE, 1, 2), 1467ec681f3Smrg __BOOLEAN_RS(SCISSORTESTENABLE), 1477ec681f3Smrg __NO_LIMIT_RS(SLOPESCALEDEPTHBIAS), 1487ec681f3Smrg __BOOLEAN_RS(ANTIALIASEDLINEENABLE), 1497ec681f3Smrg __NO_LIMIT_RS(MINTESSELLATIONLEVEL), 1507ec681f3Smrg __NO_LIMIT_RS(MAXTESSELLATIONLEVEL), 1517ec681f3Smrg __NO_LIMIT_RS(ADAPTIVETESS_X), 1527ec681f3Smrg __NO_LIMIT_RS(ADAPTIVETESS_Y), 1537ec681f3Smrg __NO_LIMIT_RS(ADAPTIVETESS_Z), 1547ec681f3Smrg __NO_LIMIT_RS(ADAPTIVETESS_W), 1557ec681f3Smrg __BOOLEAN_RS(ENABLEADAPTIVETESSELLATION), 1567ec681f3Smrg __BOOLEAN_RS(TWOSIDEDSTENCILMODE), 1577ec681f3Smrg __CLAMP_RS(CCW_STENCILFAIL, 1, 8), 1587ec681f3Smrg __CLAMP_RS(CCW_STENCILZFAIL, 1, 8), 1597ec681f3Smrg __CLAMP_RS(CCW_STENCILPASS, 1, 8), 1607ec681f3Smrg __CLAMP_RS(CCW_STENCILFUNC, 1, 8), 1617ec681f3Smrg __TO_DETERMINE_RS(COLORWRITEENABLE1, 0, 15), 1627ec681f3Smrg __TO_DETERMINE_RS(COLORWRITEENABLE2, 0, 15), 1637ec681f3Smrg __TO_DETERMINE_RS(COLORWRITEENABLE3, 0, 15), 1647ec681f3Smrg __NO_LIMIT_RS(BLENDFACTOR), 1657ec681f3Smrg __BOOLEAN_RS(SRGBWRITEENABLE), 1667ec681f3Smrg __NO_LIMIT_RS(DEPTHBIAS), 1677ec681f3Smrg __TO_DETERMINE_RS(WRAP8, 0, 15), 1687ec681f3Smrg __TO_DETERMINE_RS(WRAP9, 0, 15), 1697ec681f3Smrg __TO_DETERMINE_RS(WRAP10, 0, 15), 1707ec681f3Smrg __TO_DETERMINE_RS(WRAP11, 0, 15), 1717ec681f3Smrg __TO_DETERMINE_RS(WRAP12, 0, 15), 1727ec681f3Smrg __TO_DETERMINE_RS(WRAP13, 0, 15), 1737ec681f3Smrg __TO_DETERMINE_RS(WRAP14, 0, 15), 1747ec681f3Smrg __TO_DETERMINE_RS(WRAP15, 0, 15), 1757ec681f3Smrg __BOOLEAN_RS(SEPARATEALPHABLENDENABLE), 1767ec681f3Smrg __RANGE_DEF_VAL_RS(SRCBLENDALPHA, 1, 17, D3DBLEND_ZERO), 1777ec681f3Smrg __RANGE_DEF_VAL_RS(DESTBLENDALPHA, 1, 17, D3DBLEND_ZERO), 1787ec681f3Smrg __CLAMP_RS(BLENDOPALPHA, 1, 5) 1797ec681f3Smrg}; 1807ec681f3Smrg 1817ec681f3Smrgstatic DWORD inline 1827ec681f3Smrgnine_fix_render_state_value(D3DRENDERSTATETYPE State, 1837ec681f3Smrg DWORD Value) 1847ec681f3Smrg{ 1857ec681f3Smrg struct nine_state_behaviour behaviour = render_state_limits_table[State]; 1867ec681f3Smrg 1877ec681f3Smrg switch (behaviour.state_value_behaviour) { 1887ec681f3Smrg case NINE_STATE_NO_LIMIT: 1897ec681f3Smrg break; 1907ec681f3Smrg case NINE_STATE_CLAMP: 1917ec681f3Smrg if (Value < behaviour.u.clamp.min) 1927ec681f3Smrg Value = behaviour.u.clamp.min; 1937ec681f3Smrg else if (Value > behaviour.u.clamp.max) 1947ec681f3Smrg Value = behaviour.u.clamp.max; 1957ec681f3Smrg break; 1967ec681f3Smrg case NINE_STATE_BOOL: 1977ec681f3Smrg Value = Value ? 1 : 0; 1987ec681f3Smrg break; 1997ec681f3Smrg case NINE_STATE_MASK: 2007ec681f3Smrg Value = Value & behaviour.u.mask; 2017ec681f3Smrg break; 2027ec681f3Smrg case NINE_STATE_RANGE_DEF_VAL: 2037ec681f3Smrg if (Value < behaviour.u.range_def_val.min || Value > behaviour.u.range_def_val.max) 2047ec681f3Smrg Value = behaviour.u.range_def_val.default_val; 2057ec681f3Smrg break; 2067ec681f3Smrg } 2077ec681f3Smrg 2087ec681f3Smrg return Value; 2097ec681f3Smrg} 2107ec681f3Smrg 2117ec681f3Smrgstruct nine_limits 2127ec681f3Smrg{ 2137ec681f3Smrg unsigned min; 2147ec681f3Smrg unsigned max; 2157ec681f3Smrg}; 2167ec681f3Smrg 2177ec681f3Smrg#define __VALUE_SAMP(o, m, M) \ 2187ec681f3Smrg [D3DSAMP_##o] = {m, M} 2197ec681f3Smrg 2207ec681f3Smrgstatic const struct nine_limits 2217ec681f3Smrgsampler_state_limits_table[D3DRS_BLENDOPALPHA + 1] = { 2227ec681f3Smrg __VALUE_SAMP(ADDRESSU, 1, 5), 2237ec681f3Smrg __VALUE_SAMP(ADDRESSV, 1, 5), 2247ec681f3Smrg __VALUE_SAMP(ADDRESSW, 1, 5), 2257ec681f3Smrg __VALUE_SAMP(BORDERCOLOR, 0, 0xFFFFFFFF), 2267ec681f3Smrg __VALUE_SAMP(MAGFILTER, 0, 8), /* 4-5 should be forbidden */ 2277ec681f3Smrg __VALUE_SAMP(MINFILTER, 0, 8), /* same */ 2287ec681f3Smrg __VALUE_SAMP(MIPFILTER, 0, 8), /* same */ 2297ec681f3Smrg __VALUE_SAMP(MIPMAPLODBIAS, 0, 0xFFFFFFFF), 2307ec681f3Smrg __VALUE_SAMP(MAXMIPLEVEL, 0, 0xFFFFFFFF), 2317ec681f3Smrg __VALUE_SAMP(MAXANISOTROPY, 1, 0xFFFFFFFF), /* Max value should be pCaps->MaxAnisotropy */ 2327ec681f3Smrg __VALUE_SAMP(SRGBTEXTURE, 0, 1), 2337ec681f3Smrg __VALUE_SAMP(ELEMENTINDEX, 0, 0xFFFFFFFF), 2347ec681f3Smrg __VALUE_SAMP(DMAPOFFSET, 0, 0xFFFFFFFF) 2357ec681f3Smrg}; 2367ec681f3Smrg 2377ec681f3Smrgstatic BOOL inline 2387ec681f3Smrgnine_check_sampler_state_value(D3DSAMPLERSTATETYPE State, 2397ec681f3Smrg DWORD Value) 2407ec681f3Smrg{ 2417ec681f3Smrg struct nine_limits limit; 2427ec681f3Smrg 2437ec681f3Smrg limit = sampler_state_limits_table[State]; 2447ec681f3Smrg return (limit.min <= Value && Value <= limit.max); 2457ec681f3Smrg} 2467ec681f3Smrg 2477ec681f3Smrg#endif /* _NINE_HELPERS_H_ */ 248