2 * Copyright 2015 Axel Davy <axel.davy@ens.fr>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
23 #ifndef _NINE_LIMITS_H_
24 #define _NINE_LIMITS_H_
27 #include "d3d9types.h"
29 // state can be any value
30 #define NINE_STATE_NO_LIMIT 0
31 // value is clamped if below min or max
32 #define NINE_STATE_CLAMP 1
33 // boolean: 0 -> false; any other value -> true
34 #define NINE_STATE_BOOL 2
35 // a mask is applied on the value
36 #define NINE_STATE_MASK 3
37 // if outside a range, state value is changed to a default value
38 #define NINE_STATE_RANGE_DEF_VAL 4
40 struct nine_state_behaviour
{
41 unsigned state_value_behaviour
;
56 #define __NO_LIMIT_RS(o) \
57 [D3DRS_##o] = {NINE_STATE_NO_LIMIT}
59 #define __CLAMP_RS(o, m, M) \
60 [D3DRS_##o] = {NINE_STATE_CLAMP, {.clamp = {m, M}}}
62 #define __BOOLEAN_RS(o) \
63 [D3DRS_##o] = {NINE_STATE_BOOL}
65 #define __MASK_RS(o, m) \
66 [D3DRS_##o] = {NINE_STATE_MASK, {.mask = m}}
68 #define __RANGE_DEF_VAL_RS(o, m, M, d) \
69 [D3DRS_##o] = {NINE_STATE_RANGE_DEF_VAL, {.range_def_val = {m, M, d}}}
71 #define __TO_DETERMINE_RS(o, m, M) \
72 [D3DRS_##o] = {NINE_STATE_NO_LIMIT}
74 static const struct nine_state_behaviour
75 render_state_limits_table
[D3DRS_BLENDOPALPHA
+ 1] = {
76 __TO_DETERMINE_RS(ZENABLE
, 0, 3),
77 __TO_DETERMINE_RS(FILLMODE
, 1, 3),
78 __CLAMP_RS(SHADEMODE
, 1, 3),
79 __BOOLEAN_RS(ZWRITEENABLE
),
80 __BOOLEAN_RS(ALPHATESTENABLE
),
81 __BOOLEAN_RS(LASTPIXEL
),
82 __RANGE_DEF_VAL_RS(SRCBLEND
, 1, 17, D3DBLEND_ZERO
),
83 __RANGE_DEF_VAL_RS(DESTBLEND
, 1, 17, D3DBLEND_ZERO
),
84 __CLAMP_RS(CULLMODE
, 1, 3),
85 __CLAMP_RS(ZFUNC
, 1, 8),
86 __MASK_RS(ALPHAREF
, 0x000000FF),
87 __CLAMP_RS(ALPHAFUNC
, 1, 8),
88 __BOOLEAN_RS(DITHERENABLE
),
89 __BOOLEAN_RS(ALPHABLENDENABLE
),
90 __BOOLEAN_RS(FOGENABLE
),
91 __BOOLEAN_RS(SPECULARENABLE
),
92 __NO_LIMIT_RS(FOGCOLOR
),
93 __MASK_RS(FOGTABLEMODE
, 0x00000007),
94 __NO_LIMIT_RS(FOGSTART
), /* a bit more complex than that, lets ignore */
95 __NO_LIMIT_RS(FOGEND
),
96 __NO_LIMIT_RS(FOGDENSITY
), /* actually should be between 0.0 and 1.0 */
97 __BOOLEAN_RS(RANGEFOGENABLE
),
98 __BOOLEAN_RS(STENCILENABLE
),
99 __CLAMP_RS(STENCILFAIL
, 1, 8),
100 __CLAMP_RS(STENCILZFAIL
, 1, 8),
101 __CLAMP_RS(STENCILPASS
, 1, 8),
102 __CLAMP_RS(STENCILFUNC
, 1, 8),
103 __NO_LIMIT_RS(STENCILREF
),
104 __NO_LIMIT_RS(STENCILMASK
),
105 __NO_LIMIT_RS(STENCILWRITEMASK
),
106 __NO_LIMIT_RS(TEXTUREFACTOR
),
107 __TO_DETERMINE_RS(WRAP0
, 0, 15),
108 __TO_DETERMINE_RS(WRAP1
, 0, 15),
109 __TO_DETERMINE_RS(WRAP2
, 0, 15),
110 __TO_DETERMINE_RS(WRAP3
, 0, 15),
111 __TO_DETERMINE_RS(WRAP4
, 0, 15),
112 __TO_DETERMINE_RS(WRAP5
, 0, 15),
113 __TO_DETERMINE_RS(WRAP6
, 0, 15),
114 __TO_DETERMINE_RS(WRAP7
, 0, 15),
115 __BOOLEAN_RS(CLIPPING
),
116 __BOOLEAN_RS(LIGHTING
),
117 __NO_LIMIT_RS(AMBIENT
),
118 __MASK_RS(FOGVERTEXMODE
, 0x00000007),
119 __BOOLEAN_RS(COLORVERTEX
),
120 __BOOLEAN_RS(LOCALVIEWER
),
121 __BOOLEAN_RS(NORMALIZENORMALS
),
122 __TO_DETERMINE_RS(DIFFUSEMATERIALSOURCE
, 0, 2),
123 __TO_DETERMINE_RS(SPECULARMATERIALSOURCE
, 0, 2),
124 __TO_DETERMINE_RS(AMBIENTMATERIALSOURCE
, 0, 2),
125 __TO_DETERMINE_RS(EMISSIVEMATERIALSOURCE
, 0, 2),
126 __TO_DETERMINE_RS(VERTEXBLEND
, 0, 256), /* values between 4 and 254 -both included- are forbidden too */
127 __NO_LIMIT_RS(CLIPPLANEENABLE
), /* expected check seems complex */
128 __TO_DETERMINE_RS(POINTSIZE
, 0, 0xFFFFFFFF),
129 __TO_DETERMINE_RS(POINTSIZE_MIN
, 0, 0x7FFFFFFF), /* float >= 0.0 */
130 __BOOLEAN_RS(POINTSPRITEENABLE
),
131 __BOOLEAN_RS(POINTSCALEENABLE
),
132 __TO_DETERMINE_RS(POINTSCALE_A
, 0, 0x7FFFFFFF), /* float >= 0.0 */
133 __TO_DETERMINE_RS(POINTSCALE_B
, 0, 0x7FFFFFFF), /* float >= 0.0 */
134 __TO_DETERMINE_RS(POINTSCALE_C
, 0, 0x7FFFFFFF), /* float >= 0.0 */
135 __BOOLEAN_RS(MULTISAMPLEANTIALIAS
),
136 __NO_LIMIT_RS(MULTISAMPLEMASK
),
137 __TO_DETERMINE_RS(PATCHEDGESTYLE
, 0, 1),
138 __TO_DETERMINE_RS(DEBUGMONITORTOKEN
, 0, 1),
139 __TO_DETERMINE_RS(POINTSIZE_MAX
, 0, 0x7FFFFFFF), /* check more complex than that */
140 __BOOLEAN_RS(INDEXEDVERTEXBLENDENABLE
),
141 __TO_DETERMINE_RS(COLORWRITEENABLE
, 0, 15),
142 __NO_LIMIT_RS(TWEENFACTOR
),
143 __CLAMP_RS(BLENDOP
, 1, 5),
144 __TO_DETERMINE_RS(POSITIONDEGREE
, 1, 5), /* can actually be only 1 or 5 */
145 __TO_DETERMINE_RS(NORMALDEGREE
, 1, 2),
146 __BOOLEAN_RS(SCISSORTESTENABLE
),
147 __NO_LIMIT_RS(SLOPESCALEDEPTHBIAS
),
148 __BOOLEAN_RS(ANTIALIASEDLINEENABLE
),
149 __NO_LIMIT_RS(MINTESSELLATIONLEVEL
),
150 __NO_LIMIT_RS(MAXTESSELLATIONLEVEL
),
151 __NO_LIMIT_RS(ADAPTIVETESS_X
),
152 __NO_LIMIT_RS(ADAPTIVETESS_Y
),
153 __NO_LIMIT_RS(ADAPTIVETESS_Z
),
154 __NO_LIMIT_RS(ADAPTIVETESS_W
),
155 __BOOLEAN_RS(ENABLEADAPTIVETESSELLATION
),
156 __BOOLEAN_RS(TWOSIDEDSTENCILMODE
),
157 __CLAMP_RS(CCW_STENCILFAIL
, 1, 8),
158 __CLAMP_RS(CCW_STENCILZFAIL
, 1, 8),
159 __CLAMP_RS(CCW_STENCILPASS
, 1, 8),
160 __CLAMP_RS(CCW_STENCILFUNC
, 1, 8),
161 __TO_DETERMINE_RS(COLORWRITEENABLE1
, 0, 15),
162 __TO_DETERMINE_RS(COLORWRITEENABLE2
, 0, 15),
163 __TO_DETERMINE_RS(COLORWRITEENABLE3
, 0, 15),
164 __NO_LIMIT_RS(BLENDFACTOR
),
165 __BOOLEAN_RS(SRGBWRITEENABLE
),
166 __NO_LIMIT_RS(DEPTHBIAS
),
167 __TO_DETERMINE_RS(WRAP8
, 0, 15),
168 __TO_DETERMINE_RS(WRAP9
, 0, 15),
169 __TO_DETERMINE_RS(WRAP10
, 0, 15),
170 __TO_DETERMINE_RS(WRAP11
, 0, 15),
171 __TO_DETERMINE_RS(WRAP12
, 0, 15),
172 __TO_DETERMINE_RS(WRAP13
, 0, 15),
173 __TO_DETERMINE_RS(WRAP14
, 0, 15),
174 __TO_DETERMINE_RS(WRAP15
, 0, 15),
175 __BOOLEAN_RS(SEPARATEALPHABLENDENABLE
),
176 __RANGE_DEF_VAL_RS(SRCBLENDALPHA
, 1, 17, D3DBLEND_ZERO
),
177 __RANGE_DEF_VAL_RS(DESTBLENDALPHA
, 1, 17, D3DBLEND_ZERO
),
178 __CLAMP_RS(BLENDOPALPHA
, 1, 5)
182 nine_fix_render_state_value(D3DRENDERSTATETYPE State
,
185 struct nine_state_behaviour behaviour
= render_state_limits_table
[State
];
187 switch (behaviour
.state_value_behaviour
) {
188 case NINE_STATE_NO_LIMIT
:
190 case NINE_STATE_CLAMP
:
191 if (Value
< behaviour
.u
.clamp
.min
)
192 Value
= behaviour
.u
.clamp
.min
;
193 else if (Value
> behaviour
.u
.clamp
.max
)
194 Value
= behaviour
.u
.clamp
.max
;
196 case NINE_STATE_BOOL
:
197 Value
= Value
? 1 : 0;
199 case NINE_STATE_MASK
:
200 Value
= Value
& behaviour
.u
.mask
;
202 case NINE_STATE_RANGE_DEF_VAL
:
203 if (Value
< behaviour
.u
.range_def_val
.min
|| Value
> behaviour
.u
.range_def_val
.max
)
204 Value
= behaviour
.u
.range_def_val
.default_val
;
217 #define __VALUE_SAMP(o, m, M) \
218 [D3DSAMP_##o] = {m, M}
220 static const struct nine_limits
221 sampler_state_limits_table
[D3DRS_BLENDOPALPHA
+ 1] = {
222 __VALUE_SAMP(ADDRESSU
, 1, 5),
223 __VALUE_SAMP(ADDRESSV
, 1, 5),
224 __VALUE_SAMP(ADDRESSW
, 1, 5),
225 __VALUE_SAMP(BORDERCOLOR
, 0, 0xFFFFFFFF),
226 __VALUE_SAMP(MAGFILTER
, 0, 8), /* 4-5 should be forbidden */
227 __VALUE_SAMP(MINFILTER
, 0, 8), /* same */
228 __VALUE_SAMP(MIPFILTER
, 0, 8), /* same */
229 __VALUE_SAMP(MIPMAPLODBIAS
, 0, 0xFFFFFFFF),
230 __VALUE_SAMP(MAXMIPLEVEL
, 0, 0xFFFFFFFF),
231 __VALUE_SAMP(MAXANISOTROPY
, 1, 0xFFFFFFFF), /* Max value should be pCaps->MaxAnisotropy */
232 __VALUE_SAMP(SRGBTEXTURE
, 0, 1),
233 __VALUE_SAMP(ELEMENTINDEX
, 0, 0xFFFFFFFF),
234 __VALUE_SAMP(DMAPOFFSET
, 0, 0xFFFFFFFF)
238 nine_check_sampler_state_value(D3DSAMPLERSTATETYPE State
,
241 struct nine_limits limit
;
243 limit
= sampler_state_limits_table
[State
];
244 return (limit
.min
<= Value
&& Value
<= limit
.max
);
247 #endif /* _NINE_HELPERS_H_ */