nine_state.c revision 409ad787778461e774b5b0dfa4e6c77f355ca16f
1/* 2 * Copyright 2011 Joakim Sindholt <opensource@zhasha.com> 3 * Copyright 2013 Christoph Bumiller 4 * 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: 11 * 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 14 * Software. 15 * 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. */ 23 24#include "device9.h" 25#include "basetexture9.h" 26#include "buffer9.h" 27#include "indexbuffer9.h" 28#include "surface9.h" 29#include "vertexbuffer9.h" 30#include "vertexdeclaration9.h" 31#include "vertexshader9.h" 32#include "pixelshader9.h" 33#include "nine_pipe.h" 34#include "nine_ff.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" 42 43#define DBG_CHANNEL DBG_DEVICE 44 45/* Check if some states need to be set dirty */ 46 47static inline DWORD 48check_multisample(struct NineDevice9 *device) 49{ 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; 57 } 58 return 0; 59} 60 61/* State preparation only */ 62 63static inline void 64prepare_blend(struct NineDevice9 *device) 65{ 66 nine_convert_blend_state(&device->state.pipe.blend, device->state.rs); 67 device->state.commit |= NINE_STATE_COMMIT_BLEND; 68} 69 70static inline void 71prepare_dsa(struct NineDevice9 *device) 72{ 73 nine_convert_dsa_state(&device->state.pipe.dsa, device->state.rs); 74 device->state.commit |= NINE_STATE_COMMIT_DSA; 75} 76 77static inline void 78prepare_rasterizer(struct NineDevice9 *device) 79{ 80 nine_convert_rasterizer_state(device, &device->state.pipe.rast, device->state.rs); 81 device->state.commit |= NINE_STATE_COMMIT_RASTERIZER; 82} 83 84static void 85prepare_vs_constants_userbuf_swvp(struct NineDevice9 *device) 86{ 87 struct nine_state *state = &device->state; 88 89 if (state->changed.vs_const_f || state->changed.group & NINE_STATE_SWVP) { 90 struct pipe_constant_buffer cb; 91 92 cb.buffer = NULL; 93 cb.buffer_offset = 0; 94 cb.buffer_size = 4096 * sizeof(float[4]); 95 cb.user_buffer = state->vs_const_f_swvp; 96 97 if (state->vs->lconstf.ranges) { 98 const struct nine_lconstf *lconstf = &device->state.vs->lconstf; 99 const struct nine_range *r = lconstf->ranges; 100 unsigned n = 0; 101 float *dst = device->state.vs_lconstf_temp; 102 float *src = (float *)cb.user_buffer; 103 memcpy(dst, src, cb.buffer_size); 104 while (r) { 105 unsigned p = r->bgn; 106 unsigned c = r->end - r->bgn; 107 memcpy(&dst[p * 4], &lconstf->data[n * 4], c * 4 * sizeof(float)); 108 n += c; 109 r = r->next; 110 } 111 cb.user_buffer = dst; 112 } 113 114 state->pipe.cb0_swvp = cb; 115 116 cb.user_buffer = (char *)cb.user_buffer + 4096 * sizeof(float[4]); 117 state->pipe.cb1_swvp = cb; 118 } 119 120 if (state->changed.vs_const_i || state->changed.group & NINE_STATE_SWVP) { 121 struct pipe_constant_buffer cb; 122 123 cb.buffer = NULL; 124 cb.buffer_offset = 0; 125 cb.buffer_size = 2048 * sizeof(float[4]); 126 cb.user_buffer = state->vs_const_i; 127 128 state->pipe.cb2_swvp = cb; 129 } 130 131 if (state->changed.vs_const_b || state->changed.group & NINE_STATE_SWVP) { 132 struct pipe_constant_buffer cb; 133 134 cb.buffer = NULL; 135 cb.buffer_offset = 0; 136 cb.buffer_size = 512 * sizeof(float[4]); 137 cb.user_buffer = state->vs_const_b; 138 139 state->pipe.cb3_swvp = cb; 140 } 141 142 if (!device->driver_caps.user_cbufs) { 143 struct pipe_constant_buffer *cb = &(state->pipe.cb0_swvp); 144 u_upload_data(device->constbuf_uploader, 145 0, 146 cb->buffer_size, 147 device->constbuf_alignment, 148 cb->user_buffer, 149 &(cb->buffer_offset), 150 &(cb->buffer)); 151 u_upload_unmap(device->constbuf_uploader); 152 cb->user_buffer = NULL; 153 154 cb = &(state->pipe.cb1_swvp); 155 u_upload_data(device->constbuf_uploader, 156 0, 157 cb->buffer_size, 158 device->constbuf_alignment, 159 cb->user_buffer, 160 &(cb->buffer_offset), 161 &(cb->buffer)); 162 u_upload_unmap(device->constbuf_uploader); 163 cb->user_buffer = NULL; 164 165 cb = &(state->pipe.cb2_swvp); 166 u_upload_data(device->constbuf_uploader, 167 0, 168 cb->buffer_size, 169 device->constbuf_alignment, 170 cb->user_buffer, 171 &(cb->buffer_offset), 172 &(cb->buffer)); 173 u_upload_unmap(device->constbuf_uploader); 174 cb->user_buffer = NULL; 175 176 cb = &(state->pipe.cb3_swvp); 177 u_upload_data(device->constbuf_uploader, 178 0, 179 cb->buffer_size, 180 device->constbuf_alignment, 181 cb->user_buffer, 182 &(cb->buffer_offset), 183 &(cb->buffer)); 184 u_upload_unmap(device->constbuf_uploader); 185 cb->user_buffer = NULL; 186 } 187 188 if (device->state.changed.vs_const_f) { 189 struct nine_range *r = device->state.changed.vs_const_f; 190 struct nine_range *p = r; 191 while (p->next) 192 p = p->next; 193 nine_range_pool_put_chain(&device->range_pool, r, p); 194 device->state.changed.vs_const_f = NULL; 195 } 196 197 if (device->state.changed.vs_const_i) { 198 struct nine_range *r = device->state.changed.vs_const_i; 199 struct nine_range *p = r; 200 while (p->next) 201 p = p->next; 202 nine_range_pool_put_chain(&device->range_pool, r, p); 203 device->state.changed.vs_const_i = NULL; 204 } 205 206 if (device->state.changed.vs_const_b) { 207 struct nine_range *r = device->state.changed.vs_const_b; 208 struct nine_range *p = r; 209 while (p->next) 210 p = p->next; 211 nine_range_pool_put_chain(&device->range_pool, r, p); 212 device->state.changed.vs_const_b = NULL; 213 } 214 215 state->changed.group &= ~NINE_STATE_VS_CONST; 216 state->commit |= NINE_STATE_COMMIT_CONST_VS; 217} 218 219static void 220prepare_vs_constants_userbuf(struct NineDevice9 *device) 221{ 222 struct nine_state *state = &device->state; 223 struct pipe_constant_buffer cb; 224 cb.buffer = NULL; 225 cb.buffer_offset = 0; 226 cb.buffer_size = device->state.vs->const_used_size; 227 cb.user_buffer = device->state.vs_const_f; 228 229 if (device->swvp) { 230 prepare_vs_constants_userbuf_swvp(device); 231 return; 232 } 233 234 if (state->changed.vs_const_i || state->changed.group & NINE_STATE_SWVP) { 235 int *idst = (int *)&state->vs_const_f[4 * device->max_vs_const_f]; 236 memcpy(idst, state->vs_const_i, NINE_MAX_CONST_I * sizeof(int[4])); 237 } 238 239 if (state->changed.vs_const_b || state->changed.group & NINE_STATE_SWVP) { 240 int *idst = (int *)&state->vs_const_f[4 * device->max_vs_const_f]; 241 uint32_t *bdst = (uint32_t *)&idst[4 * NINE_MAX_CONST_I]; 242 memcpy(bdst, state->vs_const_b, NINE_MAX_CONST_B * sizeof(BOOL)); 243 } 244 245 if (device->state.changed.vs_const_i) { 246 struct nine_range *r = device->state.changed.vs_const_i; 247 struct nine_range *p = r; 248 while (p->next) 249 p = p->next; 250 nine_range_pool_put_chain(&device->range_pool, r, p); 251 device->state.changed.vs_const_i = NULL; 252 } 253 254 if (device->state.changed.vs_const_b) { 255 struct nine_range *r = device->state.changed.vs_const_b; 256 struct nine_range *p = r; 257 while (p->next) 258 p = p->next; 259 nine_range_pool_put_chain(&device->range_pool, r, p); 260 device->state.changed.vs_const_b = NULL; 261 } 262 263 if (!cb.buffer_size) 264 return; 265 266 if (device->state.vs->lconstf.ranges) { 267 /* TODO: Can we make it so that we don't have to copy everything ? */ 268 const struct nine_lconstf *lconstf = &device->state.vs->lconstf; 269 const struct nine_range *r = lconstf->ranges; 270 unsigned n = 0; 271 float *dst = device->state.vs_lconstf_temp; 272 float *src = (float *)cb.user_buffer; 273 memcpy(dst, src, cb.buffer_size); 274 while (r) { 275 unsigned p = r->bgn; 276 unsigned c = r->end - r->bgn; 277 memcpy(&dst[p * 4], &lconstf->data[n * 4], c * 4 * sizeof(float)); 278 n += c; 279 r = r->next; 280 } 281 cb.user_buffer = dst; 282 } 283 284 if (!device->driver_caps.user_cbufs) { 285 u_upload_data(device->constbuf_uploader, 286 0, 287 cb.buffer_size, 288 device->constbuf_alignment, 289 cb.user_buffer, 290 &cb.buffer_offset, 291 &cb.buffer); 292 u_upload_unmap(device->constbuf_uploader); 293 cb.user_buffer = NULL; 294 } 295 296 state->pipe.cb_vs = cb; 297 298 if (device->state.changed.vs_const_f) { 299 struct nine_range *r = device->state.changed.vs_const_f; 300 struct nine_range *p = r; 301 while (p->next) 302 p = p->next; 303 nine_range_pool_put_chain(&device->range_pool, r, p); 304 device->state.changed.vs_const_f = NULL; 305 } 306 307 state->changed.group &= ~NINE_STATE_VS_CONST; 308 state->commit |= NINE_STATE_COMMIT_CONST_VS; 309} 310 311static void 312prepare_ps_constants_userbuf(struct NineDevice9 *device) 313{ 314 struct nine_state *state = &device->state; 315 struct pipe_constant_buffer cb; 316 cb.buffer = NULL; 317 cb.buffer_offset = 0; 318 cb.buffer_size = device->state.ps->const_used_size; 319 cb.user_buffer = device->state.ps_const_f; 320 321 if (state->changed.ps_const_i) { 322 int *idst = (int *)&state->ps_const_f[4 * device->max_ps_const_f]; 323 memcpy(idst, state->ps_const_i, sizeof(state->ps_const_i)); 324 state->changed.ps_const_i = 0; 325 } 326 if (state->changed.ps_const_b) { 327 int *idst = (int *)&state->ps_const_f[4 * device->max_ps_const_f]; 328 uint32_t *bdst = (uint32_t *)&idst[4 * NINE_MAX_CONST_I]; 329 memcpy(bdst, state->ps_const_b, sizeof(state->ps_const_b)); 330 state->changed.ps_const_b = 0; 331 } 332 333 /* Upload special constants needed to implement PS1.x instructions like TEXBEM,TEXBEML and BEM */ 334 if (device->state.ps->bumpenvmat_needed) { 335 memcpy(device->state.ps_lconstf_temp, cb.user_buffer, cb.buffer_size); 336 memcpy(&device->state.ps_lconstf_temp[4 * 8], &device->state.bumpmap_vars, sizeof(device->state.bumpmap_vars)); 337 338 cb.user_buffer = device->state.ps_lconstf_temp; 339 } 340 341 if (state->ps->byte_code.version < 0x30 && 342 state->rs[D3DRS_FOGENABLE]) { 343 float *dst = &state->ps_lconstf_temp[4 * 32]; 344 if (cb.user_buffer != state->ps_lconstf_temp) { 345 memcpy(state->ps_lconstf_temp, cb.user_buffer, cb.buffer_size); 346 cb.user_buffer = state->ps_lconstf_temp; 347 } 348 349 d3dcolor_to_rgba(dst, state->rs[D3DRS_FOGCOLOR]); 350 if (state->rs[D3DRS_FOGTABLEMODE] == D3DFOG_LINEAR) { 351 dst[4] = asfloat(state->rs[D3DRS_FOGEND]); 352 dst[5] = 1.0f / (asfloat(state->rs[D3DRS_FOGEND]) - asfloat(state->rs[D3DRS_FOGSTART])); 353 } else if (state->rs[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) { 354 dst[4] = asfloat(state->rs[D3DRS_FOGDENSITY]); 355 } 356 cb.buffer_size = 4 * 4 * 34; 357 } 358 359 if (!cb.buffer_size) 360 return; 361 362 if (!device->driver_caps.user_cbufs) { 363 u_upload_data(device->constbuf_uploader, 364 0, 365 cb.buffer_size, 366 device->constbuf_alignment, 367 cb.user_buffer, 368 &cb.buffer_offset, 369 &cb.buffer); 370 u_upload_unmap(device->constbuf_uploader); 371 cb.user_buffer = NULL; 372 } 373 374 state->pipe.cb_ps = cb; 375 376 if (device->state.changed.ps_const_f) { 377 struct nine_range *r = device->state.changed.ps_const_f; 378 struct nine_range *p = r; 379 while (p->next) 380 p = p->next; 381 nine_range_pool_put_chain(&device->range_pool, r, p); 382 device->state.changed.ps_const_f = NULL; 383 } 384 state->changed.group &= ~NINE_STATE_PS_CONST; 385 state->commit |= NINE_STATE_COMMIT_CONST_PS; 386} 387 388static inline uint32_t 389prepare_vs(struct NineDevice9 *device, uint8_t shader_changed) 390{ 391 struct nine_state *state = &device->state; 392 struct NineVertexShader9 *vs = state->vs; 393 uint32_t changed_group = 0; 394 int has_key_changed = 0; 395 396 if (likely(state->programmable_vs)) 397 has_key_changed = NineVertexShader9_UpdateKey(vs, device); 398 399 if (!shader_changed && !has_key_changed) 400 return 0; 401 402 /* likely because we dislike FF */ 403 if (likely(state->programmable_vs)) { 404 state->cso.vs = NineVertexShader9_GetVariant(vs); 405 } else { 406 vs = device->ff.vs; 407 state->cso.vs = vs->ff_cso; 408 } 409 410 if (state->rs[NINED3DRS_VSPOINTSIZE] != vs->point_size) { 411 state->rs[NINED3DRS_VSPOINTSIZE] = vs->point_size; 412 changed_group |= NINE_STATE_RASTERIZER; 413 } 414 415 if ((state->bound_samplers_mask_vs & vs->sampler_mask) != vs->sampler_mask) 416 /* Bound dummy sampler. */ 417 changed_group |= NINE_STATE_SAMPLER; 418 419 state->commit |= NINE_STATE_COMMIT_VS; 420 return changed_group; 421} 422 423static inline uint32_t 424prepare_ps(struct NineDevice9 *device, uint8_t shader_changed) 425{ 426 struct nine_state *state = &device->state; 427 struct NinePixelShader9 *ps = state->ps; 428 uint32_t changed_group = 0; 429 int has_key_changed = 0; 430 431 if (likely(ps)) 432 has_key_changed = NinePixelShader9_UpdateKey(ps, state); 433 434 if (!shader_changed && !has_key_changed) 435 return 0; 436 437 if (likely(ps)) { 438 state->cso.ps = NinePixelShader9_GetVariant(ps); 439 } else { 440 ps = device->ff.ps; 441 state->cso.ps = ps->ff_cso; 442 } 443 444 if ((state->bound_samplers_mask_ps & ps->sampler_mask) != ps->sampler_mask) 445 /* Bound dummy sampler. */ 446 changed_group |= NINE_STATE_SAMPLER; 447 448 state->commit |= NINE_STATE_COMMIT_PS; 449 return changed_group; 450} 451 452/* State preparation incremental */ 453 454/* State preparation + State commit */ 455 456static void 457update_framebuffer(struct NineDevice9 *device, bool is_clear) 458{ 459 struct pipe_context *pipe = device->pipe; 460 struct nine_state *state = &device->state; 461 struct pipe_framebuffer_state *fb = &device->state.fb; 462 unsigned i; 463 struct NineSurface9 *rt0 = state->rt[0]; 464 unsigned w = rt0->desc.Width; 465 unsigned h = rt0->desc.Height; 466 unsigned nr_samples = rt0->base.info.nr_samples; 467 unsigned ps_mask = state->ps ? state->ps->rt_mask : 1; 468 unsigned mask = is_clear ? 0xf : ps_mask; 469 const int sRGB = state->rs[D3DRS_SRGBWRITEENABLE] ? 1 : 0; 470 471 DBG("\n"); 472 473 state->rt_mask = 0x0; 474 fb->nr_cbufs = 0; 475 476 /* all render targets must have the same size and the depth buffer must be 477 * bigger. Multisample has to match, according to spec. But some apps do 478 * things wrong there, and no error is returned. The behaviour they get 479 * apparently is that depth buffer is disabled if it doesn't match. 480 * Surely the same for render targets. */ 481 482 /* Special case: D3DFMT_NULL is used to bound no real render target, 483 * but render to depth buffer. We have to not take into account the render 484 * target info. TODO: know what should happen when there are several render targers 485 * and the first one is D3DFMT_NULL */ 486 if (rt0->desc.Format == D3DFMT_NULL && state->ds) { 487 w = state->ds->desc.Width; 488 h = state->ds->desc.Height; 489 nr_samples = state->ds->base.info.nr_samples; 490 } 491 492 for (i = 0; i < device->caps.NumSimultaneousRTs; ++i) { 493 struct NineSurface9 *rt = state->rt[i]; 494 495 if (rt && rt->desc.Format != D3DFMT_NULL && (mask & (1 << i)) && 496 rt->desc.Width == w && rt->desc.Height == h && 497 rt->base.info.nr_samples == nr_samples) { 498 fb->cbufs[i] = NineSurface9_GetSurface(rt, sRGB); 499 state->rt_mask |= 1 << i; 500 fb->nr_cbufs = i + 1; 501 502 if (unlikely(rt->desc.Usage & D3DUSAGE_AUTOGENMIPMAP)) { 503 assert(rt->texture == D3DRTYPE_TEXTURE || 504 rt->texture == D3DRTYPE_CUBETEXTURE); 505 NineBaseTexture9(rt->base.base.container)->dirty_mip = TRUE; 506 } 507 } else { 508 /* Color outputs must match RT slot, 509 * drivers will have to handle NULL entries for GL, too. 510 */ 511 fb->cbufs[i] = NULL; 512 } 513 } 514 515 if (state->ds && state->ds->desc.Width >= w && 516 state->ds->desc.Height >= h && 517 state->ds->base.info.nr_samples == nr_samples) { 518 fb->zsbuf = NineSurface9_GetSurface(state->ds, 0); 519 } else { 520 fb->zsbuf = NULL; 521 } 522 523 fb->width = w; 524 fb->height = h; 525 526 pipe->set_framebuffer_state(pipe, fb); /* XXX: cso ? */ 527 528 if (is_clear && state->rt_mask == ps_mask) 529 state->changed.group &= ~NINE_STATE_FB; 530} 531 532static void 533update_viewport(struct NineDevice9 *device) 534{ 535 const D3DVIEWPORT9 *vport = &device->state.viewport; 536 struct pipe_viewport_state pvport; 537 538 /* D3D coordinates are: 539 * -1 .. +1 for X,Y and 540 * 0 .. +1 for Z (we use pipe_rasterizer_state.clip_halfz) 541 */ 542 pvport.scale[0] = (float)vport->Width * 0.5f; 543 pvport.scale[1] = (float)vport->Height * -0.5f; 544 pvport.scale[2] = vport->MaxZ - vport->MinZ; 545 pvport.translate[0] = (float)vport->Width * 0.5f + (float)vport->X; 546 pvport.translate[1] = (float)vport->Height * 0.5f + (float)vport->Y; 547 pvport.translate[2] = vport->MinZ; 548 549 /* We found R600 and SI cards have some imprecision 550 * on the barycentric coordinates used for interpolation. 551 * Some shaders rely on having something precise. 552 * We found that the proprietary driver has the imprecision issue, 553 * except when the render target width and height are powers of two. 554 * It is using some sort of workaround for these cases 555 * which covers likely all the cases the applications rely 556 * on something precise. 557 * We haven't found the workaround, but it seems like it's better 558 * for applications if the imprecision is biased towards infinity 559 * instead of -infinity (which is what measured). So shift slightly 560 * the viewport: not enough to change rasterization result (in particular 561 * for multisampling), but enough to make the imprecision biased 562 * towards infinity. We do this shift only if render target width and 563 * height are powers of two. 564 * Solves 'red shadows' bug on UE3 games. 565 */ 566 if (device->driver_bugs.buggy_barycentrics && 567 ((vport->Width & (vport->Width-1)) == 0) && 568 ((vport->Height & (vport->Height-1)) == 0)) { 569 pvport.translate[0] -= 1.0f / 128.0f; 570 pvport.translate[1] -= 1.0f / 128.0f; 571 } 572 573 cso_set_viewport(device->cso, &pvport); 574} 575 576/* Loop through VS inputs and pick the vertex elements with the declared 577 * usage from the vertex declaration, then insert the instance divisor from 578 * the stream source frequency setting. 579 */ 580static void 581update_vertex_elements(struct NineDevice9 *device) 582{ 583 struct nine_state *state = &device->state; 584 const struct NineVertexDeclaration9 *vdecl = device->state.vdecl; 585 const struct NineVertexShader9 *vs; 586 unsigned n, b, i; 587 int index; 588 char vdecl_index_map[16]; /* vs->num_inputs <= 16 */ 589 char used_streams[device->caps.MaxStreams]; 590 int dummy_vbo_stream = -1; 591 BOOL need_dummy_vbo = FALSE; 592 struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS]; 593 594 state->stream_usage_mask = 0; 595 memset(vdecl_index_map, -1, 16); 596 memset(used_streams, 0, device->caps.MaxStreams); 597 vs = state->programmable_vs ? device->state.vs : device->ff.vs; 598 599 if (vdecl) { 600 for (n = 0; n < vs->num_inputs; ++n) { 601 DBG("looking up input %u (usage %u) from vdecl(%p)\n", 602 n, vs->input_map[n].ndecl, vdecl); 603 604 for (i = 0; i < vdecl->nelems; i++) { 605 if (vdecl->usage_map[i] == vs->input_map[n].ndecl) { 606 vdecl_index_map[n] = i; 607 used_streams[vdecl->elems[i].vertex_buffer_index] = 1; 608 break; 609 } 610 } 611 if (vdecl_index_map[n] < 0) 612 need_dummy_vbo = TRUE; 613 } 614 } else { 615 /* No vertex declaration. Likely will never happen in practice, 616 * but we need not crash on this */ 617 need_dummy_vbo = TRUE; 618 } 619 620 if (need_dummy_vbo) { 621 for (i = 0; i < device->caps.MaxStreams; i++ ) { 622 if (!used_streams[i]) { 623 dummy_vbo_stream = i; 624 break; 625 } 626 } 627 } 628 /* there are less vertex shader inputs than stream slots, 629 * so if we need a slot for the dummy vbo, we should have found one */ 630 assert (!need_dummy_vbo || dummy_vbo_stream != -1); 631 632 for (n = 0; n < vs->num_inputs; ++n) { 633 index = vdecl_index_map[n]; 634 if (index >= 0) { 635 ve[n] = vdecl->elems[index]; 636 b = ve[n].vertex_buffer_index; 637 state->stream_usage_mask |= 1 << b; 638 /* XXX wine just uses 1 here: */ 639 if (state->stream_freq[b] & D3DSTREAMSOURCE_INSTANCEDATA) 640 ve[n].instance_divisor = state->stream_freq[b] & 0x7FFFFF; 641 } else { 642 /* if the vertex declaration is incomplete compared to what the 643 * vertex shader needs, we bind a dummy vbo with 0 0 0 0. 644 * This is not precised by the spec, but is the behaviour 645 * tested on win */ 646 ve[n].vertex_buffer_index = dummy_vbo_stream; 647 ve[n].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 648 ve[n].src_offset = 0; 649 ve[n].instance_divisor = 0; 650 } 651 } 652 653 if (state->dummy_vbo_bound_at != dummy_vbo_stream) { 654 if (state->dummy_vbo_bound_at >= 0) 655 state->changed.vtxbuf |= 1 << state->dummy_vbo_bound_at; 656 if (dummy_vbo_stream >= 0) { 657 state->changed.vtxbuf |= 1 << dummy_vbo_stream; 658 state->vbo_bound_done = FALSE; 659 } 660 state->dummy_vbo_bound_at = dummy_vbo_stream; 661 } 662 663 cso_set_vertex_elements(device->cso, vs->num_inputs, ve); 664 665 state->changed.stream_freq = 0; 666} 667 668static void 669update_vertex_buffers(struct NineDevice9 *device) 670{ 671 struct pipe_context *pipe = device->pipe; 672 struct nine_state *state = &device->state; 673 struct pipe_vertex_buffer dummy_vtxbuf; 674 uint32_t mask = state->changed.vtxbuf; 675 unsigned i; 676 677 DBG("mask=%x\n", mask); 678 679 if (state->dummy_vbo_bound_at >= 0) { 680 if (!state->vbo_bound_done) { 681 dummy_vtxbuf.buffer = device->dummy_vbo; 682 dummy_vtxbuf.stride = 0; 683 dummy_vtxbuf.user_buffer = NULL; 684 dummy_vtxbuf.buffer_offset = 0; 685 pipe->set_vertex_buffers(pipe, state->dummy_vbo_bound_at, 686 1, &dummy_vtxbuf); 687 state->vbo_bound_done = TRUE; 688 } 689 mask &= ~(1 << state->dummy_vbo_bound_at); 690 } 691 692 for (i = 0; mask; mask >>= 1, ++i) { 693 if (mask & 1) { 694 if (state->vtxbuf[i].buffer) 695 pipe->set_vertex_buffers(pipe, i, 1, &state->vtxbuf[i]); 696 else 697 pipe->set_vertex_buffers(pipe, i, 1, NULL); 698 } 699 } 700 701 state->changed.vtxbuf = 0; 702} 703 704static inline boolean 705update_sampler_derived(struct nine_state *state, unsigned s) 706{ 707 boolean changed = FALSE; 708 709 if (state->samp[s][NINED3DSAMP_SHADOW] != state->texture[s]->shadow) { 710 changed = TRUE; 711 state->samp[s][NINED3DSAMP_SHADOW] = state->texture[s]->shadow; 712 } 713 714 if (state->samp[s][NINED3DSAMP_CUBETEX] != 715 (NineResource9(state->texture[s])->type == D3DRTYPE_CUBETEXTURE)) { 716 changed = TRUE; 717 state->samp[s][NINED3DSAMP_CUBETEX] = 718 NineResource9(state->texture[s])->type == D3DRTYPE_CUBETEXTURE; 719 } 720 721 if (state->samp[s][D3DSAMP_MIPFILTER] != D3DTEXF_NONE) { 722 int lod = state->samp[s][D3DSAMP_MAXMIPLEVEL] - state->texture[s]->managed.lod; 723 if (lod < 0) 724 lod = 0; 725 if (state->samp[s][NINED3DSAMP_MINLOD] != lod) { 726 changed = TRUE; 727 state->samp[s][NINED3DSAMP_MINLOD] = lod; 728 } 729 } else { 730 state->changed.sampler[s] &= ~0x300; /* lod changes irrelevant */ 731 } 732 733 return changed; 734} 735 736/* TODO: add sRGB override to pipe_sampler_state ? */ 737static void 738update_textures_and_samplers(struct NineDevice9 *device) 739{ 740 struct nine_state *state = &device->state; 741 struct pipe_sampler_view *view[NINE_MAX_SAMPLERS]; 742 unsigned num_textures; 743 unsigned i; 744 boolean commit_samplers; 745 uint16_t sampler_mask = state->ps ? state->ps->sampler_mask : 746 device->ff.ps->sampler_mask; 747 748 /* TODO: Can we reduce iterations here ? */ 749 750 commit_samplers = FALSE; 751 state->bound_samplers_mask_ps = 0; 752 for (num_textures = 0, i = 0; i < NINE_MAX_SAMPLERS_PS; ++i) { 753 const unsigned s = NINE_SAMPLER_PS(i); 754 int sRGB; 755 756 if (!state->texture[s] && !(sampler_mask & (1 << i))) { 757 view[i] = NULL; 758 continue; 759 } 760 761 if (state->texture[s]) { 762 sRGB = state->samp[s][D3DSAMP_SRGBTEXTURE] ? 1 : 0; 763 764 view[i] = NineBaseTexture9_GetSamplerView(state->texture[s], sRGB); 765 num_textures = i + 1; 766 767 if (update_sampler_derived(state, s) || (state->changed.sampler[s] & 0x05fe)) { 768 state->changed.sampler[s] = 0; 769 commit_samplers = TRUE; 770 nine_convert_sampler_state(device->cso, s, state->samp[s]); 771 } 772 } else { 773 /* Bind dummy sampler. We do not bind dummy sampler when 774 * it is not needed because it could add overhead. The 775 * dummy sampler should have r=g=b=0 and a=1. We do not 776 * unbind dummy sampler directly when they are not needed 777 * anymore, but they're going to be removed as long as texture 778 * or sampler states are changed. */ 779 view[i] = device->dummy_sampler_view; 780 num_textures = i + 1; 781 782 cso_single_sampler(device->cso, PIPE_SHADER_FRAGMENT, 783 s - NINE_SAMPLER_PS(0), &device->dummy_sampler_state); 784 785 commit_samplers = TRUE; 786 state->changed.sampler[s] = ~0; 787 } 788 789 state->bound_samplers_mask_ps |= (1 << s); 790 } 791 792 cso_set_sampler_views(device->cso, PIPE_SHADER_FRAGMENT, num_textures, view); 793 794 if (commit_samplers) 795 cso_single_sampler_done(device->cso, PIPE_SHADER_FRAGMENT); 796 797 commit_samplers = FALSE; 798 sampler_mask = state->programmable_vs ? state->vs->sampler_mask : 0; 799 state->bound_samplers_mask_vs = 0; 800 for (num_textures = 0, i = 0; i < NINE_MAX_SAMPLERS_VS; ++i) { 801 const unsigned s = NINE_SAMPLER_VS(i); 802 int sRGB; 803 804 if (!state->texture[s] && !(sampler_mask & (1 << i))) { 805 view[i] = NULL; 806 continue; 807 } 808 809 if (state->texture[s]) { 810 sRGB = state->samp[s][D3DSAMP_SRGBTEXTURE] ? 1 : 0; 811 812 view[i] = NineBaseTexture9_GetSamplerView(state->texture[s], sRGB); 813 num_textures = i + 1; 814 815 if (update_sampler_derived(state, s) || (state->changed.sampler[s] & 0x05fe)) { 816 state->changed.sampler[s] = 0; 817 commit_samplers = TRUE; 818 nine_convert_sampler_state(device->cso, s, state->samp[s]); 819 } 820 } else { 821 /* Bind dummy sampler. We do not bind dummy sampler when 822 * it is not needed because it could add overhead. The 823 * dummy sampler should have r=g=b=0 and a=1. We do not 824 * unbind dummy sampler directly when they are not needed 825 * anymore, but they're going to be removed as long as texture 826 * or sampler states are changed. */ 827 view[i] = device->dummy_sampler_view; 828 num_textures = i + 1; 829 830 cso_single_sampler(device->cso, PIPE_SHADER_VERTEX, 831 s - NINE_SAMPLER_VS(0), &device->dummy_sampler_state); 832 833 commit_samplers = TRUE; 834 state->changed.sampler[s] = ~0; 835 } 836 837 state->bound_samplers_mask_vs |= (1 << s); 838 } 839 840 cso_set_sampler_views(device->cso, PIPE_SHADER_VERTEX, num_textures, view); 841 842 if (commit_samplers) 843 cso_single_sampler_done(device->cso, PIPE_SHADER_VERTEX); 844 845 state->changed.texture = 0; 846} 847 848/* State commit only */ 849 850static inline void 851commit_blend(struct NineDevice9 *device) 852{ 853 cso_set_blend(device->cso, &device->state.pipe.blend); 854} 855 856static inline void 857commit_dsa(struct NineDevice9 *device) 858{ 859 cso_set_depth_stencil_alpha(device->cso, &device->state.pipe.dsa); 860} 861 862static inline void 863commit_scissor(struct NineDevice9 *device) 864{ 865 struct pipe_context *pipe = device->pipe; 866 867 pipe->set_scissor_states(pipe, 0, 1, &device->state.scissor); 868} 869 870static inline void 871commit_rasterizer(struct NineDevice9 *device) 872{ 873 cso_set_rasterizer(device->cso, &device->state.pipe.rast); 874} 875 876static inline void 877commit_index_buffer(struct NineDevice9 *device) 878{ 879 struct pipe_context *pipe = device->pipe; 880 if (device->state.idxbuf) 881 pipe->set_index_buffer(pipe, &device->state.idxbuf->buffer); 882 else 883 pipe->set_index_buffer(pipe, NULL); 884} 885 886static inline void 887commit_vs_constants(struct NineDevice9 *device) 888{ 889 struct pipe_context *pipe = device->pipe; 890 891 if (unlikely(!device->state.programmable_vs)) 892 pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &device->state.pipe.cb_vs_ff); 893 else { 894 if (device->swvp) { 895 pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &device->state.pipe.cb0_swvp); 896 pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 1, &device->state.pipe.cb1_swvp); 897 pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 2, &device->state.pipe.cb2_swvp); 898 pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 3, &device->state.pipe.cb3_swvp); 899 } else { 900 pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &device->state.pipe.cb_vs); 901 } 902 } 903} 904 905static inline void 906commit_ps_constants(struct NineDevice9 *device) 907{ 908 struct pipe_context *pipe = device->pipe; 909 910 if (unlikely(!device->state.ps)) 911 pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &device->state.pipe.cb_ps_ff); 912 else 913 pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &device->state.pipe.cb_ps); 914} 915 916static inline void 917commit_vs(struct NineDevice9 *device) 918{ 919 struct nine_state *state = &device->state; 920 921 device->pipe->bind_vs_state(device->pipe, state->cso.vs); 922} 923 924 925static inline void 926commit_ps(struct NineDevice9 *device) 927{ 928 struct nine_state *state = &device->state; 929 930 device->pipe->bind_fs_state(device->pipe, state->cso.ps); 931} 932/* State Update */ 933 934#define NINE_STATE_SHADER_CHANGE_VS \ 935 (NINE_STATE_VS | \ 936 NINE_STATE_TEXTURE | \ 937 NINE_STATE_FOG_SHADER | \ 938 NINE_STATE_POINTSIZE_SHADER | \ 939 NINE_STATE_SWVP) 940 941#define NINE_STATE_SHADER_CHANGE_PS \ 942 (NINE_STATE_PS | \ 943 NINE_STATE_TEXTURE | \ 944 NINE_STATE_FOG_SHADER | \ 945 NINE_STATE_PS1X_SHADER) 946 947#define NINE_STATE_FREQUENT \ 948 (NINE_STATE_RASTERIZER | \ 949 NINE_STATE_TEXTURE | \ 950 NINE_STATE_SAMPLER | \ 951 NINE_STATE_VS_CONST | \ 952 NINE_STATE_PS_CONST | \ 953 NINE_STATE_MULTISAMPLE) 954 955#define NINE_STATE_COMMON \ 956 (NINE_STATE_FB | \ 957 NINE_STATE_BLEND | \ 958 NINE_STATE_DSA | \ 959 NINE_STATE_VIEWPORT | \ 960 NINE_STATE_VDECL | \ 961 NINE_STATE_IDXBUF | \ 962 NINE_STATE_STREAMFREQ) 963 964#define NINE_STATE_RARE \ 965 (NINE_STATE_SCISSOR | \ 966 NINE_STATE_BLEND_COLOR | \ 967 NINE_STATE_STENCIL_REF | \ 968 NINE_STATE_SAMPLE_MASK) 969 970 971/* TODO: only go through dirty textures */ 972static void 973validate_textures(struct NineDevice9 *device) 974{ 975 struct NineBaseTexture9 *tex, *ptr; 976 LIST_FOR_EACH_ENTRY_SAFE(tex, ptr, &device->update_textures, list) { 977 list_delinit(&tex->list); 978 NineBaseTexture9_Validate(tex); 979 } 980} 981 982static void 983update_managed_buffers(struct NineDevice9 *device) 984{ 985 struct NineBuffer9 *buf, *ptr; 986 LIST_FOR_EACH_ENTRY_SAFE(buf, ptr, &device->update_buffers, managed.list) { 987 list_delinit(&buf->managed.list); 988 NineBuffer9_Upload(buf); 989 } 990} 991 992void 993nine_update_state_framebuffer_clear(struct NineDevice9 *device) 994{ 995 struct nine_state *state = &device->state; 996 997 validate_textures(device); 998 999 if (state->changed.group & NINE_STATE_FB) 1000 update_framebuffer(device, TRUE); 1001} 1002 1003boolean 1004nine_update_state(struct NineDevice9 *device) 1005{ 1006 struct pipe_context *pipe = device->pipe; 1007 struct nine_state *state = &device->state; 1008 uint32_t group; 1009 1010 DBG("changed state groups: %x\n", state->changed.group); 1011 1012 /* NOTE: We may want to use the cso cache for everything, or let 1013 * NineDevice9.RestoreNonCSOState actually set the states, then we wouldn't 1014 * have to care about state being clobbered here and could merge this back 1015 * into update_textures. Except, we also need to re-validate textures that 1016 * may be dirty anyway, even if no texture bindings changed. 1017 */ 1018 validate_textures(device); /* may clobber state */ 1019 update_managed_buffers(device); 1020 1021 /* ff_update may change VS/PS dirty bits */ 1022 if (unlikely(!state->programmable_vs || !state->ps)) 1023 nine_ff_update(device); 1024 group = state->changed.group; 1025 1026 if (group & (NINE_STATE_SHADER_CHANGE_VS | NINE_STATE_SHADER_CHANGE_PS)) { 1027 if (group & NINE_STATE_SHADER_CHANGE_VS) 1028 group |= prepare_vs(device, (group & NINE_STATE_VS) != 0); /* may set NINE_STATE_RASTERIZER and NINE_STATE_SAMPLER*/ 1029 if (group & NINE_STATE_SHADER_CHANGE_PS) 1030 group |= prepare_ps(device, (group & NINE_STATE_PS) != 0); 1031 } 1032 1033 if (group & (NINE_STATE_COMMON | NINE_STATE_VS)) { 1034 if (group & NINE_STATE_FB) 1035 update_framebuffer(device, FALSE); 1036 if (group & NINE_STATE_BLEND) 1037 prepare_blend(device); 1038 if (group & NINE_STATE_DSA) 1039 prepare_dsa(device); 1040 if (group & NINE_STATE_VIEWPORT) 1041 update_viewport(device); 1042 if (group & (NINE_STATE_VDECL | NINE_STATE_VS | NINE_STATE_STREAMFREQ)) 1043 update_vertex_elements(device); 1044 if (group & NINE_STATE_IDXBUF) 1045 commit_index_buffer(device); 1046 } 1047 1048 if (likely(group & (NINE_STATE_FREQUENT | NINE_STATE_VS | NINE_STATE_PS | NINE_STATE_SWVP))) { 1049 if (group & NINE_STATE_MULTISAMPLE) 1050 group |= check_multisample(device); 1051 if (group & NINE_STATE_RASTERIZER) 1052 prepare_rasterizer(device); 1053 if (group & (NINE_STATE_TEXTURE | NINE_STATE_SAMPLER)) 1054 update_textures_and_samplers(device); 1055 if ((group & (NINE_STATE_VS_CONST | NINE_STATE_VS | NINE_STATE_SWVP)) && state->programmable_vs) 1056 prepare_vs_constants_userbuf(device); 1057 if ((group & (NINE_STATE_PS_CONST | NINE_STATE_PS)) && state->ps) 1058 prepare_ps_constants_userbuf(device); 1059 } 1060 1061 if (state->changed.vtxbuf) 1062 update_vertex_buffers(device); 1063 1064 if (state->commit & NINE_STATE_COMMIT_BLEND) 1065 commit_blend(device); 1066 if (state->commit & NINE_STATE_COMMIT_DSA) 1067 commit_dsa(device); 1068 if (state->commit & NINE_STATE_COMMIT_RASTERIZER) 1069 commit_rasterizer(device); 1070 if (state->commit & NINE_STATE_COMMIT_CONST_VS) 1071 commit_vs_constants(device); 1072 if (state->commit & NINE_STATE_COMMIT_CONST_PS) 1073 commit_ps_constants(device); 1074 if (state->commit & NINE_STATE_COMMIT_VS) 1075 commit_vs(device); 1076 if (state->commit & NINE_STATE_COMMIT_PS) 1077 commit_ps(device); 1078 1079 state->commit = 0; 1080 1081 if (unlikely(state->changed.ucp)) { 1082 pipe->set_clip_state(pipe, &state->clip); 1083 state->changed.ucp = 0; 1084 } 1085 1086 if (unlikely(group & NINE_STATE_RARE)) { 1087 if (group & NINE_STATE_SCISSOR) 1088 commit_scissor(device); 1089 if (group & NINE_STATE_BLEND_COLOR) { 1090 struct pipe_blend_color color; 1091 d3dcolor_to_rgba(&color.color[0], state->rs[D3DRS_BLENDFACTOR]); 1092 pipe->set_blend_color(pipe, &color); 1093 } 1094 if (group & NINE_STATE_SAMPLE_MASK) { 1095 if (state->rt[0]->desc.MultiSampleType == D3DMULTISAMPLE_NONMASKABLE) { 1096 pipe->set_sample_mask(pipe, ~0); 1097 } else { 1098 pipe->set_sample_mask(pipe, state->rs[D3DRS_MULTISAMPLEMASK]); 1099 } 1100 } 1101 if (group & NINE_STATE_STENCIL_REF) { 1102 struct pipe_stencil_ref ref; 1103 ref.ref_value[0] = state->rs[D3DRS_STENCILREF]; 1104 ref.ref_value[1] = ref.ref_value[0]; 1105 pipe->set_stencil_ref(pipe, &ref); 1106 } 1107 } 1108 1109 device->state.changed.group &= 1110 (NINE_STATE_FF | NINE_STATE_VS_CONST | NINE_STATE_PS_CONST); 1111 1112 DBG("finished\n"); 1113 1114 return TRUE; 1115} 1116 1117/* State defaults */ 1118 1119static const DWORD nine_render_state_defaults[NINED3DRS_LAST + 1] = 1120{ 1121 /* [D3DRS_ZENABLE] = D3DZB_TRUE; wine: auto_depth_stencil */ 1122 [D3DRS_ZENABLE] = D3DZB_FALSE, 1123 [D3DRS_FILLMODE] = D3DFILL_SOLID, 1124 [D3DRS_SHADEMODE] = D3DSHADE_GOURAUD, 1125/* [D3DRS_LINEPATTERN] = 0x00000000, */ 1126 [D3DRS_ZWRITEENABLE] = TRUE, 1127 [D3DRS_ALPHATESTENABLE] = FALSE, 1128 [D3DRS_LASTPIXEL] = TRUE, 1129 [D3DRS_SRCBLEND] = D3DBLEND_ONE, 1130 [D3DRS_DESTBLEND] = D3DBLEND_ZERO, 1131 [D3DRS_CULLMODE] = D3DCULL_CCW, 1132 [D3DRS_ZFUNC] = D3DCMP_LESSEQUAL, 1133 [D3DRS_ALPHAFUNC] = D3DCMP_ALWAYS, 1134 [D3DRS_ALPHAREF] = 0, 1135 [D3DRS_DITHERENABLE] = FALSE, 1136 [D3DRS_ALPHABLENDENABLE] = FALSE, 1137 [D3DRS_FOGENABLE] = FALSE, 1138 [D3DRS_SPECULARENABLE] = FALSE, 1139/* [D3DRS_ZVISIBLE] = 0, */ 1140 [D3DRS_FOGCOLOR] = 0, 1141 [D3DRS_FOGTABLEMODE] = D3DFOG_NONE, 1142 [D3DRS_FOGSTART] = 0x00000000, 1143 [D3DRS_FOGEND] = 0x3F800000, 1144 [D3DRS_FOGDENSITY] = 0x3F800000, 1145/* [D3DRS_EDGEANTIALIAS] = FALSE, */ 1146 [D3DRS_RANGEFOGENABLE] = FALSE, 1147 [D3DRS_STENCILENABLE] = FALSE, 1148 [D3DRS_STENCILFAIL] = D3DSTENCILOP_KEEP, 1149 [D3DRS_STENCILZFAIL] = D3DSTENCILOP_KEEP, 1150 [D3DRS_STENCILPASS] = D3DSTENCILOP_KEEP, 1151 [D3DRS_STENCILREF] = 0, 1152 [D3DRS_STENCILMASK] = 0xFFFFFFFF, 1153 [D3DRS_STENCILFUNC] = D3DCMP_ALWAYS, 1154 [D3DRS_STENCILWRITEMASK] = 0xFFFFFFFF, 1155 [D3DRS_TEXTUREFACTOR] = 0xFFFFFFFF, 1156 [D3DRS_WRAP0] = 0, 1157 [D3DRS_WRAP1] = 0, 1158 [D3DRS_WRAP2] = 0, 1159 [D3DRS_WRAP3] = 0, 1160 [D3DRS_WRAP4] = 0, 1161 [D3DRS_WRAP5] = 0, 1162 [D3DRS_WRAP6] = 0, 1163 [D3DRS_WRAP7] = 0, 1164 [D3DRS_CLIPPING] = TRUE, 1165 [D3DRS_LIGHTING] = TRUE, 1166 [D3DRS_AMBIENT] = 0, 1167 [D3DRS_FOGVERTEXMODE] = D3DFOG_NONE, 1168 [D3DRS_COLORVERTEX] = TRUE, 1169 [D3DRS_LOCALVIEWER] = TRUE, 1170 [D3DRS_NORMALIZENORMALS] = FALSE, 1171 [D3DRS_DIFFUSEMATERIALSOURCE] = D3DMCS_COLOR1, 1172 [D3DRS_SPECULARMATERIALSOURCE] = D3DMCS_COLOR2, 1173 [D3DRS_AMBIENTMATERIALSOURCE] = D3DMCS_MATERIAL, 1174 [D3DRS_EMISSIVEMATERIALSOURCE] = D3DMCS_MATERIAL, 1175 [D3DRS_VERTEXBLEND] = D3DVBF_DISABLE, 1176 [D3DRS_CLIPPLANEENABLE] = 0, 1177/* [D3DRS_SOFTWAREVERTEXPROCESSING] = FALSE, */ 1178 [D3DRS_POINTSIZE] = 0x3F800000, 1179 [D3DRS_POINTSIZE_MIN] = 0x3F800000, 1180 [D3DRS_POINTSPRITEENABLE] = FALSE, 1181 [D3DRS_POINTSCALEENABLE] = FALSE, 1182 [D3DRS_POINTSCALE_A] = 0x3F800000, 1183 [D3DRS_POINTSCALE_B] = 0x00000000, 1184 [D3DRS_POINTSCALE_C] = 0x00000000, 1185 [D3DRS_MULTISAMPLEANTIALIAS] = TRUE, 1186 [D3DRS_MULTISAMPLEMASK] = 0xFFFFFFFF, 1187 [D3DRS_PATCHEDGESTYLE] = D3DPATCHEDGE_DISCRETE, 1188/* [D3DRS_PATCHSEGMENTS] = 0x3F800000, */ 1189 [D3DRS_DEBUGMONITORTOKEN] = 0xDEADCAFE, 1190 [D3DRS_POINTSIZE_MAX] = 0x3F800000, /* depends on cap */ 1191 [D3DRS_INDEXEDVERTEXBLENDENABLE] = FALSE, 1192 [D3DRS_COLORWRITEENABLE] = 0x0000000f, 1193 [D3DRS_TWEENFACTOR] = 0x00000000, 1194 [D3DRS_BLENDOP] = D3DBLENDOP_ADD, 1195 [D3DRS_POSITIONDEGREE] = D3DDEGREE_CUBIC, 1196 [D3DRS_NORMALDEGREE] = D3DDEGREE_LINEAR, 1197 [D3DRS_SCISSORTESTENABLE] = FALSE, 1198 [D3DRS_SLOPESCALEDEPTHBIAS] = 0, 1199 [D3DRS_MINTESSELLATIONLEVEL] = 0x3F800000, 1200 [D3DRS_MAXTESSELLATIONLEVEL] = 0x3F800000, 1201 [D3DRS_ANTIALIASEDLINEENABLE] = FALSE, 1202 [D3DRS_ADAPTIVETESS_X] = 0x00000000, 1203 [D3DRS_ADAPTIVETESS_Y] = 0x00000000, 1204 [D3DRS_ADAPTIVETESS_Z] = 0x3F800000, 1205 [D3DRS_ADAPTIVETESS_W] = 0x00000000, 1206 [D3DRS_ENABLEADAPTIVETESSELLATION] = FALSE, 1207 [D3DRS_TWOSIDEDSTENCILMODE] = FALSE, 1208 [D3DRS_CCW_STENCILFAIL] = D3DSTENCILOP_KEEP, 1209 [D3DRS_CCW_STENCILZFAIL] = D3DSTENCILOP_KEEP, 1210 [D3DRS_CCW_STENCILPASS] = D3DSTENCILOP_KEEP, 1211 [D3DRS_CCW_STENCILFUNC] = D3DCMP_ALWAYS, 1212 [D3DRS_COLORWRITEENABLE1] = 0x0000000F, 1213 [D3DRS_COLORWRITEENABLE2] = 0x0000000F, 1214 [D3DRS_COLORWRITEENABLE3] = 0x0000000F, 1215 [D3DRS_BLENDFACTOR] = 0xFFFFFFFF, 1216 [D3DRS_SRGBWRITEENABLE] = 0, 1217 [D3DRS_DEPTHBIAS] = 0, 1218 [D3DRS_WRAP8] = 0, 1219 [D3DRS_WRAP9] = 0, 1220 [D3DRS_WRAP10] = 0, 1221 [D3DRS_WRAP11] = 0, 1222 [D3DRS_WRAP12] = 0, 1223 [D3DRS_WRAP13] = 0, 1224 [D3DRS_WRAP14] = 0, 1225 [D3DRS_WRAP15] = 0, 1226 [D3DRS_SEPARATEALPHABLENDENABLE] = FALSE, 1227 [D3DRS_SRCBLENDALPHA] = D3DBLEND_ONE, 1228 [D3DRS_DESTBLENDALPHA] = D3DBLEND_ZERO, 1229 [D3DRS_BLENDOPALPHA] = D3DBLENDOP_ADD, 1230 [NINED3DRS_VSPOINTSIZE] = FALSE, 1231 [NINED3DRS_RTMASK] = 0xf, 1232 [NINED3DRS_ALPHACOVERAGE] = FALSE, 1233 [NINED3DRS_MULTISAMPLE] = FALSE 1234}; 1235static const DWORD nine_tex_stage_state_defaults[NINED3DTSS_LAST + 1] = 1236{ 1237 [D3DTSS_COLOROP] = D3DTOP_DISABLE, 1238 [D3DTSS_ALPHAOP] = D3DTOP_DISABLE, 1239 [D3DTSS_COLORARG1] = D3DTA_TEXTURE, 1240 [D3DTSS_COLORARG2] = D3DTA_CURRENT, 1241 [D3DTSS_COLORARG0] = D3DTA_CURRENT, 1242 [D3DTSS_ALPHAARG1] = D3DTA_TEXTURE, 1243 [D3DTSS_ALPHAARG2] = D3DTA_CURRENT, 1244 [D3DTSS_ALPHAARG0] = D3DTA_CURRENT, 1245 [D3DTSS_RESULTARG] = D3DTA_CURRENT, 1246 [D3DTSS_BUMPENVMAT00] = 0, 1247 [D3DTSS_BUMPENVMAT01] = 0, 1248 [D3DTSS_BUMPENVMAT10] = 0, 1249 [D3DTSS_BUMPENVMAT11] = 0, 1250 [D3DTSS_BUMPENVLSCALE] = 0, 1251 [D3DTSS_BUMPENVLOFFSET] = 0, 1252 [D3DTSS_TEXCOORDINDEX] = 0, 1253 [D3DTSS_TEXTURETRANSFORMFLAGS] = D3DTTFF_DISABLE, 1254}; 1255static const DWORD nine_samp_state_defaults[NINED3DSAMP_LAST + 1] = 1256{ 1257 [D3DSAMP_ADDRESSU] = D3DTADDRESS_WRAP, 1258 [D3DSAMP_ADDRESSV] = D3DTADDRESS_WRAP, 1259 [D3DSAMP_ADDRESSW] = D3DTADDRESS_WRAP, 1260 [D3DSAMP_BORDERCOLOR] = 0, 1261 [D3DSAMP_MAGFILTER] = D3DTEXF_POINT, 1262 [D3DSAMP_MINFILTER] = D3DTEXF_POINT, 1263 [D3DSAMP_MIPFILTER] = D3DTEXF_NONE, 1264 [D3DSAMP_MIPMAPLODBIAS] = 0, 1265 [D3DSAMP_MAXMIPLEVEL] = 0, 1266 [D3DSAMP_MAXANISOTROPY] = 1, 1267 [D3DSAMP_SRGBTEXTURE] = 0, 1268 [D3DSAMP_ELEMENTINDEX] = 0, 1269 [D3DSAMP_DMAPOFFSET] = 0, 1270 [NINED3DSAMP_MINLOD] = 0, 1271 [NINED3DSAMP_SHADOW] = 0, 1272 [NINED3DSAMP_CUBETEX] = 0 1273}; 1274 1275void nine_state_restore_non_cso(struct NineDevice9 *device) 1276{ 1277 struct nine_state *state = &device->state; 1278 1279 state->changed.group = NINE_STATE_ALL; 1280 state->changed.vtxbuf = (1ULL << device->caps.MaxStreams) - 1; 1281 state->changed.ucp = (1 << PIPE_MAX_CLIP_PLANES) - 1; 1282 state->changed.texture = NINE_PS_SAMPLERS_MASK | NINE_VS_SAMPLERS_MASK; 1283 state->commit |= NINE_STATE_COMMIT_CONST_VS | NINE_STATE_COMMIT_CONST_PS; 1284} 1285 1286void 1287nine_state_set_defaults(struct NineDevice9 *device, const D3DCAPS9 *caps, 1288 boolean is_reset) 1289{ 1290 struct nine_state *state = &device->state; 1291 unsigned s; 1292 1293 /* Initialize defaults. 1294 */ 1295 memcpy(state->rs, nine_render_state_defaults, sizeof(state->rs)); 1296 1297 for (s = 0; s < ARRAY_SIZE(state->ff.tex_stage); ++s) { 1298 memcpy(&state->ff.tex_stage[s], nine_tex_stage_state_defaults, 1299 sizeof(state->ff.tex_stage[s])); 1300 state->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] = s; 1301 } 1302 state->ff.tex_stage[0][D3DTSS_COLOROP] = D3DTOP_MODULATE; 1303 state->ff.tex_stage[0][D3DTSS_ALPHAOP] = D3DTOP_SELECTARG1; 1304 memset(&state->bumpmap_vars, 0, sizeof(state->bumpmap_vars)); 1305 1306 for (s = 0; s < ARRAY_SIZE(state->samp); ++s) { 1307 memcpy(&state->samp[s], nine_samp_state_defaults, 1308 sizeof(state->samp[s])); 1309 memcpy(&state->samp_advertised[s], nine_samp_state_defaults, 1310 sizeof(state->samp_advertised[s])); 1311 } 1312 1313 if (state->vs_const_f) 1314 memset(state->vs_const_f, 0, device->vs_const_size); 1315 if (state->ps_const_f) 1316 memset(state->ps_const_f, 0, device->ps_const_size); 1317 1318 /* Cap dependent initial state: 1319 */ 1320 state->rs[D3DRS_POINTSIZE_MAX] = fui(caps->MaxPointSize); 1321 1322 memcpy(state->rs_advertised, state->rs, sizeof(state->rs)); 1323 1324 /* Set changed flags to initialize driver. 1325 */ 1326 state->changed.group = NINE_STATE_ALL; 1327 state->changed.vtxbuf = (1ULL << device->caps.MaxStreams) - 1; 1328 state->changed.ucp = (1 << PIPE_MAX_CLIP_PLANES) - 1; 1329 state->changed.texture = NINE_PS_SAMPLERS_MASK | NINE_VS_SAMPLERS_MASK; 1330 1331 state->ff.changed.transform[0] = ~0; 1332 state->ff.changed.transform[D3DTS_WORLD / 32] |= 1 << (D3DTS_WORLD % 32); 1333 1334 if (!is_reset) { 1335 state->viewport.MinZ = 0.0f; 1336 state->viewport.MaxZ = 1.0f; 1337 } 1338 1339 for (s = 0; s < ARRAY_SIZE(state->changed.sampler); ++s) 1340 state->changed.sampler[s] = ~0; 1341 1342 if (!is_reset) { 1343 state->dummy_vbo_bound_at = -1; 1344 state->vbo_bound_done = FALSE; 1345 } 1346} 1347 1348void 1349nine_state_clear(struct nine_state *state, const boolean device) 1350{ 1351 unsigned i; 1352 1353 for (i = 0; i < ARRAY_SIZE(state->rt); ++i) 1354 nine_bind(&state->rt[i], NULL); 1355 nine_bind(&state->ds, NULL); 1356 nine_bind(&state->vs, NULL); 1357 nine_bind(&state->ps, NULL); 1358 nine_bind(&state->vdecl, NULL); 1359 for (i = 0; i < PIPE_MAX_ATTRIBS; ++i) { 1360 nine_bind(&state->stream[i], NULL); 1361 pipe_resource_reference(&state->vtxbuf[i].buffer, NULL); 1362 } 1363 nine_bind(&state->idxbuf, NULL); 1364 for (i = 0; i < NINE_MAX_SAMPLERS; ++i) { 1365 if (device && 1366 state->texture[i] && 1367 --state->texture[i]->bind_count == 0) 1368 list_delinit(&state->texture[i]->list); 1369 nine_bind(&state->texture[i], NULL); 1370 } 1371} 1372 1373void 1374nine_state_init_sw(struct NineDevice9 *device) 1375{ 1376 struct pipe_context *pipe_sw = device->pipe_sw; 1377 struct pipe_rasterizer_state rast; 1378 struct pipe_blend_state blend; 1379 struct pipe_depth_stencil_alpha_state dsa; 1380 struct pipe_framebuffer_state fb; 1381 1382 /* Only used with Streamout */ 1383 memset(&rast, 0, sizeof(rast)); 1384 rast.rasterizer_discard = true; 1385 rast.point_quad_rasterization = 1; /* to make llvmpipe happy */ 1386 cso_set_rasterizer(device->cso_sw, &rast); 1387 1388 /* dummy settings */ 1389 memset(&blend, 0, sizeof(blend)); 1390 memset(&dsa, 0, sizeof(dsa)); 1391 memset(&fb, 0, sizeof(fb)); 1392 cso_set_blend(device->cso_sw, &blend); 1393 cso_set_depth_stencil_alpha(device->cso_sw, &dsa); 1394 cso_set_framebuffer(device->cso_sw, &fb); 1395 cso_set_viewport_dims(device->cso_sw, 1.0, 1.0, false); 1396 cso_set_fragment_shader_handle(device->cso_sw, util_make_empty_fragment_shader(pipe_sw)); 1397} 1398 1399/* There is duplication with update_vertex_elements. 1400 * TODO: Share the code */ 1401 1402static void 1403update_vertex_elements_sw(struct NineDevice9 *device) 1404{ 1405 struct nine_state *state = &device->state; 1406 const struct NineVertexDeclaration9 *vdecl = device->state.vdecl; 1407 const struct NineVertexShader9 *vs; 1408 unsigned n, b, i; 1409 int index; 1410 char vdecl_index_map[16]; /* vs->num_inputs <= 16 */ 1411 char used_streams[device->caps.MaxStreams]; 1412 int dummy_vbo_stream = -1; 1413 BOOL need_dummy_vbo = FALSE; 1414 struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS]; 1415 1416 memset(vdecl_index_map, -1, 16); 1417 memset(used_streams, 0, device->caps.MaxStreams); 1418 vs = state->programmable_vs ? device->state.vs : device->ff.vs; 1419 1420 if (vdecl) { 1421 for (n = 0; n < vs->num_inputs; ++n) { 1422 DBG("looking up input %u (usage %u) from vdecl(%p)\n", 1423 n, vs->input_map[n].ndecl, vdecl); 1424 1425 for (i = 0; i < vdecl->nelems; i++) { 1426 if (vdecl->usage_map[i] == vs->input_map[n].ndecl) { 1427 vdecl_index_map[n] = i; 1428 used_streams[vdecl->elems[i].vertex_buffer_index] = 1; 1429 break; 1430 } 1431 } 1432 if (vdecl_index_map[n] < 0) 1433 need_dummy_vbo = TRUE; 1434 } 1435 } else { 1436 /* No vertex declaration. Likely will never happen in practice, 1437 * but we need not crash on this */ 1438 need_dummy_vbo = TRUE; 1439 } 1440 1441 if (need_dummy_vbo) { 1442 for (i = 0; i < device->caps.MaxStreams; i++ ) { 1443 if (!used_streams[i]) { 1444 dummy_vbo_stream = i; 1445 break; 1446 } 1447 } 1448 } 1449 /* there are less vertex shader inputs than stream slots, 1450 * so if we need a slot for the dummy vbo, we should have found one */ 1451 assert (!need_dummy_vbo || dummy_vbo_stream != -1); 1452 1453 for (n = 0; n < vs->num_inputs; ++n) { 1454 index = vdecl_index_map[n]; 1455 if (index >= 0) { 1456 ve[n] = vdecl->elems[index]; 1457 b = ve[n].vertex_buffer_index; 1458 /* XXX wine just uses 1 here: */ 1459 if (state->stream_freq[b] & D3DSTREAMSOURCE_INSTANCEDATA) 1460 ve[n].instance_divisor = state->stream_freq[b] & 0x7FFFFF; 1461 } else { 1462 /* if the vertex declaration is incomplete compared to what the 1463 * vertex shader needs, we bind a dummy vbo with 0 0 0 0. 1464 * This is not precised by the spec, but is the behaviour 1465 * tested on win */ 1466 ve[n].vertex_buffer_index = dummy_vbo_stream; 1467 ve[n].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 1468 ve[n].src_offset = 0; 1469 ve[n].instance_divisor = 0; 1470 } 1471 } 1472 1473 if (state->dummy_vbo_bound_at != dummy_vbo_stream) { 1474 if (state->dummy_vbo_bound_at >= 0) 1475 state->changed.vtxbuf |= 1 << state->dummy_vbo_bound_at; 1476 if (dummy_vbo_stream >= 0) { 1477 state->changed.vtxbuf |= 1 << dummy_vbo_stream; 1478 state->vbo_bound_done = FALSE; 1479 } 1480 state->dummy_vbo_bound_at = dummy_vbo_stream; 1481 } 1482 1483 cso_set_vertex_elements(device->cso_sw, vs->num_inputs, ve); 1484} 1485 1486static void 1487update_vertex_buffers_sw(struct NineDevice9 *device, int start_vertice, int num_vertices) 1488{ 1489 struct pipe_context *pipe = device->pipe; 1490 struct pipe_context *pipe_sw = device->pipe_sw; 1491 struct nine_state *state = &device->state; 1492 struct pipe_vertex_buffer vtxbuf; 1493 uint32_t mask = 0xf; 1494 unsigned i; 1495 1496 DBG("mask=%x\n", mask); 1497 1498 assert (state->dummy_vbo_bound_at < 0); 1499 /* TODO: handle dummy_vbo_bound_at */ 1500 1501 for (i = 0; mask; mask >>= 1, ++i) { 1502 if (mask & 1) { 1503 if (state->vtxbuf[i].buffer) { 1504 struct pipe_resource *buf; 1505 struct pipe_box box; 1506 1507 vtxbuf = state->vtxbuf[i]; 1508 1509 DBG("Locking %p (offset %d, length %d)\n", vtxbuf.buffer, 1510 vtxbuf.buffer_offset, num_vertices * vtxbuf.stride); 1511 1512 u_box_1d(vtxbuf.buffer_offset + start_vertice * vtxbuf.stride, 1513 num_vertices * vtxbuf.stride, &box); 1514 buf = vtxbuf.buffer; 1515 vtxbuf.user_buffer = pipe->transfer_map(pipe, buf, 0, PIPE_TRANSFER_READ, &box, 1516 &(state->transfers_so[i])); 1517 vtxbuf.buffer = NULL; 1518 if (!device->driver_caps.user_sw_vbufs) { 1519 u_upload_data(device->vertex_sw_uploader, 1520 0, 1521 box.width, 1522 16, 1523 vtxbuf.user_buffer, 1524 &(vtxbuf.buffer_offset), 1525 &(vtxbuf.buffer)); 1526 u_upload_unmap(device->vertex_sw_uploader); 1527 vtxbuf.user_buffer = NULL; 1528 } 1529 pipe_sw->set_vertex_buffers(pipe_sw, i, 1, &vtxbuf); 1530 if (vtxbuf.buffer) 1531 pipe_resource_reference(&vtxbuf.buffer, NULL); 1532 } else 1533 pipe_sw->set_vertex_buffers(pipe_sw, i, 1, NULL); 1534 } 1535 } 1536} 1537 1538static void 1539update_vs_constants_sw(struct NineDevice9 *device) 1540{ 1541 struct nine_state *state = &device->state; 1542 struct pipe_context *pipe_sw = device->pipe_sw; 1543 1544 DBG("updating\n"); 1545 1546 { 1547 struct pipe_constant_buffer cb; 1548 const void *buf; 1549 1550 cb.buffer = NULL; 1551 cb.buffer_offset = 0; 1552 cb.buffer_size = 4096 * sizeof(float[4]); 1553 cb.user_buffer = state->vs_const_f_swvp; 1554 1555 if (state->vs->lconstf.ranges) { 1556 const struct nine_lconstf *lconstf = &device->state.vs->lconstf; 1557 const struct nine_range *r = lconstf->ranges; 1558 unsigned n = 0; 1559 float *dst = device->state.vs_lconstf_temp; 1560 float *src = (float *)cb.user_buffer; 1561 memcpy(dst, src, 8192 * sizeof(float[4])); 1562 while (r) { 1563 unsigned p = r->bgn; 1564 unsigned c = r->end - r->bgn; 1565 memcpy(&dst[p * 4], &lconstf->data[n * 4], c * 4 * sizeof(float)); 1566 n += c; 1567 r = r->next; 1568 } 1569 cb.user_buffer = dst; 1570 } 1571 1572 buf = cb.user_buffer; 1573 if (!device->driver_caps.user_sw_cbufs) { 1574 u_upload_data(device->constbuf_sw_uploader, 1575 0, 1576 cb.buffer_size, 1577 16, 1578 cb.user_buffer, 1579 &(cb.buffer_offset), 1580 &(cb.buffer)); 1581 u_upload_unmap(device->constbuf_sw_uploader); 1582 cb.user_buffer = NULL; 1583 } 1584 1585 pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 0, &cb); 1586 if (cb.buffer) 1587 pipe_resource_reference(&cb.buffer, NULL); 1588 1589 cb.user_buffer = (char *)buf + 4096 * sizeof(float[4]); 1590 if (!device->driver_caps.user_sw_cbufs) { 1591 u_upload_data(device->constbuf_sw_uploader, 1592 0, 1593 cb.buffer_size, 1594 16, 1595 cb.user_buffer, 1596 &(cb.buffer_offset), 1597 &(cb.buffer)); 1598 u_upload_unmap(device->constbuf_sw_uploader); 1599 cb.user_buffer = NULL; 1600 } 1601 1602 pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 1, &cb); 1603 if (cb.buffer) 1604 pipe_resource_reference(&cb.buffer, NULL); 1605 } 1606 1607 { 1608 struct pipe_constant_buffer cb; 1609 1610 cb.buffer = NULL; 1611 cb.buffer_offset = 0; 1612 cb.buffer_size = 2048 * sizeof(float[4]); 1613 cb.user_buffer = state->vs_const_i; 1614 1615 if (!device->driver_caps.user_sw_cbufs) { 1616 u_upload_data(device->constbuf_sw_uploader, 1617 0, 1618 cb.buffer_size, 1619 16, 1620 cb.user_buffer, 1621 &(cb.buffer_offset), 1622 &(cb.buffer)); 1623 u_upload_unmap(device->constbuf_sw_uploader); 1624 cb.user_buffer = NULL; 1625 } 1626 1627 pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 2, &cb); 1628 if (cb.buffer) 1629 pipe_resource_reference(&cb.buffer, NULL); 1630 } 1631 1632 { 1633 struct pipe_constant_buffer cb; 1634 1635 cb.buffer = NULL; 1636 cb.buffer_offset = 0; 1637 cb.buffer_size = 512 * sizeof(float[4]); 1638 cb.user_buffer = state->vs_const_b; 1639 1640 if (!device->driver_caps.user_sw_cbufs) { 1641 u_upload_data(device->constbuf_sw_uploader, 1642 0, 1643 cb.buffer_size, 1644 16, 1645 cb.user_buffer, 1646 &(cb.buffer_offset), 1647 &(cb.buffer)); 1648 u_upload_unmap(device->constbuf_sw_uploader); 1649 cb.user_buffer = NULL; 1650 } 1651 1652 pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 3, &cb); 1653 if (cb.buffer) 1654 pipe_resource_reference(&cb.buffer, NULL); 1655 } 1656 1657 { 1658 struct pipe_constant_buffer cb; 1659 const D3DVIEWPORT9 *vport = &device->state.viewport; 1660 float viewport_data[8] = {(float)vport->Width * 0.5f, 1661 (float)vport->Height * -0.5f, vport->MaxZ - vport->MinZ, 0.f, 1662 (float)vport->Width * 0.5f + (float)vport->X, 1663 (float)vport->Height * 0.5f + (float)vport->Y, 1664 vport->MinZ, 0.f}; 1665 1666 cb.buffer = NULL; 1667 cb.buffer_offset = 0; 1668 cb.buffer_size = 2 * sizeof(float[4]); 1669 cb.user_buffer = viewport_data; 1670 1671 { 1672 u_upload_data(device->constbuf_sw_uploader, 1673 0, 1674 cb.buffer_size, 1675 16, 1676 cb.user_buffer, 1677 &(cb.buffer_offset), 1678 &(cb.buffer)); 1679 u_upload_unmap(device->constbuf_sw_uploader); 1680 cb.user_buffer = NULL; 1681 } 1682 1683 pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 4, &cb); 1684 if (cb.buffer) 1685 pipe_resource_reference(&cb.buffer, NULL); 1686 } 1687 1688} 1689 1690void 1691nine_state_prepare_draw_sw(struct NineDevice9 *device, struct NineVertexDeclaration9 *vdecl_out, 1692 int start_vertice, int num_vertices, struct pipe_stream_output_info *so) 1693{ 1694 struct nine_state *state = &device->state; 1695 1696 struct NineVertexShader9 *vs = state->programmable_vs ? device->state.vs : device->ff.vs; 1697 1698 assert(state->programmable_vs); 1699 1700 DBG("Preparing draw\n"); 1701 cso_set_vertex_shader_handle(device->cso_sw, 1702 NineVertexShader9_GetVariantProcessVertices(vs, vdecl_out, so)); 1703 update_vertex_elements_sw(device); 1704 update_vertex_buffers_sw(device, start_vertice, num_vertices); 1705 update_vs_constants_sw(device); 1706 DBG("Preparation succeeded\n"); 1707} 1708 1709void 1710nine_state_after_draw_sw(struct NineDevice9 *device) 1711{ 1712 struct nine_state *state = &device->state; 1713 struct pipe_context *pipe = device->pipe; 1714 struct pipe_context *pipe_sw = device->pipe_sw; 1715 int i; 1716 1717 for (i = 0; i < 4; i++) { 1718 pipe_sw->set_vertex_buffers(pipe_sw, i, 1, NULL); 1719 if (state->transfers_so[i]) 1720 pipe->transfer_unmap(pipe, state->transfers_so[i]); 1721 state->transfers_so[i] = NULL; 1722 } 1723} 1724 1725void 1726nine_state_destroy_sw(struct NineDevice9 *device) 1727{ 1728 (void) device; 1729 /* Everything destroyed with cso */ 1730} 1731 1732/* 1733static const DWORD nine_render_states_pixel[] = 1734{ 1735 D3DRS_ALPHABLENDENABLE, 1736 D3DRS_ALPHAFUNC, 1737 D3DRS_ALPHAREF, 1738 D3DRS_ALPHATESTENABLE, 1739 D3DRS_ANTIALIASEDLINEENABLE, 1740 D3DRS_BLENDFACTOR, 1741 D3DRS_BLENDOP, 1742 D3DRS_BLENDOPALPHA, 1743 D3DRS_CCW_STENCILFAIL, 1744 D3DRS_CCW_STENCILPASS, 1745 D3DRS_CCW_STENCILZFAIL, 1746 D3DRS_COLORWRITEENABLE, 1747 D3DRS_COLORWRITEENABLE1, 1748 D3DRS_COLORWRITEENABLE2, 1749 D3DRS_COLORWRITEENABLE3, 1750 D3DRS_DEPTHBIAS, 1751 D3DRS_DESTBLEND, 1752 D3DRS_DESTBLENDALPHA, 1753 D3DRS_DITHERENABLE, 1754 D3DRS_FILLMODE, 1755 D3DRS_FOGDENSITY, 1756 D3DRS_FOGEND, 1757 D3DRS_FOGSTART, 1758 D3DRS_LASTPIXEL, 1759 D3DRS_SCISSORTESTENABLE, 1760 D3DRS_SEPARATEALPHABLENDENABLE, 1761 D3DRS_SHADEMODE, 1762 D3DRS_SLOPESCALEDEPTHBIAS, 1763 D3DRS_SRCBLEND, 1764 D3DRS_SRCBLENDALPHA, 1765 D3DRS_SRGBWRITEENABLE, 1766 D3DRS_STENCILENABLE, 1767 D3DRS_STENCILFAIL, 1768 D3DRS_STENCILFUNC, 1769 D3DRS_STENCILMASK, 1770 D3DRS_STENCILPASS, 1771 D3DRS_STENCILREF, 1772 D3DRS_STENCILWRITEMASK, 1773 D3DRS_STENCILZFAIL, 1774 D3DRS_TEXTUREFACTOR, 1775 D3DRS_TWOSIDEDSTENCILMODE, 1776 D3DRS_WRAP0, 1777 D3DRS_WRAP1, 1778 D3DRS_WRAP10, 1779 D3DRS_WRAP11, 1780 D3DRS_WRAP12, 1781 D3DRS_WRAP13, 1782 D3DRS_WRAP14, 1783 D3DRS_WRAP15, 1784 D3DRS_WRAP2, 1785 D3DRS_WRAP3, 1786 D3DRS_WRAP4, 1787 D3DRS_WRAP5, 1788 D3DRS_WRAP6, 1789 D3DRS_WRAP7, 1790 D3DRS_WRAP8, 1791 D3DRS_WRAP9, 1792 D3DRS_ZENABLE, 1793 D3DRS_ZFUNC, 1794 D3DRS_ZWRITEENABLE 1795}; 1796*/ 1797const uint32_t nine_render_states_pixel[(NINED3DRS_LAST + 31) / 32] = 1798{ 1799 0x0f99c380, 0x1ff00070, 0x00000000, 0x00000000, 1800 0x000000ff, 0xde01c900, 0x0003ffcf 1801}; 1802 1803/* 1804static const DWORD nine_render_states_vertex[] = 1805{ 1806 D3DRS_ADAPTIVETESS_W, 1807 D3DRS_ADAPTIVETESS_X, 1808 D3DRS_ADAPTIVETESS_Y, 1809 D3DRS_ADAPTIVETESS_Z, 1810 D3DRS_AMBIENT, 1811 D3DRS_AMBIENTMATERIALSOURCE, 1812 D3DRS_CLIPPING, 1813 D3DRS_CLIPPLANEENABLE, 1814 D3DRS_COLORVERTEX, 1815 D3DRS_CULLMODE, 1816 D3DRS_DIFFUSEMATERIALSOURCE, 1817 D3DRS_EMISSIVEMATERIALSOURCE, 1818 D3DRS_ENABLEADAPTIVETESSELLATION, 1819 D3DRS_FOGCOLOR, 1820 D3DRS_FOGDENSITY, 1821 D3DRS_FOGENABLE, 1822 D3DRS_FOGEND, 1823 D3DRS_FOGSTART, 1824 D3DRS_FOGTABLEMODE, 1825 D3DRS_FOGVERTEXMODE, 1826 D3DRS_INDEXEDVERTEXBLENDENABLE, 1827 D3DRS_LIGHTING, 1828 D3DRS_LOCALVIEWER, 1829 D3DRS_MAXTESSELLATIONLEVEL, 1830 D3DRS_MINTESSELLATIONLEVEL, 1831 D3DRS_MULTISAMPLEANTIALIAS, 1832 D3DRS_MULTISAMPLEMASK, 1833 D3DRS_NORMALDEGREE, 1834 D3DRS_NORMALIZENORMALS, 1835 D3DRS_PATCHEDGESTYLE, 1836 D3DRS_POINTSCALE_A, 1837 D3DRS_POINTSCALE_B, 1838 D3DRS_POINTSCALE_C, 1839 D3DRS_POINTSCALEENABLE, 1840 D3DRS_POINTSIZE, 1841 D3DRS_POINTSIZE_MAX, 1842 D3DRS_POINTSIZE_MIN, 1843 D3DRS_POINTSPRITEENABLE, 1844 D3DRS_POSITIONDEGREE, 1845 D3DRS_RANGEFOGENABLE, 1846 D3DRS_SHADEMODE, 1847 D3DRS_SPECULARENABLE, 1848 D3DRS_SPECULARMATERIALSOURCE, 1849 D3DRS_TWEENFACTOR, 1850 D3DRS_VERTEXBLEND 1851}; 1852*/ 1853const uint32_t nine_render_states_vertex[(NINED3DRS_LAST + 31) / 32] = 1854{ 1855 0x30400200, 0x0001007c, 0x00000000, 0x00000000, 1856 0xfd9efb00, 0x01fc34cf, 0x00000000 1857}; 1858 1859/* TODO: put in the right values */ 1860const uint32_t nine_render_state_group[NINED3DRS_LAST + 1] = 1861{ 1862 [D3DRS_ZENABLE] = NINE_STATE_DSA | NINE_STATE_MULTISAMPLE, 1863 [D3DRS_FILLMODE] = NINE_STATE_RASTERIZER, 1864 [D3DRS_SHADEMODE] = NINE_STATE_RASTERIZER, 1865 [D3DRS_ZWRITEENABLE] = NINE_STATE_DSA, 1866 [D3DRS_ALPHATESTENABLE] = NINE_STATE_DSA, 1867 [D3DRS_LASTPIXEL] = NINE_STATE_RASTERIZER, 1868 [D3DRS_SRCBLEND] = NINE_STATE_BLEND, 1869 [D3DRS_DESTBLEND] = NINE_STATE_BLEND, 1870 [D3DRS_CULLMODE] = NINE_STATE_RASTERIZER, 1871 [D3DRS_ZFUNC] = NINE_STATE_DSA, 1872 [D3DRS_ALPHAREF] = NINE_STATE_DSA, 1873 [D3DRS_ALPHAFUNC] = NINE_STATE_DSA, 1874 [D3DRS_DITHERENABLE] = NINE_STATE_BLEND, 1875 [D3DRS_ALPHABLENDENABLE] = NINE_STATE_BLEND, 1876 [D3DRS_FOGENABLE] = NINE_STATE_FF_OTHER | NINE_STATE_FOG_SHADER | NINE_STATE_PS_CONST, 1877 [D3DRS_SPECULARENABLE] = NINE_STATE_FF_LIGHTING, 1878 [D3DRS_FOGCOLOR] = NINE_STATE_FF_OTHER | NINE_STATE_PS_CONST, 1879 [D3DRS_FOGTABLEMODE] = NINE_STATE_FF_OTHER | NINE_STATE_FOG_SHADER | NINE_STATE_PS_CONST, 1880 [D3DRS_FOGSTART] = NINE_STATE_FF_OTHER | NINE_STATE_PS_CONST, 1881 [D3DRS_FOGEND] = NINE_STATE_FF_OTHER | NINE_STATE_PS_CONST, 1882 [D3DRS_FOGDENSITY] = NINE_STATE_FF_OTHER | NINE_STATE_PS_CONST, 1883 [D3DRS_RANGEFOGENABLE] = NINE_STATE_FF_OTHER, 1884 [D3DRS_STENCILENABLE] = NINE_STATE_DSA | NINE_STATE_MULTISAMPLE, 1885 [D3DRS_STENCILFAIL] = NINE_STATE_DSA, 1886 [D3DRS_STENCILZFAIL] = NINE_STATE_DSA, 1887 [D3DRS_STENCILPASS] = NINE_STATE_DSA, 1888 [D3DRS_STENCILFUNC] = NINE_STATE_DSA, 1889 [D3DRS_STENCILREF] = NINE_STATE_STENCIL_REF, 1890 [D3DRS_STENCILMASK] = NINE_STATE_DSA, 1891 [D3DRS_STENCILWRITEMASK] = NINE_STATE_DSA, 1892 [D3DRS_TEXTUREFACTOR] = NINE_STATE_FF_PSSTAGES, 1893 [D3DRS_WRAP0] = NINE_STATE_UNHANDLED, /* cylindrical wrap is crazy */ 1894 [D3DRS_WRAP1] = NINE_STATE_UNHANDLED, 1895 [D3DRS_WRAP2] = NINE_STATE_UNHANDLED, 1896 [D3DRS_WRAP3] = NINE_STATE_UNHANDLED, 1897 [D3DRS_WRAP4] = NINE_STATE_UNHANDLED, 1898 [D3DRS_WRAP5] = NINE_STATE_UNHANDLED, 1899 [D3DRS_WRAP6] = NINE_STATE_UNHANDLED, 1900 [D3DRS_WRAP7] = NINE_STATE_UNHANDLED, 1901 [D3DRS_CLIPPING] = 0, /* software vertex processing only */ 1902 [D3DRS_LIGHTING] = NINE_STATE_FF_LIGHTING, 1903 [D3DRS_AMBIENT] = NINE_STATE_FF_LIGHTING | NINE_STATE_FF_MATERIAL, 1904 [D3DRS_FOGVERTEXMODE] = NINE_STATE_FF_OTHER, 1905 [D3DRS_COLORVERTEX] = NINE_STATE_FF_LIGHTING, 1906 [D3DRS_LOCALVIEWER] = NINE_STATE_FF_LIGHTING, 1907 [D3DRS_NORMALIZENORMALS] = NINE_STATE_FF_OTHER, 1908 [D3DRS_DIFFUSEMATERIALSOURCE] = NINE_STATE_FF_LIGHTING, 1909 [D3DRS_SPECULARMATERIALSOURCE] = NINE_STATE_FF_LIGHTING, 1910 [D3DRS_AMBIENTMATERIALSOURCE] = NINE_STATE_FF_LIGHTING, 1911 [D3DRS_EMISSIVEMATERIALSOURCE] = NINE_STATE_FF_LIGHTING, 1912 [D3DRS_VERTEXBLEND] = NINE_STATE_FF_OTHER, 1913 [D3DRS_CLIPPLANEENABLE] = NINE_STATE_RASTERIZER, 1914 [D3DRS_POINTSIZE] = NINE_STATE_RASTERIZER, 1915 [D3DRS_POINTSIZE_MIN] = NINE_STATE_RASTERIZER | NINE_STATE_POINTSIZE_SHADER, 1916 [D3DRS_POINTSPRITEENABLE] = NINE_STATE_RASTERIZER, 1917 [D3DRS_POINTSCALEENABLE] = NINE_STATE_FF_OTHER, 1918 [D3DRS_POINTSCALE_A] = NINE_STATE_FF_OTHER, 1919 [D3DRS_POINTSCALE_B] = NINE_STATE_FF_OTHER, 1920 [D3DRS_POINTSCALE_C] = NINE_STATE_FF_OTHER, 1921 [D3DRS_MULTISAMPLEANTIALIAS] = NINE_STATE_MULTISAMPLE, 1922 [D3DRS_MULTISAMPLEMASK] = NINE_STATE_SAMPLE_MASK, 1923 [D3DRS_PATCHEDGESTYLE] = NINE_STATE_UNHANDLED, 1924 [D3DRS_DEBUGMONITORTOKEN] = NINE_STATE_UNHANDLED, 1925 [D3DRS_POINTSIZE_MAX] = NINE_STATE_RASTERIZER | NINE_STATE_POINTSIZE_SHADER, 1926 [D3DRS_INDEXEDVERTEXBLENDENABLE] = NINE_STATE_FF_OTHER, 1927 [D3DRS_COLORWRITEENABLE] = NINE_STATE_BLEND, 1928 [D3DRS_TWEENFACTOR] = NINE_STATE_FF_OTHER, 1929 [D3DRS_BLENDOP] = NINE_STATE_BLEND, 1930 [D3DRS_POSITIONDEGREE] = NINE_STATE_UNHANDLED, 1931 [D3DRS_NORMALDEGREE] = NINE_STATE_UNHANDLED, 1932 [D3DRS_SCISSORTESTENABLE] = NINE_STATE_RASTERIZER, 1933 [D3DRS_SLOPESCALEDEPTHBIAS] = NINE_STATE_RASTERIZER, 1934 [D3DRS_ANTIALIASEDLINEENABLE] = NINE_STATE_RASTERIZER, 1935 [D3DRS_MINTESSELLATIONLEVEL] = NINE_STATE_UNHANDLED, 1936 [D3DRS_MAXTESSELLATIONLEVEL] = NINE_STATE_UNHANDLED, 1937 [D3DRS_ADAPTIVETESS_X] = NINE_STATE_UNHANDLED, 1938 [D3DRS_ADAPTIVETESS_Y] = NINE_STATE_UNHANDLED, 1939 [D3DRS_ADAPTIVETESS_Z] = NINE_STATE_UNHANDLED, 1940 [D3DRS_ADAPTIVETESS_W] = NINE_STATE_UNHANDLED, 1941 [D3DRS_ENABLEADAPTIVETESSELLATION] = NINE_STATE_UNHANDLED, 1942 [D3DRS_TWOSIDEDSTENCILMODE] = NINE_STATE_DSA, 1943 [D3DRS_CCW_STENCILFAIL] = NINE_STATE_DSA, 1944 [D3DRS_CCW_STENCILZFAIL] = NINE_STATE_DSA, 1945 [D3DRS_CCW_STENCILPASS] = NINE_STATE_DSA, 1946 [D3DRS_CCW_STENCILFUNC] = NINE_STATE_DSA, 1947 [D3DRS_COLORWRITEENABLE1] = NINE_STATE_BLEND, 1948 [D3DRS_COLORWRITEENABLE2] = NINE_STATE_BLEND, 1949 [D3DRS_COLORWRITEENABLE3] = NINE_STATE_BLEND, 1950 [D3DRS_BLENDFACTOR] = NINE_STATE_BLEND_COLOR, 1951 [D3DRS_SRGBWRITEENABLE] = NINE_STATE_FB, 1952 [D3DRS_DEPTHBIAS] = NINE_STATE_RASTERIZER, 1953 [D3DRS_WRAP8] = NINE_STATE_UNHANDLED, /* cylwrap has to be done via GP */ 1954 [D3DRS_WRAP9] = NINE_STATE_UNHANDLED, 1955 [D3DRS_WRAP10] = NINE_STATE_UNHANDLED, 1956 [D3DRS_WRAP11] = NINE_STATE_UNHANDLED, 1957 [D3DRS_WRAP12] = NINE_STATE_UNHANDLED, 1958 [D3DRS_WRAP13] = NINE_STATE_UNHANDLED, 1959 [D3DRS_WRAP14] = NINE_STATE_UNHANDLED, 1960 [D3DRS_WRAP15] = NINE_STATE_UNHANDLED, 1961 [D3DRS_SEPARATEALPHABLENDENABLE] = NINE_STATE_BLEND, 1962 [D3DRS_SRCBLENDALPHA] = NINE_STATE_BLEND, 1963 [D3DRS_DESTBLENDALPHA] = NINE_STATE_BLEND, 1964 [D3DRS_BLENDOPALPHA] = NINE_STATE_BLEND 1965}; 1966 1967/* Misc */ 1968 1969D3DMATRIX * 1970nine_state_access_transform(struct nine_state *state, D3DTRANSFORMSTATETYPE t, 1971 boolean alloc) 1972{ 1973 static D3DMATRIX Identity = { .m[0] = { 1, 0, 0, 0 }, 1974 .m[1] = { 0, 1, 0, 0 }, 1975 .m[2] = { 0, 0, 1, 0 }, 1976 .m[3] = { 0, 0, 0, 1 } }; 1977 unsigned index; 1978 1979 switch (t) { 1980 case D3DTS_VIEW: index = 0; break; 1981 case D3DTS_PROJECTION: index = 1; break; 1982 case D3DTS_TEXTURE0: index = 2; break; 1983 case D3DTS_TEXTURE1: index = 3; break; 1984 case D3DTS_TEXTURE2: index = 4; break; 1985 case D3DTS_TEXTURE3: index = 5; break; 1986 case D3DTS_TEXTURE4: index = 6; break; 1987 case D3DTS_TEXTURE5: index = 7; break; 1988 case D3DTS_TEXTURE6: index = 8; break; 1989 case D3DTS_TEXTURE7: index = 9; break; 1990 default: 1991 if (!(t >= D3DTS_WORLDMATRIX(0) && t <= D3DTS_WORLDMATRIX(255))) 1992 return NULL; 1993 index = 10 + (t - D3DTS_WORLDMATRIX(0)); 1994 break; 1995 } 1996 1997 if (index >= state->ff.num_transforms) { 1998 unsigned N = index + 1; 1999 unsigned n = state->ff.num_transforms; 2000 2001 if (!alloc) 2002 return &Identity; 2003 state->ff.transform = REALLOC(state->ff.transform, 2004 n * sizeof(D3DMATRIX), 2005 N * sizeof(D3DMATRIX)); 2006 for (; n < N; ++n) 2007 state->ff.transform[n] = Identity; 2008 state->ff.num_transforms = N; 2009 } 2010 return &state->ff.transform[index]; 2011} 2012 2013#define D3DRS_TO_STRING_CASE(n) case D3DRS_##n: return "D3DRS_"#n 2014const char *nine_d3drs_to_string(DWORD State) 2015{ 2016 switch (State) { 2017 D3DRS_TO_STRING_CASE(ZENABLE); 2018 D3DRS_TO_STRING_CASE(FILLMODE); 2019 D3DRS_TO_STRING_CASE(SHADEMODE); 2020 D3DRS_TO_STRING_CASE(ZWRITEENABLE); 2021 D3DRS_TO_STRING_CASE(ALPHATESTENABLE); 2022 D3DRS_TO_STRING_CASE(LASTPIXEL); 2023 D3DRS_TO_STRING_CASE(SRCBLEND); 2024 D3DRS_TO_STRING_CASE(DESTBLEND); 2025 D3DRS_TO_STRING_CASE(CULLMODE); 2026 D3DRS_TO_STRING_CASE(ZFUNC); 2027 D3DRS_TO_STRING_CASE(ALPHAREF); 2028 D3DRS_TO_STRING_CASE(ALPHAFUNC); 2029 D3DRS_TO_STRING_CASE(DITHERENABLE); 2030 D3DRS_TO_STRING_CASE(ALPHABLENDENABLE); 2031 D3DRS_TO_STRING_CASE(FOGENABLE); 2032 D3DRS_TO_STRING_CASE(SPECULARENABLE); 2033 D3DRS_TO_STRING_CASE(FOGCOLOR); 2034 D3DRS_TO_STRING_CASE(FOGTABLEMODE); 2035 D3DRS_TO_STRING_CASE(FOGSTART); 2036 D3DRS_TO_STRING_CASE(FOGEND); 2037 D3DRS_TO_STRING_CASE(FOGDENSITY); 2038 D3DRS_TO_STRING_CASE(RANGEFOGENABLE); 2039 D3DRS_TO_STRING_CASE(STENCILENABLE); 2040 D3DRS_TO_STRING_CASE(STENCILFAIL); 2041 D3DRS_TO_STRING_CASE(STENCILZFAIL); 2042 D3DRS_TO_STRING_CASE(STENCILPASS); 2043 D3DRS_TO_STRING_CASE(STENCILFUNC); 2044 D3DRS_TO_STRING_CASE(STENCILREF); 2045 D3DRS_TO_STRING_CASE(STENCILMASK); 2046 D3DRS_TO_STRING_CASE(STENCILWRITEMASK); 2047 D3DRS_TO_STRING_CASE(TEXTUREFACTOR); 2048 D3DRS_TO_STRING_CASE(WRAP0); 2049 D3DRS_TO_STRING_CASE(WRAP1); 2050 D3DRS_TO_STRING_CASE(WRAP2); 2051 D3DRS_TO_STRING_CASE(WRAP3); 2052 D3DRS_TO_STRING_CASE(WRAP4); 2053 D3DRS_TO_STRING_CASE(WRAP5); 2054 D3DRS_TO_STRING_CASE(WRAP6); 2055 D3DRS_TO_STRING_CASE(WRAP7); 2056 D3DRS_TO_STRING_CASE(CLIPPING); 2057 D3DRS_TO_STRING_CASE(LIGHTING); 2058 D3DRS_TO_STRING_CASE(AMBIENT); 2059 D3DRS_TO_STRING_CASE(FOGVERTEXMODE); 2060 D3DRS_TO_STRING_CASE(COLORVERTEX); 2061 D3DRS_TO_STRING_CASE(LOCALVIEWER); 2062 D3DRS_TO_STRING_CASE(NORMALIZENORMALS); 2063 D3DRS_TO_STRING_CASE(DIFFUSEMATERIALSOURCE); 2064 D3DRS_TO_STRING_CASE(SPECULARMATERIALSOURCE); 2065 D3DRS_TO_STRING_CASE(AMBIENTMATERIALSOURCE); 2066 D3DRS_TO_STRING_CASE(EMISSIVEMATERIALSOURCE); 2067 D3DRS_TO_STRING_CASE(VERTEXBLEND); 2068 D3DRS_TO_STRING_CASE(CLIPPLANEENABLE); 2069 D3DRS_TO_STRING_CASE(POINTSIZE); 2070 D3DRS_TO_STRING_CASE(POINTSIZE_MIN); 2071 D3DRS_TO_STRING_CASE(POINTSPRITEENABLE); 2072 D3DRS_TO_STRING_CASE(POINTSCALEENABLE); 2073 D3DRS_TO_STRING_CASE(POINTSCALE_A); 2074 D3DRS_TO_STRING_CASE(POINTSCALE_B); 2075 D3DRS_TO_STRING_CASE(POINTSCALE_C); 2076 D3DRS_TO_STRING_CASE(MULTISAMPLEANTIALIAS); 2077 D3DRS_TO_STRING_CASE(MULTISAMPLEMASK); 2078 D3DRS_TO_STRING_CASE(PATCHEDGESTYLE); 2079 D3DRS_TO_STRING_CASE(DEBUGMONITORTOKEN); 2080 D3DRS_TO_STRING_CASE(POINTSIZE_MAX); 2081 D3DRS_TO_STRING_CASE(INDEXEDVERTEXBLENDENABLE); 2082 D3DRS_TO_STRING_CASE(COLORWRITEENABLE); 2083 D3DRS_TO_STRING_CASE(TWEENFACTOR); 2084 D3DRS_TO_STRING_CASE(BLENDOP); 2085 D3DRS_TO_STRING_CASE(POSITIONDEGREE); 2086 D3DRS_TO_STRING_CASE(NORMALDEGREE); 2087 D3DRS_TO_STRING_CASE(SCISSORTESTENABLE); 2088 D3DRS_TO_STRING_CASE(SLOPESCALEDEPTHBIAS); 2089 D3DRS_TO_STRING_CASE(ANTIALIASEDLINEENABLE); 2090 D3DRS_TO_STRING_CASE(MINTESSELLATIONLEVEL); 2091 D3DRS_TO_STRING_CASE(MAXTESSELLATIONLEVEL); 2092 D3DRS_TO_STRING_CASE(ADAPTIVETESS_X); 2093 D3DRS_TO_STRING_CASE(ADAPTIVETESS_Y); 2094 D3DRS_TO_STRING_CASE(ADAPTIVETESS_Z); 2095 D3DRS_TO_STRING_CASE(ADAPTIVETESS_W); 2096 D3DRS_TO_STRING_CASE(ENABLEADAPTIVETESSELLATION); 2097 D3DRS_TO_STRING_CASE(TWOSIDEDSTENCILMODE); 2098 D3DRS_TO_STRING_CASE(CCW_STENCILFAIL); 2099 D3DRS_TO_STRING_CASE(CCW_STENCILZFAIL); 2100 D3DRS_TO_STRING_CASE(CCW_STENCILPASS); 2101 D3DRS_TO_STRING_CASE(CCW_STENCILFUNC); 2102 D3DRS_TO_STRING_CASE(COLORWRITEENABLE1); 2103 D3DRS_TO_STRING_CASE(COLORWRITEENABLE2); 2104 D3DRS_TO_STRING_CASE(COLORWRITEENABLE3); 2105 D3DRS_TO_STRING_CASE(BLENDFACTOR); 2106 D3DRS_TO_STRING_CASE(SRGBWRITEENABLE); 2107 D3DRS_TO_STRING_CASE(DEPTHBIAS); 2108 D3DRS_TO_STRING_CASE(WRAP8); 2109 D3DRS_TO_STRING_CASE(WRAP9); 2110 D3DRS_TO_STRING_CASE(WRAP10); 2111 D3DRS_TO_STRING_CASE(WRAP11); 2112 D3DRS_TO_STRING_CASE(WRAP12); 2113 D3DRS_TO_STRING_CASE(WRAP13); 2114 D3DRS_TO_STRING_CASE(WRAP14); 2115 D3DRS_TO_STRING_CASE(WRAP15); 2116 D3DRS_TO_STRING_CASE(SEPARATEALPHABLENDENABLE); 2117 D3DRS_TO_STRING_CASE(SRCBLENDALPHA); 2118 D3DRS_TO_STRING_CASE(DESTBLENDALPHA); 2119 D3DRS_TO_STRING_CASE(BLENDOPALPHA); 2120 default: 2121 return "(invalid)"; 2122 } 2123} 2124