2 * Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
3 * Copyright 2013 Christoph Bumiller
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
25 #include "basetexture9.h"
27 #include "indexbuffer9.h"
29 #include "vertexbuffer9.h"
30 #include "vertexdeclaration9.h"
31 #include "vertexshader9.h"
32 #include "pixelshader9.h"
33 #include "nine_pipe.h"
35 #include "pipe/p_context.h"
36 #include "pipe/p_state.h"
37 #include "cso_cache/cso_context.h"
38 #include "util/u_upload_mgr.h"
39 #include "util/u_math.h"
40 #include "util/u_box.h"
41 #include "util/u_simple_shaders.h"
43 #define DBG_CHANNEL DBG_DEVICE
45 /* Check if some states need to be set dirty */
48 check_multisample(struct NineDevice9
*device
)
50 DWORD
*rs
= device
->state
.rs
;
51 DWORD new_value
= (rs
[D3DRS_ZENABLE
] || rs
[D3DRS_STENCILENABLE
]) &&
52 device
->state
.rt
[0]->desc
.MultiSampleType
>= 1 &&
53 rs
[D3DRS_MULTISAMPLEANTIALIAS
];
54 if (rs
[NINED3DRS_MULTISAMPLE
] != new_value
) {
55 rs
[NINED3DRS_MULTISAMPLE
] = new_value
;
56 return NINE_STATE_RASTERIZER
;
61 /* State preparation only */
64 prepare_blend(struct NineDevice9
*device
)
66 nine_convert_blend_state(&device
->context
.pipe
.blend
, device
->state
.rs
);
67 device
->context
.commit
|= NINE_STATE_COMMIT_BLEND
;
71 prepare_dsa(struct NineDevice9
*device
)
73 nine_convert_dsa_state(&device
->context
.pipe
.dsa
, device
->state
.rs
);
74 device
->context
.commit
|= NINE_STATE_COMMIT_DSA
;
78 prepare_rasterizer(struct NineDevice9
*device
)
80 nine_convert_rasterizer_state(device
, &device
->context
.pipe
.rast
, device
->state
.rs
);
81 device
->context
.commit
|= NINE_STATE_COMMIT_RASTERIZER
;
85 prepare_vs_constants_userbuf_swvp(struct NineDevice9
*device
)
87 struct nine_state
*state
= &device
->state
;
88 struct nine_context
*context
= &device
->context
;
90 if (state
->changed
.vs_const_f
|| state
->changed
.group
& NINE_STATE_SWVP
) {
91 struct pipe_constant_buffer cb
;
94 cb
.buffer_size
= 4096 * sizeof(float[4]);
95 cb
.user_buffer
= state
->vs_const_f_swvp
;
97 if (state
->vs
->lconstf
.ranges
) {
98 const struct nine_lconstf
*lconstf
= &device
->state
.vs
->lconstf
;
99 const struct nine_range
*r
= lconstf
->ranges
;
101 float *dst
= device
->state
.vs_lconstf_temp
;
102 float *src
= (float *)cb
.user_buffer
;
103 memcpy(dst
, src
, cb
.buffer_size
);
106 unsigned c
= r
->end
- r
->bgn
;
107 memcpy(&dst
[p
* 4], &lconstf
->data
[n
* 4], c
* 4 * sizeof(float));
111 cb
.user_buffer
= dst
;
114 /* Do not erase the buffer field.
115 * It is either NULL (user_cbufs), or a resource.
116 * u_upload_data will do the proper refcount */
117 context
->pipe
.cb0_swvp
.buffer_offset
= cb
.buffer_offset
;
118 context
->pipe
.cb0_swvp
.buffer_size
= cb
.buffer_size
;
119 context
->pipe
.cb0_swvp
.user_buffer
= cb
.user_buffer
;
121 cb
.user_buffer
= (char *)cb
.user_buffer
+ 4096 * sizeof(float[4]);
122 context
->pipe
.cb1_swvp
.buffer_offset
= cb
.buffer_offset
;
123 context
->pipe
.cb1_swvp
.buffer_size
= cb
.buffer_size
;
124 context
->pipe
.cb1_swvp
.user_buffer
= cb
.user_buffer
;
127 if (state
->changed
.vs_const_i
|| state
->changed
.group
& NINE_STATE_SWVP
) {
128 struct pipe_constant_buffer cb
;
130 cb
.buffer_offset
= 0;
131 cb
.buffer_size
= 2048 * sizeof(float[4]);
132 cb
.user_buffer
= state
->vs_const_i
;
134 context
->pipe
.cb2_swvp
.buffer_offset
= cb
.buffer_offset
;
135 context
->pipe
.cb2_swvp
.buffer_size
= cb
.buffer_size
;
136 context
->pipe
.cb2_swvp
.user_buffer
= cb
.user_buffer
;
139 if (state
->changed
.vs_const_b
|| state
->changed
.group
& NINE_STATE_SWVP
) {
140 struct pipe_constant_buffer cb
;
142 cb
.buffer_offset
= 0;
143 cb
.buffer_size
= 512 * sizeof(float[4]);
144 cb
.user_buffer
= state
->vs_const_b
;
146 context
->pipe
.cb3_swvp
.buffer_offset
= cb
.buffer_offset
;
147 context
->pipe
.cb3_swvp
.buffer_size
= cb
.buffer_size
;
148 context
->pipe
.cb3_swvp
.user_buffer
= cb
.user_buffer
;
151 if (!device
->driver_caps
.user_cbufs
) {
152 struct pipe_constant_buffer
*cb
= &(context
->pipe
.cb0_swvp
);
153 u_upload_data(device
->constbuf_uploader
,
156 device
->constbuf_alignment
,
158 &(cb
->buffer_offset
),
160 u_upload_unmap(device
->constbuf_uploader
);
161 cb
->user_buffer
= NULL
;
163 cb
= &(context
->pipe
.cb1_swvp
);
164 u_upload_data(device
->constbuf_uploader
,
167 device
->constbuf_alignment
,
169 &(cb
->buffer_offset
),
171 u_upload_unmap(device
->constbuf_uploader
);
172 cb
->user_buffer
= NULL
;
174 cb
= &(context
->pipe
.cb2_swvp
);
175 u_upload_data(device
->constbuf_uploader
,
178 device
->constbuf_alignment
,
180 &(cb
->buffer_offset
),
182 u_upload_unmap(device
->constbuf_uploader
);
183 cb
->user_buffer
= NULL
;
185 cb
= &(context
->pipe
.cb3_swvp
);
186 u_upload_data(device
->constbuf_uploader
,
189 device
->constbuf_alignment
,
191 &(cb
->buffer_offset
),
193 u_upload_unmap(device
->constbuf_uploader
);
194 cb
->user_buffer
= NULL
;
197 if (device
->state
.changed
.vs_const_f
) {
198 struct nine_range
*r
= device
->state
.changed
.vs_const_f
;
199 struct nine_range
*p
= r
;
202 nine_range_pool_put_chain(&device
->range_pool
, r
, p
);
203 device
->state
.changed
.vs_const_f
= NULL
;
206 if (device
->state
.changed
.vs_const_i
) {
207 struct nine_range
*r
= device
->state
.changed
.vs_const_i
;
208 struct nine_range
*p
= r
;
211 nine_range_pool_put_chain(&device
->range_pool
, r
, p
);
212 device
->state
.changed
.vs_const_i
= NULL
;
215 if (device
->state
.changed
.vs_const_b
) {
216 struct nine_range
*r
= device
->state
.changed
.vs_const_b
;
217 struct nine_range
*p
= r
;
220 nine_range_pool_put_chain(&device
->range_pool
, r
, p
);
221 device
->state
.changed
.vs_const_b
= NULL
;
224 state
->changed
.group
&= ~NINE_STATE_VS_CONST
;
225 context
->commit
|= NINE_STATE_COMMIT_CONST_VS
;
229 prepare_vs_constants_userbuf(struct NineDevice9
*device
)
231 struct nine_state
*state
= &device
->state
;
232 struct nine_context
*context
= &device
->context
;
233 struct pipe_constant_buffer cb
;
235 cb
.buffer_offset
= 0;
236 cb
.buffer_size
= device
->state
.vs
->const_used_size
;
237 cb
.user_buffer
= device
->state
.vs_const_f
;
240 prepare_vs_constants_userbuf_swvp(device
);
244 if (state
->changed
.vs_const_i
|| state
->changed
.group
& NINE_STATE_SWVP
) {
245 int *idst
= (int *)&state
->vs_const_f
[4 * device
->max_vs_const_f
];
246 memcpy(idst
, state
->vs_const_i
, NINE_MAX_CONST_I
* sizeof(int[4]));
249 if (state
->changed
.vs_const_b
|| state
->changed
.group
& NINE_STATE_SWVP
) {
250 int *idst
= (int *)&state
->vs_const_f
[4 * device
->max_vs_const_f
];
251 uint32_t *bdst
= (uint32_t *)&idst
[4 * NINE_MAX_CONST_I
];
252 memcpy(bdst
, state
->vs_const_b
, NINE_MAX_CONST_B
* sizeof(BOOL
));
255 if (device
->state
.changed
.vs_const_i
) {
256 struct nine_range
*r
= device
->state
.changed
.vs_const_i
;
257 struct nine_range
*p
= r
;
260 nine_range_pool_put_chain(&device
->range_pool
, r
, p
);
261 device
->state
.changed
.vs_const_i
= NULL
;
264 if (device
->state
.changed
.vs_const_b
) {
265 struct nine_range
*r
= device
->state
.changed
.vs_const_b
;
266 struct nine_range
*p
= r
;
269 nine_range_pool_put_chain(&device
->range_pool
, r
, p
);
270 device
->state
.changed
.vs_const_b
= NULL
;
276 if (device
->state
.vs
->lconstf
.ranges
) {
277 /* TODO: Can we make it so that we don't have to copy everything ? */
278 const struct nine_lconstf
*lconstf
= &device
->state
.vs
->lconstf
;
279 const struct nine_range
*r
= lconstf
->ranges
;
281 float *dst
= device
->state
.vs_lconstf_temp
;
282 float *src
= (float *)cb
.user_buffer
;
283 memcpy(dst
, src
, cb
.buffer_size
);
286 unsigned c
= r
->end
- r
->bgn
;
287 memcpy(&dst
[p
* 4], &lconstf
->data
[n
* 4], c
* 4 * sizeof(float));
291 cb
.user_buffer
= dst
;
294 if (!device
->driver_caps
.user_cbufs
) {
295 context
->pipe
.cb_vs
.buffer_size
= cb
.buffer_size
;
296 u_upload_data(device
->constbuf_uploader
,
299 device
->constbuf_alignment
,
301 &context
->pipe
.cb_vs
.buffer_offset
,
302 &context
->pipe
.cb_vs
.buffer
);
303 u_upload_unmap(device
->constbuf_uploader
);
304 context
->pipe
.cb_vs
.user_buffer
= NULL
;
306 context
->pipe
.cb_vs
= cb
;
308 if (device
->state
.changed
.vs_const_f
) {
309 struct nine_range
*r
= device
->state
.changed
.vs_const_f
;
310 struct nine_range
*p
= r
;
313 nine_range_pool_put_chain(&device
->range_pool
, r
, p
);
314 device
->state
.changed
.vs_const_f
= NULL
;
317 state
->changed
.group
&= ~NINE_STATE_VS_CONST
;
318 context
->commit
|= NINE_STATE_COMMIT_CONST_VS
;
322 prepare_ps_constants_userbuf(struct NineDevice9
*device
)
324 struct nine_state
*state
= &device
->state
;
325 struct nine_context
*context
= &device
->context
;
326 struct pipe_constant_buffer cb
;
328 cb
.buffer_offset
= 0;
329 cb
.buffer_size
= device
->state
.ps
->const_used_size
;
330 cb
.user_buffer
= device
->state
.ps_const_f
;
332 if (state
->changed
.ps_const_i
) {
333 int *idst
= (int *)&state
->ps_const_f
[4 * device
->max_ps_const_f
];
334 memcpy(idst
, state
->ps_const_i
, sizeof(state
->ps_const_i
));
335 state
->changed
.ps_const_i
= 0;
337 if (state
->changed
.ps_const_b
) {
338 int *idst
= (int *)&state
->ps_const_f
[4 * device
->max_ps_const_f
];
339 uint32_t *bdst
= (uint32_t *)&idst
[4 * NINE_MAX_CONST_I
];
340 memcpy(bdst
, state
->ps_const_b
, sizeof(state
->ps_const_b
));
341 state
->changed
.ps_const_b
= 0;
344 /* Upload special constants needed to implement PS1.x instructions like TEXBEM,TEXBEML and BEM */
345 if (device
->state
.ps
->bumpenvmat_needed
) {
346 memcpy(device
->state
.ps_lconstf_temp
, cb
.user_buffer
, cb
.buffer_size
);
347 memcpy(&device
->state
.ps_lconstf_temp
[4 * 8], &device
->context
.bumpmap_vars
, sizeof(device
->context
.bumpmap_vars
));
349 cb
.user_buffer
= device
->state
.ps_lconstf_temp
;
352 if (state
->ps
->byte_code
.version
< 0x30 &&
353 state
->rs
[D3DRS_FOGENABLE
]) {
354 float *dst
= &state
->ps_lconstf_temp
[4 * 32];
355 if (cb
.user_buffer
!= state
->ps_lconstf_temp
) {
356 memcpy(state
->ps_lconstf_temp
, cb
.user_buffer
, cb
.buffer_size
);
357 cb
.user_buffer
= state
->ps_lconstf_temp
;
360 d3dcolor_to_rgba(dst
, state
->rs
[D3DRS_FOGCOLOR
]);
361 if (state
->rs
[D3DRS_FOGTABLEMODE
] == D3DFOG_LINEAR
) {
362 dst
[4] = asfloat(state
->rs
[D3DRS_FOGEND
]);
363 dst
[5] = 1.0f
/ (asfloat(state
->rs
[D3DRS_FOGEND
]) - asfloat(state
->rs
[D3DRS_FOGSTART
]));
364 } else if (state
->rs
[D3DRS_FOGTABLEMODE
] != D3DFOG_NONE
) {
365 dst
[4] = asfloat(state
->rs
[D3DRS_FOGDENSITY
]);
367 cb
.buffer_size
= 4 * 4 * 34;
373 if (!device
->driver_caps
.user_cbufs
) {
374 context
->pipe
.cb_ps
.buffer_size
= cb
.buffer_size
;
375 u_upload_data(device
->constbuf_uploader
,
378 device
->constbuf_alignment
,
380 &context
->pipe
.cb_ps
.buffer_offset
,
381 &context
->pipe
.cb_ps
.buffer
);
382 u_upload_unmap(device
->constbuf_uploader
);
383 context
->pipe
.cb_ps
.user_buffer
= NULL
;
385 context
->pipe
.cb_ps
= cb
;
387 if (device
->state
.changed
.ps_const_f
) {
388 struct nine_range
*r
= device
->state
.changed
.ps_const_f
;
389 struct nine_range
*p
= r
;
392 nine_range_pool_put_chain(&device
->range_pool
, r
, p
);
393 device
->state
.changed
.ps_const_f
= NULL
;
395 state
->changed
.group
&= ~NINE_STATE_PS_CONST
;
396 context
->commit
|= NINE_STATE_COMMIT_CONST_PS
;
399 static inline uint32_t
400 prepare_vs(struct NineDevice9
*device
, uint8_t shader_changed
)
402 struct nine_state
*state
= &device
->state
;
403 struct nine_context
*context
= &device
->context
;
404 struct NineVertexShader9
*vs
= state
->vs
;
405 uint32_t changed_group
= 0;
406 int has_key_changed
= 0;
408 if (likely(state
->programmable_vs
))
409 has_key_changed
= NineVertexShader9_UpdateKey(vs
, device
);
411 if (!shader_changed
&& !has_key_changed
)
414 /* likely because we dislike FF */
415 if (likely(state
->programmable_vs
)) {
416 context
->cso
.vs
= NineVertexShader9_GetVariant(vs
);
419 context
->cso
.vs
= vs
->ff_cso
;
422 if (state
->rs
[NINED3DRS_VSPOINTSIZE
] != vs
->point_size
) {
423 state
->rs
[NINED3DRS_VSPOINTSIZE
] = vs
->point_size
;
424 changed_group
|= NINE_STATE_RASTERIZER
;
427 if ((context
->bound_samplers_mask_vs
& vs
->sampler_mask
) != vs
->sampler_mask
)
428 /* Bound dummy sampler. */
429 changed_group
|= NINE_STATE_SAMPLER
;
431 context
->commit
|= NINE_STATE_COMMIT_VS
;
432 return changed_group
;
435 static inline uint32_t
436 prepare_ps(struct NineDevice9
*device
, uint8_t shader_changed
)
438 struct nine_state
*state
= &device
->state
;
439 struct nine_context
*context
= &device
->context
;
440 struct NinePixelShader9
*ps
= state
->ps
;
441 uint32_t changed_group
= 0;
442 int has_key_changed
= 0;
445 has_key_changed
= NinePixelShader9_UpdateKey(ps
, state
);
447 if (!shader_changed
&& !has_key_changed
)
451 context
->cso
.ps
= NinePixelShader9_GetVariant(ps
);
454 context
->cso
.ps
= ps
->ff_cso
;
457 if ((context
->bound_samplers_mask_ps
& ps
->sampler_mask
) != ps
->sampler_mask
)
458 /* Bound dummy sampler. */
459 changed_group
|= NINE_STATE_SAMPLER
;
461 context
->commit
|= NINE_STATE_COMMIT_PS
;
462 return changed_group
;
465 /* State preparation incremental */
467 /* State preparation + State commit */
470 update_framebuffer(struct NineDevice9
*device
, bool is_clear
)
472 struct pipe_context
*pipe
= device
->pipe
;
473 struct nine_state
*state
= &device
->state
;
474 struct nine_context
*context
= &device
->context
;
475 struct pipe_framebuffer_state
*fb
= &context
->pipe
.fb
;
477 struct NineSurface9
*rt0
= state
->rt
[0];
478 unsigned w
= rt0
->desc
.Width
;
479 unsigned h
= rt0
->desc
.Height
;
480 unsigned nr_samples
= rt0
->base
.info
.nr_samples
;
481 unsigned ps_mask
= state
->ps
? state
->ps
->rt_mask
: 1;
482 unsigned mask
= is_clear
? 0xf : ps_mask
;
483 const int sRGB
= state
->rs
[D3DRS_SRGBWRITEENABLE
] ? 1 : 0;
487 context
->rt_mask
= 0x0;
490 /* all render targets must have the same size and the depth buffer must be
491 * bigger. Multisample has to match, according to spec. But some apps do
492 * things wrong there, and no error is returned. The behaviour they get
493 * apparently is that depth buffer is disabled if it doesn't match.
494 * Surely the same for render targets. */
496 /* Special case: D3DFMT_NULL is used to bound no real render target,
497 * but render to depth buffer. We have to not take into account the render
498 * target info. TODO: know what should happen when there are several render targers
499 * and the first one is D3DFMT_NULL */
500 if (rt0
->desc
.Format
== D3DFMT_NULL
&& state
->ds
) {
501 w
= state
->ds
->desc
.Width
;
502 h
= state
->ds
->desc
.Height
;
503 nr_samples
= state
->ds
->base
.info
.nr_samples
;
506 for (i
= 0; i
< device
->caps
.NumSimultaneousRTs
; ++i
) {
507 struct NineSurface9
*rt
= state
->rt
[i
];
509 if (rt
&& rt
->desc
.Format
!= D3DFMT_NULL
&& (mask
& (1 << i
)) &&
510 rt
->desc
.Width
== w
&& rt
->desc
.Height
== h
&&
511 rt
->base
.info
.nr_samples
== nr_samples
) {
512 fb
->cbufs
[i
] = NineSurface9_GetSurface(rt
, sRGB
);
513 context
->rt_mask
|= 1 << i
;
514 fb
->nr_cbufs
= i
+ 1;
516 if (unlikely(rt
->desc
.Usage
& D3DUSAGE_AUTOGENMIPMAP
)) {
517 assert(rt
->texture
== D3DRTYPE_TEXTURE
||
518 rt
->texture
== D3DRTYPE_CUBETEXTURE
);
519 NineBaseTexture9(rt
->base
.base
.container
)->dirty_mip
= TRUE
;
522 /* Color outputs must match RT slot,
523 * drivers will have to handle NULL entries for GL, too.
529 if (state
->ds
&& state
->ds
->desc
.Width
>= w
&&
530 state
->ds
->desc
.Height
>= h
&&
531 state
->ds
->base
.info
.nr_samples
== nr_samples
) {
532 fb
->zsbuf
= NineSurface9_GetSurface(state
->ds
, 0);
540 pipe
->set_framebuffer_state(pipe
, fb
); /* XXX: cso ? */
542 if (is_clear
&& context
->rt_mask
== ps_mask
)
543 state
->changed
.group
&= ~NINE_STATE_FB
;
547 update_viewport(struct NineDevice9
*device
)
549 const D3DVIEWPORT9
*vport
= &device
->state
.viewport
;
550 struct pipe_viewport_state pvport
;
552 /* D3D coordinates are:
553 * -1 .. +1 for X,Y and
554 * 0 .. +1 for Z (we use pipe_rasterizer_state.clip_halfz)
556 pvport
.scale
[0] = (float)vport
->Width
* 0.5f
;
557 pvport
.scale
[1] = (float)vport
->Height
* -0.5f
;
558 pvport
.scale
[2] = vport
->MaxZ
- vport
->MinZ
;
559 pvport
.translate
[0] = (float)vport
->Width
* 0.5f
+ (float)vport
->X
;
560 pvport
.translate
[1] = (float)vport
->Height
* 0.5f
+ (float)vport
->Y
;
561 pvport
.translate
[2] = vport
->MinZ
;
563 /* We found R600 and SI cards have some imprecision
564 * on the barycentric coordinates used for interpolation.
565 * Some shaders rely on having something precise.
566 * We found that the proprietary driver has the imprecision issue,
567 * except when the render target width and height are powers of two.
568 * It is using some sort of workaround for these cases
569 * which covers likely all the cases the applications rely
570 * on something precise.
571 * We haven't found the workaround, but it seems like it's better
572 * for applications if the imprecision is biased towards infinity
573 * instead of -infinity (which is what measured). So shift slightly
574 * the viewport: not enough to change rasterization result (in particular
575 * for multisampling), but enough to make the imprecision biased
576 * towards infinity. We do this shift only if render target width and
577 * height are powers of two.
578 * Solves 'red shadows' bug on UE3 games.
580 if (device
->driver_bugs
.buggy_barycentrics
&&
581 ((vport
->Width
& (vport
->Width
-1)) == 0) &&
582 ((vport
->Height
& (vport
->Height
-1)) == 0)) {
583 pvport
.translate
[0] -= 1.0f
/ 128.0f
;
584 pvport
.translate
[1] -= 1.0f
/ 128.0f
;
587 cso_set_viewport(device
->cso
, &pvport
);
590 /* Loop through VS inputs and pick the vertex elements with the declared
591 * usage from the vertex declaration, then insert the instance divisor from
592 * the stream source frequency setting.
595 update_vertex_elements(struct NineDevice9
*device
)
597 struct nine_state
*state
= &device
->state
;
598 struct nine_context
*context
= &device
->context
;
599 const struct NineVertexDeclaration9
*vdecl
= device
->state
.vdecl
;
600 const struct NineVertexShader9
*vs
;
603 char vdecl_index_map
[16]; /* vs->num_inputs <= 16 */
604 char used_streams
[device
->caps
.MaxStreams
];
605 int dummy_vbo_stream
= -1;
606 BOOL need_dummy_vbo
= FALSE
;
607 struct pipe_vertex_element ve
[PIPE_MAX_ATTRIBS
];
609 state
->stream_usage_mask
= 0;
610 memset(vdecl_index_map
, -1, 16);
611 memset(used_streams
, 0, device
->caps
.MaxStreams
);
612 vs
= state
->programmable_vs
? device
->state
.vs
: device
->ff
.vs
;
615 for (n
= 0; n
< vs
->num_inputs
; ++n
) {
616 DBG("looking up input %u (usage %u) from vdecl(%p)\n",
617 n
, vs
->input_map
[n
].ndecl
, vdecl
);
619 for (i
= 0; i
< vdecl
->nelems
; i
++) {
620 if (vdecl
->usage_map
[i
] == vs
->input_map
[n
].ndecl
) {
621 vdecl_index_map
[n
] = i
;
622 used_streams
[vdecl
->elems
[i
].vertex_buffer_index
] = 1;
626 if (vdecl_index_map
[n
] < 0)
627 need_dummy_vbo
= TRUE
;
630 /* No vertex declaration. Likely will never happen in practice,
631 * but we need not crash on this */
632 need_dummy_vbo
= TRUE
;
635 if (need_dummy_vbo
) {
636 for (i
= 0; i
< device
->caps
.MaxStreams
; i
++ ) {
637 if (!used_streams
[i
]) {
638 dummy_vbo_stream
= i
;
643 /* there are less vertex shader inputs than stream slots,
644 * so if we need a slot for the dummy vbo, we should have found one */
645 assert (!need_dummy_vbo
|| dummy_vbo_stream
!= -1);
647 for (n
= 0; n
< vs
->num_inputs
; ++n
) {
648 index
= vdecl_index_map
[n
];
650 ve
[n
] = vdecl
->elems
[index
];
651 b
= ve
[n
].vertex_buffer_index
;
652 state
->stream_usage_mask
|= 1 << b
;
653 /* XXX wine just uses 1 here: */
654 if (state
->stream_freq
[b
] & D3DSTREAMSOURCE_INSTANCEDATA
)
655 ve
[n
].instance_divisor
= state
->stream_freq
[b
] & 0x7FFFFF;
657 /* if the vertex declaration is incomplete compared to what the
658 * vertex shader needs, we bind a dummy vbo with 0 0 0 0.
659 * This is not precised by the spec, but is the behaviour
661 ve
[n
].vertex_buffer_index
= dummy_vbo_stream
;
662 ve
[n
].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
663 ve
[n
].src_offset
= 0;
664 ve
[n
].instance_divisor
= 0;
668 if (context
->dummy_vbo_bound_at
!= dummy_vbo_stream
) {
669 if (context
->dummy_vbo_bound_at
>= 0)
670 state
->changed
.vtxbuf
|= 1 << context
->dummy_vbo_bound_at
;
671 if (dummy_vbo_stream
>= 0) {
672 state
->changed
.vtxbuf
|= 1 << dummy_vbo_stream
;
673 context
->vbo_bound_done
= FALSE
;
675 context
->dummy_vbo_bound_at
= dummy_vbo_stream
;
678 cso_set_vertex_elements(device
->cso
, vs
->num_inputs
, ve
);
680 state
->changed
.stream_freq
= 0;
684 update_vertex_buffers(struct NineDevice9
*device
)
686 struct pipe_context
*pipe
= device
->pipe
;
687 struct nine_context
*context
= &device
->context
;
688 struct nine_state
*state
= &device
->state
;
689 struct pipe_vertex_buffer dummy_vtxbuf
;
690 uint32_t mask
= state
->changed
.vtxbuf
;
693 DBG("mask=%x\n", mask
);
695 if (context
->dummy_vbo_bound_at
>= 0) {
696 if (!context
->vbo_bound_done
) {
697 dummy_vtxbuf
.buffer
= device
->dummy_vbo
;
698 dummy_vtxbuf
.stride
= 0;
699 dummy_vtxbuf
.user_buffer
= NULL
;
700 dummy_vtxbuf
.buffer_offset
= 0;
701 pipe
->set_vertex_buffers(pipe
, context
->dummy_vbo_bound_at
,
703 context
->vbo_bound_done
= TRUE
;
705 mask
&= ~(1 << context
->dummy_vbo_bound_at
);
708 for (i
= 0; mask
; mask
>>= 1, ++i
) {
710 if (state
->vtxbuf
[i
].buffer
)
711 pipe
->set_vertex_buffers(pipe
, i
, 1, &state
->vtxbuf
[i
]);
713 pipe
->set_vertex_buffers(pipe
, i
, 1, NULL
);
717 state
->changed
.vtxbuf
= 0;
720 static inline boolean
721 update_sampler_derived(struct nine_state
*state
, unsigned s
)
723 boolean changed
= FALSE
;
725 if (state
->samp
[s
][NINED3DSAMP_SHADOW
] != state
->texture
[s
]->shadow
) {
727 state
->samp
[s
][NINED3DSAMP_SHADOW
] = state
->texture
[s
]->shadow
;
730 if (state
->samp
[s
][NINED3DSAMP_CUBETEX
] !=
731 (NineResource9(state
->texture
[s
])->type
== D3DRTYPE_CUBETEXTURE
)) {
733 state
->samp
[s
][NINED3DSAMP_CUBETEX
] =
734 NineResource9(state
->texture
[s
])->type
== D3DRTYPE_CUBETEXTURE
;
737 if (state
->samp
[s
][D3DSAMP_MIPFILTER
] != D3DTEXF_NONE
) {
738 int lod
= state
->samp
[s
][D3DSAMP_MAXMIPLEVEL
] - state
->texture
[s
]->managed
.lod
;
741 if (state
->samp
[s
][NINED3DSAMP_MINLOD
] != lod
) {
743 state
->samp
[s
][NINED3DSAMP_MINLOD
] = lod
;
746 state
->changed
.sampler
[s
] &= ~0x300; /* lod changes irrelevant */
752 /* TODO: add sRGB override to pipe_sampler_state ? */
754 update_textures_and_samplers(struct NineDevice9
*device
)
756 struct nine_state
*state
= &device
->state
;
757 struct nine_context
*context
= &device
->context
;
758 struct pipe_sampler_view
*view
[NINE_MAX_SAMPLERS
];
759 unsigned num_textures
;
761 boolean commit_samplers
;
762 uint16_t sampler_mask
= state
->ps
? state
->ps
->sampler_mask
:
763 device
->ff
.ps
->sampler_mask
;
765 /* TODO: Can we reduce iterations here ? */
767 commit_samplers
= FALSE
;
768 context
->bound_samplers_mask_ps
= 0;
769 for (num_textures
= 0, i
= 0; i
< NINE_MAX_SAMPLERS_PS
; ++i
) {
770 const unsigned s
= NINE_SAMPLER_PS(i
);
773 if (!state
->texture
[s
] && !(sampler_mask
& (1 << i
))) {
778 if (state
->texture
[s
]) {
779 sRGB
= state
->samp
[s
][D3DSAMP_SRGBTEXTURE
] ? 1 : 0;
781 view
[i
] = NineBaseTexture9_GetSamplerView(state
->texture
[s
], sRGB
);
782 num_textures
= i
+ 1;
784 if (update_sampler_derived(state
, s
) || (state
->changed
.sampler
[s
] & 0x05fe)) {
785 state
->changed
.sampler
[s
] = 0;
786 commit_samplers
= TRUE
;
787 nine_convert_sampler_state(device
->cso
, s
, state
->samp
[s
]);
790 /* Bind dummy sampler. We do not bind dummy sampler when
791 * it is not needed because it could add overhead. The
792 * dummy sampler should have r=g=b=0 and a=1. We do not
793 * unbind dummy sampler directly when they are not needed
794 * anymore, but they're going to be removed as long as texture
795 * or sampler states are changed. */
796 view
[i
] = device
->dummy_sampler_view
;
797 num_textures
= i
+ 1;
799 cso_single_sampler(device
->cso
, PIPE_SHADER_FRAGMENT
,
800 s
- NINE_SAMPLER_PS(0), &device
->dummy_sampler_state
);
802 commit_samplers
= TRUE
;
803 state
->changed
.sampler
[s
] = ~0;
806 context
->bound_samplers_mask_ps
|= (1 << s
);
809 cso_set_sampler_views(device
->cso
, PIPE_SHADER_FRAGMENT
, num_textures
, view
);
812 cso_single_sampler_done(device
->cso
, PIPE_SHADER_FRAGMENT
);
814 commit_samplers
= FALSE
;
815 sampler_mask
= state
->programmable_vs
? state
->vs
->sampler_mask
: 0;
816 context
->bound_samplers_mask_vs
= 0;
817 for (num_textures
= 0, i
= 0; i
< NINE_MAX_SAMPLERS_VS
; ++i
) {
818 const unsigned s
= NINE_SAMPLER_VS(i
);
821 if (!state
->texture
[s
] && !(sampler_mask
& (1 << i
))) {
826 if (state
->texture
[s
]) {
827 sRGB
= state
->samp
[s
][D3DSAMP_SRGBTEXTURE
] ? 1 : 0;
829 view
[i
] = NineBaseTexture9_GetSamplerView(state
->texture
[s
], sRGB
);
830 num_textures
= i
+ 1;
832 if (update_sampler_derived(state
, s
) || (state
->changed
.sampler
[s
] & 0x05fe)) {
833 state
->changed
.sampler
[s
] = 0;
834 commit_samplers
= TRUE
;
835 nine_convert_sampler_state(device
->cso
, s
, state
->samp
[s
]);
838 /* Bind dummy sampler. We do not bind dummy sampler when
839 * it is not needed because it could add overhead. The
840 * dummy sampler should have r=g=b=0 and a=1. We do not
841 * unbind dummy sampler directly when they are not needed
842 * anymore, but they're going to be removed as long as texture
843 * or sampler states are changed. */
844 view
[i
] = device
->dummy_sampler_view
;
845 num_textures
= i
+ 1;
847 cso_single_sampler(device
->cso
, PIPE_SHADER_VERTEX
,
848 s
- NINE_SAMPLER_VS(0), &device
->dummy_sampler_state
);
850 commit_samplers
= TRUE
;
851 state
->changed
.sampler
[s
] = ~0;
854 context
->bound_samplers_mask_vs
|= (1 << s
);
857 cso_set_sampler_views(device
->cso
, PIPE_SHADER_VERTEX
, num_textures
, view
);
860 cso_single_sampler_done(device
->cso
, PIPE_SHADER_VERTEX
);
862 state
->changed
.texture
= 0;
865 /* State commit only */
868 commit_blend(struct NineDevice9
*device
)
870 cso_set_blend(device
->cso
, &device
->context
.pipe
.blend
);
874 commit_dsa(struct NineDevice9
*device
)
876 cso_set_depth_stencil_alpha(device
->cso
, &device
->context
.pipe
.dsa
);
880 commit_scissor(struct NineDevice9
*device
)
882 struct pipe_context
*pipe
= device
->pipe
;
884 pipe
->set_scissor_states(pipe
, 0, 1, &device
->state
.scissor
);
888 commit_rasterizer(struct NineDevice9
*device
)
890 cso_set_rasterizer(device
->cso
, &device
->context
.pipe
.rast
);
894 commit_index_buffer(struct NineDevice9
*device
)
896 struct pipe_context
*pipe
= device
->pipe
;
897 if (device
->state
.idxbuf
)
898 pipe
->set_index_buffer(pipe
, &device
->state
.idxbuf
->buffer
);
900 pipe
->set_index_buffer(pipe
, NULL
);
904 commit_vs_constants(struct NineDevice9
*device
)
906 struct pipe_context
*pipe
= device
->pipe
;
908 if (unlikely(!device
->state
.programmable_vs
))
909 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_VERTEX
, 0, &device
->context
.pipe
.cb_vs_ff
);
912 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_VERTEX
, 0, &device
->context
.pipe
.cb0_swvp
);
913 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_VERTEX
, 1, &device
->context
.pipe
.cb1_swvp
);
914 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_VERTEX
, 2, &device
->context
.pipe
.cb2_swvp
);
915 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_VERTEX
, 3, &device
->context
.pipe
.cb3_swvp
);
917 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_VERTEX
, 0, &device
->context
.pipe
.cb_vs
);
923 commit_ps_constants(struct NineDevice9
*device
)
925 struct pipe_context
*pipe
= device
->pipe
;
927 if (unlikely(!device
->state
.ps
))
928 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_FRAGMENT
, 0, &device
->context
.pipe
.cb_ps_ff
);
930 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_FRAGMENT
, 0, &device
->context
.pipe
.cb_ps
);
934 commit_vs(struct NineDevice9
*device
)
936 struct nine_context
*context
= &device
->context
;
938 device
->pipe
->bind_vs_state(device
->pipe
, context
->cso
.vs
);
943 commit_ps(struct NineDevice9
*device
)
945 struct nine_context
*context
= &device
->context
;
947 device
->pipe
->bind_fs_state(device
->pipe
, context
->cso
.ps
);
951 #define NINE_STATE_SHADER_CHANGE_VS \
953 NINE_STATE_TEXTURE | \
954 NINE_STATE_FOG_SHADER | \
955 NINE_STATE_POINTSIZE_SHADER | \
958 #define NINE_STATE_SHADER_CHANGE_PS \
960 NINE_STATE_TEXTURE | \
961 NINE_STATE_FOG_SHADER | \
962 NINE_STATE_PS1X_SHADER)
964 #define NINE_STATE_FREQUENT \
965 (NINE_STATE_RASTERIZER | \
966 NINE_STATE_TEXTURE | \
967 NINE_STATE_SAMPLER | \
968 NINE_STATE_VS_CONST | \
969 NINE_STATE_PS_CONST | \
970 NINE_STATE_MULTISAMPLE)
972 #define NINE_STATE_COMMON \
976 NINE_STATE_VIEWPORT | \
978 NINE_STATE_IDXBUF | \
979 NINE_STATE_STREAMFREQ)
981 #define NINE_STATE_RARE \
982 (NINE_STATE_SCISSOR | \
983 NINE_STATE_BLEND_COLOR | \
984 NINE_STATE_STENCIL_REF | \
985 NINE_STATE_SAMPLE_MASK)
988 /* TODO: only go through dirty textures */
990 validate_textures(struct NineDevice9
*device
)
992 struct NineBaseTexture9
*tex
, *ptr
;
993 LIST_FOR_EACH_ENTRY_SAFE(tex
, ptr
, &device
->update_textures
, list
) {
994 list_delinit(&tex
->list
);
995 NineBaseTexture9_Validate(tex
);
1000 update_managed_buffers(struct NineDevice9
*device
)
1002 struct NineBuffer9
*buf
, *ptr
;
1003 LIST_FOR_EACH_ENTRY_SAFE(buf
, ptr
, &device
->update_buffers
, managed
.list
) {
1004 list_delinit(&buf
->managed
.list
);
1005 NineBuffer9_Upload(buf
);
1010 nine_update_state(struct NineDevice9
*device
)
1012 struct pipe_context
*pipe
= device
->pipe
;
1013 struct nine_state
*state
= &device
->state
;
1014 struct nine_context
*context
= &device
->context
;
1017 DBG("changed state groups: %x\n", state
->changed
.group
);
1019 /* NOTE: We may want to use the cso cache for everything, or let
1020 * NineDevice9.RestoreNonCSOState actually set the states, then we wouldn't
1021 * have to care about state being clobbered here and could merge this back
1022 * into update_textures. Except, we also need to re-validate textures that
1023 * may be dirty anyway, even if no texture bindings changed.
1025 validate_textures(device
); /* may clobber state */
1026 update_managed_buffers(device
);
1028 /* ff_update may change VS/PS dirty bits */
1029 if (unlikely(!state
->programmable_vs
|| !state
->ps
))
1030 nine_ff_update(device
);
1031 group
= state
->changed
.group
;
1033 if (group
& (NINE_STATE_SHADER_CHANGE_VS
| NINE_STATE_SHADER_CHANGE_PS
)) {
1034 if (group
& NINE_STATE_SHADER_CHANGE_VS
)
1035 group
|= prepare_vs(device
, (group
& NINE_STATE_VS
) != 0); /* may set NINE_STATE_RASTERIZER and NINE_STATE_SAMPLER*/
1036 if (group
& NINE_STATE_SHADER_CHANGE_PS
)
1037 group
|= prepare_ps(device
, (group
& NINE_STATE_PS
) != 0);
1040 if (group
& (NINE_STATE_COMMON
| NINE_STATE_VS
)) {
1041 if (group
& NINE_STATE_FB
)
1042 update_framebuffer(device
, FALSE
);
1043 if (group
& NINE_STATE_BLEND
)
1044 prepare_blend(device
);
1045 if (group
& NINE_STATE_DSA
)
1046 prepare_dsa(device
);
1047 if (group
& NINE_STATE_VIEWPORT
)
1048 update_viewport(device
);
1049 if (group
& (NINE_STATE_VDECL
| NINE_STATE_VS
| NINE_STATE_STREAMFREQ
))
1050 update_vertex_elements(device
);
1051 if (group
& NINE_STATE_IDXBUF
)
1052 commit_index_buffer(device
);
1055 if (likely(group
& (NINE_STATE_FREQUENT
| NINE_STATE_VS
| NINE_STATE_PS
| NINE_STATE_SWVP
))) {
1056 if (group
& NINE_STATE_MULTISAMPLE
)
1057 group
|= check_multisample(device
);
1058 if (group
& NINE_STATE_RASTERIZER
)
1059 prepare_rasterizer(device
);
1060 if (group
& (NINE_STATE_TEXTURE
| NINE_STATE_SAMPLER
))
1061 update_textures_and_samplers(device
);
1062 if ((group
& (NINE_STATE_VS_CONST
| NINE_STATE_VS
| NINE_STATE_SWVP
)) && state
->programmable_vs
)
1063 prepare_vs_constants_userbuf(device
);
1064 if ((group
& (NINE_STATE_PS_CONST
| NINE_STATE_PS
)) && state
->ps
)
1065 prepare_ps_constants_userbuf(device
);
1068 if (state
->changed
.vtxbuf
)
1069 update_vertex_buffers(device
);
1071 if (context
->commit
& NINE_STATE_COMMIT_BLEND
)
1072 commit_blend(device
);
1073 if (context
->commit
& NINE_STATE_COMMIT_DSA
)
1075 if (context
->commit
& NINE_STATE_COMMIT_RASTERIZER
)
1076 commit_rasterizer(device
);
1077 if (context
->commit
& NINE_STATE_COMMIT_CONST_VS
)
1078 commit_vs_constants(device
);
1079 if (context
->commit
& NINE_STATE_COMMIT_CONST_PS
)
1080 commit_ps_constants(device
);
1081 if (context
->commit
& NINE_STATE_COMMIT_VS
)
1083 if (context
->commit
& NINE_STATE_COMMIT_PS
)
1086 context
->commit
= 0;
1088 if (unlikely(state
->changed
.ucp
)) {
1089 pipe
->set_clip_state(pipe
, &state
->clip
);
1090 state
->changed
.ucp
= 0;
1093 if (unlikely(group
& NINE_STATE_RARE
)) {
1094 if (group
& NINE_STATE_SCISSOR
)
1095 commit_scissor(device
);
1096 if (group
& NINE_STATE_BLEND_COLOR
) {
1097 struct pipe_blend_color color
;
1098 d3dcolor_to_rgba(&color
.color
[0], state
->rs
[D3DRS_BLENDFACTOR
]);
1099 pipe
->set_blend_color(pipe
, &color
);
1101 if (group
& NINE_STATE_SAMPLE_MASK
) {
1102 if (state
->rt
[0]->desc
.MultiSampleType
<= D3DMULTISAMPLE_NONMASKABLE
) {
1103 pipe
->set_sample_mask(pipe
, ~0);
1105 pipe
->set_sample_mask(pipe
, state
->rs
[D3DRS_MULTISAMPLEMASK
]);
1108 if (group
& NINE_STATE_STENCIL_REF
) {
1109 struct pipe_stencil_ref ref
;
1110 ref
.ref_value
[0] = state
->rs
[D3DRS_STENCILREF
];
1111 ref
.ref_value
[1] = ref
.ref_value
[0];
1112 pipe
->set_stencil_ref(pipe
, &ref
);
1116 device
->state
.changed
.group
&=
1117 (NINE_STATE_FF
| NINE_STATE_VS_CONST
| NINE_STATE_PS_CONST
);
1125 nine_update_state_framebuffer_clear(struct NineDevice9
*device
)
1127 struct nine_state
*state
= &device
->state
;
1129 validate_textures(device
);
1131 if (state
->changed
.group
& NINE_STATE_FB
)
1132 update_framebuffer(device
, TRUE
);
1135 /* Checks were already done before the call */
1137 nine_context_clear_fb(struct NineDevice9
*device
,
1139 const D3DRECT
*pRects
,
1145 const int sRGB
= device
->state
.rs
[D3DRS_SRGBWRITEENABLE
] ? 1 : 0;
1146 struct pipe_surface
*cbuf
, *zsbuf
;
1147 struct pipe_context
*pipe
= device
->pipe
;
1148 struct NineSurface9
*zsbuf_surf
= device
->state
.ds
;
1149 struct NineSurface9
*rt
;
1152 union pipe_color_union rgba
;
1153 unsigned rt_mask
= 0;
1156 nine_update_state_framebuffer_clear(device
);
1158 if (Flags
& D3DCLEAR_TARGET
) bufs
|= PIPE_CLEAR_COLOR
;
1159 /* Ignore Z buffer if not bound */
1160 if (device
->context
.pipe
.fb
.zsbuf
!= NULL
) {
1161 if (Flags
& D3DCLEAR_ZBUFFER
) bufs
|= PIPE_CLEAR_DEPTH
;
1162 if (Flags
& D3DCLEAR_STENCIL
) bufs
|= PIPE_CLEAR_STENCIL
;
1166 d3dcolor_to_pipe_color_union(&rgba
, Color
);
1168 rect
.x1
= device
->state
.viewport
.X
;
1169 rect
.y1
= device
->state
.viewport
.Y
;
1170 rect
.x2
= device
->state
.viewport
.Width
+ rect
.x1
;
1171 rect
.y2
= device
->state
.viewport
.Height
+ rect
.y1
;
1173 /* Both rectangles apply, which is weird, but that's D3D9. */
1174 if (device
->state
.rs
[D3DRS_SCISSORTESTENABLE
]) {
1175 rect
.x1
= MAX2(rect
.x1
, device
->state
.scissor
.minx
);
1176 rect
.y1
= MAX2(rect
.y1
, device
->state
.scissor
.miny
);
1177 rect
.x2
= MIN2(rect
.x2
, device
->state
.scissor
.maxx
);
1178 rect
.y2
= MIN2(rect
.y2
, device
->state
.scissor
.maxy
);
1182 /* Maybe apps like to specify a large rect ? */
1183 if (pRects
[0].x1
<= rect
.x1
&& pRects
[0].x2
>= rect
.x2
&&
1184 pRects
[0].y1
<= rect
.y1
&& pRects
[0].y2
>= rect
.y2
) {
1185 DBG("First rect covers viewport.\n");
1191 if (rect
.x1
>= device
->context
.pipe
.fb
.width
|| rect
.y1
>= device
->context
.pipe
.fb
.height
)
1194 for (i
= 0; i
< device
->caps
.NumSimultaneousRTs
; ++i
) {
1195 if (device
->state
.rt
[i
] && device
->state
.rt
[i
]->desc
.Format
!= D3DFMT_NULL
)
1199 /* fast path, clears everything at once */
1201 (!(bufs
& PIPE_CLEAR_COLOR
) || (rt_mask
== device
->context
.rt_mask
)) &&
1202 rect
.x1
== 0 && rect
.y1
== 0 &&
1203 /* Case we clear only render target. Check clear region vs rt. */
1204 ((!(bufs
& (PIPE_CLEAR_DEPTH
| PIPE_CLEAR_STENCIL
)) &&
1205 rect
.x2
>= device
->context
.pipe
.fb
.width
&&
1206 rect
.y2
>= device
->context
.pipe
.fb
.height
) ||
1207 /* Case we clear depth buffer (and eventually rt too).
1208 * depth buffer size is always >= rt size. Compare to clear region */
1209 ((bufs
& (PIPE_CLEAR_DEPTH
| PIPE_CLEAR_STENCIL
)) &&
1210 rect
.x2
>= zsbuf_surf
->desc
.Width
&&
1211 rect
.y2
>= zsbuf_surf
->desc
.Height
))) {
1212 DBG("Clear fast path\n");
1213 pipe
->clear(pipe
, bufs
, &rgba
, Z
, Stencil
);
1222 for (i
= 0; i
< device
->caps
.NumSimultaneousRTs
; ++i
) {
1223 rt
= device
->state
.rt
[i
];
1224 if (!rt
|| rt
->desc
.Format
== D3DFMT_NULL
||
1225 !(bufs
& PIPE_CLEAR_COLOR
))
1226 continue; /* save space, compiler should hoist this */
1227 cbuf
= NineSurface9_GetSurface(rt
, sRGB
);
1228 for (r
= 0; r
< Count
; ++r
) {
1229 /* Don't trust users to pass these in the right order. */
1230 unsigned x1
= MIN2(pRects
[r
].x1
, pRects
[r
].x2
);
1231 unsigned y1
= MIN2(pRects
[r
].y1
, pRects
[r
].y2
);
1232 unsigned x2
= MAX2(pRects
[r
].x1
, pRects
[r
].x2
);
1233 unsigned y2
= MAX2(pRects
[r
].y1
, pRects
[r
].y2
);
1235 /* Drop negative rectangles (like wine expects). */
1236 if (pRects
[r
].x1
> pRects
[r
].x2
) continue;
1237 if (pRects
[r
].y1
> pRects
[r
].y2
) continue;
1240 x1
= MAX2(x1
, rect
.x1
);
1241 y1
= MAX2(y1
, rect
.y1
);
1242 x2
= MIN3(x2
, rect
.x2
, rt
->desc
.Width
);
1243 y2
= MIN3(y2
, rect
.y2
, rt
->desc
.Height
);
1245 DBG("Clearing (%u..%u)x(%u..%u)\n", x1
, x2
, y1
, y2
);
1246 pipe
->clear_render_target(pipe
, cbuf
, &rgba
,
1247 x1
, y1
, x2
- x1
, y2
- y1
, false);
1250 if (!(bufs
& PIPE_CLEAR_DEPTHSTENCIL
))
1253 bufs
&= PIPE_CLEAR_DEPTHSTENCIL
;
1255 for (r
= 0; r
< Count
; ++r
) {
1256 unsigned x1
= MIN2(pRects
[r
].x1
, pRects
[r
].x2
);
1257 unsigned y1
= MIN2(pRects
[r
].y1
, pRects
[r
].y2
);
1258 unsigned x2
= MAX2(pRects
[r
].x1
, pRects
[r
].x2
);
1259 unsigned y2
= MAX2(pRects
[r
].y1
, pRects
[r
].y2
);
1261 /* Drop negative rectangles. */
1262 if (pRects
[r
].x1
> pRects
[r
].x2
) continue;
1263 if (pRects
[r
].y1
> pRects
[r
].y2
) continue;
1266 x1
= MIN2(x1
, rect
.x1
);
1267 y1
= MIN2(y1
, rect
.y1
);
1268 x2
= MIN3(x2
, rect
.x2
, zsbuf_surf
->desc
.Width
);
1269 y2
= MIN3(y2
, rect
.y2
, zsbuf_surf
->desc
.Height
);
1271 zsbuf
= NineSurface9_GetSurface(zsbuf_surf
, 0);
1273 pipe
->clear_depth_stencil(pipe
, zsbuf
, bufs
, Z
, Stencil
,
1274 x1
, y1
, x2
- x1
, y2
- y1
, false);
1279 /* State defaults */
1281 static const DWORD nine_render_state_defaults
[NINED3DRS_LAST
+ 1] =
1283 /* [D3DRS_ZENABLE] = D3DZB_TRUE; wine: auto_depth_stencil */
1284 [D3DRS_ZENABLE
] = D3DZB_FALSE
,
1285 [D3DRS_FILLMODE
] = D3DFILL_SOLID
,
1286 [D3DRS_SHADEMODE
] = D3DSHADE_GOURAUD
,
1287 /* [D3DRS_LINEPATTERN] = 0x00000000, */
1288 [D3DRS_ZWRITEENABLE
] = TRUE
,
1289 [D3DRS_ALPHATESTENABLE
] = FALSE
,
1290 [D3DRS_LASTPIXEL
] = TRUE
,
1291 [D3DRS_SRCBLEND
] = D3DBLEND_ONE
,
1292 [D3DRS_DESTBLEND
] = D3DBLEND_ZERO
,
1293 [D3DRS_CULLMODE
] = D3DCULL_CCW
,
1294 [D3DRS_ZFUNC
] = D3DCMP_LESSEQUAL
,
1295 [D3DRS_ALPHAFUNC
] = D3DCMP_ALWAYS
,
1296 [D3DRS_ALPHAREF
] = 0,
1297 [D3DRS_DITHERENABLE
] = FALSE
,
1298 [D3DRS_ALPHABLENDENABLE
] = FALSE
,
1299 [D3DRS_FOGENABLE
] = FALSE
,
1300 [D3DRS_SPECULARENABLE
] = FALSE
,
1301 /* [D3DRS_ZVISIBLE] = 0, */
1302 [D3DRS_FOGCOLOR
] = 0,
1303 [D3DRS_FOGTABLEMODE
] = D3DFOG_NONE
,
1304 [D3DRS_FOGSTART
] = 0x00000000,
1305 [D3DRS_FOGEND
] = 0x3F800000,
1306 [D3DRS_FOGDENSITY
] = 0x3F800000,
1307 /* [D3DRS_EDGEANTIALIAS] = FALSE, */
1308 [D3DRS_RANGEFOGENABLE
] = FALSE
,
1309 [D3DRS_STENCILENABLE
] = FALSE
,
1310 [D3DRS_STENCILFAIL
] = D3DSTENCILOP_KEEP
,
1311 [D3DRS_STENCILZFAIL
] = D3DSTENCILOP_KEEP
,
1312 [D3DRS_STENCILPASS
] = D3DSTENCILOP_KEEP
,
1313 [D3DRS_STENCILREF
] = 0,
1314 [D3DRS_STENCILMASK
] = 0xFFFFFFFF,
1315 [D3DRS_STENCILFUNC
] = D3DCMP_ALWAYS
,
1316 [D3DRS_STENCILWRITEMASK
] = 0xFFFFFFFF,
1317 [D3DRS_TEXTUREFACTOR
] = 0xFFFFFFFF,
1326 [D3DRS_CLIPPING
] = TRUE
,
1327 [D3DRS_LIGHTING
] = TRUE
,
1328 [D3DRS_AMBIENT
] = 0,
1329 [D3DRS_FOGVERTEXMODE
] = D3DFOG_NONE
,
1330 [D3DRS_COLORVERTEX
] = TRUE
,
1331 [D3DRS_LOCALVIEWER
] = TRUE
,
1332 [D3DRS_NORMALIZENORMALS
] = FALSE
,
1333 [D3DRS_DIFFUSEMATERIALSOURCE
] = D3DMCS_COLOR1
,
1334 [D3DRS_SPECULARMATERIALSOURCE
] = D3DMCS_COLOR2
,
1335 [D3DRS_AMBIENTMATERIALSOURCE
] = D3DMCS_MATERIAL
,
1336 [D3DRS_EMISSIVEMATERIALSOURCE
] = D3DMCS_MATERIAL
,
1337 [D3DRS_VERTEXBLEND
] = D3DVBF_DISABLE
,
1338 [D3DRS_CLIPPLANEENABLE
] = 0,
1339 /* [D3DRS_SOFTWAREVERTEXPROCESSING] = FALSE, */
1340 [D3DRS_POINTSIZE
] = 0x3F800000,
1341 [D3DRS_POINTSIZE_MIN
] = 0x3F800000,
1342 [D3DRS_POINTSPRITEENABLE
] = FALSE
,
1343 [D3DRS_POINTSCALEENABLE
] = FALSE
,
1344 [D3DRS_POINTSCALE_A
] = 0x3F800000,
1345 [D3DRS_POINTSCALE_B
] = 0x00000000,
1346 [D3DRS_POINTSCALE_C
] = 0x00000000,
1347 [D3DRS_MULTISAMPLEANTIALIAS
] = TRUE
,
1348 [D3DRS_MULTISAMPLEMASK
] = 0xFFFFFFFF,
1349 [D3DRS_PATCHEDGESTYLE
] = D3DPATCHEDGE_DISCRETE
,
1350 /* [D3DRS_PATCHSEGMENTS] = 0x3F800000, */
1351 [D3DRS_DEBUGMONITORTOKEN
] = 0xDEADCAFE,
1352 [D3DRS_POINTSIZE_MAX
] = 0x3F800000, /* depends on cap */
1353 [D3DRS_INDEXEDVERTEXBLENDENABLE
] = FALSE
,
1354 [D3DRS_COLORWRITEENABLE
] = 0x0000000f,
1355 [D3DRS_TWEENFACTOR
] = 0x00000000,
1356 [D3DRS_BLENDOP
] = D3DBLENDOP_ADD
,
1357 [D3DRS_POSITIONDEGREE
] = D3DDEGREE_CUBIC
,
1358 [D3DRS_NORMALDEGREE
] = D3DDEGREE_LINEAR
,
1359 [D3DRS_SCISSORTESTENABLE
] = FALSE
,
1360 [D3DRS_SLOPESCALEDEPTHBIAS
] = 0,
1361 [D3DRS_MINTESSELLATIONLEVEL
] = 0x3F800000,
1362 [D3DRS_MAXTESSELLATIONLEVEL
] = 0x3F800000,
1363 [D3DRS_ANTIALIASEDLINEENABLE
] = FALSE
,
1364 [D3DRS_ADAPTIVETESS_X
] = 0x00000000,
1365 [D3DRS_ADAPTIVETESS_Y
] = 0x00000000,
1366 [D3DRS_ADAPTIVETESS_Z
] = 0x3F800000,
1367 [D3DRS_ADAPTIVETESS_W
] = 0x00000000,
1368 [D3DRS_ENABLEADAPTIVETESSELLATION
] = FALSE
,
1369 [D3DRS_TWOSIDEDSTENCILMODE
] = FALSE
,
1370 [D3DRS_CCW_STENCILFAIL
] = D3DSTENCILOP_KEEP
,
1371 [D3DRS_CCW_STENCILZFAIL
] = D3DSTENCILOP_KEEP
,
1372 [D3DRS_CCW_STENCILPASS
] = D3DSTENCILOP_KEEP
,
1373 [D3DRS_CCW_STENCILFUNC
] = D3DCMP_ALWAYS
,
1374 [D3DRS_COLORWRITEENABLE1
] = 0x0000000F,
1375 [D3DRS_COLORWRITEENABLE2
] = 0x0000000F,
1376 [D3DRS_COLORWRITEENABLE3
] = 0x0000000F,
1377 [D3DRS_BLENDFACTOR
] = 0xFFFFFFFF,
1378 [D3DRS_SRGBWRITEENABLE
] = 0,
1379 [D3DRS_DEPTHBIAS
] = 0,
1388 [D3DRS_SEPARATEALPHABLENDENABLE
] = FALSE
,
1389 [D3DRS_SRCBLENDALPHA
] = D3DBLEND_ONE
,
1390 [D3DRS_DESTBLENDALPHA
] = D3DBLEND_ZERO
,
1391 [D3DRS_BLENDOPALPHA
] = D3DBLENDOP_ADD
,
1392 [NINED3DRS_VSPOINTSIZE
] = FALSE
,
1393 [NINED3DRS_RTMASK
] = 0xf,
1394 [NINED3DRS_ALPHACOVERAGE
] = FALSE
,
1395 [NINED3DRS_MULTISAMPLE
] = FALSE
1397 static const DWORD nine_tex_stage_state_defaults
[NINED3DTSS_LAST
+ 1] =
1399 [D3DTSS_COLOROP
] = D3DTOP_DISABLE
,
1400 [D3DTSS_ALPHAOP
] = D3DTOP_DISABLE
,
1401 [D3DTSS_COLORARG1
] = D3DTA_TEXTURE
,
1402 [D3DTSS_COLORARG2
] = D3DTA_CURRENT
,
1403 [D3DTSS_COLORARG0
] = D3DTA_CURRENT
,
1404 [D3DTSS_ALPHAARG1
] = D3DTA_TEXTURE
,
1405 [D3DTSS_ALPHAARG2
] = D3DTA_CURRENT
,
1406 [D3DTSS_ALPHAARG0
] = D3DTA_CURRENT
,
1407 [D3DTSS_RESULTARG
] = D3DTA_CURRENT
,
1408 [D3DTSS_BUMPENVMAT00
] = 0,
1409 [D3DTSS_BUMPENVMAT01
] = 0,
1410 [D3DTSS_BUMPENVMAT10
] = 0,
1411 [D3DTSS_BUMPENVMAT11
] = 0,
1412 [D3DTSS_BUMPENVLSCALE
] = 0,
1413 [D3DTSS_BUMPENVLOFFSET
] = 0,
1414 [D3DTSS_TEXCOORDINDEX
] = 0,
1415 [D3DTSS_TEXTURETRANSFORMFLAGS
] = D3DTTFF_DISABLE
,
1417 static const DWORD nine_samp_state_defaults
[NINED3DSAMP_LAST
+ 1] =
1419 [D3DSAMP_ADDRESSU
] = D3DTADDRESS_WRAP
,
1420 [D3DSAMP_ADDRESSV
] = D3DTADDRESS_WRAP
,
1421 [D3DSAMP_ADDRESSW
] = D3DTADDRESS_WRAP
,
1422 [D3DSAMP_BORDERCOLOR
] = 0,
1423 [D3DSAMP_MAGFILTER
] = D3DTEXF_POINT
,
1424 [D3DSAMP_MINFILTER
] = D3DTEXF_POINT
,
1425 [D3DSAMP_MIPFILTER
] = D3DTEXF_NONE
,
1426 [D3DSAMP_MIPMAPLODBIAS
] = 0,
1427 [D3DSAMP_MAXMIPLEVEL
] = 0,
1428 [D3DSAMP_MAXANISOTROPY
] = 1,
1429 [D3DSAMP_SRGBTEXTURE
] = 0,
1430 [D3DSAMP_ELEMENTINDEX
] = 0,
1431 [D3DSAMP_DMAPOFFSET
] = 0,
1432 [NINED3DSAMP_MINLOD
] = 0,
1433 [NINED3DSAMP_SHADOW
] = 0,
1434 [NINED3DSAMP_CUBETEX
] = 0
1437 void nine_state_restore_non_cso(struct NineDevice9
*device
)
1439 struct nine_state
*state
= &device
->state
;
1440 struct nine_context
*context
= &device
->context
;
1442 state
->changed
.group
= NINE_STATE_ALL
;
1443 state
->changed
.vtxbuf
= (1ULL << device
->caps
.MaxStreams
) - 1;
1444 state
->changed
.ucp
= (1 << PIPE_MAX_CLIP_PLANES
) - 1;
1445 state
->changed
.texture
= NINE_PS_SAMPLERS_MASK
| NINE_VS_SAMPLERS_MASK
;
1446 context
->commit
|= NINE_STATE_COMMIT_CONST_VS
| NINE_STATE_COMMIT_CONST_PS
;
1450 nine_state_set_defaults(struct NineDevice9
*device
, const D3DCAPS9
*caps
,
1453 struct nine_state
*state
= &device
->state
;
1454 struct nine_context
*context
= &device
->context
;
1457 /* Initialize defaults.
1459 memcpy(state
->rs
, nine_render_state_defaults
, sizeof(state
->rs
));
1461 for (s
= 0; s
< ARRAY_SIZE(state
->ff
.tex_stage
); ++s
) {
1462 memcpy(&state
->ff
.tex_stage
[s
], nine_tex_stage_state_defaults
,
1463 sizeof(state
->ff
.tex_stage
[s
]));
1464 state
->ff
.tex_stage
[s
][D3DTSS_TEXCOORDINDEX
] = s
;
1466 state
->ff
.tex_stage
[0][D3DTSS_COLOROP
] = D3DTOP_MODULATE
;
1467 state
->ff
.tex_stage
[0][D3DTSS_ALPHAOP
] = D3DTOP_SELECTARG1
;
1468 memset(&context
->bumpmap_vars
, 0, sizeof(context
->bumpmap_vars
));
1470 for (s
= 0; s
< ARRAY_SIZE(state
->samp
); ++s
) {
1471 memcpy(&state
->samp
[s
], nine_samp_state_defaults
,
1472 sizeof(state
->samp
[s
]));
1473 memcpy(&state
->samp_advertised
[s
], nine_samp_state_defaults
,
1474 sizeof(state
->samp_advertised
[s
]));
1477 if (state
->vs_const_f
)
1478 memset(state
->vs_const_f
, 0, device
->vs_const_size
);
1479 if (state
->ps_const_f
)
1480 memset(state
->ps_const_f
, 0, device
->ps_const_size
);
1482 /* Cap dependent initial state:
1484 state
->rs
[D3DRS_POINTSIZE_MAX
] = fui(caps
->MaxPointSize
);
1486 memcpy(state
->rs_advertised
, state
->rs
, sizeof(state
->rs
));
1488 /* Set changed flags to initialize driver.
1490 state
->changed
.group
= NINE_STATE_ALL
;
1491 state
->changed
.vtxbuf
= (1ULL << device
->caps
.MaxStreams
) - 1;
1492 state
->changed
.ucp
= (1 << PIPE_MAX_CLIP_PLANES
) - 1;
1493 state
->changed
.texture
= NINE_PS_SAMPLERS_MASK
| NINE_VS_SAMPLERS_MASK
;
1495 state
->ff
.changed
.transform
[0] = ~0;
1496 state
->ff
.changed
.transform
[D3DTS_WORLD
/ 32] |= 1 << (D3DTS_WORLD
% 32);
1499 state
->viewport
.MinZ
= 0.0f
;
1500 state
->viewport
.MaxZ
= 1.0f
;
1503 for (s
= 0; s
< ARRAY_SIZE(state
->changed
.sampler
); ++s
)
1504 state
->changed
.sampler
[s
] = ~0;
1507 context
->dummy_vbo_bound_at
= -1;
1508 context
->vbo_bound_done
= FALSE
;
1513 nine_state_clear(struct nine_state
*state
, const boolean device
)
1517 for (i
= 0; i
< ARRAY_SIZE(state
->rt
); ++i
)
1518 nine_bind(&state
->rt
[i
], NULL
);
1519 nine_bind(&state
->ds
, NULL
);
1520 nine_bind(&state
->vs
, NULL
);
1521 nine_bind(&state
->ps
, NULL
);
1522 nine_bind(&state
->vdecl
, NULL
);
1523 for (i
= 0; i
< PIPE_MAX_ATTRIBS
; ++i
) {
1524 nine_bind(&state
->stream
[i
], NULL
);
1525 pipe_resource_reference(&state
->vtxbuf
[i
].buffer
, NULL
);
1527 nine_bind(&state
->idxbuf
, NULL
);
1528 for (i
= 0; i
< NINE_MAX_SAMPLERS
; ++i
) {
1530 state
->texture
[i
] &&
1531 --state
->texture
[i
]->bind_count
== 0)
1532 list_delinit(&state
->texture
[i
]->list
);
1533 nine_bind(&state
->texture
[i
], NULL
);
1538 nine_state_init_sw(struct NineDevice9
*device
)
1540 struct pipe_context
*pipe_sw
= device
->pipe_sw
;
1541 struct pipe_rasterizer_state rast
;
1542 struct pipe_blend_state blend
;
1543 struct pipe_depth_stencil_alpha_state dsa
;
1544 struct pipe_framebuffer_state fb
;
1546 /* Only used with Streamout */
1547 memset(&rast
, 0, sizeof(rast
));
1548 rast
.rasterizer_discard
= true;
1549 rast
.point_quad_rasterization
= 1; /* to make llvmpipe happy */
1550 cso_set_rasterizer(device
->cso_sw
, &rast
);
1552 /* dummy settings */
1553 memset(&blend
, 0, sizeof(blend
));
1554 memset(&dsa
, 0, sizeof(dsa
));
1555 memset(&fb
, 0, sizeof(fb
));
1556 cso_set_blend(device
->cso_sw
, &blend
);
1557 cso_set_depth_stencil_alpha(device
->cso_sw
, &dsa
);
1558 cso_set_framebuffer(device
->cso_sw
, &fb
);
1559 cso_set_viewport_dims(device
->cso_sw
, 1.0, 1.0, false);
1560 cso_set_fragment_shader_handle(device
->cso_sw
, util_make_empty_fragment_shader(pipe_sw
));
1563 /* There is duplication with update_vertex_elements.
1564 * TODO: Share the code */
1567 update_vertex_elements_sw(struct NineDevice9
*device
)
1569 struct nine_state
*state
= &device
->state
;
1570 const struct NineVertexDeclaration9
*vdecl
= device
->state
.vdecl
;
1571 const struct NineVertexShader9
*vs
;
1574 char vdecl_index_map
[16]; /* vs->num_inputs <= 16 */
1575 char used_streams
[device
->caps
.MaxStreams
];
1576 int dummy_vbo_stream
= -1;
1577 BOOL need_dummy_vbo
= FALSE
;
1578 struct pipe_vertex_element ve
[PIPE_MAX_ATTRIBS
];
1580 memset(vdecl_index_map
, -1, 16);
1581 memset(used_streams
, 0, device
->caps
.MaxStreams
);
1582 vs
= state
->programmable_vs
? device
->state
.vs
: device
->ff
.vs
;
1585 for (n
= 0; n
< vs
->num_inputs
; ++n
) {
1586 DBG("looking up input %u (usage %u) from vdecl(%p)\n",
1587 n
, vs
->input_map
[n
].ndecl
, vdecl
);
1589 for (i
= 0; i
< vdecl
->nelems
; i
++) {
1590 if (vdecl
->usage_map
[i
] == vs
->input_map
[n
].ndecl
) {
1591 vdecl_index_map
[n
] = i
;
1592 used_streams
[vdecl
->elems
[i
].vertex_buffer_index
] = 1;
1596 if (vdecl_index_map
[n
] < 0)
1597 need_dummy_vbo
= TRUE
;
1600 /* No vertex declaration. Likely will never happen in practice,
1601 * but we need not crash on this */
1602 need_dummy_vbo
= TRUE
;
1605 if (need_dummy_vbo
) {
1606 for (i
= 0; i
< device
->caps
.MaxStreams
; i
++ ) {
1607 if (!used_streams
[i
]) {
1608 dummy_vbo_stream
= i
;
1613 /* TODO handle dummy_vbo */
1614 assert (!need_dummy_vbo
);
1616 for (n
= 0; n
< vs
->num_inputs
; ++n
) {
1617 index
= vdecl_index_map
[n
];
1619 ve
[n
] = vdecl
->elems
[index
];
1620 b
= ve
[n
].vertex_buffer_index
;
1621 /* XXX wine just uses 1 here: */
1622 if (state
->stream_freq
[b
] & D3DSTREAMSOURCE_INSTANCEDATA
)
1623 ve
[n
].instance_divisor
= state
->stream_freq
[b
] & 0x7FFFFF;
1625 /* if the vertex declaration is incomplete compared to what the
1626 * vertex shader needs, we bind a dummy vbo with 0 0 0 0.
1627 * This is not precised by the spec, but is the behaviour
1629 ve
[n
].vertex_buffer_index
= dummy_vbo_stream
;
1630 ve
[n
].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
1631 ve
[n
].src_offset
= 0;
1632 ve
[n
].instance_divisor
= 0;
1636 cso_set_vertex_elements(device
->cso_sw
, vs
->num_inputs
, ve
);
1640 update_vertex_buffers_sw(struct NineDevice9
*device
, int start_vertice
, int num_vertices
)
1642 struct pipe_context
*pipe
= device
->pipe
;
1643 struct pipe_context
*pipe_sw
= device
->pipe_sw
;
1644 struct nine_state
*state
= &device
->state
;
1645 struct nine_state_sw_internal
*sw_internal
= &device
->state_sw_internal
;
1646 struct pipe_vertex_buffer vtxbuf
;
1647 uint32_t mask
= 0xf;
1650 DBG("mask=%x\n", mask
);
1652 /* TODO: handle dummy_vbo_bound_at */
1654 for (i
= 0; mask
; mask
>>= 1, ++i
) {
1656 if (state
->vtxbuf
[i
].buffer
) {
1657 struct pipe_resource
*buf
;
1658 struct pipe_box box
;
1660 vtxbuf
= state
->vtxbuf
[i
];
1662 DBG("Locking %p (offset %d, length %d)\n", vtxbuf
.buffer
,
1663 vtxbuf
.buffer_offset
, num_vertices
* vtxbuf
.stride
);
1665 u_box_1d(vtxbuf
.buffer_offset
+ start_vertice
* vtxbuf
.stride
,
1666 num_vertices
* vtxbuf
.stride
, &box
);
1667 buf
= vtxbuf
.buffer
;
1668 vtxbuf
.user_buffer
= pipe
->transfer_map(pipe
, buf
, 0, PIPE_TRANSFER_READ
, &box
,
1669 &(sw_internal
->transfers_so
[i
]));
1670 vtxbuf
.buffer
= NULL
;
1671 if (!device
->driver_caps
.user_sw_vbufs
) {
1672 u_upload_data(device
->vertex_sw_uploader
,
1677 &(vtxbuf
.buffer_offset
),
1679 u_upload_unmap(device
->vertex_sw_uploader
);
1680 vtxbuf
.user_buffer
= NULL
;
1682 pipe_sw
->set_vertex_buffers(pipe_sw
, i
, 1, &vtxbuf
);
1684 pipe_resource_reference(&vtxbuf
.buffer
, NULL
);
1686 pipe_sw
->set_vertex_buffers(pipe_sw
, i
, 1, NULL
);
1692 update_vs_constants_sw(struct NineDevice9
*device
)
1694 struct nine_state
*state
= &device
->state
;
1695 struct pipe_context
*pipe_sw
= device
->pipe_sw
;
1700 struct pipe_constant_buffer cb
;
1704 cb
.buffer_offset
= 0;
1705 cb
.buffer_size
= 4096 * sizeof(float[4]);
1706 cb
.user_buffer
= state
->vs_const_f_swvp
;
1708 if (state
->vs
->lconstf
.ranges
) {
1709 const struct nine_lconstf
*lconstf
= &device
->state
.vs
->lconstf
;
1710 const struct nine_range
*r
= lconstf
->ranges
;
1712 float *dst
= device
->state
.vs_lconstf_temp
;
1713 float *src
= (float *)cb
.user_buffer
;
1714 memcpy(dst
, src
, 8192 * sizeof(float[4]));
1716 unsigned p
= r
->bgn
;
1717 unsigned c
= r
->end
- r
->bgn
;
1718 memcpy(&dst
[p
* 4], &lconstf
->data
[n
* 4], c
* 4 * sizeof(float));
1722 cb
.user_buffer
= dst
;
1725 buf
= cb
.user_buffer
;
1726 if (!device
->driver_caps
.user_sw_cbufs
) {
1727 u_upload_data(device
->constbuf_sw_uploader
,
1732 &(cb
.buffer_offset
),
1734 u_upload_unmap(device
->constbuf_sw_uploader
);
1735 cb
.user_buffer
= NULL
;
1738 pipe_sw
->set_constant_buffer(pipe_sw
, PIPE_SHADER_VERTEX
, 0, &cb
);
1740 pipe_resource_reference(&cb
.buffer
, NULL
);
1742 cb
.user_buffer
= (char *)buf
+ 4096 * sizeof(float[4]);
1743 if (!device
->driver_caps
.user_sw_cbufs
) {
1744 u_upload_data(device
->constbuf_sw_uploader
,
1749 &(cb
.buffer_offset
),
1751 u_upload_unmap(device
->constbuf_sw_uploader
);
1752 cb
.user_buffer
= NULL
;
1755 pipe_sw
->set_constant_buffer(pipe_sw
, PIPE_SHADER_VERTEX
, 1, &cb
);
1757 pipe_resource_reference(&cb
.buffer
, NULL
);
1761 struct pipe_constant_buffer cb
;
1764 cb
.buffer_offset
= 0;
1765 cb
.buffer_size
= 2048 * sizeof(float[4]);
1766 cb
.user_buffer
= state
->vs_const_i
;
1768 if (!device
->driver_caps
.user_sw_cbufs
) {
1769 u_upload_data(device
->constbuf_sw_uploader
,
1774 &(cb
.buffer_offset
),
1776 u_upload_unmap(device
->constbuf_sw_uploader
);
1777 cb
.user_buffer
= NULL
;
1780 pipe_sw
->set_constant_buffer(pipe_sw
, PIPE_SHADER_VERTEX
, 2, &cb
);
1782 pipe_resource_reference(&cb
.buffer
, NULL
);
1786 struct pipe_constant_buffer cb
;
1789 cb
.buffer_offset
= 0;
1790 cb
.buffer_size
= 512 * sizeof(float[4]);
1791 cb
.user_buffer
= state
->vs_const_b
;
1793 if (!device
->driver_caps
.user_sw_cbufs
) {
1794 u_upload_data(device
->constbuf_sw_uploader
,
1799 &(cb
.buffer_offset
),
1801 u_upload_unmap(device
->constbuf_sw_uploader
);
1802 cb
.user_buffer
= NULL
;
1805 pipe_sw
->set_constant_buffer(pipe_sw
, PIPE_SHADER_VERTEX
, 3, &cb
);
1807 pipe_resource_reference(&cb
.buffer
, NULL
);
1811 struct pipe_constant_buffer cb
;
1812 const D3DVIEWPORT9
*vport
= &device
->state
.viewport
;
1813 float viewport_data
[8] = {(float)vport
->Width
* 0.5f
,
1814 (float)vport
->Height
* -0.5f
, vport
->MaxZ
- vport
->MinZ
, 0.f
,
1815 (float)vport
->Width
* 0.5f
+ (float)vport
->X
,
1816 (float)vport
->Height
* 0.5f
+ (float)vport
->Y
,
1820 cb
.buffer_offset
= 0;
1821 cb
.buffer_size
= 2 * sizeof(float[4]);
1822 cb
.user_buffer
= viewport_data
;
1825 u_upload_data(device
->constbuf_sw_uploader
,
1830 &(cb
.buffer_offset
),
1832 u_upload_unmap(device
->constbuf_sw_uploader
);
1833 cb
.user_buffer
= NULL
;
1836 pipe_sw
->set_constant_buffer(pipe_sw
, PIPE_SHADER_VERTEX
, 4, &cb
);
1838 pipe_resource_reference(&cb
.buffer
, NULL
);
1844 nine_state_prepare_draw_sw(struct NineDevice9
*device
, struct NineVertexDeclaration9
*vdecl_out
,
1845 int start_vertice
, int num_vertices
, struct pipe_stream_output_info
*so
)
1847 struct nine_state
*state
= &device
->state
;
1849 struct NineVertexShader9
*vs
= state
->programmable_vs
? device
->state
.vs
: device
->ff
.vs
;
1851 assert(state
->programmable_vs
);
1853 DBG("Preparing draw\n");
1854 cso_set_vertex_shader_handle(device
->cso_sw
,
1855 NineVertexShader9_GetVariantProcessVertices(vs
, vdecl_out
, so
));
1856 update_vertex_elements_sw(device
);
1857 update_vertex_buffers_sw(device
, start_vertice
, num_vertices
);
1858 update_vs_constants_sw(device
);
1859 DBG("Preparation succeeded\n");
1863 nine_state_after_draw_sw(struct NineDevice9
*device
)
1865 struct nine_state_sw_internal
*sw_internal
= &device
->state_sw_internal
;
1866 struct pipe_context
*pipe
= device
->pipe
;
1867 struct pipe_context
*pipe_sw
= device
->pipe_sw
;
1870 for (i
= 0; i
< 4; i
++) {
1871 pipe_sw
->set_vertex_buffers(pipe_sw
, i
, 1, NULL
);
1872 if (sw_internal
->transfers_so
[i
])
1873 pipe
->transfer_unmap(pipe
, sw_internal
->transfers_so
[i
]);
1874 sw_internal
->transfers_so
[i
] = NULL
;
1879 nine_state_destroy_sw(struct NineDevice9
*device
)
1882 /* Everything destroyed with cso */
1886 static const DWORD nine_render_states_pixel[] =
1888 D3DRS_ALPHABLENDENABLE,
1891 D3DRS_ALPHATESTENABLE,
1892 D3DRS_ANTIALIASEDLINEENABLE,
1896 D3DRS_CCW_STENCILFAIL,
1897 D3DRS_CCW_STENCILPASS,
1898 D3DRS_CCW_STENCILZFAIL,
1899 D3DRS_COLORWRITEENABLE,
1900 D3DRS_COLORWRITEENABLE1,
1901 D3DRS_COLORWRITEENABLE2,
1902 D3DRS_COLORWRITEENABLE3,
1905 D3DRS_DESTBLENDALPHA,
1912 D3DRS_SCISSORTESTENABLE,
1913 D3DRS_SEPARATEALPHABLENDENABLE,
1915 D3DRS_SLOPESCALEDEPTHBIAS,
1917 D3DRS_SRCBLENDALPHA,
1918 D3DRS_SRGBWRITEENABLE,
1919 D3DRS_STENCILENABLE,
1925 D3DRS_STENCILWRITEMASK,
1927 D3DRS_TEXTUREFACTOR,
1928 D3DRS_TWOSIDEDSTENCILMODE,
1950 const uint32_t nine_render_states_pixel
[(NINED3DRS_LAST
+ 31) / 32] =
1952 0x0f99c380, 0x1ff00070, 0x00000000, 0x00000000,
1953 0x000000ff, 0xde01c900, 0x0003ffcf
1957 static const DWORD nine_render_states_vertex[] =
1959 D3DRS_ADAPTIVETESS_W,
1960 D3DRS_ADAPTIVETESS_X,
1961 D3DRS_ADAPTIVETESS_Y,
1962 D3DRS_ADAPTIVETESS_Z,
1964 D3DRS_AMBIENTMATERIALSOURCE,
1966 D3DRS_CLIPPLANEENABLE,
1969 D3DRS_DIFFUSEMATERIALSOURCE,
1970 D3DRS_EMISSIVEMATERIALSOURCE,
1971 D3DRS_ENABLEADAPTIVETESSELLATION,
1978 D3DRS_FOGVERTEXMODE,
1979 D3DRS_INDEXEDVERTEXBLENDENABLE,
1982 D3DRS_MAXTESSELLATIONLEVEL,
1983 D3DRS_MINTESSELLATIONLEVEL,
1984 D3DRS_MULTISAMPLEANTIALIAS,
1985 D3DRS_MULTISAMPLEMASK,
1987 D3DRS_NORMALIZENORMALS,
1988 D3DRS_PATCHEDGESTYLE,
1992 D3DRS_POINTSCALEENABLE,
1994 D3DRS_POINTSIZE_MAX,
1995 D3DRS_POINTSIZE_MIN,
1996 D3DRS_POINTSPRITEENABLE,
1997 D3DRS_POSITIONDEGREE,
1998 D3DRS_RANGEFOGENABLE,
2000 D3DRS_SPECULARENABLE,
2001 D3DRS_SPECULARMATERIALSOURCE,
2006 const uint32_t nine_render_states_vertex
[(NINED3DRS_LAST
+ 31) / 32] =
2008 0x30400200, 0x0001007c, 0x00000000, 0x00000000,
2009 0xfd9efb00, 0x01fc34cf, 0x00000000
2012 /* TODO: put in the right values */
2013 const uint32_t nine_render_state_group
[NINED3DRS_LAST
+ 1] =
2015 [D3DRS_ZENABLE
] = NINE_STATE_DSA
| NINE_STATE_MULTISAMPLE
,
2016 [D3DRS_FILLMODE
] = NINE_STATE_RASTERIZER
,
2017 [D3DRS_SHADEMODE
] = NINE_STATE_RASTERIZER
,
2018 [D3DRS_ZWRITEENABLE
] = NINE_STATE_DSA
,
2019 [D3DRS_ALPHATESTENABLE
] = NINE_STATE_DSA
,
2020 [D3DRS_LASTPIXEL
] = NINE_STATE_RASTERIZER
,
2021 [D3DRS_SRCBLEND
] = NINE_STATE_BLEND
,
2022 [D3DRS_DESTBLEND
] = NINE_STATE_BLEND
,
2023 [D3DRS_CULLMODE
] = NINE_STATE_RASTERIZER
,
2024 [D3DRS_ZFUNC
] = NINE_STATE_DSA
,
2025 [D3DRS_ALPHAREF
] = NINE_STATE_DSA
,
2026 [D3DRS_ALPHAFUNC
] = NINE_STATE_DSA
,
2027 [D3DRS_DITHERENABLE
] = NINE_STATE_BLEND
,
2028 [D3DRS_ALPHABLENDENABLE
] = NINE_STATE_BLEND
,
2029 [D3DRS_FOGENABLE
] = NINE_STATE_FF_OTHER
| NINE_STATE_FOG_SHADER
| NINE_STATE_PS_CONST
,
2030 [D3DRS_SPECULARENABLE
] = NINE_STATE_FF_LIGHTING
,
2031 [D3DRS_FOGCOLOR
] = NINE_STATE_FF_OTHER
| NINE_STATE_PS_CONST
,
2032 [D3DRS_FOGTABLEMODE
] = NINE_STATE_FF_OTHER
| NINE_STATE_FOG_SHADER
| NINE_STATE_PS_CONST
,
2033 [D3DRS_FOGSTART
] = NINE_STATE_FF_OTHER
| NINE_STATE_PS_CONST
,
2034 [D3DRS_FOGEND
] = NINE_STATE_FF_OTHER
| NINE_STATE_PS_CONST
,
2035 [D3DRS_FOGDENSITY
] = NINE_STATE_FF_OTHER
| NINE_STATE_PS_CONST
,
2036 [D3DRS_RANGEFOGENABLE
] = NINE_STATE_FF_OTHER
,
2037 [D3DRS_STENCILENABLE
] = NINE_STATE_DSA
| NINE_STATE_MULTISAMPLE
,
2038 [D3DRS_STENCILFAIL
] = NINE_STATE_DSA
,
2039 [D3DRS_STENCILZFAIL
] = NINE_STATE_DSA
,
2040 [D3DRS_STENCILPASS
] = NINE_STATE_DSA
,
2041 [D3DRS_STENCILFUNC
] = NINE_STATE_DSA
,
2042 [D3DRS_STENCILREF
] = NINE_STATE_STENCIL_REF
,
2043 [D3DRS_STENCILMASK
] = NINE_STATE_DSA
,
2044 [D3DRS_STENCILWRITEMASK
] = NINE_STATE_DSA
,
2045 [D3DRS_TEXTUREFACTOR
] = NINE_STATE_FF_PSSTAGES
,
2046 [D3DRS_WRAP0
] = NINE_STATE_UNHANDLED
, /* cylindrical wrap is crazy */
2047 [D3DRS_WRAP1
] = NINE_STATE_UNHANDLED
,
2048 [D3DRS_WRAP2
] = NINE_STATE_UNHANDLED
,
2049 [D3DRS_WRAP3
] = NINE_STATE_UNHANDLED
,
2050 [D3DRS_WRAP4
] = NINE_STATE_UNHANDLED
,
2051 [D3DRS_WRAP5
] = NINE_STATE_UNHANDLED
,
2052 [D3DRS_WRAP6
] = NINE_STATE_UNHANDLED
,
2053 [D3DRS_WRAP7
] = NINE_STATE_UNHANDLED
,
2054 [D3DRS_CLIPPING
] = 0, /* software vertex processing only */
2055 [D3DRS_LIGHTING
] = NINE_STATE_FF_LIGHTING
,
2056 [D3DRS_AMBIENT
] = NINE_STATE_FF_LIGHTING
| NINE_STATE_FF_MATERIAL
,
2057 [D3DRS_FOGVERTEXMODE
] = NINE_STATE_FF_OTHER
,
2058 [D3DRS_COLORVERTEX
] = NINE_STATE_FF_LIGHTING
,
2059 [D3DRS_LOCALVIEWER
] = NINE_STATE_FF_LIGHTING
,
2060 [D3DRS_NORMALIZENORMALS
] = NINE_STATE_FF_OTHER
,
2061 [D3DRS_DIFFUSEMATERIALSOURCE
] = NINE_STATE_FF_LIGHTING
,
2062 [D3DRS_SPECULARMATERIALSOURCE
] = NINE_STATE_FF_LIGHTING
,
2063 [D3DRS_AMBIENTMATERIALSOURCE
] = NINE_STATE_FF_LIGHTING
,
2064 [D3DRS_EMISSIVEMATERIALSOURCE
] = NINE_STATE_FF_LIGHTING
,
2065 [D3DRS_VERTEXBLEND
] = NINE_STATE_FF_OTHER
,
2066 [D3DRS_CLIPPLANEENABLE
] = NINE_STATE_RASTERIZER
,
2067 [D3DRS_POINTSIZE
] = NINE_STATE_RASTERIZER
,
2068 [D3DRS_POINTSIZE_MIN
] = NINE_STATE_RASTERIZER
| NINE_STATE_POINTSIZE_SHADER
,
2069 [D3DRS_POINTSPRITEENABLE
] = NINE_STATE_RASTERIZER
,
2070 [D3DRS_POINTSCALEENABLE
] = NINE_STATE_FF_OTHER
,
2071 [D3DRS_POINTSCALE_A
] = NINE_STATE_FF_OTHER
,
2072 [D3DRS_POINTSCALE_B
] = NINE_STATE_FF_OTHER
,
2073 [D3DRS_POINTSCALE_C
] = NINE_STATE_FF_OTHER
,
2074 [D3DRS_MULTISAMPLEANTIALIAS
] = NINE_STATE_MULTISAMPLE
,
2075 [D3DRS_MULTISAMPLEMASK
] = NINE_STATE_SAMPLE_MASK
,
2076 [D3DRS_PATCHEDGESTYLE
] = NINE_STATE_UNHANDLED
,
2077 [D3DRS_DEBUGMONITORTOKEN
] = NINE_STATE_UNHANDLED
,
2078 [D3DRS_POINTSIZE_MAX
] = NINE_STATE_RASTERIZER
| NINE_STATE_POINTSIZE_SHADER
,
2079 [D3DRS_INDEXEDVERTEXBLENDENABLE
] = NINE_STATE_FF_OTHER
,
2080 [D3DRS_COLORWRITEENABLE
] = NINE_STATE_BLEND
,
2081 [D3DRS_TWEENFACTOR
] = NINE_STATE_FF_OTHER
,
2082 [D3DRS_BLENDOP
] = NINE_STATE_BLEND
,
2083 [D3DRS_POSITIONDEGREE
] = NINE_STATE_UNHANDLED
,
2084 [D3DRS_NORMALDEGREE
] = NINE_STATE_UNHANDLED
,
2085 [D3DRS_SCISSORTESTENABLE
] = NINE_STATE_RASTERIZER
,
2086 [D3DRS_SLOPESCALEDEPTHBIAS
] = NINE_STATE_RASTERIZER
,
2087 [D3DRS_ANTIALIASEDLINEENABLE
] = NINE_STATE_RASTERIZER
,
2088 [D3DRS_MINTESSELLATIONLEVEL
] = NINE_STATE_UNHANDLED
,
2089 [D3DRS_MAXTESSELLATIONLEVEL
] = NINE_STATE_UNHANDLED
,
2090 [D3DRS_ADAPTIVETESS_X
] = NINE_STATE_UNHANDLED
,
2091 [D3DRS_ADAPTIVETESS_Y
] = NINE_STATE_UNHANDLED
,
2092 [D3DRS_ADAPTIVETESS_Z
] = NINE_STATE_UNHANDLED
,
2093 [D3DRS_ADAPTIVETESS_W
] = NINE_STATE_UNHANDLED
,
2094 [D3DRS_ENABLEADAPTIVETESSELLATION
] = NINE_STATE_UNHANDLED
,
2095 [D3DRS_TWOSIDEDSTENCILMODE
] = NINE_STATE_DSA
,
2096 [D3DRS_CCW_STENCILFAIL
] = NINE_STATE_DSA
,
2097 [D3DRS_CCW_STENCILZFAIL
] = NINE_STATE_DSA
,
2098 [D3DRS_CCW_STENCILPASS
] = NINE_STATE_DSA
,
2099 [D3DRS_CCW_STENCILFUNC
] = NINE_STATE_DSA
,
2100 [D3DRS_COLORWRITEENABLE1
] = NINE_STATE_BLEND
,
2101 [D3DRS_COLORWRITEENABLE2
] = NINE_STATE_BLEND
,
2102 [D3DRS_COLORWRITEENABLE3
] = NINE_STATE_BLEND
,
2103 [D3DRS_BLENDFACTOR
] = NINE_STATE_BLEND_COLOR
,
2104 [D3DRS_SRGBWRITEENABLE
] = NINE_STATE_FB
,
2105 [D3DRS_DEPTHBIAS
] = NINE_STATE_RASTERIZER
,
2106 [D3DRS_WRAP8
] = NINE_STATE_UNHANDLED
, /* cylwrap has to be done via GP */
2107 [D3DRS_WRAP9
] = NINE_STATE_UNHANDLED
,
2108 [D3DRS_WRAP10
] = NINE_STATE_UNHANDLED
,
2109 [D3DRS_WRAP11
] = NINE_STATE_UNHANDLED
,
2110 [D3DRS_WRAP12
] = NINE_STATE_UNHANDLED
,
2111 [D3DRS_WRAP13
] = NINE_STATE_UNHANDLED
,
2112 [D3DRS_WRAP14
] = NINE_STATE_UNHANDLED
,
2113 [D3DRS_WRAP15
] = NINE_STATE_UNHANDLED
,
2114 [D3DRS_SEPARATEALPHABLENDENABLE
] = NINE_STATE_BLEND
,
2115 [D3DRS_SRCBLENDALPHA
] = NINE_STATE_BLEND
,
2116 [D3DRS_DESTBLENDALPHA
] = NINE_STATE_BLEND
,
2117 [D3DRS_BLENDOPALPHA
] = NINE_STATE_BLEND
2123 nine_state_access_transform(struct nine_state
*state
, D3DTRANSFORMSTATETYPE t
,
2126 static D3DMATRIX Identity
= { .m
[0] = { 1, 0, 0, 0 },
2127 .m
[1] = { 0, 1, 0, 0 },
2128 .m
[2] = { 0, 0, 1, 0 },
2129 .m
[3] = { 0, 0, 0, 1 } };
2133 case D3DTS_VIEW
: index
= 0; break;
2134 case D3DTS_PROJECTION
: index
= 1; break;
2135 case D3DTS_TEXTURE0
: index
= 2; break;
2136 case D3DTS_TEXTURE1
: index
= 3; break;
2137 case D3DTS_TEXTURE2
: index
= 4; break;
2138 case D3DTS_TEXTURE3
: index
= 5; break;
2139 case D3DTS_TEXTURE4
: index
= 6; break;
2140 case D3DTS_TEXTURE5
: index
= 7; break;
2141 case D3DTS_TEXTURE6
: index
= 8; break;
2142 case D3DTS_TEXTURE7
: index
= 9; break;
2144 if (!(t
>= D3DTS_WORLDMATRIX(0) && t
<= D3DTS_WORLDMATRIX(255)))
2146 index
= 10 + (t
- D3DTS_WORLDMATRIX(0));
2150 if (index
>= state
->ff
.num_transforms
) {
2151 unsigned N
= index
+ 1;
2152 unsigned n
= state
->ff
.num_transforms
;
2156 state
->ff
.transform
= REALLOC(state
->ff
.transform
,
2157 n
* sizeof(D3DMATRIX
),
2158 N
* sizeof(D3DMATRIX
));
2160 state
->ff
.transform
[n
] = Identity
;
2161 state
->ff
.num_transforms
= N
;
2163 return &state
->ff
.transform
[index
];
2166 #define D3DRS_TO_STRING_CASE(n) case D3DRS_##n: return "D3DRS_"#n
2167 const char *nine_d3drs_to_string(DWORD State
)
2170 D3DRS_TO_STRING_CASE(ZENABLE
);
2171 D3DRS_TO_STRING_CASE(FILLMODE
);
2172 D3DRS_TO_STRING_CASE(SHADEMODE
);
2173 D3DRS_TO_STRING_CASE(ZWRITEENABLE
);
2174 D3DRS_TO_STRING_CASE(ALPHATESTENABLE
);
2175 D3DRS_TO_STRING_CASE(LASTPIXEL
);
2176 D3DRS_TO_STRING_CASE(SRCBLEND
);
2177 D3DRS_TO_STRING_CASE(DESTBLEND
);
2178 D3DRS_TO_STRING_CASE(CULLMODE
);
2179 D3DRS_TO_STRING_CASE(ZFUNC
);
2180 D3DRS_TO_STRING_CASE(ALPHAREF
);
2181 D3DRS_TO_STRING_CASE(ALPHAFUNC
);
2182 D3DRS_TO_STRING_CASE(DITHERENABLE
);
2183 D3DRS_TO_STRING_CASE(ALPHABLENDENABLE
);
2184 D3DRS_TO_STRING_CASE(FOGENABLE
);
2185 D3DRS_TO_STRING_CASE(SPECULARENABLE
);
2186 D3DRS_TO_STRING_CASE(FOGCOLOR
);
2187 D3DRS_TO_STRING_CASE(FOGTABLEMODE
);
2188 D3DRS_TO_STRING_CASE(FOGSTART
);
2189 D3DRS_TO_STRING_CASE(FOGEND
);
2190 D3DRS_TO_STRING_CASE(FOGDENSITY
);
2191 D3DRS_TO_STRING_CASE(RANGEFOGENABLE
);
2192 D3DRS_TO_STRING_CASE(STENCILENABLE
);
2193 D3DRS_TO_STRING_CASE(STENCILFAIL
);
2194 D3DRS_TO_STRING_CASE(STENCILZFAIL
);
2195 D3DRS_TO_STRING_CASE(STENCILPASS
);
2196 D3DRS_TO_STRING_CASE(STENCILFUNC
);
2197 D3DRS_TO_STRING_CASE(STENCILREF
);
2198 D3DRS_TO_STRING_CASE(STENCILMASK
);
2199 D3DRS_TO_STRING_CASE(STENCILWRITEMASK
);
2200 D3DRS_TO_STRING_CASE(TEXTUREFACTOR
);
2201 D3DRS_TO_STRING_CASE(WRAP0
);
2202 D3DRS_TO_STRING_CASE(WRAP1
);
2203 D3DRS_TO_STRING_CASE(WRAP2
);
2204 D3DRS_TO_STRING_CASE(WRAP3
);
2205 D3DRS_TO_STRING_CASE(WRAP4
);
2206 D3DRS_TO_STRING_CASE(WRAP5
);
2207 D3DRS_TO_STRING_CASE(WRAP6
);
2208 D3DRS_TO_STRING_CASE(WRAP7
);
2209 D3DRS_TO_STRING_CASE(CLIPPING
);
2210 D3DRS_TO_STRING_CASE(LIGHTING
);
2211 D3DRS_TO_STRING_CASE(AMBIENT
);
2212 D3DRS_TO_STRING_CASE(FOGVERTEXMODE
);
2213 D3DRS_TO_STRING_CASE(COLORVERTEX
);
2214 D3DRS_TO_STRING_CASE(LOCALVIEWER
);
2215 D3DRS_TO_STRING_CASE(NORMALIZENORMALS
);
2216 D3DRS_TO_STRING_CASE(DIFFUSEMATERIALSOURCE
);
2217 D3DRS_TO_STRING_CASE(SPECULARMATERIALSOURCE
);
2218 D3DRS_TO_STRING_CASE(AMBIENTMATERIALSOURCE
);
2219 D3DRS_TO_STRING_CASE(EMISSIVEMATERIALSOURCE
);
2220 D3DRS_TO_STRING_CASE(VERTEXBLEND
);
2221 D3DRS_TO_STRING_CASE(CLIPPLANEENABLE
);
2222 D3DRS_TO_STRING_CASE(POINTSIZE
);
2223 D3DRS_TO_STRING_CASE(POINTSIZE_MIN
);
2224 D3DRS_TO_STRING_CASE(POINTSPRITEENABLE
);
2225 D3DRS_TO_STRING_CASE(POINTSCALEENABLE
);
2226 D3DRS_TO_STRING_CASE(POINTSCALE_A
);
2227 D3DRS_TO_STRING_CASE(POINTSCALE_B
);
2228 D3DRS_TO_STRING_CASE(POINTSCALE_C
);
2229 D3DRS_TO_STRING_CASE(MULTISAMPLEANTIALIAS
);
2230 D3DRS_TO_STRING_CASE(MULTISAMPLEMASK
);
2231 D3DRS_TO_STRING_CASE(PATCHEDGESTYLE
);
2232 D3DRS_TO_STRING_CASE(DEBUGMONITORTOKEN
);
2233 D3DRS_TO_STRING_CASE(POINTSIZE_MAX
);
2234 D3DRS_TO_STRING_CASE(INDEXEDVERTEXBLENDENABLE
);
2235 D3DRS_TO_STRING_CASE(COLORWRITEENABLE
);
2236 D3DRS_TO_STRING_CASE(TWEENFACTOR
);
2237 D3DRS_TO_STRING_CASE(BLENDOP
);
2238 D3DRS_TO_STRING_CASE(POSITIONDEGREE
);
2239 D3DRS_TO_STRING_CASE(NORMALDEGREE
);
2240 D3DRS_TO_STRING_CASE(SCISSORTESTENABLE
);
2241 D3DRS_TO_STRING_CASE(SLOPESCALEDEPTHBIAS
);
2242 D3DRS_TO_STRING_CASE(ANTIALIASEDLINEENABLE
);
2243 D3DRS_TO_STRING_CASE(MINTESSELLATIONLEVEL
);
2244 D3DRS_TO_STRING_CASE(MAXTESSELLATIONLEVEL
);
2245 D3DRS_TO_STRING_CASE(ADAPTIVETESS_X
);
2246 D3DRS_TO_STRING_CASE(ADAPTIVETESS_Y
);
2247 D3DRS_TO_STRING_CASE(ADAPTIVETESS_Z
);
2248 D3DRS_TO_STRING_CASE(ADAPTIVETESS_W
);
2249 D3DRS_TO_STRING_CASE(ENABLEADAPTIVETESSELLATION
);
2250 D3DRS_TO_STRING_CASE(TWOSIDEDSTENCILMODE
);
2251 D3DRS_TO_STRING_CASE(CCW_STENCILFAIL
);
2252 D3DRS_TO_STRING_CASE(CCW_STENCILZFAIL
);
2253 D3DRS_TO_STRING_CASE(CCW_STENCILPASS
);
2254 D3DRS_TO_STRING_CASE(CCW_STENCILFUNC
);
2255 D3DRS_TO_STRING_CASE(COLORWRITEENABLE1
);
2256 D3DRS_TO_STRING_CASE(COLORWRITEENABLE2
);
2257 D3DRS_TO_STRING_CASE(COLORWRITEENABLE3
);
2258 D3DRS_TO_STRING_CASE(BLENDFACTOR
);
2259 D3DRS_TO_STRING_CASE(SRGBWRITEENABLE
);
2260 D3DRS_TO_STRING_CASE(DEPTHBIAS
);
2261 D3DRS_TO_STRING_CASE(WRAP8
);
2262 D3DRS_TO_STRING_CASE(WRAP9
);
2263 D3DRS_TO_STRING_CASE(WRAP10
);
2264 D3DRS_TO_STRING_CASE(WRAP11
);
2265 D3DRS_TO_STRING_CASE(WRAP12
);
2266 D3DRS_TO_STRING_CASE(WRAP13
);
2267 D3DRS_TO_STRING_CASE(WRAP14
);
2268 D3DRS_TO_STRING_CASE(WRAP15
);
2269 D3DRS_TO_STRING_CASE(SEPARATEALPHABLENDENABLE
);
2270 D3DRS_TO_STRING_CASE(SRCBLENDALPHA
);
2271 D3DRS_TO_STRING_CASE(DESTBLENDALPHA
);
2272 D3DRS_TO_STRING_CASE(BLENDOPALPHA
);