Home | History | Annotate | Download | only in nine
      1 /*
      2  * Copyright 2011 Joakim Sindholt <opensource (at) 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 #define NINE_STATE
     25 
     26 #include "device9.h"
     27 #include "swapchain9.h"
     28 #include "basetexture9.h"
     29 #include "buffer9.h"
     30 #include "indexbuffer9.h"
     31 #include "surface9.h"
     32 #include "vertexbuffer9.h"
     33 #include "vertexdeclaration9.h"
     34 #include "vertexshader9.h"
     35 #include "pixelshader9.h"
     36 #include "nine_pipe.h"
     37 #include "nine_ff.h"
     38 #include "nine_limits.h"
     39 #include "pipe/p_context.h"
     40 #include "pipe/p_state.h"
     41 #include "cso_cache/cso_context.h"
     42 #include "util/u_atomic.h"
     43 #include "util/u_upload_mgr.h"
     44 #include "util/u_math.h"
     45 #include "util/u_box.h"
     46 #include "util/u_simple_shaders.h"
     47 #include "util/u_gen_mipmap.h"
     48 
     49 /* CSMT headers */
     50 #include "nine_queue.h"
     51 #include "nine_csmt_helper.h"
     52 #include "os/os_thread.h"
     53 
     54 #define DBG_CHANNEL DBG_DEVICE
     55 
     56 /* Nine CSMT */
     57 
     58 struct csmt_instruction {
     59     int (* func)(struct NineDevice9 *This, struct csmt_instruction *instr);
     60 };
     61 
     62 struct csmt_context {
     63     thrd_t worker;
     64     struct nine_queue_pool* pool;
     65     BOOL terminate;
     66     cnd_t event_processed;
     67     mtx_t mutex_processed;
     68     struct NineDevice9 *device;
     69     BOOL processed;
     70     BOOL toPause;
     71     BOOL hasPaused;
     72     mtx_t thread_running;
     73     mtx_t thread_resume;
     74 };
     75 
     76 /* Wait for instruction to be processed.
     77  * Caller has to ensure that only one thread waits at time.
     78  */
     79 static void
     80 nine_csmt_wait_processed(struct csmt_context *ctx)
     81 {
     82     mtx_lock(&ctx->mutex_processed);
     83     while (!p_atomic_read(&ctx->processed)) {
     84         cnd_wait(&ctx->event_processed, &ctx->mutex_processed);
     85     }
     86     mtx_unlock(&ctx->mutex_processed);
     87 }
     88 
     89 /* CSMT worker thread */
     90 static
     91 int
     92 nine_csmt_worker(void *arg)
     93 {
     94     struct csmt_context *ctx = arg;
     95     struct csmt_instruction *instr;
     96     DBG("CSMT worker spawned\n");
     97 
     98     u_thread_setname("CSMT-Worker");
     99 
    100     while (1) {
    101         nine_queue_wait_flush(ctx->pool);
    102         mtx_lock(&ctx->thread_running);
    103 
    104         /* Get instruction. NULL on empty cmdbuf. */
    105         while (!p_atomic_read(&ctx->terminate) &&
    106                (instr = (struct csmt_instruction *)nine_queue_get(ctx->pool))) {
    107 
    108             /* decode */
    109             if (instr->func(ctx->device, instr)) {
    110                 mtx_lock(&ctx->mutex_processed);
    111                 p_atomic_set(&ctx->processed, TRUE);
    112                 cnd_signal(&ctx->event_processed);
    113                 mtx_unlock(&ctx->mutex_processed);
    114             }
    115             if (p_atomic_read(&ctx->toPause)) {
    116                 mtx_unlock(&ctx->thread_running);
    117                 /* will wait here the thread can be resumed */
    118                 mtx_lock(&ctx->thread_resume);
    119                 mtx_lock(&ctx->thread_running);
    120                 mtx_unlock(&ctx->thread_resume);
    121             }
    122         }
    123 
    124         mtx_unlock(&ctx->thread_running);
    125         if (p_atomic_read(&ctx->terminate)) {
    126             mtx_lock(&ctx->mutex_processed);
    127             p_atomic_set(&ctx->processed, TRUE);
    128             cnd_signal(&ctx->event_processed);
    129             mtx_unlock(&ctx->mutex_processed);
    130             break;
    131         }
    132     }
    133 
    134     DBG("CSMT worker destroyed\n");
    135     return 0;
    136 }
    137 
    138 /* Create a CSMT context.
    139  * Spawns a worker thread.
    140  */
    141 struct csmt_context *
    142 nine_csmt_create( struct NineDevice9 *This )
    143 {
    144     struct csmt_context *ctx;
    145 
    146     ctx = CALLOC_STRUCT(csmt_context);
    147     if (!ctx)
    148         return NULL;
    149 
    150     ctx->pool = nine_queue_create();
    151     if (!ctx->pool) {
    152         FREE(ctx);
    153         return NULL;
    154     }
    155     cnd_init(&ctx->event_processed);
    156     (void) mtx_init(&ctx->mutex_processed, mtx_plain);
    157     (void) mtx_init(&ctx->thread_running, mtx_plain);
    158     (void) mtx_init(&ctx->thread_resume, mtx_plain);
    159 
    160 #if DEBUG
    161     u_thread_setname("Main thread");
    162 #endif
    163 
    164     ctx->device = This;
    165 
    166     ctx->worker = u_thread_create(nine_csmt_worker, ctx);
    167     if (!ctx->worker) {
    168         nine_queue_delete(ctx->pool);
    169         FREE(ctx);
    170         return NULL;
    171     }
    172 
    173     DBG("Returning context %p\n", ctx);
    174 
    175     return ctx;
    176 }
    177 
    178 static int
    179 nop_func( struct NineDevice9 *This, struct csmt_instruction *instr )
    180 {
    181     (void) This;
    182     (void) instr;
    183 
    184     return 1;
    185 }
    186 
    187 /* Push nop instruction and flush the queue.
    188  * Waits for the worker to complete. */
    189 void
    190 nine_csmt_process( struct NineDevice9 *device )
    191 {
    192     struct csmt_instruction* instr;
    193     struct csmt_context *ctx = device->csmt_ctx;
    194 
    195     if (!device->csmt_active)
    196         return;
    197 
    198     if (nine_queue_isempty(ctx->pool))
    199         return;
    200 
    201     DBG("device=%p\n", device);
    202 
    203     /* NOP */
    204     instr = nine_queue_alloc(ctx->pool, sizeof(struct csmt_instruction));
    205     assert(instr);
    206     instr->func = nop_func;
    207 
    208     p_atomic_set(&ctx->processed, FALSE);
    209     nine_queue_flush(ctx->pool);
    210 
    211     nine_csmt_wait_processed(ctx);
    212 }
    213 
    214 /* Destroys a CSMT context.
    215  * Waits for the worker thread to terminate.
    216  */
    217 void
    218 nine_csmt_destroy( struct NineDevice9 *device, struct csmt_context *ctx )
    219 {
    220     struct csmt_instruction* instr;
    221     thrd_t render_thread = ctx->worker;
    222 
    223     DBG("device=%p ctx=%p\n", device, ctx);
    224 
    225     /* Push nop and flush the queue. */
    226     instr = nine_queue_alloc(ctx->pool, sizeof(struct csmt_instruction));
    227     assert(instr);
    228     instr->func = nop_func;
    229 
    230     p_atomic_set(&ctx->processed, FALSE);
    231     /* Signal worker to terminate. */
    232     p_atomic_set(&ctx->terminate, TRUE);
    233     nine_queue_flush(ctx->pool);
    234 
    235     nine_csmt_wait_processed(ctx);
    236     nine_queue_delete(ctx->pool);
    237     mtx_destroy(&ctx->mutex_processed);
    238 
    239     FREE(ctx);
    240 
    241     thrd_join(render_thread, NULL);
    242 }
    243 
    244 static void
    245 nine_csmt_pause( struct NineDevice9 *device )
    246 {
    247     struct csmt_context *ctx = device->csmt_ctx;
    248 
    249     if (!device->csmt_active)
    250         return;
    251 
    252     /* No need to pause the thread */
    253     if (nine_queue_no_flushed_work(ctx->pool))
    254         return;
    255 
    256     mtx_lock(&ctx->thread_resume);
    257     p_atomic_set(&ctx->toPause, TRUE);
    258 
    259     /* Wait the thread is paused */
    260     mtx_lock(&ctx->thread_running);
    261     ctx->hasPaused = TRUE;
    262     p_atomic_set(&ctx->toPause, FALSE);
    263 }
    264 
    265 static void
    266 nine_csmt_resume( struct NineDevice9 *device )
    267 {
    268     struct csmt_context *ctx = device->csmt_ctx;
    269 
    270     if (!device->csmt_active)
    271         return;
    272 
    273     if (!ctx->hasPaused)
    274         return;
    275 
    276     ctx->hasPaused = FALSE;
    277     mtx_unlock(&ctx->thread_running);
    278     mtx_unlock(&ctx->thread_resume);
    279 }
    280 
    281 struct pipe_context *
    282 nine_context_get_pipe( struct NineDevice9 *device )
    283 {
    284     nine_csmt_process(device);
    285     return device->context.pipe;
    286 }
    287 
    288 struct pipe_context *
    289 nine_context_get_pipe_multithread( struct NineDevice9 *device )
    290 {
    291     struct csmt_context *ctx = device->csmt_ctx;
    292 
    293     if (!device->csmt_active)
    294         return device->context.pipe;
    295 
    296     if (!u_thread_is_self(ctx->worker))
    297         nine_csmt_process(device);
    298 
    299     return device->context.pipe;
    300 }
    301 
    302 struct pipe_context *
    303 nine_context_get_pipe_acquire( struct NineDevice9 *device )
    304 {
    305     nine_csmt_pause(device);
    306     return device->context.pipe;
    307 }
    308 
    309 void
    310 nine_context_get_pipe_release( struct NineDevice9 *device )
    311 {
    312     nine_csmt_resume(device);
    313 }
    314 
    315 /* Nine state functions */
    316 
    317 /* Check if some states need to be set dirty */
    318 
    319 static inline DWORD
    320 check_multisample(struct NineDevice9 *device)
    321 {
    322     DWORD *rs = device->context.rs;
    323     DWORD new_value = (rs[D3DRS_ZENABLE] || rs[D3DRS_STENCILENABLE]) &&
    324                       device->context.rt[0]->desc.MultiSampleType >= 1 &&
    325                       rs[D3DRS_MULTISAMPLEANTIALIAS];
    326     if (rs[NINED3DRS_MULTISAMPLE] != new_value) {
    327         rs[NINED3DRS_MULTISAMPLE] = new_value;
    328         return NINE_STATE_RASTERIZER;
    329     }
    330     return 0;
    331 }
    332 
    333 /* State preparation only */
    334 
    335 static inline void
    336 prepare_blend(struct NineDevice9 *device)
    337 {
    338     nine_convert_blend_state(&device->context.pipe_data.blend, device->context.rs);
    339     device->context.commit |= NINE_STATE_COMMIT_BLEND;
    340 }
    341 
    342 static inline void
    343 prepare_dsa(struct NineDevice9 *device)
    344 {
    345     nine_convert_dsa_state(&device->context.pipe_data.dsa, device->context.rs);
    346     device->context.commit |= NINE_STATE_COMMIT_DSA;
    347 }
    348 
    349 static inline void
    350 prepare_rasterizer(struct NineDevice9 *device)
    351 {
    352     nine_convert_rasterizer_state(device, &device->context.pipe_data.rast, device->context.rs);
    353     device->context.commit |= NINE_STATE_COMMIT_RASTERIZER;
    354 }
    355 
    356 static void
    357 prepare_vs_constants_userbuf_swvp(struct NineDevice9 *device)
    358 {
    359     struct nine_context *context = &device->context;
    360 
    361     if (context->changed.vs_const_f || context->changed.group & NINE_STATE_SWVP) {
    362         struct pipe_constant_buffer cb;
    363 
    364         cb.buffer_offset = 0;
    365         cb.buffer_size = 4096 * sizeof(float[4]);
    366         cb.user_buffer = context->vs_const_f_swvp;
    367 
    368         if (context->vs->lconstf.ranges) {
    369             const struct nine_lconstf *lconstf = &(context->vs->lconstf);
    370             const struct nine_range *r = lconstf->ranges;
    371             unsigned n = 0;
    372             float *dst = context->vs_lconstf_temp;
    373             float *src = (float *)cb.user_buffer;
    374             memcpy(dst, src, cb.buffer_size);
    375             while (r) {
    376                 unsigned p = r->bgn;
    377                 unsigned c = r->end - r->bgn;
    378                 memcpy(&dst[p * 4], &lconstf->data[n * 4], c * 4 * sizeof(float));
    379                 n += c;
    380                 r = r->next;
    381             }
    382             cb.user_buffer = dst;
    383         }
    384 
    385         context->pipe_data.cb0_swvp.buffer_offset = cb.buffer_offset;
    386         context->pipe_data.cb0_swvp.buffer_size = cb.buffer_size;
    387         context->pipe_data.cb0_swvp.user_buffer = cb.user_buffer;
    388 
    389         cb.user_buffer = (char *)cb.user_buffer + 4096 * sizeof(float[4]);
    390         context->pipe_data.cb1_swvp.buffer_offset = cb.buffer_offset;
    391         context->pipe_data.cb1_swvp.buffer_size = cb.buffer_size;
    392         context->pipe_data.cb1_swvp.user_buffer = cb.user_buffer;
    393 
    394         context->changed.vs_const_f = 0;
    395     }
    396 
    397     if (context->changed.vs_const_i || context->changed.group & NINE_STATE_SWVP) {
    398         struct pipe_constant_buffer cb;
    399 
    400         cb.buffer_offset = 0;
    401         cb.buffer_size = 2048 * sizeof(float[4]);
    402         cb.user_buffer = context->vs_const_i;
    403 
    404         context->pipe_data.cb2_swvp.buffer_offset = cb.buffer_offset;
    405         context->pipe_data.cb2_swvp.buffer_size = cb.buffer_size;
    406         context->pipe_data.cb2_swvp.user_buffer = cb.user_buffer;
    407         context->changed.vs_const_i = 0;
    408     }
    409 
    410     if (context->changed.vs_const_b || context->changed.group & NINE_STATE_SWVP) {
    411         struct pipe_constant_buffer cb;
    412 
    413         cb.buffer_offset = 0;
    414         cb.buffer_size = 512 * sizeof(float[4]);
    415         cb.user_buffer = context->vs_const_b;
    416 
    417         context->pipe_data.cb3_swvp.buffer_offset = cb.buffer_offset;
    418         context->pipe_data.cb3_swvp.buffer_size = cb.buffer_size;
    419         context->pipe_data.cb3_swvp.user_buffer = cb.user_buffer;
    420         context->changed.vs_const_b = 0;
    421     }
    422 
    423     context->changed.group &= ~NINE_STATE_VS_CONST;
    424     context->commit |= NINE_STATE_COMMIT_CONST_VS;
    425 }
    426 
    427 static void
    428 prepare_vs_constants_userbuf(struct NineDevice9 *device)
    429 {
    430     struct nine_context *context = &device->context;
    431     struct pipe_constant_buffer cb;
    432     cb.buffer = NULL;
    433     cb.buffer_offset = 0;
    434     cb.buffer_size = context->vs->const_used_size;
    435     cb.user_buffer = context->vs_const_f;
    436 
    437     if (context->swvp) {
    438         prepare_vs_constants_userbuf_swvp(device);
    439         return;
    440     }
    441 
    442     if (context->changed.vs_const_i || context->changed.group & NINE_STATE_SWVP) {
    443         int *idst = (int *)&context->vs_const_f[4 * device->max_vs_const_f];
    444         memcpy(idst, context->vs_const_i, NINE_MAX_CONST_I * sizeof(int[4]));
    445         context->changed.vs_const_i = 0;
    446     }
    447 
    448     if (context->changed.vs_const_b || context->changed.group & NINE_STATE_SWVP) {
    449         int *idst = (int *)&context->vs_const_f[4 * device->max_vs_const_f];
    450         uint32_t *bdst = (uint32_t *)&idst[4 * NINE_MAX_CONST_I];
    451         memcpy(bdst, context->vs_const_b, NINE_MAX_CONST_B * sizeof(BOOL));
    452         context->changed.vs_const_b = 0;
    453     }
    454 
    455     if (!cb.buffer_size)
    456         return;
    457 
    458     if (context->vs->lconstf.ranges) {
    459         /* TODO: Can we make it so that we don't have to copy everything ? */
    460         const struct nine_lconstf *lconstf =  &(context->vs->lconstf);
    461         const struct nine_range *r = lconstf->ranges;
    462         unsigned n = 0;
    463         float *dst = context->vs_lconstf_temp;
    464         float *src = (float *)cb.user_buffer;
    465         memcpy(dst, src, cb.buffer_size);
    466         while (r) {
    467             unsigned p = r->bgn;
    468             unsigned c = r->end - r->bgn;
    469             memcpy(&dst[p * 4], &lconstf->data[n * 4], c * 4 * sizeof(float));
    470             n += c;
    471             r = r->next;
    472         }
    473         cb.user_buffer = dst;
    474     }
    475 
    476     context->pipe_data.cb_vs = cb;
    477     context->changed.vs_const_f = 0;
    478 
    479     context->changed.group &= ~NINE_STATE_VS_CONST;
    480     context->commit |= NINE_STATE_COMMIT_CONST_VS;
    481 }
    482 
    483 static void
    484 prepare_ps_constants_userbuf(struct NineDevice9 *device)
    485 {
    486     struct nine_context *context = &device->context;
    487     struct pipe_constant_buffer cb;
    488     cb.buffer = NULL;
    489     cb.buffer_offset = 0;
    490     cb.buffer_size = context->ps->const_used_size;
    491     cb.user_buffer = context->ps_const_f;
    492 
    493     if (context->changed.ps_const_i) {
    494         int *idst = (int *)&context->ps_const_f[4 * device->max_ps_const_f];
    495         memcpy(idst, context->ps_const_i, sizeof(context->ps_const_i));
    496         context->changed.ps_const_i = 0;
    497     }
    498     if (context->changed.ps_const_b) {
    499         int *idst = (int *)&context->ps_const_f[4 * device->max_ps_const_f];
    500         uint32_t *bdst = (uint32_t *)&idst[4 * NINE_MAX_CONST_I];
    501         memcpy(bdst, context->ps_const_b, sizeof(context->ps_const_b));
    502         context->changed.ps_const_b = 0;
    503     }
    504 
    505     /* Upload special constants needed to implement PS1.x instructions like TEXBEM,TEXBEML and BEM */
    506     if (context->ps->bumpenvmat_needed) {
    507         memcpy(context->ps_lconstf_temp, cb.user_buffer, cb.buffer_size);
    508         memcpy(&context->ps_lconstf_temp[4 * 8], &device->context.bumpmap_vars, sizeof(device->context.bumpmap_vars));
    509 
    510         cb.user_buffer = context->ps_lconstf_temp;
    511     }
    512 
    513     if (context->ps->byte_code.version < 0x30 &&
    514         context->rs[D3DRS_FOGENABLE]) {
    515         float *dst = &context->ps_lconstf_temp[4 * 32];
    516         if (cb.user_buffer != context->ps_lconstf_temp) {
    517             memcpy(context->ps_lconstf_temp, cb.user_buffer, cb.buffer_size);
    518             cb.user_buffer = context->ps_lconstf_temp;
    519         }
    520 
    521         d3dcolor_to_rgba(dst, context->rs[D3DRS_FOGCOLOR]);
    522         if (context->rs[D3DRS_FOGTABLEMODE] == D3DFOG_LINEAR) {
    523             dst[4] = asfloat(context->rs[D3DRS_FOGEND]);
    524             dst[5] = 1.0f / (asfloat(context->rs[D3DRS_FOGEND]) - asfloat(context->rs[D3DRS_FOGSTART]));
    525         } else if (context->rs[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) {
    526             dst[4] = asfloat(context->rs[D3DRS_FOGDENSITY]);
    527         }
    528         cb.buffer_size = 4 * 4 * 34;
    529     }
    530 
    531     if (!cb.buffer_size)
    532         return;
    533 
    534     context->pipe_data.cb_ps = cb;
    535     context->changed.ps_const_f = 0;
    536 
    537     context->changed.group &= ~NINE_STATE_PS_CONST;
    538     context->commit |= NINE_STATE_COMMIT_CONST_PS;
    539 }
    540 
    541 static inline uint32_t
    542 prepare_vs(struct NineDevice9 *device, uint8_t shader_changed)
    543 {
    544     struct nine_context *context = &device->context;
    545     struct NineVertexShader9 *vs = context->vs;
    546     uint32_t changed_group = 0;
    547     int has_key_changed = 0;
    548 
    549     if (likely(context->programmable_vs))
    550         has_key_changed = NineVertexShader9_UpdateKey(vs, device);
    551 
    552     if (!shader_changed && !has_key_changed)
    553         return 0;
    554 
    555     /* likely because we dislike FF */
    556     if (likely(context->programmable_vs)) {
    557         context->cso_shader.vs = NineVertexShader9_GetVariant(vs);
    558     } else {
    559         vs = device->ff.vs;
    560         context->cso_shader.vs = vs->ff_cso;
    561     }
    562 
    563     if (context->rs[NINED3DRS_VSPOINTSIZE] != vs->point_size) {
    564         context->rs[NINED3DRS_VSPOINTSIZE] = vs->point_size;
    565         changed_group |= NINE_STATE_RASTERIZER;
    566     }
    567 
    568     if ((context->bound_samplers_mask_vs & vs->sampler_mask) != vs->sampler_mask)
    569         /* Bound dummy sampler. */
    570         changed_group |= NINE_STATE_SAMPLER;
    571 
    572     context->commit |= NINE_STATE_COMMIT_VS;
    573     return changed_group;
    574 }
    575 
    576 static inline uint32_t
    577 prepare_ps(struct NineDevice9 *device, uint8_t shader_changed)
    578 {
    579     struct nine_context *context = &device->context;
    580     struct NinePixelShader9 *ps = context->ps;
    581     uint32_t changed_group = 0;
    582     int has_key_changed = 0;
    583 
    584     if (likely(ps))
    585         has_key_changed = NinePixelShader9_UpdateKey(ps, context);
    586 
    587     if (!shader_changed && !has_key_changed)
    588         return 0;
    589 
    590     if (likely(ps)) {
    591         context->cso_shader.ps = NinePixelShader9_GetVariant(ps);
    592     } else {
    593         ps = device->ff.ps;
    594         context->cso_shader.ps = ps->ff_cso;
    595     }
    596 
    597     if ((context->bound_samplers_mask_ps & ps->sampler_mask) != ps->sampler_mask)
    598         /* Bound dummy sampler. */
    599         changed_group |= NINE_STATE_SAMPLER;
    600 
    601     context->commit |= NINE_STATE_COMMIT_PS;
    602     return changed_group;
    603 }
    604 
    605 /* State preparation incremental */
    606 
    607 /* State preparation + State commit */
    608 
    609 static void
    610 update_framebuffer(struct NineDevice9 *device, bool is_clear)
    611 {
    612     struct nine_context *context = &device->context;
    613     struct pipe_context *pipe = context->pipe;
    614     struct pipe_framebuffer_state *fb = &context->pipe_data.fb;
    615     unsigned i;
    616     struct NineSurface9 *rt0 = context->rt[0];
    617     unsigned w = rt0->desc.Width;
    618     unsigned h = rt0->desc.Height;
    619     unsigned nr_samples = rt0->base.info.nr_samples;
    620     unsigned ps_mask = context->ps ? context->ps->rt_mask : 1;
    621     unsigned mask = is_clear ? 0xf : ps_mask;
    622     const int sRGB = context->rs[D3DRS_SRGBWRITEENABLE] ? 1 : 0;
    623 
    624     DBG("\n");
    625 
    626     context->rt_mask = 0x0;
    627     fb->nr_cbufs = 0;
    628 
    629     /* all render targets must have the same size and the depth buffer must be
    630      * bigger. Multisample has to match, according to spec. But some apps do
    631      * things wrong there, and no error is returned. The behaviour they get
    632      * apparently is that depth buffer is disabled if it doesn't match.
    633      * Surely the same for render targets. */
    634 
    635     /* Special case: D3DFMT_NULL is used to bound no real render target,
    636      * but render to depth buffer. We have to not take into account the render
    637      * target info. TODO: know what should happen when there are several render targers
    638      * and the first one is D3DFMT_NULL */
    639     if (rt0->desc.Format == D3DFMT_NULL && context->ds) {
    640         w = context->ds->desc.Width;
    641         h = context->ds->desc.Height;
    642         nr_samples = context->ds->base.info.nr_samples;
    643     }
    644 
    645     for (i = 0; i < device->caps.NumSimultaneousRTs; ++i) {
    646         struct NineSurface9 *rt = context->rt[i];
    647 
    648         if (rt && rt->desc.Format != D3DFMT_NULL && (mask & (1 << i)) &&
    649             rt->desc.Width == w && rt->desc.Height == h &&
    650             rt->base.info.nr_samples == nr_samples) {
    651             fb->cbufs[i] = NineSurface9_GetSurface(rt, sRGB);
    652             context->rt_mask |= 1 << i;
    653             fb->nr_cbufs = i + 1;
    654         } else {
    655             /* Color outputs must match RT slot,
    656              * drivers will have to handle NULL entries for GL, too.
    657              */
    658             fb->cbufs[i] = NULL;
    659         }
    660     }
    661 
    662     if (context->ds && context->ds->desc.Width >= w &&
    663         context->ds->desc.Height >= h &&
    664         context->ds->base.info.nr_samples == nr_samples) {
    665         fb->zsbuf = NineSurface9_GetSurface(context->ds, 0);
    666     } else {
    667         fb->zsbuf = NULL;
    668     }
    669 
    670     fb->width = w;
    671     fb->height = h;
    672 
    673     pipe->set_framebuffer_state(pipe, fb); /* XXX: cso ? */
    674 
    675     if (is_clear && context->rt_mask == ps_mask)
    676         context->changed.group &= ~NINE_STATE_FB;
    677 }
    678 
    679 static void
    680 update_viewport(struct NineDevice9 *device)
    681 {
    682     struct nine_context *context = &device->context;
    683     const D3DVIEWPORT9 *vport = &context->viewport;
    684     struct pipe_viewport_state pvport;
    685 
    686     /* D3D coordinates are:
    687      * -1 .. +1 for X,Y and
    688      *  0 .. +1 for Z (we use pipe_rasterizer_state.clip_halfz)
    689      */
    690     pvport.scale[0] = (float)vport->Width * 0.5f;
    691     pvport.scale[1] = (float)vport->Height * -0.5f;
    692     pvport.scale[2] = vport->MaxZ - vport->MinZ;
    693     pvport.translate[0] = (float)vport->Width * 0.5f + (float)vport->X;
    694     pvport.translate[1] = (float)vport->Height * 0.5f + (float)vport->Y;
    695     pvport.translate[2] = vport->MinZ;
    696 
    697     /* We found R600 and SI cards have some imprecision
    698      * on the barycentric coordinates used for interpolation.
    699      * Some shaders rely on having something precise.
    700      * We found that the proprietary driver has the imprecision issue,
    701      * except when the render target width and height are powers of two.
    702      * It is using some sort of workaround for these cases
    703      * which covers likely all the cases the applications rely
    704      * on something precise.
    705      * We haven't found the workaround, but it seems like it's better
    706      * for applications if the imprecision is biased towards infinity
    707      * instead of -infinity (which is what measured). So shift slightly
    708      * the viewport: not enough to change rasterization result (in particular
    709      * for multisampling), but enough to make the imprecision biased
    710      * towards infinity. We do this shift only if render target width and
    711      * height are powers of two.
    712      * Solves 'red shadows' bug on UE3 games.
    713      */
    714     if (device->driver_bugs.buggy_barycentrics &&
    715         ((vport->Width & (vport->Width-1)) == 0) &&
    716         ((vport->Height & (vport->Height-1)) == 0)) {
    717         pvport.translate[0] -= 1.0f / 128.0f;
    718         pvport.translate[1] -= 1.0f / 128.0f;
    719     }
    720 
    721     cso_set_viewport(context->cso, &pvport);
    722 }
    723 
    724 /* Loop through VS inputs and pick the vertex elements with the declared
    725  * usage from the vertex declaration, then insert the instance divisor from
    726  * the stream source frequency setting.
    727  */
    728 static void
    729 update_vertex_elements(struct NineDevice9 *device)
    730 {
    731     struct nine_context *context = &device->context;
    732     const struct NineVertexDeclaration9 *vdecl = device->context.vdecl;
    733     const struct NineVertexShader9 *vs;
    734     unsigned n, b, i;
    735     int index;
    736     char vdecl_index_map[16]; /* vs->num_inputs <= 16 */
    737     char used_streams[device->caps.MaxStreams];
    738     int dummy_vbo_stream = -1;
    739     BOOL need_dummy_vbo = FALSE;
    740     struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS];
    741 
    742     context->stream_usage_mask = 0;
    743     memset(vdecl_index_map, -1, 16);
    744     memset(used_streams, 0, device->caps.MaxStreams);
    745     vs = context->programmable_vs ? context->vs : device->ff.vs;
    746 
    747     if (vdecl) {
    748         for (n = 0; n < vs->num_inputs; ++n) {
    749             DBG("looking up input %u (usage %u) from vdecl(%p)\n",
    750                 n, vs->input_map[n].ndecl, vdecl);
    751 
    752             for (i = 0; i < vdecl->nelems; i++) {
    753                 if (vdecl->usage_map[i] == vs->input_map[n].ndecl) {
    754                     vdecl_index_map[n] = i;
    755                     used_streams[vdecl->elems[i].vertex_buffer_index] = 1;
    756                     break;
    757                 }
    758             }
    759             if (vdecl_index_map[n] < 0)
    760                 need_dummy_vbo = TRUE;
    761         }
    762     } else {
    763         /* No vertex declaration. Likely will never happen in practice,
    764          * but we need not crash on this */
    765         need_dummy_vbo = TRUE;
    766     }
    767 
    768     if (need_dummy_vbo) {
    769         for (i = 0; i < device->caps.MaxStreams; i++ ) {
    770             if (!used_streams[i]) {
    771                 dummy_vbo_stream = i;
    772                 break;
    773             }
    774         }
    775     }
    776     /* there are less vertex shader inputs than stream slots,
    777      * so if we need a slot for the dummy vbo, we should have found one */
    778     assert (!need_dummy_vbo || dummy_vbo_stream != -1);
    779 
    780     for (n = 0; n < vs->num_inputs; ++n) {
    781         index = vdecl_index_map[n];
    782         if (index >= 0) {
    783             ve[n] = vdecl->elems[index];
    784             b = ve[n].vertex_buffer_index;
    785             context->stream_usage_mask |= 1 << b;
    786             /* XXX wine just uses 1 here: */
    787             if (context->stream_freq[b] & D3DSTREAMSOURCE_INSTANCEDATA)
    788                 ve[n].instance_divisor = context->stream_freq[b] & 0x7FFFFF;
    789         } else {
    790             /* if the vertex declaration is incomplete compared to what the
    791              * vertex shader needs, we bind a dummy vbo with 0 0 0 0.
    792              * This is not precised by the spec, but is the behaviour
    793              * tested on win */
    794             ve[n].vertex_buffer_index = dummy_vbo_stream;
    795             ve[n].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
    796             ve[n].src_offset = 0;
    797             ve[n].instance_divisor = 0;
    798         }
    799     }
    800 
    801     if (context->dummy_vbo_bound_at != dummy_vbo_stream) {
    802         if (context->dummy_vbo_bound_at >= 0)
    803             context->changed.vtxbuf |= 1 << context->dummy_vbo_bound_at;
    804         if (dummy_vbo_stream >= 0) {
    805             context->changed.vtxbuf |= 1 << dummy_vbo_stream;
    806             context->vbo_bound_done = FALSE;
    807         }
    808         context->dummy_vbo_bound_at = dummy_vbo_stream;
    809     }
    810 
    811     cso_set_vertex_elements(context->cso, vs->num_inputs, ve);
    812 }
    813 
    814 static void
    815 update_vertex_buffers(struct NineDevice9 *device)
    816 {
    817     struct nine_context *context = &device->context;
    818     struct pipe_context *pipe = context->pipe;
    819     struct pipe_vertex_buffer dummy_vtxbuf;
    820     uint32_t mask = context->changed.vtxbuf;
    821     unsigned i;
    822 
    823     DBG("mask=%x\n", mask);
    824 
    825     if (context->dummy_vbo_bound_at >= 0) {
    826         if (!context->vbo_bound_done) {
    827             dummy_vtxbuf.buffer.resource = device->dummy_vbo;
    828             dummy_vtxbuf.stride = 0;
    829             dummy_vtxbuf.is_user_buffer = false;
    830             dummy_vtxbuf.buffer_offset = 0;
    831             pipe->set_vertex_buffers(pipe, context->dummy_vbo_bound_at,
    832                                      1, &dummy_vtxbuf);
    833             context->vbo_bound_done = TRUE;
    834         }
    835         mask &= ~(1 << context->dummy_vbo_bound_at);
    836     }
    837 
    838     for (i = 0; mask; mask >>= 1, ++i) {
    839         if (mask & 1) {
    840             if (context->vtxbuf[i].buffer.resource)
    841                 pipe->set_vertex_buffers(pipe, i, 1, &context->vtxbuf[i]);
    842             else
    843                 pipe->set_vertex_buffers(pipe, i, 1, NULL);
    844         }
    845     }
    846 
    847     context->changed.vtxbuf = 0;
    848 }
    849 
    850 static inline boolean
    851 update_sampler_derived(struct nine_context *context, unsigned s)
    852 {
    853     boolean changed = FALSE;
    854 
    855     if (context->samp[s][NINED3DSAMP_SHADOW] != context->texture[s].shadow) {
    856         changed = TRUE;
    857         context->samp[s][NINED3DSAMP_SHADOW] = context->texture[s].shadow;
    858     }
    859 
    860     if (context->samp[s][NINED3DSAMP_CUBETEX] !=
    861         (context->texture[s].type == D3DRTYPE_CUBETEXTURE)) {
    862         changed = TRUE;
    863         context->samp[s][NINED3DSAMP_CUBETEX] =
    864                 context->texture[s].type == D3DRTYPE_CUBETEXTURE;
    865     }
    866 
    867     if (context->samp[s][D3DSAMP_MIPFILTER] != D3DTEXF_NONE) {
    868         int lod = context->samp[s][D3DSAMP_MAXMIPLEVEL] - context->texture[s].lod;
    869         if (lod < 0)
    870             lod = 0;
    871         if (context->samp[s][NINED3DSAMP_MINLOD] != lod) {
    872             changed = TRUE;
    873             context->samp[s][NINED3DSAMP_MINLOD] = lod;
    874         }
    875     } else {
    876         context->changed.sampler[s] &= ~0x300; /* lod changes irrelevant */
    877     }
    878 
    879     return changed;
    880 }
    881 
    882 /* TODO: add sRGB override to pipe_sampler_state ? */
    883 static void
    884 update_textures_and_samplers(struct NineDevice9 *device)
    885 {
    886     struct nine_context *context = &device->context;
    887     struct pipe_sampler_view *view[NINE_MAX_SAMPLERS];
    888     unsigned num_textures;
    889     unsigned i;
    890     boolean commit_samplers;
    891     uint16_t sampler_mask = context->ps ? context->ps->sampler_mask :
    892                             device->ff.ps->sampler_mask;
    893 
    894     /* TODO: Can we reduce iterations here ? */
    895 
    896     commit_samplers = FALSE;
    897     context->bound_samplers_mask_ps = 0;
    898     for (num_textures = 0, i = 0; i < NINE_MAX_SAMPLERS_PS; ++i) {
    899         const unsigned s = NINE_SAMPLER_PS(i);
    900         int sRGB;
    901 
    902         if (!context->texture[s].enabled && !(sampler_mask & (1 << i))) {
    903             view[i] = NULL;
    904             continue;
    905         }
    906 
    907         if (context->texture[s].enabled) {
    908             sRGB = context->samp[s][D3DSAMP_SRGBTEXTURE] ? 1 : 0;
    909 
    910             view[i] = context->texture[s].view[sRGB];
    911             num_textures = i + 1;
    912 
    913             if (update_sampler_derived(context, s) || (context->changed.sampler[s] & 0x05fe)) {
    914                 context->changed.sampler[s] = 0;
    915                 commit_samplers = TRUE;
    916                 nine_convert_sampler_state(context->cso, s, context->samp[s]);
    917             }
    918         } else {
    919             /* Bind dummy sampler. We do not bind dummy sampler when
    920              * it is not needed because it could add overhead. The
    921              * dummy sampler should have r=g=b=0 and a=1. We do not
    922              * unbind dummy sampler directly when they are not needed
    923              * anymore, but they're going to be removed as long as texture
    924              * or sampler states are changed. */
    925             view[i] = device->dummy_sampler_view;
    926             num_textures = i + 1;
    927 
    928             cso_single_sampler(context->cso, PIPE_SHADER_FRAGMENT,
    929                                s - NINE_SAMPLER_PS(0), &device->dummy_sampler_state);
    930 
    931             commit_samplers = TRUE;
    932             context->changed.sampler[s] = ~0;
    933         }
    934 
    935         context->bound_samplers_mask_ps |= (1 << s);
    936     }
    937 
    938     cso_set_sampler_views(context->cso, PIPE_SHADER_FRAGMENT, num_textures, view);
    939 
    940     if (commit_samplers)
    941         cso_single_sampler_done(context->cso, PIPE_SHADER_FRAGMENT);
    942 
    943     commit_samplers = FALSE;
    944     sampler_mask = context->programmable_vs ? context->vs->sampler_mask : 0;
    945     context->bound_samplers_mask_vs = 0;
    946     for (num_textures = 0, i = 0; i < NINE_MAX_SAMPLERS_VS; ++i) {
    947         const unsigned s = NINE_SAMPLER_VS(i);
    948         int sRGB;
    949 
    950         if (!context->texture[s].enabled && !(sampler_mask & (1 << i))) {
    951             view[i] = NULL;
    952             continue;
    953         }
    954 
    955         if (context->texture[s].enabled) {
    956             sRGB = context->samp[s][D3DSAMP_SRGBTEXTURE] ? 1 : 0;
    957 
    958             view[i] = context->texture[s].view[sRGB];
    959             num_textures = i + 1;
    960 
    961             if (update_sampler_derived(context, s) || (context->changed.sampler[s] & 0x05fe)) {
    962                 context->changed.sampler[s] = 0;
    963                 commit_samplers = TRUE;
    964                 nine_convert_sampler_state(context->cso, s, context->samp[s]);
    965             }
    966         } else {
    967             /* Bind dummy sampler. We do not bind dummy sampler when
    968              * it is not needed because it could add overhead. The
    969              * dummy sampler should have r=g=b=0 and a=1. We do not
    970              * unbind dummy sampler directly when they are not needed
    971              * anymore, but they're going to be removed as long as texture
    972              * or sampler states are changed. */
    973             view[i] = device->dummy_sampler_view;
    974             num_textures = i + 1;
    975 
    976             cso_single_sampler(context->cso, PIPE_SHADER_VERTEX,
    977                                s - NINE_SAMPLER_VS(0), &device->dummy_sampler_state);
    978 
    979             commit_samplers = TRUE;
    980             context->changed.sampler[s] = ~0;
    981         }
    982 
    983         context->bound_samplers_mask_vs |= (1 << s);
    984     }
    985 
    986     cso_set_sampler_views(context->cso, PIPE_SHADER_VERTEX, num_textures, view);
    987 
    988     if (commit_samplers)
    989         cso_single_sampler_done(context->cso, PIPE_SHADER_VERTEX);
    990 }
    991 
    992 /* State commit only */
    993 
    994 static inline void
    995 commit_blend(struct NineDevice9 *device)
    996 {
    997     struct nine_context *context = &device->context;
    998 
    999     cso_set_blend(context->cso, &context->pipe_data.blend);
   1000 }
   1001 
   1002 static inline void
   1003 commit_dsa(struct NineDevice9 *device)
   1004 {
   1005     struct nine_context *context = &device->context;
   1006 
   1007     cso_set_depth_stencil_alpha(context->cso, &context->pipe_data.dsa);
   1008 }
   1009 
   1010 static inline void
   1011 commit_scissor(struct NineDevice9 *device)
   1012 {
   1013     struct nine_context *context = &device->context;
   1014     struct pipe_context *pipe = context->pipe;
   1015 
   1016     pipe->set_scissor_states(pipe, 0, 1, &context->scissor);
   1017 }
   1018 
   1019 static inline void
   1020 commit_rasterizer(struct NineDevice9 *device)
   1021 {
   1022     struct nine_context *context = &device->context;
   1023 
   1024     cso_set_rasterizer(context->cso, &context->pipe_data.rast);
   1025 }
   1026 
   1027 static inline void
   1028 commit_vs_constants(struct NineDevice9 *device)
   1029 {
   1030     struct nine_context *context = &device->context;
   1031     struct pipe_context *pipe = context->pipe;
   1032 
   1033     if (unlikely(!context->programmable_vs))
   1034         pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &context->pipe_data.cb_vs_ff);
   1035     else {
   1036         if (context->swvp) {
   1037             pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &context->pipe_data.cb0_swvp);
   1038             pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 1, &context->pipe_data.cb1_swvp);
   1039             pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 2, &context->pipe_data.cb2_swvp);
   1040             pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 3, &context->pipe_data.cb3_swvp);
   1041         } else {
   1042             pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &context->pipe_data.cb_vs);
   1043         }
   1044     }
   1045 }
   1046 
   1047 static inline void
   1048 commit_ps_constants(struct NineDevice9 *device)
   1049 {
   1050     struct nine_context *context = &device->context;
   1051     struct pipe_context *pipe = context->pipe;
   1052 
   1053     if (unlikely(!context->ps))
   1054         pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &context->pipe_data.cb_ps_ff);
   1055     else
   1056         pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &context->pipe_data.cb_ps);
   1057 }
   1058 
   1059 static inline void
   1060 commit_vs(struct NineDevice9 *device)
   1061 {
   1062     struct nine_context *context = &device->context;
   1063 
   1064     context->pipe->bind_vs_state(context->pipe, context->cso_shader.vs);
   1065 }
   1066 
   1067 
   1068 static inline void
   1069 commit_ps(struct NineDevice9 *device)
   1070 {
   1071     struct nine_context *context = &device->context;
   1072 
   1073     context->pipe->bind_fs_state(context->pipe, context->cso_shader.ps);
   1074 }
   1075 /* State Update */
   1076 
   1077 #define NINE_STATE_SHADER_CHANGE_VS \
   1078    (NINE_STATE_VS |         \
   1079     NINE_STATE_TEXTURE |    \
   1080     NINE_STATE_FOG_SHADER | \
   1081     NINE_STATE_POINTSIZE_SHADER | \
   1082     NINE_STATE_SWVP)
   1083 
   1084 #define NINE_STATE_SHADER_CHANGE_PS \
   1085    (NINE_STATE_PS |         \
   1086     NINE_STATE_TEXTURE |    \
   1087     NINE_STATE_FOG_SHADER | \
   1088     NINE_STATE_PS1X_SHADER)
   1089 
   1090 #define NINE_STATE_FREQUENT \
   1091    (NINE_STATE_RASTERIZER | \
   1092     NINE_STATE_TEXTURE |    \
   1093     NINE_STATE_SAMPLER |    \
   1094     NINE_STATE_VS_CONST |   \
   1095     NINE_STATE_PS_CONST |   \
   1096     NINE_STATE_MULTISAMPLE)
   1097 
   1098 #define NINE_STATE_COMMON \
   1099    (NINE_STATE_FB |       \
   1100     NINE_STATE_BLEND |    \
   1101     NINE_STATE_DSA |      \
   1102     NINE_STATE_VIEWPORT | \
   1103     NINE_STATE_VDECL |    \
   1104     NINE_STATE_IDXBUF |   \
   1105     NINE_STATE_STREAMFREQ)
   1106 
   1107 #define NINE_STATE_RARE      \
   1108    (NINE_STATE_SCISSOR |     \
   1109     NINE_STATE_BLEND_COLOR | \
   1110     NINE_STATE_STENCIL_REF | \
   1111     NINE_STATE_SAMPLE_MASK)
   1112 
   1113 static void
   1114 nine_update_state(struct NineDevice9 *device)
   1115 {
   1116     struct nine_context *context = &device->context;
   1117     struct pipe_context *pipe = context->pipe;
   1118     uint32_t group;
   1119 
   1120     DBG("changed state groups: %x\n", context->changed.group);
   1121 
   1122     /* NOTE: We may want to use the cso cache for everything, or let
   1123      * NineDevice9.RestoreNonCSOState actually set the states, then we wouldn't
   1124      * have to care about state being clobbered here and could merge this back
   1125      * into update_textures. Except, we also need to re-validate textures that
   1126      * may be dirty anyway, even if no texture bindings changed.
   1127      */
   1128 
   1129     /* ff_update may change VS/PS dirty bits */
   1130     if (unlikely(!context->programmable_vs || !context->ps))
   1131         nine_ff_update(device);
   1132     group = context->changed.group;
   1133 
   1134     if (group & (NINE_STATE_SHADER_CHANGE_VS | NINE_STATE_SHADER_CHANGE_PS)) {
   1135         if (group & NINE_STATE_SHADER_CHANGE_VS)
   1136             group |= prepare_vs(device, (group & NINE_STATE_VS) != 0); /* may set NINE_STATE_RASTERIZER and NINE_STATE_SAMPLER*/
   1137         if (group & NINE_STATE_SHADER_CHANGE_PS)
   1138             group |= prepare_ps(device, (group & NINE_STATE_PS) != 0);
   1139     }
   1140 
   1141     if (group & (NINE_STATE_COMMON | NINE_STATE_VS)) {
   1142         if (group & NINE_STATE_FB)
   1143             update_framebuffer(device, FALSE);
   1144         if (group & NINE_STATE_BLEND)
   1145             prepare_blend(device);
   1146         if (group & NINE_STATE_DSA)
   1147             prepare_dsa(device);
   1148         if (group & NINE_STATE_VIEWPORT)
   1149             update_viewport(device);
   1150         if (group & (NINE_STATE_VDECL | NINE_STATE_VS | NINE_STATE_STREAMFREQ))
   1151             update_vertex_elements(device);
   1152     }
   1153 
   1154     if (likely(group & (NINE_STATE_FREQUENT | NINE_STATE_VS | NINE_STATE_PS | NINE_STATE_SWVP))) {
   1155         if (group & NINE_STATE_MULTISAMPLE)
   1156             group |= check_multisample(device);
   1157         if (group & NINE_STATE_RASTERIZER)
   1158             prepare_rasterizer(device);
   1159         if (group & (NINE_STATE_TEXTURE | NINE_STATE_SAMPLER))
   1160             update_textures_and_samplers(device);
   1161         if ((group & (NINE_STATE_VS_CONST | NINE_STATE_VS | NINE_STATE_SWVP)) && context->programmable_vs)
   1162             prepare_vs_constants_userbuf(device);
   1163         if ((group & (NINE_STATE_PS_CONST | NINE_STATE_PS)) && context->ps)
   1164             prepare_ps_constants_userbuf(device);
   1165     }
   1166 
   1167     if (context->changed.vtxbuf)
   1168         update_vertex_buffers(device);
   1169 
   1170     if (context->commit & NINE_STATE_COMMIT_BLEND)
   1171         commit_blend(device);
   1172     if (context->commit & NINE_STATE_COMMIT_DSA)
   1173         commit_dsa(device);
   1174     if (context->commit & NINE_STATE_COMMIT_RASTERIZER)
   1175         commit_rasterizer(device);
   1176     if (context->commit & NINE_STATE_COMMIT_CONST_VS)
   1177         commit_vs_constants(device);
   1178     if (context->commit & NINE_STATE_COMMIT_CONST_PS)
   1179         commit_ps_constants(device);
   1180     if (context->commit & NINE_STATE_COMMIT_VS)
   1181         commit_vs(device);
   1182     if (context->commit & NINE_STATE_COMMIT_PS)
   1183         commit_ps(device);
   1184 
   1185     context->commit = 0;
   1186 
   1187     if (unlikely(context->changed.ucp)) {
   1188         pipe->set_clip_state(pipe, &context->clip);
   1189         context->changed.ucp = FALSE;
   1190     }
   1191 
   1192     if (unlikely(group & NINE_STATE_RARE)) {
   1193         if (group & NINE_STATE_SCISSOR)
   1194             commit_scissor(device);
   1195         if (group & NINE_STATE_BLEND_COLOR) {
   1196             struct pipe_blend_color color;
   1197             d3dcolor_to_rgba(&color.color[0], context->rs[D3DRS_BLENDFACTOR]);
   1198             pipe->set_blend_color(pipe, &color);
   1199         }
   1200         if (group & NINE_STATE_SAMPLE_MASK) {
   1201             if (context->rt[0]->desc.MultiSampleType <= D3DMULTISAMPLE_NONMASKABLE) {
   1202                 pipe->set_sample_mask(pipe, ~0);
   1203             } else {
   1204                 pipe->set_sample_mask(pipe, context->rs[D3DRS_MULTISAMPLEMASK]);
   1205             }
   1206         }
   1207         if (group & NINE_STATE_STENCIL_REF) {
   1208             struct pipe_stencil_ref ref;
   1209             ref.ref_value[0] = context->rs[D3DRS_STENCILREF];
   1210             ref.ref_value[1] = ref.ref_value[0];
   1211             pipe->set_stencil_ref(pipe, &ref);
   1212         }
   1213     }
   1214 
   1215     context->changed.group &=
   1216         (NINE_STATE_FF | NINE_STATE_VS_CONST | NINE_STATE_PS_CONST);
   1217 
   1218     DBG("finished\n");
   1219 }
   1220 
   1221 #define RESZ_CODE 0x7fa05000
   1222 
   1223 static void
   1224 NineDevice9_ResolveZ( struct NineDevice9 *device )
   1225 {
   1226     struct nine_context *context = &device->context;
   1227     const struct util_format_description *desc;
   1228     struct NineSurface9 *source = context->ds;
   1229     struct pipe_resource *src, *dst;
   1230     struct pipe_blit_info blit;
   1231 
   1232     DBG("RESZ resolve\n");
   1233 
   1234     if (!source || !context->texture[0].enabled ||
   1235         context->texture[0].type != D3DRTYPE_TEXTURE)
   1236         return;
   1237 
   1238     src = source->base.resource;
   1239     dst = context->texture[0].resource;
   1240 
   1241     if (!src || !dst)
   1242         return;
   1243 
   1244     /* check dst is depth format. we know already for src */
   1245     desc = util_format_description(dst->format);
   1246     if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
   1247         return;
   1248 
   1249     memset(&blit, 0, sizeof(blit));
   1250     blit.src.resource = src;
   1251     blit.src.level = 0;
   1252     blit.src.format = src->format;
   1253     blit.src.box.z = 0;
   1254     blit.src.box.depth = 1;
   1255     blit.src.box.x = 0;
   1256     blit.src.box.y = 0;
   1257     blit.src.box.width = src->width0;
   1258     blit.src.box.height = src->height0;
   1259 
   1260     blit.dst.resource = dst;
   1261     blit.dst.level = 0;
   1262     blit.dst.format = dst->format;
   1263     blit.dst.box.z = 0;
   1264     blit.dst.box.depth = 1;
   1265     blit.dst.box.x = 0;
   1266     blit.dst.box.y = 0;
   1267     blit.dst.box.width = dst->width0;
   1268     blit.dst.box.height = dst->height0;
   1269 
   1270     blit.mask = PIPE_MASK_ZS;
   1271     blit.filter = PIPE_TEX_FILTER_NEAREST;
   1272     blit.scissor_enable = FALSE;
   1273 
   1274     context->pipe->blit(context->pipe, &blit);
   1275 }
   1276 
   1277 #define ALPHA_TO_COVERAGE_ENABLE   MAKEFOURCC('A', '2', 'M', '1')
   1278 #define ALPHA_TO_COVERAGE_DISABLE  MAKEFOURCC('A', '2', 'M', '0')
   1279 
   1280 /* Nine_context functions.
   1281  * Serialized through CSMT macros.
   1282  */
   1283 
   1284 static void
   1285 nine_context_set_texture_apply(struct NineDevice9 *device,
   1286                                DWORD stage,
   1287                                BOOL enabled,
   1288                                BOOL shadow,
   1289                                DWORD lod,
   1290                                D3DRESOURCETYPE type,
   1291                                uint8_t pstype,
   1292                                struct pipe_resource *res,
   1293                                struct pipe_sampler_view *view0,
   1294                                struct pipe_sampler_view *view1);
   1295 static void
   1296 nine_context_set_stream_source_apply(struct NineDevice9 *device,
   1297                                     UINT StreamNumber,
   1298                                     struct pipe_resource *res,
   1299                                     UINT OffsetInBytes,
   1300                                     UINT Stride);
   1301 
   1302 static void
   1303 nine_context_set_indices_apply(struct NineDevice9 *device,
   1304                                struct pipe_resource *res,
   1305                                UINT IndexSize,
   1306                                UINT OffsetInBytes);
   1307 
   1308 static void
   1309 nine_context_set_pixel_shader_constant_i_transformed(struct NineDevice9 *device,
   1310                                                      UINT StartRegister,
   1311                                                      const int *pConstantData,
   1312                                                      unsigned pConstantData_size,
   1313                                                      UINT Vector4iCount);
   1314 
   1315 CSMT_ITEM_NO_WAIT(nine_context_set_render_state,
   1316                   ARG_VAL(D3DRENDERSTATETYPE, State),
   1317                   ARG_VAL(DWORD, Value))
   1318 {
   1319     struct nine_context *context = &device->context;
   1320 
   1321     /* Amd hacks (equivalent to GL extensions) */
   1322     if (unlikely(State == D3DRS_POINTSIZE)) {
   1323         if (Value == RESZ_CODE) {
   1324             NineDevice9_ResolveZ(device);
   1325             return;
   1326         }
   1327 
   1328         if (Value == ALPHA_TO_COVERAGE_ENABLE ||
   1329             Value == ALPHA_TO_COVERAGE_DISABLE) {
   1330             context->rs[NINED3DRS_ALPHACOVERAGE] = (Value == ALPHA_TO_COVERAGE_ENABLE);
   1331             context->changed.group |= NINE_STATE_BLEND;
   1332             return;
   1333         }
   1334     }
   1335 
   1336     /* NV hack */
   1337     if (unlikely(State == D3DRS_ADAPTIVETESS_Y)) {
   1338         if (Value == D3DFMT_ATOC || (Value == D3DFMT_UNKNOWN && context->rs[NINED3DRS_ALPHACOVERAGE])) {
   1339             context->rs[NINED3DRS_ALPHACOVERAGE] = (Value == D3DFMT_ATOC) ? 3 : 0;
   1340             context->rs[NINED3DRS_ALPHACOVERAGE] &= context->rs[D3DRS_ALPHATESTENABLE] ? 3 : 2;
   1341             context->changed.group |= NINE_STATE_BLEND;
   1342             return;
   1343         }
   1344     }
   1345     if (unlikely(State == D3DRS_ALPHATESTENABLE && (context->rs[NINED3DRS_ALPHACOVERAGE] & 2))) {
   1346         DWORD alphacoverage_prev = context->rs[NINED3DRS_ALPHACOVERAGE];
   1347         context->rs[NINED3DRS_ALPHACOVERAGE] = (Value ? 3 : 2);
   1348         if (context->rs[NINED3DRS_ALPHACOVERAGE] != alphacoverage_prev)
   1349             context->changed.group |= NINE_STATE_BLEND;
   1350     }
   1351 
   1352     context->rs[State] = nine_fix_render_state_value(State, Value);
   1353     context->changed.group |= nine_render_state_group[State];
   1354 }
   1355 
   1356 CSMT_ITEM_NO_WAIT(nine_context_set_texture_apply,
   1357                   ARG_VAL(DWORD, stage),
   1358                   ARG_VAL(BOOL, enabled),
   1359                   ARG_VAL(BOOL, shadow),
   1360                   ARG_VAL(DWORD, lod),
   1361                   ARG_VAL(D3DRESOURCETYPE, type),
   1362                   ARG_VAL(uint8_t, pstype),
   1363                   ARG_BIND_RES(struct pipe_resource, res),
   1364                   ARG_BIND_VIEW(struct pipe_sampler_view, view0),
   1365                   ARG_BIND_VIEW(struct pipe_sampler_view, view1))
   1366 {
   1367     struct nine_context *context = &device->context;
   1368 
   1369     context->texture[stage].enabled = enabled;
   1370     context->samplers_shadow &= ~(1 << stage);
   1371     context->samplers_shadow |= shadow << stage;
   1372     context->texture[stage].shadow = shadow;
   1373     context->texture[stage].lod = lod;
   1374     context->texture[stage].type = type;
   1375     context->texture[stage].pstype = pstype;
   1376     pipe_resource_reference(&context->texture[stage].resource, res);
   1377     pipe_sampler_view_reference(&context->texture[stage].view[0], view0);
   1378     pipe_sampler_view_reference(&context->texture[stage].view[1], view1);
   1379 
   1380     context->changed.group |= NINE_STATE_TEXTURE;
   1381 }
   1382 
   1383 void
   1384 nine_context_set_texture(struct NineDevice9 *device,
   1385                          DWORD Stage,
   1386                          struct NineBaseTexture9 *tex)
   1387 {
   1388     BOOL enabled = FALSE;
   1389     BOOL shadow = FALSE;
   1390     DWORD lod = 0;
   1391     D3DRESOURCETYPE type = D3DRTYPE_TEXTURE;
   1392     uint8_t pstype = 0;
   1393     struct pipe_resource *res = NULL;
   1394     struct pipe_sampler_view *view0 = NULL, *view1 = NULL;
   1395 
   1396     /* For managed pool, the data can be initially incomplete.
   1397      * In that case, the texture is rebound later
   1398      * (in NineBaseTexture9_Validate/NineBaseTexture9_UploadSelf). */
   1399     if (tex && tex->base.resource) {
   1400         enabled = TRUE;
   1401         shadow = tex->shadow;
   1402         lod = tex->managed.lod;
   1403         type = tex->base.type;
   1404         pstype = tex->pstype;
   1405         res = tex->base.resource;
   1406         view0 = NineBaseTexture9_GetSamplerView(tex, 0);
   1407         view1 = NineBaseTexture9_GetSamplerView(tex, 1);
   1408     }
   1409 
   1410     nine_context_set_texture_apply(device, Stage, enabled,
   1411                                    shadow, lod, type, pstype,
   1412                                    res, view0, view1);
   1413 }
   1414 
   1415 CSMT_ITEM_NO_WAIT(nine_context_set_sampler_state,
   1416                   ARG_VAL(DWORD, Sampler),
   1417                   ARG_VAL(D3DSAMPLERSTATETYPE, Type),
   1418                   ARG_VAL(DWORD, Value))
   1419 {
   1420     struct nine_context *context = &device->context;
   1421 
   1422     if (unlikely(!nine_check_sampler_state_value(Type, Value)))
   1423         return;
   1424 
   1425     context->samp[Sampler][Type] = Value;
   1426     context->changed.group |= NINE_STATE_SAMPLER;
   1427     context->changed.sampler[Sampler] |= 1 << Type;
   1428 }
   1429 
   1430 CSMT_ITEM_NO_WAIT(nine_context_set_stream_source_apply,
   1431                   ARG_VAL(UINT, StreamNumber),
   1432                   ARG_BIND_RES(struct pipe_resource, res),
   1433                   ARG_VAL(UINT, OffsetInBytes),
   1434                   ARG_VAL(UINT, Stride))
   1435 {
   1436     struct nine_context *context = &device->context;
   1437     const unsigned i = StreamNumber;
   1438 
   1439     context->vtxbuf[i].stride = Stride;
   1440     context->vtxbuf[i].buffer_offset = OffsetInBytes;
   1441     pipe_resource_reference(&context->vtxbuf[i].buffer.resource, res);
   1442 
   1443     context->changed.vtxbuf |= 1 << StreamNumber;
   1444 }
   1445 
   1446 void
   1447 nine_context_set_stream_source(struct NineDevice9 *device,
   1448                                UINT StreamNumber,
   1449                                struct NineVertexBuffer9 *pVBuf9,
   1450                                UINT OffsetInBytes,
   1451                                UINT Stride)
   1452 {
   1453     struct pipe_resource *res = NULL;
   1454     unsigned offset = 0;
   1455 
   1456     if (pVBuf9)
   1457         res = NineVertexBuffer9_GetResource(pVBuf9, &offset);
   1458     /* in the future when there is internal offset, add it
   1459      * to OffsetInBytes */
   1460 
   1461     nine_context_set_stream_source_apply(device, StreamNumber,
   1462                                          res, offset + OffsetInBytes,
   1463                                          Stride);
   1464 }
   1465 
   1466 CSMT_ITEM_NO_WAIT(nine_context_set_stream_source_freq,
   1467                   ARG_VAL(UINT, StreamNumber),
   1468                   ARG_VAL(UINT, Setting))
   1469 {
   1470     struct nine_context *context = &device->context;
   1471 
   1472     context->stream_freq[StreamNumber] = Setting;
   1473 
   1474     if (Setting & D3DSTREAMSOURCE_INSTANCEDATA)
   1475         context->stream_instancedata_mask |= 1 << StreamNumber;
   1476     else
   1477         context->stream_instancedata_mask &= ~(1 << StreamNumber);
   1478 
   1479     if (StreamNumber != 0)
   1480         context->changed.group |= NINE_STATE_STREAMFREQ;
   1481 }
   1482 
   1483 CSMT_ITEM_NO_WAIT(nine_context_set_indices_apply,
   1484                   ARG_BIND_RES(struct pipe_resource, res),
   1485                   ARG_VAL(UINT, IndexSize),
   1486                   ARG_VAL(UINT, OffsetInBytes))
   1487 {
   1488     struct nine_context *context = &device->context;
   1489 
   1490     context->index_size = IndexSize;
   1491     context->index_offset = OffsetInBytes;
   1492     pipe_resource_reference(&context->idxbuf, res);
   1493 
   1494     context->changed.group |= NINE_STATE_IDXBUF;
   1495 }
   1496 
   1497 void
   1498 nine_context_set_indices(struct NineDevice9 *device,
   1499                          struct NineIndexBuffer9 *idxbuf)
   1500 {
   1501     struct pipe_resource *res = NULL;
   1502     UINT IndexSize = 0;
   1503     unsigned OffsetInBytes = 0;
   1504 
   1505     if (idxbuf) {
   1506         res = NineIndexBuffer9_GetBuffer(idxbuf, &OffsetInBytes);
   1507         IndexSize = idxbuf->index_size;
   1508     }
   1509 
   1510     nine_context_set_indices_apply(device, res, IndexSize, OffsetInBytes);
   1511 }
   1512 
   1513 CSMT_ITEM_NO_WAIT(nine_context_set_vertex_declaration,
   1514                   ARG_BIND_REF(struct NineVertexDeclaration9, vdecl))
   1515 {
   1516     struct nine_context *context = &device->context;
   1517     BOOL was_programmable_vs = context->programmable_vs;
   1518 
   1519     nine_bind(&context->vdecl, vdecl);
   1520 
   1521     context->programmable_vs = context->vs && !(context->vdecl && context->vdecl->position_t);
   1522     if (was_programmable_vs != context->programmable_vs) {
   1523         context->commit |= NINE_STATE_COMMIT_CONST_VS;
   1524         context->changed.group |= NINE_STATE_VS;
   1525     }
   1526 
   1527     context->changed.group |= NINE_STATE_VDECL;
   1528 }
   1529 
   1530 CSMT_ITEM_NO_WAIT(nine_context_set_vertex_shader,
   1531                   ARG_BIND_REF(struct NineVertexShader9, pShader))
   1532 {
   1533     struct nine_context *context = &device->context;
   1534     BOOL was_programmable_vs = context->programmable_vs;
   1535 
   1536     nine_bind(&context->vs, pShader);
   1537 
   1538     context->programmable_vs = context->vs && !(context->vdecl && context->vdecl->position_t);
   1539 
   1540     /* ff -> non-ff: commit back non-ff constants */
   1541     if (!was_programmable_vs && context->programmable_vs)
   1542         context->commit |= NINE_STATE_COMMIT_CONST_VS;
   1543 
   1544     context->changed.group |= NINE_STATE_VS;
   1545 }
   1546 
   1547 CSMT_ITEM_NO_WAIT(nine_context_set_vertex_shader_constant_f,
   1548                   ARG_VAL(UINT, StartRegister),
   1549                   ARG_MEM(float, pConstantData),
   1550                   ARG_MEM_SIZE(unsigned, pConstantData_size),
   1551                   ARG_VAL(UINT, Vector4fCount))
   1552 {
   1553     struct nine_context *context = &device->context;
   1554     float *vs_const_f = device->may_swvp ? context->vs_const_f_swvp : context->vs_const_f;
   1555 
   1556     memcpy(&vs_const_f[StartRegister * 4],
   1557            pConstantData,
   1558            pConstantData_size);
   1559 
   1560     if (device->may_swvp) {
   1561         Vector4fCount = MIN2(StartRegister + Vector4fCount, NINE_MAX_CONST_F) - StartRegister;
   1562         if (StartRegister < NINE_MAX_CONST_F)
   1563             memcpy(&context->vs_const_f[StartRegister * 4],
   1564                    pConstantData,
   1565                    Vector4fCount * 4 * sizeof(context->vs_const_f[0]));
   1566     }
   1567 
   1568     context->changed.vs_const_f = TRUE;
   1569     context->changed.group |= NINE_STATE_VS_CONST;
   1570 }
   1571 
   1572 CSMT_ITEM_NO_WAIT(nine_context_set_vertex_shader_constant_i,
   1573                   ARG_VAL(UINT, StartRegister),
   1574                   ARG_MEM(int, pConstantData),
   1575                   ARG_MEM_SIZE(unsigned, pConstantData_size),
   1576                   ARG_VAL(UINT, Vector4iCount))
   1577 {
   1578     struct nine_context *context = &device->context;
   1579     int i;
   1580 
   1581     if (device->driver_caps.vs_integer) {
   1582         memcpy(&context->vs_const_i[4 * StartRegister],
   1583                pConstantData,
   1584                pConstantData_size);
   1585     } else {
   1586         for (i = 0; i < Vector4iCount; i++) {
   1587             context->vs_const_i[4 * (StartRegister + i)] = fui((float)(pConstantData[4 * i]));
   1588             context->vs_const_i[4 * (StartRegister + i) + 1] = fui((float)(pConstantData[4 * i + 1]));
   1589             context->vs_const_i[4 * (StartRegister + i) + 2] = fui((float)(pConstantData[4 * i + 2]));
   1590             context->vs_const_i[4 * (StartRegister + i) + 3] = fui((float)(pConstantData[4 * i + 3]));
   1591         }
   1592     }
   1593 
   1594     context->changed.vs_const_i = TRUE;
   1595     context->changed.group |= NINE_STATE_VS_CONST;
   1596 }
   1597 
   1598 CSMT_ITEM_NO_WAIT(nine_context_set_vertex_shader_constant_b,
   1599                   ARG_VAL(UINT, StartRegister),
   1600                   ARG_MEM(BOOL, pConstantData),
   1601                   ARG_MEM_SIZE(unsigned, pConstantData_size),
   1602                   ARG_VAL(UINT, BoolCount))
   1603 {
   1604     struct nine_context *context = &device->context;
   1605     int i;
   1606     uint32_t bool_true = device->driver_caps.vs_integer ? 0xFFFFFFFF : fui(1.0f);
   1607 
   1608     (void) pConstantData_size;
   1609 
   1610     for (i = 0; i < BoolCount; i++)
   1611         context->vs_const_b[StartRegister + i] = pConstantData[i] ? bool_true : 0;
   1612 
   1613     context->changed.vs_const_b = TRUE;
   1614     context->changed.group |= NINE_STATE_VS_CONST;
   1615 }
   1616 
   1617 CSMT_ITEM_NO_WAIT(nine_context_set_pixel_shader,
   1618                   ARG_BIND_REF(struct NinePixelShader9, ps))
   1619 {
   1620     struct nine_context *context = &device->context;
   1621     unsigned old_mask = context->ps ? context->ps->rt_mask : 1;
   1622     unsigned mask;
   1623 
   1624     /* ff -> non-ff: commit back non-ff constants */
   1625     if (!context->ps && ps)
   1626         context->commit |= NINE_STATE_COMMIT_CONST_PS;
   1627 
   1628     nine_bind(&context->ps, ps);
   1629 
   1630     context->changed.group |= NINE_STATE_PS;
   1631 
   1632     mask = context->ps ? context->ps->rt_mask : 1;
   1633     /* We need to update cbufs if the pixel shader would
   1634      * write to different render targets */
   1635     if (mask != old_mask)
   1636         context->changed.group |= NINE_STATE_FB;
   1637 }
   1638 
   1639 CSMT_ITEM_NO_WAIT(nine_context_set_pixel_shader_constant_f,
   1640                   ARG_VAL(UINT, StartRegister),
   1641                   ARG_MEM(float, pConstantData),
   1642                   ARG_MEM_SIZE(unsigned, pConstantData_size),
   1643                   ARG_VAL(UINT, Vector4fCount))
   1644 {
   1645     struct nine_context *context = &device->context;
   1646 
   1647     memcpy(&context->ps_const_f[StartRegister * 4],
   1648            pConstantData,
   1649            pConstantData_size);
   1650 
   1651     context->changed.ps_const_f = TRUE;
   1652     context->changed.group |= NINE_STATE_PS_CONST;
   1653 }
   1654 
   1655 /* For stateblocks */
   1656 CSMT_ITEM_NO_WAIT(nine_context_set_pixel_shader_constant_i_transformed,
   1657                   ARG_VAL(UINT, StartRegister),
   1658                   ARG_MEM(int, pConstantData),
   1659                   ARG_MEM_SIZE(unsigned, pConstantData_size),
   1660                   ARG_VAL(UINT, Vector4iCount))
   1661 {
   1662     struct nine_context *context = &device->context;
   1663 
   1664     memcpy(&context->ps_const_i[StartRegister][0],
   1665            pConstantData,
   1666            Vector4iCount * sizeof(context->ps_const_i[0]));
   1667 
   1668     context->changed.ps_const_i = TRUE;
   1669     context->changed.group |= NINE_STATE_PS_CONST;
   1670 }
   1671 
   1672 CSMT_ITEM_NO_WAIT(nine_context_set_pixel_shader_constant_i,
   1673                   ARG_VAL(UINT, StartRegister),
   1674                   ARG_MEM(int, pConstantData),
   1675                   ARG_MEM_SIZE(unsigned, pConstantData_size),
   1676                   ARG_VAL(UINT, Vector4iCount))
   1677 {
   1678     struct nine_context *context = &device->context;
   1679     int i;
   1680 
   1681     if (device->driver_caps.ps_integer) {
   1682         memcpy(&context->ps_const_i[StartRegister][0],
   1683                pConstantData,
   1684                pConstantData_size);
   1685     } else {
   1686         for (i = 0; i < Vector4iCount; i++) {
   1687             context->ps_const_i[StartRegister+i][0] = fui((float)(pConstantData[4*i]));
   1688             context->ps_const_i[StartRegister+i][1] = fui((float)(pConstantData[4*i+1]));
   1689             context->ps_const_i[StartRegister+i][2] = fui((float)(pConstantData[4*i+2]));
   1690             context->ps_const_i[StartRegister+i][3] = fui((float)(pConstantData[4*i+3]));
   1691         }
   1692     }
   1693     context->changed.ps_const_i = TRUE;
   1694     context->changed.group |= NINE_STATE_PS_CONST;
   1695 }
   1696 
   1697 CSMT_ITEM_NO_WAIT(nine_context_set_pixel_shader_constant_b,
   1698                   ARG_VAL(UINT, StartRegister),
   1699                   ARG_MEM(BOOL, pConstantData),
   1700                   ARG_MEM_SIZE(unsigned, pConstantData_size),
   1701                   ARG_VAL(UINT, BoolCount))
   1702 {
   1703     struct nine_context *context = &device->context;
   1704     int i;
   1705     uint32_t bool_true = device->driver_caps.ps_integer ? 0xFFFFFFFF : fui(1.0f);
   1706 
   1707     (void) pConstantData_size;
   1708 
   1709     for (i = 0; i < BoolCount; i++)
   1710         context->ps_const_b[StartRegister + i] = pConstantData[i] ? bool_true : 0;
   1711 
   1712     context->changed.ps_const_b = TRUE;
   1713     context->changed.group |= NINE_STATE_PS_CONST;
   1714 }
   1715 
   1716 /* XXX: use resource, as resource might change */
   1717 CSMT_ITEM_NO_WAIT(nine_context_set_render_target,
   1718                   ARG_VAL(DWORD, RenderTargetIndex),
   1719                   ARG_BIND_REF(struct NineSurface9, rt))
   1720 {
   1721     struct nine_context *context = &device->context;
   1722     const unsigned i = RenderTargetIndex;
   1723 
   1724     if (i == 0) {
   1725         context->viewport.X = 0;
   1726         context->viewport.Y = 0;
   1727         context->viewport.Width = rt->desc.Width;
   1728         context->viewport.Height = rt->desc.Height;
   1729         context->viewport.MinZ = 0.0f;
   1730         context->viewport.MaxZ = 1.0f;
   1731 
   1732         context->scissor.minx = 0;
   1733         context->scissor.miny = 0;
   1734         context->scissor.maxx = rt->desc.Width;
   1735         context->scissor.maxy = rt->desc.Height;
   1736 
   1737         context->changed.group |= NINE_STATE_VIEWPORT | NINE_STATE_SCISSOR | NINE_STATE_MULTISAMPLE;
   1738 
   1739         if (context->rt[0] &&
   1740             (context->rt[0]->desc.MultiSampleType <= D3DMULTISAMPLE_NONMASKABLE) !=
   1741             (rt->desc.MultiSampleType <= D3DMULTISAMPLE_NONMASKABLE))
   1742             context->changed.group |= NINE_STATE_SAMPLE_MASK;
   1743     }
   1744 
   1745     if (context->rt[i] != rt) {
   1746        nine_bind(&context->rt[i], rt);
   1747        context->changed.group |= NINE_STATE_FB;
   1748     }
   1749 }
   1750 
   1751 /* XXX: use resource instead of ds, as resource might change */
   1752 CSMT_ITEM_NO_WAIT(nine_context_set_depth_stencil,
   1753                   ARG_BIND_REF(struct NineSurface9, ds))
   1754 {
   1755     struct nine_context *context = &device->context;
   1756 
   1757     nine_bind(&context->ds, ds);
   1758     context->changed.group |= NINE_STATE_FB;
   1759 }
   1760 
   1761 CSMT_ITEM_NO_WAIT(nine_context_set_viewport,
   1762                   ARG_COPY_REF(D3DVIEWPORT9, viewport))
   1763 {
   1764     struct nine_context *context = &device->context;
   1765 
   1766     context->viewport = *viewport;
   1767     context->changed.group |= NINE_STATE_VIEWPORT;
   1768 }
   1769 
   1770 CSMT_ITEM_NO_WAIT(nine_context_set_scissor,
   1771                   ARG_COPY_REF(struct pipe_scissor_state, scissor))
   1772 {
   1773     struct nine_context *context = &device->context;
   1774 
   1775     context->scissor = *scissor;
   1776     context->changed.group |= NINE_STATE_SCISSOR;
   1777 }
   1778 
   1779 CSMT_ITEM_NO_WAIT(nine_context_set_transform,
   1780                   ARG_VAL(D3DTRANSFORMSTATETYPE, State),
   1781                   ARG_COPY_REF(D3DMATRIX, pMatrix))
   1782 {
   1783     struct nine_context *context = &device->context;
   1784     D3DMATRIX *M = nine_state_access_transform(&context->ff, State, TRUE);
   1785 
   1786     *M = *pMatrix;
   1787     context->ff.changed.transform[State / 32] |= 1 << (State % 32);
   1788     context->changed.group |= NINE_STATE_FF;
   1789 }
   1790 
   1791 CSMT_ITEM_NO_WAIT(nine_context_set_material,
   1792                   ARG_COPY_REF(D3DMATERIAL9, pMaterial))
   1793 {
   1794     struct nine_context *context = &device->context;
   1795 
   1796     context->ff.material = *pMaterial;
   1797     context->changed.group |= NINE_STATE_FF_MATERIAL;
   1798 }
   1799 
   1800 CSMT_ITEM_NO_WAIT(nine_context_set_light,
   1801                   ARG_VAL(DWORD, Index),
   1802                   ARG_COPY_REF(D3DLIGHT9, pLight))
   1803 {
   1804     struct nine_context *context = &device->context;
   1805 
   1806     (void)nine_state_set_light(&context->ff, Index, pLight);
   1807     context->changed.group |= NINE_STATE_FF_LIGHTING;
   1808 }
   1809 
   1810 
   1811 /* For stateblocks */
   1812 static void
   1813 nine_context_light_enable_stateblock(struct NineDevice9 *device,
   1814                                      const uint16_t active_light[NINE_MAX_LIGHTS_ACTIVE], /* TODO: use pointer that convey size for csmt */
   1815                                      unsigned int num_lights_active)
   1816 {
   1817     struct nine_context *context = &device->context;
   1818 
   1819     /* TODO: Use CSMT_* to avoid calling nine_csmt_process */
   1820     nine_csmt_process(device);
   1821     memcpy(context->ff.active_light, active_light, NINE_MAX_LIGHTS_ACTIVE * sizeof(context->ff.active_light[0]));
   1822     context->ff.num_lights_active = num_lights_active;
   1823     context->changed.group |= NINE_STATE_FF_LIGHTING;
   1824 }
   1825 
   1826 CSMT_ITEM_NO_WAIT(nine_context_light_enable,
   1827                   ARG_VAL(DWORD, Index),
   1828                   ARG_VAL(BOOL, Enable))
   1829 {
   1830     struct nine_context *context = &device->context;
   1831 
   1832     nine_state_light_enable(&context->ff, &context->changed.group, Index, Enable);
   1833 }
   1834 
   1835 CSMT_ITEM_NO_WAIT(nine_context_set_texture_stage_state,
   1836                   ARG_VAL(DWORD, Stage),
   1837                   ARG_VAL(D3DTEXTURESTAGESTATETYPE, Type),
   1838                   ARG_VAL(DWORD, Value))
   1839 {
   1840     struct nine_context *context = &device->context;
   1841     int bumpmap_index = -1;
   1842 
   1843     context->ff.tex_stage[Stage][Type] = Value;
   1844     switch (Type) {
   1845     case D3DTSS_BUMPENVMAT00:
   1846         bumpmap_index = 4 * Stage;
   1847         break;
   1848     case D3DTSS_BUMPENVMAT01:
   1849         bumpmap_index = 4 * Stage + 1;
   1850         break;
   1851     case D3DTSS_BUMPENVMAT10:
   1852         bumpmap_index = 4 * Stage + 2;
   1853         break;
   1854     case D3DTSS_BUMPENVMAT11:
   1855         bumpmap_index = 4 * Stage + 3;
   1856         break;
   1857     case D3DTSS_BUMPENVLSCALE:
   1858         bumpmap_index = 4 * 8 + 2 * Stage;
   1859         break;
   1860     case D3DTSS_BUMPENVLOFFSET:
   1861         bumpmap_index = 4 * 8 + 2 * Stage + 1;
   1862         break;
   1863     case D3DTSS_TEXTURETRANSFORMFLAGS:
   1864         context->changed.group |= NINE_STATE_PS1X_SHADER;
   1865         break;
   1866     default:
   1867         break;
   1868     }
   1869 
   1870     if (bumpmap_index >= 0) {
   1871         context->bumpmap_vars[bumpmap_index] = Value;
   1872         context->changed.group |= NINE_STATE_PS_CONST;
   1873     }
   1874 
   1875     context->changed.group |= NINE_STATE_FF_PSSTAGES;
   1876     context->ff.changed.tex_stage[Stage][Type / 32] |= 1 << (Type % 32);
   1877 }
   1878 
   1879 CSMT_ITEM_NO_WAIT(nine_context_set_clip_plane,
   1880                   ARG_VAL(DWORD, Index),
   1881                   ARG_COPY_REF(struct nine_clipplane, pPlane))
   1882 {
   1883     struct nine_context *context = &device->context;
   1884 
   1885     memcpy(&context->clip.ucp[Index][0], pPlane, sizeof(context->clip.ucp[0]));
   1886     context->changed.ucp = TRUE;
   1887 }
   1888 
   1889 CSMT_ITEM_NO_WAIT(nine_context_set_swvp,
   1890                   ARG_VAL(boolean, swvp))
   1891 {
   1892     struct nine_context *context = &device->context;
   1893 
   1894     context->swvp = swvp;
   1895     context->changed.group |= NINE_STATE_SWVP;
   1896 }
   1897 
   1898 #if 0
   1899 
   1900 void
   1901 nine_context_apply_stateblock(struct NineDevice9 *device,
   1902                               const struct nine_state *src)
   1903 {
   1904     struct nine_context *context = &device->context;
   1905     int i;
   1906 
   1907     context->changed.group |= src->changed.group;
   1908 
   1909     for (i = 0; i < ARRAY_SIZE(src->changed.rs); ++i) {
   1910         uint32_t m = src->changed.rs[i];
   1911         while (m) {
   1912             const int r = ffs(m) - 1;
   1913             m &= ~(1 << r);
   1914             context->rs[i * 32 + r] = nine_fix_render_state_value(i * 32 + r, src->rs_advertised[i * 32 + r]);
   1915         }
   1916     }
   1917 
   1918     /* Textures */
   1919     if (src->changed.texture) {
   1920         uint32_t m = src->changed.texture;
   1921         unsigned s;
   1922 
   1923         for (s = 0; m; ++s, m >>= 1) {
   1924             struct NineBaseTexture9 *tex = src->texture[s];
   1925             if (!(m & 1))
   1926                 continue;
   1927             nine_context_set_texture(device, s, tex);
   1928         }
   1929     }
   1930 
   1931     /* Sampler state */
   1932     if (src->changed.group & NINE_STATE_SAMPLER) {
   1933         unsigned s;
   1934 
   1935         for (s = 0; s < NINE_MAX_SAMPLERS; ++s) {
   1936             uint32_t m = src->changed.sampler[s];
   1937             while (m) {
   1938                 const int i = ffs(m) - 1;
   1939                 m &= ~(1 << i);
   1940                 if (nine_check_sampler_state_value(i, src->samp_advertised[s][i]))
   1941                     context->samp[s][i] = src->samp_advertised[s][i];
   1942             }
   1943             context->changed.sampler[s] |= src->changed.sampler[s];
   1944         }
   1945     }
   1946 
   1947     /* Vertex buffers */
   1948     if (src->changed.vtxbuf | src->changed.stream_freq) {
   1949         uint32_t m = src->changed.vtxbuf | src->changed.stream_freq;
   1950         for (i = 0; m; ++i, m >>= 1) {
   1951             if (src->changed.vtxbuf & (1 << i)) {
   1952                 if (src->stream[i]) {
   1953                     unsigned offset = 0;
   1954                     pipe_resource_reference(&context->vtxbuf[i].buffer,
   1955                         src->stream[i] ? NineVertexBuffer9_GetResource(src->stream[i], &offset) : NULL);
   1956                     context->vtxbuf[i].buffer_offset = src->vtxbuf[i].buffer_offset + offset;
   1957                     context->vtxbuf[i].stride = src->vtxbuf[i].stride;
   1958                 }
   1959             }
   1960             if (src->changed.stream_freq & (1 << i)) {
   1961                 context->stream_freq[i] = src->stream_freq[i];
   1962                 if (src->stream_freq[i] & D3DSTREAMSOURCE_INSTANCEDATA)
   1963                     context->stream_instancedata_mask |= 1 << i;
   1964                 else
   1965                     context->stream_instancedata_mask &= ~(1 << i);
   1966             }
   1967         }
   1968         context->changed.vtxbuf |= src->changed.vtxbuf;
   1969     }
   1970 
   1971     /* Index buffer */
   1972     if (src->changed.group & NINE_STATE_IDXBUF)
   1973         nine_context_set_indices(device, src->idxbuf);
   1974 
   1975     /* Vertex declaration */
   1976     if ((src->changed.group & NINE_STATE_VDECL) && src->vdecl)
   1977         nine_context_set_vertex_declaration(device, src->vdecl);
   1978 
   1979     /* Vertex shader */
   1980     if (src->changed.group & NINE_STATE_VS)
   1981         nine_bind(&context->vs, src->vs);
   1982 
   1983     context->programmable_vs = context->vs && !(context->vdecl && context->vdecl->position_t);
   1984 
   1985     /* Pixel shader */
   1986     if (src->changed.group & NINE_STATE_PS)
   1987         nine_bind(&context->ps, src->ps);
   1988 
   1989     /* Vertex constants */
   1990     if (src->changed.group & NINE_STATE_VS_CONST) {
   1991         struct nine_range *r;
   1992         if (device->may_swvp) {
   1993             for (r = src->changed.vs_const_f; r; r = r->next) {
   1994                 int bgn = r->bgn;
   1995                 int end = r->end;
   1996                 memcpy(&context->vs_const_f_swvp[bgn * 4],
   1997                        &src->vs_const_f[bgn * 4],
   1998                        (end - bgn) * 4 * sizeof(float));
   1999                 if (bgn < device->max_vs_const_f) {
   2000                     end = MIN2(end, device->max_vs_const_f);
   2001                     memcpy(&context->vs_const_f[bgn * 4],
   2002                            &src->vs_const_f[bgn * 4],
   2003                            (end - bgn) * 4 * sizeof(float));
   2004                 }
   2005             }
   2006         } else {
   2007             for (r = src->changed.vs_const_f; r; r = r->next) {
   2008                 memcpy(&context->vs_const_f[r->bgn * 4],
   2009                        &src->vs_const_f[r->bgn * 4],
   2010                        (r->end - r->bgn) * 4 * sizeof(float));
   2011             }
   2012         }
   2013         for (r = src->changed.vs_const_i; r; r = r->next) {
   2014             memcpy(&context->vs_const_i[r->bgn * 4],
   2015                    &src->vs_const_i[r->bgn * 4],
   2016                    (r->end - r->bgn) * 4 * sizeof(int));
   2017         }
   2018         for (r = src->changed.vs_const_b; r; r = r->next) {
   2019             memcpy(&context->vs_const_b[r->bgn],
   2020                    &src->vs_const_b[r->bgn],
   2021                    (r->end - r->bgn) * sizeof(int));
   2022         }
   2023         context->changed.vs_const_f = !!src->changed.vs_const_f;
   2024         context->changed.vs_const_i = !!src->changed.vs_const_i;
   2025         context->changed.vs_const_b = !!src->changed.vs_const_b;
   2026     }
   2027 
   2028     /* Pixel constants */
   2029     if (src->changed.group & NINE_STATE_PS_CONST) {
   2030         struct nine_range *r;
   2031         for (r = src->changed.ps_const_f; r; r = r->next) {
   2032             memcpy(&context->ps_const_f[r->bgn * 4],
   2033                    &src->ps_const_f[r->bgn * 4],
   2034                    (r->end - r->bgn) * 4 * sizeof(float));
   2035         }
   2036         if (src->changed.ps_const_i) {
   2037             uint16_t m = src->changed.ps_const_i;
   2038             for (i = ffs(m) - 1, m >>= i; m; ++i, m >>= 1)
   2039                 if (m & 1)
   2040                     memcpy(context->ps_const_i[i], src->ps_const_i[i], 4 * sizeof(int));
   2041         }
   2042         if (src->changed.ps_const_b) {
   2043             uint16_t m = src->changed.ps_const_b;
   2044             for (i = ffs(m) - 1, m >>= i; m; ++i, m >>= 1)
   2045                 if (m & 1)
   2046                     context->ps_const_b[i] = src->ps_const_b[i];
   2047         }
   2048         context->changed.ps_const_f = !!src->changed.ps_const_f;
   2049         context->changed.ps_const_i = !!src->changed.ps_const_i;
   2050         context->changed.ps_const_b = !!src->changed.ps_const_b;
   2051     }
   2052 
   2053     /* Viewport */
   2054     if (src->changed.group & NINE_STATE_VIEWPORT)
   2055         context->viewport = src->viewport;
   2056 
   2057     /* Scissor */
   2058     if (src->changed.group & NINE_STATE_SCISSOR)
   2059         context->scissor = src->scissor;
   2060 
   2061     /* User Clip Planes */
   2062     if (src->changed.ucp) {
   2063         for (i = 0; i < PIPE_MAX_CLIP_PLANES; ++i)
   2064             if (src->changed.ucp & (1 << i))
   2065                 memcpy(context->clip.ucp[i],
   2066                        src->clip.ucp[i], sizeof(src->clip.ucp[0]));
   2067         context->changed.ucp = TRUE;
   2068     }
   2069 
   2070     if (!(src->changed.group & NINE_STATE_FF))
   2071         return;
   2072 
   2073     /* Fixed function state. */
   2074 
   2075     if (src->changed.group & NINE_STATE_FF_MATERIAL)
   2076         context->ff.material = src->ff.material;
   2077 
   2078     if (src->changed.group & NINE_STATE_FF_PSSTAGES) {
   2079         unsigned s;
   2080         for (s = 0; s < NINE_MAX_TEXTURE_STAGES; ++s) {
   2081             for (i = 0; i < NINED3DTSS_COUNT; ++i)
   2082                 if (src->ff.changed.tex_stage[s][i / 32] & (1 << (i % 32)))
   2083                     context->ff.tex_stage[s][i] = src->ff.tex_stage[s][i];
   2084         }
   2085     }
   2086     if (src->changed.group & NINE_STATE_FF_LIGHTING) {
   2087         unsigned num_lights = MAX2(context->ff.num_lights, src->ff.num_lights);
   2088         /* Can happen if the stateblock had recorded the creation of
   2089          * new lights. */
   2090         if (context->ff.num_lights < num_lights) {
   2091             context->ff.light = REALLOC(context->ff.light,
   2092                                     context->ff.num_lights * sizeof(D3DLIGHT9),
   2093                                     num_lights * sizeof(D3DLIGHT9));
   2094             memset(&context->ff.light[context->ff.num_lights], 0, (num_lights - context->ff.num_lights) * sizeof(D3DLIGHT9));
   2095             for (i = context->ff.num_lights; i < num_lights; ++i)
   2096                 context->ff.light[i].Type = (D3DLIGHTTYPE)NINED3DLIGHT_INVALID;
   2097             context->ff.num_lights = num_lights;
   2098         }
   2099         /* src->ff.num_lights < num_lights has been handled before */
   2100         assert (src->ff.num_lights == num_lights);
   2101 
   2102         for (i = 0; i < num_lights; ++i)
   2103             if (src->ff.light[i].Type != NINED3DLIGHT_INVALID)
   2104                 context->ff.light[i] = src->ff.light[i];
   2105 
   2106         memcpy(context->ff.active_light, src->ff.active_light, sizeof(src->ff.active_light) );
   2107         context->ff.num_lights_active = src->ff.num_lights_active;
   2108     }
   2109     if (src->changed.group & NINE_STATE_FF_VSTRANSF) {
   2110         for (i = 0; i < ARRAY_SIZE(src->ff.changed.transform); ++i) {
   2111             unsigned s;
   2112             if (!src->ff.changed.transform[i])
   2113                 continue;
   2114             for (s = i * 32; s < (i * 32 + 32); ++s) {
   2115                 if (!(src->ff.changed.transform[i] & (1 << (s % 32))))
   2116                     continue;
   2117                 *nine_state_access_transform(&context->ff, s, TRUE) =
   2118                     *nine_state_access_transform( /* const because !alloc */
   2119                         (struct nine_ff_state *)&src->ff, s, FALSE);
   2120             }
   2121             context->ff.changed.transform[i] |= src->ff.changed.transform[i];
   2122         }
   2123     }
   2124 }
   2125 
   2126 #endif
   2127 
   2128 /* Do not write to nine_context directly. Slower,
   2129  * but works with csmt. TODO: write a special csmt version that
   2130  * would record the list of commands as much as possible,
   2131  * and use the version above else.
   2132  */
   2133 void
   2134 nine_context_apply_stateblock(struct NineDevice9 *device,
   2135                               const struct nine_state *src)
   2136 {
   2137     int i;
   2138 
   2139     /* No need to apply src->changed.group, since all calls do
   2140     * set context->changed.group */
   2141 
   2142     for (i = 0; i < ARRAY_SIZE(src->changed.rs); ++i) {
   2143         uint32_t m = src->changed.rs[i];
   2144         while (m) {
   2145             const int r = ffs(m) - 1;
   2146             m &= ~(1 << r);
   2147             nine_context_set_render_state(device, i * 32 + r, src->rs_advertised[i * 32 + r]);
   2148         }
   2149     }
   2150 
   2151     /* Textures */
   2152     if (src->changed.texture) {
   2153         uint32_t m = src->changed.texture;
   2154         unsigned s;
   2155 
   2156         for (s = 0; m; ++s, m >>= 1) {
   2157             struct NineBaseTexture9 *tex = src->texture[s];
   2158             if (!(m & 1))
   2159                 continue;
   2160             nine_context_set_texture(device, s, tex);
   2161         }
   2162     }
   2163 
   2164     /* Sampler state */
   2165     if (src->changed.group & NINE_STATE_SAMPLER) {
   2166         unsigned s;
   2167 
   2168         for (s = 0; s < NINE_MAX_SAMPLERS; ++s) {
   2169             uint32_t m = src->changed.sampler[s];
   2170             while (m) {
   2171                 const int i = ffs(m) - 1;
   2172                 m &= ~(1 << i);
   2173                 nine_context_set_sampler_state(device, s, i, src->samp_advertised[s][i]);
   2174             }
   2175         }
   2176     }
   2177 
   2178     /* Vertex buffers */
   2179     if (src->changed.vtxbuf | src->changed.stream_freq) {
   2180         uint32_t m = src->changed.vtxbuf | src->changed.stream_freq;
   2181         for (i = 0; m; ++i, m >>= 1) {
   2182             if (src->changed.vtxbuf & (1 << i))
   2183                 nine_context_set_stream_source(device, i, src->stream[i], src->vtxbuf[i].buffer_offset, src->vtxbuf[i].stride);
   2184             if (src->changed.stream_freq & (1 << i))
   2185                 nine_context_set_stream_source_freq(device, i, src->stream_freq[i]);
   2186         }
   2187     }
   2188 
   2189     /* Index buffer */
   2190     if (src->changed.group & NINE_STATE_IDXBUF)
   2191         nine_context_set_indices(device, src->idxbuf);
   2192 
   2193     /* Vertex declaration */
   2194     if ((src->changed.group & NINE_STATE_VDECL) && src->vdecl)
   2195         nine_context_set_vertex_declaration(device, src->vdecl);
   2196 
   2197     /* Vertex shader */
   2198     if (src->changed.group & NINE_STATE_VS)
   2199         nine_context_set_vertex_shader(device, src->vs);
   2200 
   2201     /* Pixel shader */
   2202     if (src->changed.group & NINE_STATE_PS)
   2203         nine_context_set_pixel_shader(device, src->ps);
   2204 
   2205     /* Vertex constants */
   2206     if (src->changed.group & NINE_STATE_VS_CONST) {
   2207         struct nine_range *r;
   2208         for (r = src->changed.vs_const_f; r; r = r->next)
   2209             nine_context_set_vertex_shader_constant_f(device, r->bgn,
   2210                                                       &src->vs_const_f[r->bgn * 4],
   2211                                                       sizeof(float[4]) * (r->end - r->bgn),
   2212                                                       r->end - r->bgn);
   2213         for (r = src->changed.vs_const_i; r; r = r->next)
   2214             nine_context_set_vertex_shader_constant_i(device, r->bgn,
   2215                                                       &src->vs_const_i[r->bgn * 4],
   2216                                                       sizeof(int[4]) * (r->end - r->bgn),
   2217                                                       r->end - r->bgn);
   2218         for (r = src->changed.vs_const_b; r; r = r->next)
   2219             nine_context_set_vertex_shader_constant_b(device, r->bgn,
   2220                                                       &src->vs_const_b[r->bgn * 4],
   2221                                                       sizeof(BOOL) * (r->end - r->bgn),
   2222                                                       r->end - r->bgn);
   2223     }
   2224 
   2225     /* Pixel constants */
   2226     if (src->changed.group & NINE_STATE_PS_CONST) {
   2227         struct nine_range *r;
   2228         for (r = src->changed.ps_const_f; r; r = r->next)
   2229             nine_context_set_pixel_shader_constant_f(device, r->bgn,
   2230                                                      &src->ps_const_f[r->bgn * 4],
   2231                                                      sizeof(float[4]) * (r->end - r->bgn),
   2232                                                      r->end - r->bgn);
   2233         if (src->changed.ps_const_i) {
   2234             uint16_t m = src->changed.ps_const_i;
   2235             for (i = ffs(m) - 1, m >>= i; m; ++i, m >>= 1)
   2236                 if (m & 1)
   2237                     nine_context_set_pixel_shader_constant_i_transformed(device, i,
   2238                                                                          src->ps_const_i[i], sizeof(int[4]), 1);
   2239         }
   2240         if (src->changed.ps_const_b) {
   2241             uint16_t m = src->changed.ps_const_b;
   2242             for (i = ffs(m) - 1, m >>= i; m; ++i, m >>= 1)
   2243                 if (m & 1)
   2244                     nine_context_set_pixel_shader_constant_b(device, i,
   2245                                                              &src->ps_const_b[i], sizeof(BOOL), 1);
   2246         }
   2247     }
   2248 
   2249     /* Viewport */
   2250     if (src->changed.group & NINE_STATE_VIEWPORT)
   2251         nine_context_set_viewport(device, &src->viewport);
   2252 
   2253     /* Scissor */
   2254     if (src->changed.group & NINE_STATE_SCISSOR)
   2255         nine_context_set_scissor(device, &src->scissor);
   2256 
   2257     /* User Clip Planes */
   2258     if (src->changed.ucp)
   2259         for (i = 0; i < PIPE_MAX_CLIP_PLANES; ++i)
   2260             if (src->changed.ucp & (1 << i))
   2261                 nine_context_set_clip_plane(device, i, (struct nine_clipplane*)&src->clip.ucp[i][0]);
   2262 
   2263     if (!(src->changed.group & NINE_STATE_FF))
   2264         return;
   2265 
   2266     /* Fixed function state. */
   2267 
   2268     if (src->changed.group & NINE_STATE_FF_MATERIAL)
   2269         nine_context_set_material(device, &src->ff.material);
   2270 
   2271     if (src->changed.group & NINE_STATE_FF_PSSTAGES) {
   2272         unsigned s;
   2273         for (s = 0; s < NINE_MAX_TEXTURE_STAGES; ++s) {
   2274             for (i = 0; i < NINED3DTSS_COUNT; ++i)
   2275                 if (src->ff.changed.tex_stage[s][i / 32] & (1 << (i % 32)))
   2276                    nine_context_set_texture_stage_state(device, s, i, src->ff.tex_stage[s][i]);
   2277         }
   2278     }
   2279     if (src->changed.group & NINE_STATE_FF_LIGHTING) {
   2280         for (i = 0; i < src->ff.num_lights; ++i)
   2281             if (src->ff.light[i].Type != NINED3DLIGHT_INVALID)
   2282                 nine_context_set_light(device, i, &src->ff.light[i]);
   2283 
   2284         nine_context_light_enable_stateblock(device, src->ff.active_light, src->ff.num_lights_active);
   2285     }
   2286     if (src->changed.group & NINE_STATE_FF_VSTRANSF) {
   2287         for (i = 0; i < ARRAY_SIZE(src->ff.changed.transform); ++i) {
   2288             unsigned s;
   2289             if (!src->ff.changed.transform[i])
   2290                 continue;
   2291             for (s = i * 32; s < (i * 32 + 32); ++s) {
   2292                 if (!(src->ff.changed.transform[i] & (1 << (s % 32))))
   2293                     continue;
   2294                 nine_context_set_transform(device, s,
   2295                                            nine_state_access_transform(
   2296                                                (struct nine_ff_state *)&src->ff,
   2297                                                                        s, FALSE));
   2298             }
   2299         }
   2300     }
   2301 }
   2302 
   2303 static void
   2304 nine_update_state_framebuffer_clear(struct NineDevice9 *device)
   2305 {
   2306     struct nine_context *context = &device->context;
   2307 
   2308     if (context->changed.group & NINE_STATE_FB)
   2309         update_framebuffer(device, TRUE);
   2310 }
   2311 
   2312 CSMT_ITEM_NO_WAIT(nine_context_clear_fb,
   2313                   ARG_VAL(DWORD, Count),
   2314                   ARG_COPY_REF(D3DRECT, pRects),
   2315                   ARG_VAL(DWORD, Flags),
   2316                   ARG_VAL(D3DCOLOR, Color),
   2317                   ARG_VAL(float, Z),
   2318                   ARG_VAL(DWORD, Stencil))
   2319 {
   2320     struct nine_context *context = &device->context;
   2321     const int sRGB = context->rs[D3DRS_SRGBWRITEENABLE] ? 1 : 0;
   2322     struct pipe_surface *cbuf, *zsbuf;
   2323     struct pipe_context *pipe = context->pipe;
   2324     struct NineSurface9 *zsbuf_surf = context->ds;
   2325     struct NineSurface9 *rt;
   2326     unsigned bufs = 0;
   2327     unsigned r, i;
   2328     union pipe_color_union rgba;
   2329     unsigned rt_mask = 0;
   2330     D3DRECT rect;
   2331 
   2332     nine_update_state_framebuffer_clear(device);
   2333 
   2334     if (Flags & D3DCLEAR_TARGET) bufs |= PIPE_CLEAR_COLOR;
   2335     /* Ignore Z buffer if not bound */
   2336     if (context->pipe_data.fb.zsbuf != NULL) {
   2337         if (Flags & D3DCLEAR_ZBUFFER) bufs |= PIPE_CLEAR_DEPTH;
   2338         if (Flags & D3DCLEAR_STENCIL) bufs |= PIPE_CLEAR_STENCIL;
   2339     }
   2340     if (!bufs)
   2341         return;
   2342     d3dcolor_to_pipe_color_union(&rgba, Color);
   2343 
   2344     rect.x1 = context->viewport.X;
   2345     rect.y1 = context->viewport.Y;
   2346     rect.x2 = context->viewport.Width + rect.x1;
   2347     rect.y2 = context->viewport.Height + rect.y1;
   2348 
   2349     /* Both rectangles apply, which is weird, but that's D3D9. */
   2350     if (context->rs[D3DRS_SCISSORTESTENABLE]) {
   2351         rect.x1 = MAX2(rect.x1, context->scissor.minx);
   2352         rect.y1 = MAX2(rect.y1, context->scissor.miny);
   2353         rect.x2 = MIN2(rect.x2, context->scissor.maxx);
   2354         rect.y2 = MIN2(rect.y2, context->scissor.maxy);
   2355     }
   2356 
   2357     if (Count) {
   2358         /* Maybe apps like to specify a large rect ? */
   2359         if (pRects[0].x1 <= rect.x1 && pRects[0].x2 >= rect.x2 &&
   2360             pRects[0].y1 <= rect.y1 && pRects[0].y2 >= rect.y2) {
   2361             DBG("First rect covers viewport.\n");
   2362             Count = 0;
   2363             pRects = NULL;
   2364         }
   2365     }
   2366 
   2367     if (rect.x1 >= context->pipe_data.fb.width || rect.y1 >= context->pipe_data.fb.height)
   2368         return;
   2369 
   2370     for (i = 0; i < device->caps.NumSimultaneousRTs; ++i) {
   2371         if (context->rt[i] && context->rt[i]->desc.Format != D3DFMT_NULL)
   2372             rt_mask |= 1 << i;
   2373     }
   2374 
   2375     /* fast path, clears everything at once */
   2376     if (!Count &&
   2377         (!(bufs & PIPE_CLEAR_COLOR) || (rt_mask == context->rt_mask)) &&
   2378         rect.x1 == 0 && rect.y1 == 0 &&
   2379         /* Case we clear only render target. Check clear region vs rt. */
   2380         ((!(bufs & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) &&
   2381          rect.x2 >= context->pipe_data.fb.width &&
   2382          rect.y2 >= context->pipe_data.fb.height) ||
   2383         /* Case we clear depth buffer (and eventually rt too).
   2384          * depth buffer size is always >= rt size. Compare to clear region */
   2385         ((bufs & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) &&
   2386          rect.x2 >= zsbuf_surf->desc.Width &&
   2387          rect.y2 >= zsbuf_surf->desc.Height))) {
   2388         DBG("Clear fast path\n");
   2389         pipe->clear(pipe, bufs, &rgba, Z, Stencil);
   2390         return;
   2391     }
   2392 
   2393     if (!Count) {
   2394         Count = 1;
   2395         pRects = &rect;
   2396     }
   2397 
   2398     for (i = 0; i < device->caps.NumSimultaneousRTs; ++i) {
   2399         rt = context->rt[i];
   2400         if (!rt || rt->desc.Format == D3DFMT_NULL ||
   2401             !(bufs & PIPE_CLEAR_COLOR))
   2402             continue; /* save space, compiler should hoist this */
   2403         cbuf = NineSurface9_GetSurface(rt, sRGB);
   2404         for (r = 0; r < Count; ++r) {
   2405             /* Don't trust users to pass these in the right order. */
   2406             unsigned x1 = MIN2(pRects[r].x1, pRects[r].x2);
   2407             unsigned y1 = MIN2(pRects[r].y1, pRects[r].y2);
   2408             unsigned x2 = MAX2(pRects[r].x1, pRects[r].x2);
   2409             unsigned y2 = MAX2(pRects[r].y1, pRects[r].y2);
   2410 #ifndef NINE_LAX
   2411             /* Drop negative rectangles (like wine expects). */
   2412             if (pRects[r].x1 > pRects[r].x2) continue;
   2413             if (pRects[r].y1 > pRects[r].y2) continue;
   2414 #endif
   2415 
   2416             x1 = MAX2(x1, rect.x1);
   2417             y1 = MAX2(y1, rect.y1);
   2418             x2 = MIN3(x2, rect.x2, rt->desc.Width);
   2419             y2 = MIN3(y2, rect.y2, rt->desc.Height);
   2420 
   2421             DBG("Clearing (%u..%u)x(%u..%u)\n", x1, x2, y1, y2);
   2422             pipe->clear_render_target(pipe, cbuf, &rgba,
   2423                                       x1, y1, x2 - x1, y2 - y1, false);
   2424         }
   2425     }
   2426     if (!(bufs & PIPE_CLEAR_DEPTHSTENCIL))
   2427         return;
   2428 
   2429     bufs &= PIPE_CLEAR_DEPTHSTENCIL;
   2430 
   2431     for (r = 0; r < Count; ++r) {
   2432         unsigned x1 = MIN2(pRects[r].x1, pRects[r].x2);
   2433         unsigned y1 = MIN2(pRects[r].y1, pRects[r].y2);
   2434         unsigned x2 = MAX2(pRects[r].x1, pRects[r].x2);
   2435         unsigned y2 = MAX2(pRects[r].y1, pRects[r].y2);
   2436 #ifndef NINE_LAX
   2437         /* Drop negative rectangles. */
   2438         if (pRects[r].x1 > pRects[r].x2) continue;
   2439         if (pRects[r].y1 > pRects[r].y2) continue;
   2440 #endif
   2441 
   2442         x1 = MIN2(x1, rect.x1);
   2443         y1 = MIN2(y1, rect.y1);
   2444         x2 = MIN3(x2, rect.x2, zsbuf_surf->desc.Width);
   2445         y2 = MIN3(y2, rect.y2, zsbuf_surf->desc.Height);
   2446 
   2447         zsbuf = NineSurface9_GetSurface(zsbuf_surf, 0);
   2448         assert(zsbuf);
   2449         pipe->clear_depth_stencil(pipe, zsbuf, bufs, Z, Stencil,
   2450                                   x1, y1, x2 - x1, y2 - y1, false);
   2451     }
   2452     return;
   2453 }
   2454 
   2455 
   2456 static inline void
   2457 init_draw_info(struct pipe_draw_info *info,
   2458                struct NineDevice9 *dev, D3DPRIMITIVETYPE type, UINT count)
   2459 {
   2460     info->mode = d3dprimitivetype_to_pipe_prim(type);
   2461     info->count = prim_count_to_vertex_count(type, count);
   2462     info->start_instance = 0;
   2463     info->instance_count = 1;
   2464     if (dev->context.stream_instancedata_mask & dev->context.stream_usage_mask)
   2465         info->instance_count = MAX2(dev->context.stream_freq[0] & 0x7FFFFF, 1);
   2466     info->primitive_restart = FALSE;
   2467     info->has_user_indices = FALSE;
   2468     info->restart_index = 0;
   2469     info->count_from_stream_output = NULL;
   2470     info->indirect = NULL;
   2471 }
   2472 
   2473 CSMT_ITEM_NO_WAIT(nine_context_draw_primitive,
   2474                   ARG_VAL(D3DPRIMITIVETYPE, PrimitiveType),
   2475                   ARG_VAL(UINT, StartVertex),
   2476                   ARG_VAL(UINT, PrimitiveCount))
   2477 {
   2478     struct nine_context *context = &device->context;
   2479     struct pipe_draw_info info;
   2480 
   2481     nine_update_state(device);
   2482 
   2483     init_draw_info(&info, device, PrimitiveType, PrimitiveCount);
   2484     info.index_size = 0;
   2485     info.start = StartVertex;
   2486     info.index_bias = 0;
   2487     info.min_index = info.start;
   2488     info.max_index = info.count - 1;
   2489     info.index.resource = NULL;
   2490 
   2491     context->pipe->draw_vbo(context->pipe, &info);
   2492 }
   2493 
   2494 CSMT_ITEM_NO_WAIT(nine_context_draw_indexed_primitive,
   2495                   ARG_VAL(D3DPRIMITIVETYPE, PrimitiveType),
   2496                   ARG_VAL(INT, BaseVertexIndex),
   2497                   ARG_VAL(UINT, MinVertexIndex),
   2498                   ARG_VAL(UINT, NumVertices),
   2499                   ARG_VAL(UINT, StartIndex),
   2500                   ARG_VAL(UINT, PrimitiveCount))
   2501 {
   2502     struct nine_context *context = &device->context;
   2503     struct pipe_draw_info info;
   2504 
   2505     nine_update_state(device);
   2506 
   2507     init_draw_info(&info, device, PrimitiveType, PrimitiveCount);
   2508     info.index_size = context->index_size;
   2509     info.start = context->index_offset / context->index_size + StartIndex;
   2510     info.index_bias = BaseVertexIndex;
   2511     /* These don't include index bias: */
   2512     info.min_index = MinVertexIndex;
   2513     info.max_index = MinVertexIndex + NumVertices - 1;
   2514     info.index.resource = context->idxbuf;
   2515 
   2516     context->pipe->draw_vbo(context->pipe, &info);
   2517 }
   2518 
   2519 CSMT_ITEM_NO_WAIT(nine_context_draw_primitive_from_vtxbuf,
   2520                   ARG_VAL(D3DPRIMITIVETYPE, PrimitiveType),
   2521                   ARG_VAL(UINT, PrimitiveCount),
   2522                   ARG_BIND_VBUF(struct pipe_vertex_buffer, vtxbuf))
   2523 {
   2524     struct nine_context *context = &device->context;
   2525     struct pipe_draw_info info;
   2526 
   2527     nine_update_state(device);
   2528 
   2529     init_draw_info(&info, device, PrimitiveType, PrimitiveCount);
   2530     info.index_size = 0;
   2531     info.start = 0;
   2532     info.index_bias = 0;
   2533     info.min_index = 0;
   2534     info.max_index = info.count - 1;
   2535     info.index.resource = NULL;
   2536 
   2537     context->pipe->set_vertex_buffers(context->pipe, 0, 1, vtxbuf);
   2538 
   2539     context->pipe->draw_vbo(context->pipe, &info);
   2540 }
   2541 
   2542 CSMT_ITEM_NO_WAIT(nine_context_draw_indexed_primitive_from_vtxbuf_idxbuf,
   2543                   ARG_VAL(D3DPRIMITIVETYPE, PrimitiveType),
   2544                   ARG_VAL(UINT, MinVertexIndex),
   2545                   ARG_VAL(UINT, NumVertices),
   2546                   ARG_VAL(UINT, PrimitiveCount),
   2547                   ARG_BIND_VBUF(struct pipe_vertex_buffer, vbuf),
   2548                   ARG_BIND_RES(struct pipe_resource, ibuf),
   2549                   ARG_VAL(void *, user_ibuf),
   2550                   ARG_VAL(UINT, index_offset),
   2551                   ARG_VAL(UINT, index_size))
   2552 {
   2553     struct nine_context *context = &device->context;
   2554     struct pipe_draw_info info;
   2555 
   2556     nine_update_state(device);
   2557 
   2558     init_draw_info(&info, device, PrimitiveType, PrimitiveCount);
   2559     info.index_size = index_size;
   2560     info.start = index_offset / info.index_size;
   2561     info.index_bias = 0;
   2562     info.min_index = MinVertexIndex;
   2563     info.max_index = MinVertexIndex + NumVertices - 1;
   2564     info.has_user_indices = ibuf == NULL;
   2565     if (ibuf)
   2566         info.index.resource = ibuf;
   2567     else
   2568         info.index.user = user_ibuf;
   2569 
   2570     context->pipe->set_vertex_buffers(context->pipe, 0, 1, vbuf);
   2571 
   2572     context->pipe->draw_vbo(context->pipe, &info);
   2573 }
   2574 
   2575 CSMT_ITEM_NO_WAIT(nine_context_resource_copy_region,
   2576                   ARG_BIND_REF(struct NineUnknown, dst),
   2577                   ARG_BIND_REF(struct NineUnknown, src),
   2578                   ARG_BIND_RES(struct pipe_resource, dst_res),
   2579                   ARG_VAL(unsigned, dst_level),
   2580                   ARG_COPY_REF(struct pipe_box, dst_box),
   2581                   ARG_BIND_RES(struct pipe_resource, src_res),
   2582                   ARG_VAL(unsigned, src_level),
   2583                   ARG_COPY_REF(struct pipe_box, src_box))
   2584 {
   2585     struct nine_context *context = &device->context;
   2586 
   2587     (void) dst;
   2588     (void) src;
   2589 
   2590     context->pipe->resource_copy_region(context->pipe,
   2591             dst_res, dst_level,
   2592             dst_box->x, dst_box->y, dst_box->z,
   2593             src_res, src_level,
   2594             src_box);
   2595 }
   2596 
   2597 CSMT_ITEM_NO_WAIT(nine_context_blit,
   2598                   ARG_BIND_REF(struct NineUnknown, dst),
   2599                   ARG_BIND_REF(struct NineUnknown, src),
   2600                   ARG_BIND_BLIT(struct pipe_blit_info, blit))
   2601 {
   2602     struct nine_context *context = &device->context;
   2603 
   2604     (void) dst;
   2605     (void) src;
   2606 
   2607     context->pipe->blit(context->pipe, blit);
   2608 }
   2609 
   2610 CSMT_ITEM_NO_WAIT(nine_context_clear_render_target,
   2611                   ARG_BIND_REF(struct NineSurface9, surface),
   2612                   ARG_VAL(D3DCOLOR, color),
   2613                   ARG_VAL(UINT, x),
   2614                   ARG_VAL(UINT, y),
   2615                   ARG_VAL(UINT, width),
   2616                   ARG_VAL(UINT, height))
   2617 {
   2618     struct nine_context *context = &device->context;
   2619     struct pipe_surface *surf;
   2620     union pipe_color_union rgba;
   2621 
   2622     d3dcolor_to_pipe_color_union(&rgba, color);
   2623     surf = NineSurface9_GetSurface(surface, 0);
   2624     context->pipe->clear_render_target(context->pipe, surf, &rgba, x, y, width, height, false);
   2625 }
   2626 
   2627 CSMT_ITEM_NO_WAIT(nine_context_gen_mipmap,
   2628                   ARG_BIND_REF(struct NineUnknown, dst),
   2629                   ARG_BIND_RES(struct pipe_resource, res),
   2630                   ARG_VAL(UINT, base_level),
   2631                   ARG_VAL(UINT, last_level),
   2632                   ARG_VAL(UINT, first_layer),
   2633                   ARG_VAL(UINT, last_layer),
   2634                   ARG_VAL(UINT, filter))
   2635 {
   2636     struct nine_context *context = &device->context;
   2637 
   2638     /* We just bind dst for the bind count */
   2639     (void)dst;
   2640 
   2641     util_gen_mipmap(context->pipe, res, res->format, base_level,
   2642                     last_level, first_layer, last_layer, filter);
   2643 }
   2644 
   2645 CSMT_ITEM_NO_WAIT_WITH_COUNTER(nine_context_range_upload,
   2646                                ARG_BIND_RES(struct pipe_resource, res),
   2647                                ARG_VAL(unsigned, offset),
   2648                                ARG_VAL(unsigned, size),
   2649                                ARG_VAL(const void *, data))
   2650 {
   2651     struct nine_context *context = &device->context;
   2652 
   2653     context->pipe->buffer_subdata(context->pipe, res, 0, offset, size, data);
   2654 }
   2655 
   2656 CSMT_ITEM_NO_WAIT_WITH_COUNTER(nine_context_box_upload,
   2657                                ARG_BIND_REF(struct NineUnknown, dst),
   2658                                ARG_BIND_RES(struct pipe_resource, res),
   2659                                ARG_VAL(unsigned, level),
   2660                                ARG_COPY_REF(struct pipe_box, dst_box),
   2661                                ARG_VAL(enum pipe_format, src_format),
   2662                                ARG_VAL(const void *, src),
   2663                                ARG_VAL(unsigned, src_stride),
   2664                                ARG_VAL(unsigned, src_layer_stride),
   2665                                ARG_COPY_REF(struct pipe_box, src_box))
   2666 {
   2667     struct nine_context *context = &device->context;
   2668     struct pipe_context *pipe = context->pipe;
   2669     struct pipe_transfer *transfer = NULL;
   2670     uint8_t *map;
   2671 
   2672     /* We just bind dst for the bind count */
   2673     (void)dst;
   2674 
   2675     map = pipe->transfer_map(pipe,
   2676                              res,
   2677                              level,
   2678                              PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE,
   2679                              dst_box, &transfer);
   2680     if (!map)
   2681         return;
   2682 
   2683     /* Note: if formats are the sames, it will revert
   2684      * to normal memcpy */
   2685     (void) util_format_translate_3d(res->format,
   2686                                     map, transfer->stride,
   2687                                     transfer->layer_stride,
   2688                                     0, 0, 0,
   2689                                     src_format,
   2690                                     src, src_stride,
   2691                                     src_layer_stride,
   2692                                     src_box->x, src_box->y, src_box->z,
   2693                                     dst_box->width, dst_box->height,
   2694                                     dst_box->depth);
   2695 
   2696     pipe_transfer_unmap(pipe, transfer);
   2697 }
   2698 
   2699 struct pipe_query *
   2700 nine_context_create_query(struct NineDevice9 *device, unsigned query_type)
   2701 {
   2702     struct pipe_context *pipe;
   2703     struct pipe_query *res;
   2704 
   2705     pipe = nine_context_get_pipe_acquire(device);
   2706     res = pipe->create_query(pipe, query_type, 0);
   2707     nine_context_get_pipe_release(device);
   2708     return res;
   2709 }
   2710 
   2711 CSMT_ITEM_DO_WAIT(nine_context_destroy_query,
   2712                   ARG_REF(struct pipe_query, query))
   2713 {
   2714     struct nine_context *context = &device->context;
   2715 
   2716     context->pipe->destroy_query(context->pipe, query);
   2717 }
   2718 
   2719 CSMT_ITEM_NO_WAIT_WITH_COUNTER(nine_context_begin_query,
   2720                                ARG_REF(struct pipe_query, query))
   2721 {
   2722     struct nine_context *context = &device->context;
   2723 
   2724     (void) context->pipe->begin_query(context->pipe, query);
   2725 }
   2726 
   2727 CSMT_ITEM_NO_WAIT_WITH_COUNTER(nine_context_end_query,
   2728                                ARG_REF(struct pipe_query, query))
   2729 {
   2730     struct nine_context *context = &device->context;
   2731 
   2732     (void) context->pipe->end_query(context->pipe, query);
   2733 }
   2734 
   2735 boolean
   2736 nine_context_get_query_result(struct NineDevice9 *device, struct pipe_query *query,
   2737                               unsigned *counter, boolean flush, boolean wait,
   2738                               union pipe_query_result *result)
   2739 {
   2740     struct pipe_context *pipe;
   2741     boolean ret;
   2742 
   2743     if (wait)
   2744         nine_csmt_process(device);
   2745     else if (p_atomic_read(counter) > 0) {
   2746         if (flush && device->csmt_active)
   2747             nine_queue_flush(device->csmt_ctx->pool);
   2748         DBG("Pending begin/end. Returning\n");
   2749         return false;
   2750     }
   2751 
   2752     pipe = nine_context_get_pipe_acquire(device);
   2753     ret = pipe->get_query_result(pipe, query, wait, result);
   2754     nine_context_get_pipe_release(device);
   2755 
   2756     DBG("Query result %s\n", ret ? "found" : "not yet available");
   2757     return ret;
   2758 }
   2759 
   2760 /* State defaults */
   2761 
   2762 static const DWORD nine_render_state_defaults[NINED3DRS_LAST + 1] =
   2763 {
   2764  /* [D3DRS_ZENABLE] = D3DZB_TRUE; wine: auto_depth_stencil */
   2765     [D3DRS_ZENABLE] = D3DZB_FALSE,
   2766     [D3DRS_FILLMODE] = D3DFILL_SOLID,
   2767     [D3DRS_SHADEMODE] = D3DSHADE_GOURAUD,
   2768 /*  [D3DRS_LINEPATTERN] = 0x00000000, */
   2769     [D3DRS_ZWRITEENABLE] = TRUE,
   2770     [D3DRS_ALPHATESTENABLE] = FALSE,
   2771     [D3DRS_LASTPIXEL] = TRUE,
   2772     [D3DRS_SRCBLEND] = D3DBLEND_ONE,
   2773     [D3DRS_DESTBLEND] = D3DBLEND_ZERO,
   2774     [D3DRS_CULLMODE] = D3DCULL_CCW,
   2775     [D3DRS_ZFUNC] = D3DCMP_LESSEQUAL,
   2776     [D3DRS_ALPHAFUNC] = D3DCMP_ALWAYS,
   2777     [D3DRS_ALPHAREF] = 0,
   2778     [D3DRS_DITHERENABLE] = FALSE,
   2779     [D3DRS_ALPHABLENDENABLE] = FALSE,
   2780     [D3DRS_FOGENABLE] = FALSE,
   2781     [D3DRS_SPECULARENABLE] = FALSE,
   2782 /*  [D3DRS_ZVISIBLE] = 0, */
   2783     [D3DRS_FOGCOLOR] = 0,
   2784     [D3DRS_FOGTABLEMODE] = D3DFOG_NONE,
   2785     [D3DRS_FOGSTART] = 0x00000000,
   2786     [D3DRS_FOGEND] = 0x3F800000,
   2787     [D3DRS_FOGDENSITY] = 0x3F800000,
   2788 /*  [D3DRS_EDGEANTIALIAS] = FALSE, */
   2789     [D3DRS_RANGEFOGENABLE] = FALSE,
   2790     [D3DRS_STENCILENABLE] = FALSE,
   2791     [D3DRS_STENCILFAIL] = D3DSTENCILOP_KEEP,
   2792     [D3DRS_STENCILZFAIL] = D3DSTENCILOP_KEEP,
   2793     [D3DRS_STENCILPASS] = D3DSTENCILOP_KEEP,
   2794     [D3DRS_STENCILREF] = 0,
   2795     [D3DRS_STENCILMASK] = 0xFFFFFFFF,
   2796     [D3DRS_STENCILFUNC] = D3DCMP_ALWAYS,
   2797     [D3DRS_STENCILWRITEMASK] = 0xFFFFFFFF,
   2798     [D3DRS_TEXTUREFACTOR] = 0xFFFFFFFF,
   2799     [D3DRS_WRAP0] = 0,
   2800     [D3DRS_WRAP1] = 0,
   2801     [D3DRS_WRAP2] = 0,
   2802     [D3DRS_WRAP3] = 0,
   2803     [D3DRS_WRAP4] = 0,
   2804     [D3DRS_WRAP5] = 0,
   2805     [D3DRS_WRAP6] = 0,
   2806     [D3DRS_WRAP7] = 0,
   2807     [D3DRS_CLIPPING] = TRUE,
   2808     [D3DRS_LIGHTING] = TRUE,
   2809     [D3DRS_AMBIENT] = 0,
   2810     [D3DRS_FOGVERTEXMODE] = D3DFOG_NONE,
   2811     [D3DRS_COLORVERTEX] = TRUE,
   2812     [D3DRS_LOCALVIEWER] = TRUE,
   2813     [D3DRS_NORMALIZENORMALS] = FALSE,
   2814     [D3DRS_DIFFUSEMATERIALSOURCE] = D3DMCS_COLOR1,
   2815     [D3DRS_SPECULARMATERIALSOURCE] = D3DMCS_COLOR2,
   2816     [D3DRS_AMBIENTMATERIALSOURCE] = D3DMCS_MATERIAL,
   2817     [D3DRS_EMISSIVEMATERIALSOURCE] = D3DMCS_MATERIAL,
   2818     [D3DRS_VERTEXBLEND] = D3DVBF_DISABLE,
   2819     [D3DRS_CLIPPLANEENABLE] = 0,
   2820 /*  [D3DRS_SOFTWAREVERTEXPROCESSING] = FALSE, */
   2821     [D3DRS_POINTSIZE] = 0x3F800000,
   2822     [D3DRS_POINTSIZE_MIN] = 0x3F800000,
   2823     [D3DRS_POINTSPRITEENABLE] = FALSE,
   2824     [D3DRS_POINTSCALEENABLE] = FALSE,
   2825     [D3DRS_POINTSCALE_A] = 0x3F800000,
   2826     [D3DRS_POINTSCALE_B] = 0x00000000,
   2827     [D3DRS_POINTSCALE_C] = 0x00000000,
   2828     [D3DRS_MULTISAMPLEANTIALIAS] = TRUE,
   2829     [D3DRS_MULTISAMPLEMASK] = 0xFFFFFFFF,
   2830     [D3DRS_PATCHEDGESTYLE] = D3DPATCHEDGE_DISCRETE,
   2831 /*  [D3DRS_PATCHSEGMENTS] = 0x3F800000, */
   2832     [D3DRS_DEBUGMONITORTOKEN] = 0xDEADCAFE,
   2833     [D3DRS_POINTSIZE_MAX] = 0x3F800000, /* depends on cap */
   2834     [D3DRS_INDEXEDVERTEXBLENDENABLE] = FALSE,
   2835     [D3DRS_COLORWRITEENABLE] = 0x0000000f,
   2836     [D3DRS_TWEENFACTOR] = 0x00000000,
   2837     [D3DRS_BLENDOP] = D3DBLENDOP_ADD,
   2838     [D3DRS_POSITIONDEGREE] = D3DDEGREE_CUBIC,
   2839     [D3DRS_NORMALDEGREE] = D3DDEGREE_LINEAR,
   2840     [D3DRS_SCISSORTESTENABLE] = FALSE,
   2841     [D3DRS_SLOPESCALEDEPTHBIAS] = 0,
   2842     [D3DRS_MINTESSELLATIONLEVEL] = 0x3F800000,
   2843     [D3DRS_MAXTESSELLATIONLEVEL] = 0x3F800000,
   2844     [D3DRS_ANTIALIASEDLINEENABLE] = FALSE,
   2845     [D3DRS_ADAPTIVETESS_X] = 0x00000000,
   2846     [D3DRS_ADAPTIVETESS_Y] = 0x00000000,
   2847     [D3DRS_ADAPTIVETESS_Z] = 0x3F800000,
   2848     [D3DRS_ADAPTIVETESS_W] = 0x00000000,
   2849     [D3DRS_ENABLEADAPTIVETESSELLATION] = FALSE,
   2850     [D3DRS_TWOSIDEDSTENCILMODE] = FALSE,
   2851     [D3DRS_CCW_STENCILFAIL] = D3DSTENCILOP_KEEP,
   2852     [D3DRS_CCW_STENCILZFAIL] = D3DSTENCILOP_KEEP,
   2853     [D3DRS_CCW_STENCILPASS] = D3DSTENCILOP_KEEP,
   2854     [D3DRS_CCW_STENCILFUNC] = D3DCMP_ALWAYS,
   2855     [D3DRS_COLORWRITEENABLE1] = 0x0000000F,
   2856     [D3DRS_COLORWRITEENABLE2] = 0x0000000F,
   2857     [D3DRS_COLORWRITEENABLE3] = 0x0000000F,
   2858     [D3DRS_BLENDFACTOR] = 0xFFFFFFFF,
   2859     [D3DRS_SRGBWRITEENABLE] = 0,
   2860     [D3DRS_DEPTHBIAS] = 0,
   2861     [D3DRS_WRAP8] = 0,
   2862     [D3DRS_WRAP9] = 0,
   2863     [D3DRS_WRAP10] = 0,
   2864     [D3DRS_WRAP11] = 0,
   2865     [D3DRS_WRAP12] = 0,
   2866     [D3DRS_WRAP13] = 0,
   2867     [D3DRS_WRAP14] = 0,
   2868     [D3DRS_WRAP15] = 0,
   2869     [D3DRS_SEPARATEALPHABLENDENABLE] = FALSE,
   2870     [D3DRS_SRCBLENDALPHA] = D3DBLEND_ONE,
   2871     [D3DRS_DESTBLENDALPHA] = D3DBLEND_ZERO,
   2872     [D3DRS_BLENDOPALPHA] = D3DBLENDOP_ADD,
   2873     [NINED3DRS_VSPOINTSIZE] = FALSE,
   2874     [NINED3DRS_RTMASK] = 0xf,
   2875     [NINED3DRS_ALPHACOVERAGE] = FALSE,
   2876     [NINED3DRS_MULTISAMPLE] = FALSE
   2877 };
   2878 static const DWORD nine_tex_stage_state_defaults[NINED3DTSS_LAST + 1] =
   2879 {
   2880     [D3DTSS_COLOROP] = D3DTOP_DISABLE,
   2881     [D3DTSS_ALPHAOP] = D3DTOP_DISABLE,
   2882     [D3DTSS_COLORARG1] = D3DTA_TEXTURE,
   2883     [D3DTSS_COLORARG2] = D3DTA_CURRENT,
   2884     [D3DTSS_COLORARG0] = D3DTA_CURRENT,
   2885     [D3DTSS_ALPHAARG1] = D3DTA_TEXTURE,
   2886     [D3DTSS_ALPHAARG2] = D3DTA_CURRENT,
   2887     [D3DTSS_ALPHAARG0] = D3DTA_CURRENT,
   2888     [D3DTSS_RESULTARG] = D3DTA_CURRENT,
   2889     [D3DTSS_BUMPENVMAT00] = 0,
   2890     [D3DTSS_BUMPENVMAT01] = 0,
   2891     [D3DTSS_BUMPENVMAT10] = 0,
   2892     [D3DTSS_BUMPENVMAT11] = 0,
   2893     [D3DTSS_BUMPENVLSCALE] = 0,
   2894     [D3DTSS_BUMPENVLOFFSET] = 0,
   2895     [D3DTSS_TEXCOORDINDEX] = 0,
   2896     [D3DTSS_TEXTURETRANSFORMFLAGS] = D3DTTFF_DISABLE,
   2897 };
   2898 static const DWORD nine_samp_state_defaults[NINED3DSAMP_LAST + 1] =
   2899 {
   2900     [D3DSAMP_ADDRESSU] = D3DTADDRESS_WRAP,
   2901     [D3DSAMP_ADDRESSV] = D3DTADDRESS_WRAP,
   2902     [D3DSAMP_ADDRESSW] = D3DTADDRESS_WRAP,
   2903     [D3DSAMP_BORDERCOLOR] = 0,
   2904     [D3DSAMP_MAGFILTER] = D3DTEXF_POINT,
   2905     [D3DSAMP_MINFILTER] = D3DTEXF_POINT,
   2906     [D3DSAMP_MIPFILTER] = D3DTEXF_NONE,
   2907     [D3DSAMP_MIPMAPLODBIAS] = 0,
   2908     [D3DSAMP_MAXMIPLEVEL] = 0,
   2909     [D3DSAMP_MAXANISOTROPY] = 1,
   2910     [D3DSAMP_SRGBTEXTURE] = 0,
   2911     [D3DSAMP_ELEMENTINDEX] = 0,
   2912     [D3DSAMP_DMAPOFFSET] = 0,
   2913     [NINED3DSAMP_MINLOD] = 0,
   2914     [NINED3DSAMP_SHADOW] = 0,
   2915     [NINED3DSAMP_CUBETEX] = 0
   2916 };
   2917 
   2918 /* Note: The following 4 functions assume there is no
   2919  * pending commands */
   2920 
   2921 void nine_state_restore_non_cso(struct NineDevice9 *device)
   2922 {
   2923     struct nine_context *context = &device->context;
   2924 
   2925     context->changed.group = NINE_STATE_ALL;
   2926     context->changed.vtxbuf = (1ULL << device->caps.MaxStreams) - 1;
   2927     context->changed.ucp = TRUE;
   2928     context->commit |= NINE_STATE_COMMIT_CONST_VS | NINE_STATE_COMMIT_CONST_PS;
   2929 }
   2930 
   2931 void
   2932 nine_state_set_defaults(struct NineDevice9 *device, const D3DCAPS9 *caps,
   2933                         boolean is_reset)
   2934 {
   2935     struct nine_state *state = &device->state;
   2936     struct nine_context *context = &device->context;
   2937     unsigned s;
   2938 
   2939     /* Initialize defaults.
   2940      */
   2941     memcpy(context->rs, nine_render_state_defaults, sizeof(context->rs));
   2942 
   2943     for (s = 0; s < ARRAY_SIZE(state->ff.tex_stage); ++s) {
   2944         memcpy(&state->ff.tex_stage[s], nine_tex_stage_state_defaults,
   2945                sizeof(state->ff.tex_stage[s]));
   2946         state->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] = s;
   2947     }
   2948     state->ff.tex_stage[0][D3DTSS_COLOROP] = D3DTOP_MODULATE;
   2949     state->ff.tex_stage[0][D3DTSS_ALPHAOP] = D3DTOP_SELECTARG1;
   2950 
   2951     for (s = 0; s < ARRAY_SIZE(state->ff.tex_stage); ++s)
   2952         memcpy(&context->ff.tex_stage[s], state->ff.tex_stage[s],
   2953                sizeof(state->ff.tex_stage[s]));
   2954 
   2955     memset(&context->bumpmap_vars, 0, sizeof(context->bumpmap_vars));
   2956 
   2957     for (s = 0; s < NINE_MAX_SAMPLERS; ++s) {
   2958         memcpy(&context->samp[s], nine_samp_state_defaults,
   2959                sizeof(context->samp[s]));
   2960         memcpy(&state->samp_advertised[s], nine_samp_state_defaults,
   2961                sizeof(state->samp_advertised[s]));
   2962     }
   2963 
   2964     memset(state->vs_const_f, 0, VS_CONST_F_SIZE(device));
   2965     memset(context->vs_const_f, 0, device->vs_const_size);
   2966     if (context->vs_const_f_swvp)
   2967         memset(context->vs_const_f_swvp, 0, NINE_MAX_CONST_F_SWVP * sizeof(float[4]));
   2968     memset(state->vs_const_i, 0, VS_CONST_I_SIZE(device));
   2969     memset(context->vs_const_i, 0, VS_CONST_I_SIZE(device));
   2970     memset(state->vs_const_b, 0, VS_CONST_B_SIZE(device));
   2971     memset(context->vs_const_b, 0, VS_CONST_B_SIZE(device));
   2972     memset(state->ps_const_f, 0, device->ps_const_size);
   2973     memset(context->ps_const_f, 0, device->ps_const_size);
   2974     memset(state->ps_const_i, 0, sizeof(state->ps_const_i));
   2975     memset(context->ps_const_i, 0, sizeof(context->ps_const_i));
   2976     memset(state->ps_const_b, 0, sizeof(state->ps_const_b));
   2977     memset(context->ps_const_b, 0, sizeof(context->ps_const_b));
   2978 
   2979     /* Cap dependent initial state:
   2980      */
   2981     context->rs[D3DRS_POINTSIZE_MAX] = fui(caps->MaxPointSize);
   2982 
   2983     memcpy(state->rs_advertised, context->rs, sizeof(context->rs));
   2984 
   2985     /* Set changed flags to initialize driver.
   2986      */
   2987     context->changed.group = NINE_STATE_ALL;
   2988     context->changed.vtxbuf = (1ULL << device->caps.MaxStreams) - 1;
   2989     context->changed.ucp = TRUE;
   2990 
   2991     context->ff.changed.transform[0] = ~0;
   2992     context->ff.changed.transform[D3DTS_WORLD / 32] |= 1 << (D3DTS_WORLD % 32);
   2993 
   2994     if (!is_reset) {
   2995         state->viewport.MinZ = context->viewport.MinZ = 0.0f;
   2996         state->viewport.MaxZ = context->viewport.MaxZ = 1.0f;
   2997     }
   2998 
   2999     for (s = 0; s < NINE_MAX_SAMPLERS; ++s)
   3000         context->changed.sampler[s] = ~0;
   3001 
   3002     if (!is_reset) {
   3003         context->dummy_vbo_bound_at = -1;
   3004         context->vbo_bound_done = FALSE;
   3005     }
   3006 }
   3007 
   3008 void
   3009 nine_state_clear(struct nine_state *state, const boolean device)
   3010 {
   3011     unsigned i;
   3012 
   3013     for (i = 0; i < ARRAY_SIZE(state->rt); ++i)
   3014        nine_bind(&state->rt[i], NULL);
   3015     nine_bind(&state->ds, NULL);
   3016     nine_bind(&state->vs, NULL);
   3017     nine_bind(&state->ps, NULL);
   3018     nine_bind(&state->vdecl, NULL);
   3019     for (i = 0; i < PIPE_MAX_ATTRIBS; ++i)
   3020         nine_bind(&state->stream[i], NULL);
   3021 
   3022     nine_bind(&state->idxbuf, NULL);
   3023     for (i = 0; i < NINE_MAX_SAMPLERS; ++i) {
   3024         if (device &&
   3025             state->texture[i] &&
   3026           --state->texture[i]->bind_count == 0)
   3027             list_delinit(&state->texture[i]->list);
   3028         nine_bind(&state->texture[i], NULL);
   3029     }
   3030 }
   3031 
   3032 void
   3033 nine_context_clear(struct NineDevice9 *device)
   3034 {
   3035     struct nine_context *context = &device->context;
   3036     struct pipe_context *pipe = context->pipe;
   3037     struct cso_context *cso = context->cso;
   3038     unsigned i;
   3039 
   3040     /* Early device ctor failure. Nothing to do */
   3041     if (!pipe || !cso)
   3042         return;
   3043 
   3044     pipe->bind_vs_state(pipe, NULL);
   3045     pipe->bind_fs_state(pipe, NULL);
   3046 
   3047     /* Don't unbind constant buffers, they're device-private and
   3048      * do not change on Reset.
   3049      */
   3050 
   3051     cso_set_samplers(cso, PIPE_SHADER_VERTEX, 0, NULL);
   3052     cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, 0, NULL);
   3053 
   3054     cso_set_sampler_views(cso, PIPE_SHADER_VERTEX, 0, NULL);
   3055     cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, 0, NULL);
   3056 
   3057     pipe->set_vertex_buffers(pipe, 0, device->caps.MaxStreams, NULL);
   3058 
   3059     for (i = 0; i < ARRAY_SIZE(context->rt); ++i)
   3060        nine_bind(&context->rt[i], NULL);
   3061     nine_bind(&context->ds, NULL);
   3062     nine_bind(&context->vs, NULL);
   3063     nine_bind(&context->ps, NULL);
   3064     nine_bind(&context->vdecl, NULL);
   3065     for (i = 0; i < PIPE_MAX_ATTRIBS; ++i)
   3066         pipe_vertex_buffer_unreference(&context->vtxbuf[i]);
   3067     pipe_resource_reference(&context->idxbuf, NULL);
   3068 
   3069     for (i = 0; i < NINE_MAX_SAMPLERS; ++i) {
   3070         context->texture[i].enabled = FALSE;
   3071         pipe_resource_reference(&context->texture[i].resource,
   3072                                 NULL);
   3073         pipe_sampler_view_reference(&context->texture[i].view[0],
   3074                                     NULL);
   3075         pipe_sampler_view_reference(&context->texture[i].view[1],
   3076                                     NULL);
   3077     }
   3078 }
   3079 
   3080 void
   3081 nine_state_init_sw(struct NineDevice9 *device)
   3082 {
   3083     struct pipe_context *pipe_sw = device->pipe_sw;
   3084     struct pipe_rasterizer_state rast;
   3085     struct pipe_blend_state blend;
   3086     struct pipe_depth_stencil_alpha_state dsa;
   3087     struct pipe_framebuffer_state fb;
   3088 
   3089     /* Only used with Streamout */
   3090     memset(&rast, 0, sizeof(rast));
   3091     rast.rasterizer_discard = true;
   3092     rast.point_quad_rasterization = 1; /* to make llvmpipe happy */
   3093     cso_set_rasterizer(device->cso_sw, &rast);
   3094 
   3095     /* dummy settings */
   3096     memset(&blend, 0, sizeof(blend));
   3097     memset(&dsa, 0, sizeof(dsa));
   3098     memset(&fb, 0, sizeof(fb));
   3099     cso_set_blend(device->cso_sw, &blend);
   3100     cso_set_depth_stencil_alpha(device->cso_sw, &dsa);
   3101     cso_set_framebuffer(device->cso_sw, &fb);
   3102     cso_set_viewport_dims(device->cso_sw, 1.0, 1.0, false);
   3103     cso_set_fragment_shader_handle(device->cso_sw, util_make_empty_fragment_shader(pipe_sw));
   3104 }
   3105 
   3106 /* There is duplication with update_vertex_elements.
   3107  * TODO: Share the code */
   3108 
   3109 static void
   3110 update_vertex_elements_sw(struct NineDevice9 *device)
   3111 {
   3112     struct nine_state *state = &device->state;
   3113     const struct NineVertexDeclaration9 *vdecl = device->state.vdecl;
   3114     const struct NineVertexShader9 *vs;
   3115     unsigned n, b, i;
   3116     int index;
   3117     char vdecl_index_map[16]; /* vs->num_inputs <= 16 */
   3118     char used_streams[device->caps.MaxStreams];
   3119     int dummy_vbo_stream = -1;
   3120     BOOL need_dummy_vbo = FALSE;
   3121     struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS];
   3122     bool programmable_vs = state->vs && !(state->vdecl && state->vdecl->position_t);
   3123 
   3124     memset(vdecl_index_map, -1, 16);
   3125     memset(used_streams, 0, device->caps.MaxStreams);
   3126     vs = programmable_vs ? device->state.vs : device->ff.vs;
   3127 
   3128     if (vdecl) {
   3129         for (n = 0; n < vs->num_inputs; ++n) {
   3130             DBG("looking up input %u (usage %u) from vdecl(%p)\n",
   3131                 n, vs->input_map[n].ndecl, vdecl);
   3132 
   3133             for (i = 0; i < vdecl->nelems; i++) {
   3134                 if (vdecl->usage_map[i] == vs->input_map[n].ndecl) {
   3135                     vdecl_index_map[n] = i;
   3136                     used_streams[vdecl->elems[i].vertex_buffer_index] = 1;
   3137                     break;
   3138                 }
   3139             }
   3140             if (vdecl_index_map[n] < 0)
   3141                 need_dummy_vbo = TRUE;
   3142         }
   3143     } else {
   3144         /* No vertex declaration. Likely will never happen in practice,
   3145          * but we need not crash on this */
   3146         need_dummy_vbo = TRUE;
   3147     }
   3148 
   3149     if (need_dummy_vbo) {
   3150         for (i = 0; i < device->caps.MaxStreams; i++ ) {
   3151             if (!used_streams[i]) {
   3152                 dummy_vbo_stream = i;
   3153                 break;
   3154             }
   3155         }
   3156     }
   3157     /* TODO handle dummy_vbo */
   3158     assert (!need_dummy_vbo);
   3159 
   3160     for (n = 0; n < vs->num_inputs; ++n) {
   3161         index = vdecl_index_map[n];
   3162         if (index >= 0) {
   3163             ve[n] = vdecl->elems[index];
   3164             b = ve[n].vertex_buffer_index;
   3165             /* XXX wine just uses 1 here: */
   3166             if (state->stream_freq[b] & D3DSTREAMSOURCE_INSTANCEDATA)
   3167                 ve[n].instance_divisor = state->stream_freq[b] & 0x7FFFFF;
   3168         } else {
   3169             /* if the vertex declaration is incomplete compared to what the
   3170              * vertex shader needs, we bind a dummy vbo with 0 0 0 0.
   3171              * This is not precised by the spec, but is the behaviour
   3172              * tested on win */
   3173             ve[n].vertex_buffer_index = dummy_vbo_stream;
   3174             ve[n].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
   3175             ve[n].src_offset = 0;
   3176             ve[n].instance_divisor = 0;
   3177         }
   3178     }
   3179 
   3180     cso_set_vertex_elements(device->cso_sw, vs->num_inputs, ve);
   3181 }
   3182 
   3183 static void
   3184 update_vertex_buffers_sw(struct NineDevice9 *device, int start_vertice, int num_vertices)
   3185 {
   3186     struct pipe_context *pipe = nine_context_get_pipe_acquire(device);
   3187     struct pipe_context *pipe_sw = device->pipe_sw;
   3188     struct nine_state *state = &device->state;
   3189     struct nine_state_sw_internal *sw_internal = &device->state_sw_internal;
   3190     struct pipe_vertex_buffer vtxbuf;
   3191     uint32_t mask = 0xf;
   3192     unsigned i;
   3193 
   3194     DBG("mask=%x\n", mask);
   3195 
   3196     /* TODO: handle dummy_vbo_bound_at */
   3197 
   3198     for (i = 0; mask; mask >>= 1, ++i) {
   3199         if (mask & 1) {
   3200             if (state->stream[i]) {
   3201                 unsigned offset;
   3202                 struct pipe_resource *buf;
   3203                 struct pipe_box box;
   3204                 void *userbuf;
   3205 
   3206                 vtxbuf = state->vtxbuf[i];
   3207                 buf = NineVertexBuffer9_GetResource(state->stream[i], &offset);
   3208 
   3209                 DBG("Locking %p (offset %d, length %d)\n", buf,
   3210                     vtxbuf.buffer_offset, num_vertices * vtxbuf.stride);
   3211 
   3212                 u_box_1d(vtxbuf.buffer_offset + offset + start_vertice * vtxbuf.stride,
   3213                          num_vertices * vtxbuf.stride, &box);
   3214 
   3215                 userbuf = pipe->transfer_map(pipe, buf, 0, PIPE_TRANSFER_READ, &box,
   3216                                              &(sw_internal->transfers_so[i]));
   3217                 vtxbuf.is_user_buffer = true;
   3218                 vtxbuf.buffer.user = userbuf;
   3219 
   3220                 if (!device->driver_caps.user_sw_vbufs) {
   3221                     vtxbuf.buffer.resource = NULL;
   3222                     vtxbuf.is_user_buffer = false;
   3223                     u_upload_data(device->pipe_sw->stream_uploader,
   3224                                   0,
   3225                                   box.width,
   3226                                   16,
   3227                                   userbuf,
   3228                                   &(vtxbuf.buffer_offset),
   3229                                   &(vtxbuf.buffer.resource));
   3230                     u_upload_unmap(device->pipe_sw->stream_uploader);
   3231                 }
   3232                 pipe_sw->set_vertex_buffers(pipe_sw, i, 1, &vtxbuf);
   3233                 pipe_vertex_buffer_unreference(&vtxbuf);
   3234             } else
   3235                 pipe_sw->set_vertex_buffers(pipe_sw, i, 1, NULL);
   3236         }
   3237     }
   3238     nine_context_get_pipe_release(device);
   3239 }
   3240 
   3241 static void
   3242 update_vs_constants_sw(struct NineDevice9 *device)
   3243 {
   3244     struct nine_state *state = &device->state;
   3245     struct pipe_context *pipe_sw = device->pipe_sw;
   3246 
   3247     DBG("updating\n");
   3248 
   3249     {
   3250         struct pipe_constant_buffer cb;
   3251         const void *buf;
   3252 
   3253         cb.buffer = NULL;
   3254         cb.buffer_offset = 0;
   3255         cb.buffer_size = 4096 * sizeof(float[4]);
   3256         cb.user_buffer = state->vs_const_f;
   3257 
   3258         if (state->vs->lconstf.ranges) {
   3259             const struct nine_lconstf *lconstf =  &device->state.vs->lconstf;
   3260             const struct nine_range *r = lconstf->ranges;
   3261             unsigned n = 0;
   3262             float *dst = device->state.vs_lconstf_temp;
   3263             float *src = (float *)cb.user_buffer;
   3264             memcpy(dst, src, 8192 * sizeof(float[4]));
   3265             while (r) {
   3266                 unsigned p = r->bgn;
   3267                 unsigned c = r->end - r->bgn;
   3268                 memcpy(&dst[p * 4], &lconstf->data[n * 4], c * 4 * sizeof(float));
   3269                 n += c;
   3270                 r = r->next;
   3271             }
   3272             cb.user_buffer = dst;
   3273         }
   3274 
   3275         buf = cb.user_buffer;
   3276 
   3277         pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 0, &cb);
   3278         if (cb.buffer)
   3279             pipe_resource_reference(&cb.buffer, NULL);
   3280 
   3281         cb.user_buffer = (char *)buf + 4096 * sizeof(float[4]);
   3282 
   3283         pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 1, &cb);
   3284         if (cb.buffer)
   3285             pipe_resource_reference(&cb.buffer, NULL);
   3286     }
   3287 
   3288     {
   3289         struct pipe_constant_buffer cb;
   3290 
   3291         cb.buffer = NULL;
   3292         cb.buffer_offset = 0;
   3293         cb.buffer_size = 2048 * sizeof(float[4]);
   3294         cb.user_buffer = state->vs_const_i;
   3295 
   3296         pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 2, &cb);
   3297         if (cb.buffer)
   3298             pipe_resource_reference(&cb.buffer, NULL);
   3299     }
   3300 
   3301     {
   3302         struct pipe_constant_buffer cb;
   3303 
   3304         cb.buffer = NULL;
   3305         cb.buffer_offset = 0;
   3306         cb.buffer_size = 512 * sizeof(float[4]);
   3307         cb.user_buffer = state->vs_const_b;
   3308 
   3309         pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 3, &cb);
   3310         if (cb.buffer)
   3311             pipe_resource_reference(&cb.buffer, NULL);
   3312     }
   3313 
   3314     {
   3315         struct pipe_constant_buffer cb;
   3316         const D3DVIEWPORT9 *vport = &device->state.viewport;
   3317         float viewport_data[8] = {(float)vport->Width * 0.5f,
   3318             (float)vport->Height * -0.5f, vport->MaxZ - vport->MinZ, 0.f,
   3319             (float)vport->Width * 0.5f + (float)vport->X,
   3320             (float)vport->Height * 0.5f + (float)vport->Y,
   3321             vport->MinZ, 0.f};
   3322 
   3323         cb.buffer = NULL;
   3324         cb.buffer_offset = 0;
   3325         cb.buffer_size = 2 * sizeof(float[4]);
   3326         cb.user_buffer = viewport_data;
   3327 
   3328         {
   3329             u_upload_data(device->pipe_sw->const_uploader,
   3330                           0,
   3331                           cb.buffer_size,
   3332                           16,
   3333                           cb.user_buffer,
   3334                           &(cb.buffer_offset),
   3335                           &(cb.buffer));
   3336             u_upload_unmap(device->pipe_sw->const_uploader);
   3337             cb.user_buffer = NULL;
   3338         }
   3339 
   3340         pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 4, &cb);
   3341         if (cb.buffer)
   3342             pipe_resource_reference(&cb.buffer, NULL);
   3343     }
   3344 
   3345 }
   3346 
   3347 void
   3348 nine_state_prepare_draw_sw(struct NineDevice9 *device, struct NineVertexDeclaration9 *vdecl_out,
   3349                            int start_vertice, int num_vertices, struct pipe_stream_output_info *so)
   3350 {
   3351     struct nine_state *state = &device->state;
   3352     bool programmable_vs = state->vs && !(state->vdecl && state->vdecl->position_t);
   3353     struct NineVertexShader9 *vs = programmable_vs ? device->state.vs : device->ff.vs;
   3354 
   3355     assert(programmable_vs);
   3356 
   3357     DBG("Preparing draw\n");
   3358     cso_set_vertex_shader_handle(device->cso_sw,
   3359                                  NineVertexShader9_GetVariantProcessVertices(vs, vdecl_out, so));
   3360     update_vertex_elements_sw(device);
   3361     update_vertex_buffers_sw(device, start_vertice, num_vertices);
   3362     update_vs_constants_sw(device);
   3363     DBG("Preparation succeeded\n");
   3364 }
   3365 
   3366 void
   3367 nine_state_after_draw_sw(struct NineDevice9 *device)
   3368 {
   3369     struct nine_state_sw_internal *sw_internal = &device->state_sw_internal;
   3370     struct pipe_context *pipe = nine_context_get_pipe_acquire(device);
   3371     struct pipe_context *pipe_sw = device->pipe_sw;
   3372     int i;
   3373 
   3374     for (i = 0; i < 4; i++) {
   3375         pipe_sw->set_vertex_buffers(pipe_sw, i, 1, NULL);
   3376         if (sw_internal->transfers_so[i])
   3377             pipe->transfer_unmap(pipe, sw_internal->transfers_so[i]);
   3378         sw_internal->transfers_so[i] = NULL;
   3379     }
   3380     nine_context_get_pipe_release(device);
   3381 }
   3382 
   3383 void
   3384 nine_state_destroy_sw(struct NineDevice9 *device)
   3385 {
   3386     (void) device;
   3387     /* Everything destroyed with cso */
   3388 }
   3389 
   3390 /*
   3391 static const DWORD nine_render_states_pixel[] =
   3392 {
   3393     D3DRS_ALPHABLENDENABLE,
   3394     D3DRS_ALPHAFUNC,
   3395     D3DRS_ALPHAREF,
   3396     D3DRS_ALPHATESTENABLE,
   3397     D3DRS_ANTIALIASEDLINEENABLE,
   3398     D3DRS_BLENDFACTOR,
   3399     D3DRS_BLENDOP,
   3400     D3DRS_BLENDOPALPHA,
   3401     D3DRS_CCW_STENCILFAIL,
   3402     D3DRS_CCW_STENCILPASS,
   3403     D3DRS_CCW_STENCILZFAIL,
   3404     D3DRS_COLORWRITEENABLE,
   3405     D3DRS_COLORWRITEENABLE1,
   3406     D3DRS_COLORWRITEENABLE2,
   3407     D3DRS_COLORWRITEENABLE3,
   3408     D3DRS_DEPTHBIAS,
   3409     D3DRS_DESTBLEND,
   3410     D3DRS_DESTBLENDALPHA,
   3411     D3DRS_DITHERENABLE,
   3412     D3DRS_FILLMODE,
   3413     D3DRS_FOGDENSITY,
   3414     D3DRS_FOGEND,
   3415     D3DRS_FOGSTART,
   3416     D3DRS_LASTPIXEL,
   3417     D3DRS_SCISSORTESTENABLE,
   3418     D3DRS_SEPARATEALPHABLENDENABLE,
   3419     D3DRS_SHADEMODE,
   3420     D3DRS_SLOPESCALEDEPTHBIAS,
   3421     D3DRS_SRCBLEND,
   3422     D3DRS_SRCBLENDALPHA,
   3423     D3DRS_SRGBWRITEENABLE,
   3424     D3DRS_STENCILENABLE,
   3425     D3DRS_STENCILFAIL,
   3426     D3DRS_STENCILFUNC,
   3427     D3DRS_STENCILMASK,
   3428     D3DRS_STENCILPASS,
   3429     D3DRS_STENCILREF,
   3430     D3DRS_STENCILWRITEMASK,
   3431     D3DRS_STENCILZFAIL,
   3432     D3DRS_TEXTUREFACTOR,
   3433     D3DRS_TWOSIDEDSTENCILMODE,
   3434     D3DRS_WRAP0,
   3435     D3DRS_WRAP1,
   3436     D3DRS_WRAP10,
   3437     D3DRS_WRAP11,
   3438     D3DRS_WRAP12,
   3439     D3DRS_WRAP13,
   3440     D3DRS_WRAP14,
   3441     D3DRS_WRAP15,
   3442     D3DRS_WRAP2,
   3443     D3DRS_WRAP3,
   3444     D3DRS_WRAP4,
   3445     D3DRS_WRAP5,
   3446     D3DRS_WRAP6,
   3447     D3DRS_WRAP7,
   3448     D3DRS_WRAP8,
   3449     D3DRS_WRAP9,
   3450     D3DRS_ZENABLE,
   3451     D3DRS_ZFUNC,
   3452     D3DRS_ZWRITEENABLE
   3453 };
   3454 */
   3455 const uint32_t nine_render_states_pixel[(NINED3DRS_LAST + 31) / 32] =
   3456 {
   3457     0x0f99c380, 0x1ff00070, 0x00000000, 0x00000000,
   3458     0x000000ff, 0xde01c900, 0x0003ffcf
   3459 };
   3460 
   3461 /*
   3462 static const DWORD nine_render_states_vertex[] =
   3463 {
   3464     D3DRS_ADAPTIVETESS_W,
   3465     D3DRS_ADAPTIVETESS_X,
   3466     D3DRS_ADAPTIVETESS_Y,
   3467     D3DRS_ADAPTIVETESS_Z,
   3468     D3DRS_AMBIENT,
   3469     D3DRS_AMBIENTMATERIALSOURCE,
   3470     D3DRS_CLIPPING,
   3471     D3DRS_CLIPPLANEENABLE,
   3472     D3DRS_COLORVERTEX,
   3473     D3DRS_CULLMODE,
   3474     D3DRS_DIFFUSEMATERIALSOURCE,
   3475     D3DRS_EMISSIVEMATERIALSOURCE,
   3476     D3DRS_ENABLEADAPTIVETESSELLATION,
   3477     D3DRS_FOGCOLOR,
   3478     D3DRS_FOGDENSITY,
   3479     D3DRS_FOGENABLE,
   3480     D3DRS_FOGEND,
   3481     D3DRS_FOGSTART,
   3482     D3DRS_FOGTABLEMODE,
   3483     D3DRS_FOGVERTEXMODE,
   3484     D3DRS_INDEXEDVERTEXBLENDENABLE,
   3485     D3DRS_LIGHTING,
   3486     D3DRS_LOCALVIEWER,
   3487     D3DRS_MAXTESSELLATIONLEVEL,
   3488     D3DRS_MINTESSELLATIONLEVEL,
   3489     D3DRS_MULTISAMPLEANTIALIAS,
   3490     D3DRS_MULTISAMPLEMASK,
   3491     D3DRS_NORMALDEGREE,
   3492     D3DRS_NORMALIZENORMALS,
   3493     D3DRS_PATCHEDGESTYLE,
   3494     D3DRS_POINTSCALE_A,
   3495     D3DRS_POINTSCALE_B,
   3496     D3DRS_POINTSCALE_C,
   3497     D3DRS_POINTSCALEENABLE,
   3498     D3DRS_POINTSIZE,
   3499     D3DRS_POINTSIZE_MAX,
   3500     D3DRS_POINTSIZE_MIN,
   3501     D3DRS_POINTSPRITEENABLE,
   3502     D3DRS_POSITIONDEGREE,
   3503     D3DRS_RANGEFOGENABLE,
   3504     D3DRS_SHADEMODE,
   3505     D3DRS_SPECULARENABLE,
   3506     D3DRS_SPECULARMATERIALSOURCE,
   3507     D3DRS_TWEENFACTOR,
   3508     D3DRS_VERTEXBLEND
   3509 };
   3510 */
   3511 const uint32_t nine_render_states_vertex[(NINED3DRS_LAST + 31) / 32] =
   3512 {
   3513     0x30400200, 0x0001007c, 0x00000000, 0x00000000,
   3514     0xfd9efb00, 0x01fc34cf, 0x00000000
   3515 };
   3516 
   3517 /* TODO: put in the right values */
   3518 const uint32_t nine_render_state_group[NINED3DRS_LAST + 1] =
   3519 {
   3520     [D3DRS_ZENABLE] = NINE_STATE_DSA | NINE_STATE_MULTISAMPLE,
   3521     [D3DRS_FILLMODE] = NINE_STATE_RASTERIZER,
   3522     [D3DRS_SHADEMODE] = NINE_STATE_RASTERIZER,
   3523     [D3DRS_ZWRITEENABLE] = NINE_STATE_DSA,
   3524     [D3DRS_ALPHATESTENABLE] = NINE_STATE_DSA,
   3525     [D3DRS_LASTPIXEL] = NINE_STATE_RASTERIZER,
   3526     [D3DRS_SRCBLEND] = NINE_STATE_BLEND,
   3527     [D3DRS_DESTBLEND] = NINE_STATE_BLEND,
   3528     [D3DRS_CULLMODE] = NINE_STATE_RASTERIZER,
   3529     [D3DRS_ZFUNC] = NINE_STATE_DSA,
   3530     [D3DRS_ALPHAREF] = NINE_STATE_DSA,
   3531     [D3DRS_ALPHAFUNC] = NINE_STATE_DSA,
   3532     [D3DRS_DITHERENABLE] = NINE_STATE_BLEND,
   3533     [D3DRS_ALPHABLENDENABLE] = NINE_STATE_BLEND,
   3534     [D3DRS_FOGENABLE] = NINE_STATE_FF_OTHER | NINE_STATE_FOG_SHADER | NINE_STATE_PS_CONST,
   3535     [D3DRS_SPECULARENABLE] = NINE_STATE_FF_LIGHTING,
   3536     [D3DRS_FOGCOLOR] = NINE_STATE_FF_OTHER | NINE_STATE_PS_CONST,
   3537     [D3DRS_FOGTABLEMODE] = NINE_STATE_FF_OTHER | NINE_STATE_FOG_SHADER | NINE_STATE_PS_CONST,
   3538     [D3DRS_FOGSTART] = NINE_STATE_FF_OTHER | NINE_STATE_PS_CONST,
   3539     [D3DRS_FOGEND] = NINE_STATE_FF_OTHER | NINE_STATE_PS_CONST,
   3540     [D3DRS_FOGDENSITY] = NINE_STATE_FF_OTHER | NINE_STATE_PS_CONST,
   3541     [D3DRS_RANGEFOGENABLE] = NINE_STATE_FF_OTHER,
   3542     [D3DRS_STENCILENABLE] = NINE_STATE_DSA | NINE_STATE_MULTISAMPLE,
   3543     [D3DRS_STENCILFAIL] = NINE_STATE_DSA,
   3544     [D3DRS_STENCILZFAIL] = NINE_STATE_DSA,
   3545     [D3DRS_STENCILPASS] = NINE_STATE_DSA,
   3546     [D3DRS_STENCILFUNC] = NINE_STATE_DSA,
   3547     [D3DRS_STENCILREF] = NINE_STATE_STENCIL_REF,
   3548     [D3DRS_STENCILMASK] = NINE_STATE_DSA,
   3549     [D3DRS_STENCILWRITEMASK] = NINE_STATE_DSA,
   3550     [D3DRS_TEXTUREFACTOR] = NINE_STATE_FF_PSSTAGES,
   3551     [D3DRS_WRAP0] = NINE_STATE_UNHANDLED, /* cylindrical wrap is crazy */
   3552     [D3DRS_WRAP1] = NINE_STATE_UNHANDLED,
   3553     [D3DRS_WRAP2] = NINE_STATE_UNHANDLED,
   3554     [D3DRS_WRAP3] = NINE_STATE_UNHANDLED,
   3555     [D3DRS_WRAP4] = NINE_STATE_UNHANDLED,
   3556     [D3DRS_WRAP5] = NINE_STATE_UNHANDLED,
   3557     [D3DRS_WRAP6] = NINE_STATE_UNHANDLED,
   3558     [D3DRS_WRAP7] = NINE_STATE_UNHANDLED,
   3559     [D3DRS_CLIPPING] = 0, /* software vertex processing only */
   3560     [D3DRS_LIGHTING] = NINE_STATE_FF_LIGHTING,
   3561     [D3DRS_AMBIENT] = NINE_STATE_FF_LIGHTING | NINE_STATE_FF_MATERIAL,
   3562     [D3DRS_FOGVERTEXMODE] = NINE_STATE_FF_OTHER,
   3563     [D3DRS_COLORVERTEX] = NINE_STATE_FF_LIGHTING,
   3564     [D3DRS_LOCALVIEWER] = NINE_STATE_FF_LIGHTING,
   3565     [D3DRS_NORMALIZENORMALS] = NINE_STATE_FF_OTHER,
   3566     [D3DRS_DIFFUSEMATERIALSOURCE] = NINE_STATE_FF_LIGHTING,
   3567     [D3DRS_SPECULARMATERIALSOURCE] = NINE_STATE_FF_LIGHTING,
   3568     [D3DRS_AMBIENTMATERIALSOURCE] = NINE_STATE_FF_LIGHTING,
   3569     [D3DRS_EMISSIVEMATERIALSOURCE] = NINE_STATE_FF_LIGHTING,
   3570     [D3DRS_VERTEXBLEND] = NINE_STATE_FF_OTHER,
   3571     [D3DRS_CLIPPLANEENABLE] = NINE_STATE_RASTERIZER,
   3572     [D3DRS_POINTSIZE] = NINE_STATE_RASTERIZER,
   3573     [D3DRS_POINTSIZE_MIN] = NINE_STATE_RASTERIZER | NINE_STATE_POINTSIZE_SHADER,
   3574     [D3DRS_POINTSPRITEENABLE] = NINE_STATE_RASTERIZER,
   3575     [D3DRS_POINTSCALEENABLE] = NINE_STATE_FF_OTHER,
   3576     [D3DRS_POINTSCALE_A] = NINE_STATE_FF_OTHER,
   3577     [D3DRS_POINTSCALE_B] = NINE_STATE_FF_OTHER,
   3578     [D3DRS_POINTSCALE_C] = NINE_STATE_FF_OTHER,
   3579     [D3DRS_MULTISAMPLEANTIALIAS] = NINE_STATE_MULTISAMPLE,
   3580     [D3DRS_MULTISAMPLEMASK] = NINE_STATE_SAMPLE_MASK,
   3581     [D3DRS_PATCHEDGESTYLE] = NINE_STATE_UNHANDLED,
   3582     [D3DRS_DEBUGMONITORTOKEN] = NINE_STATE_UNHANDLED,
   3583     [D3DRS_POINTSIZE_MAX] = NINE_STATE_RASTERIZER | NINE_STATE_POINTSIZE_SHADER,
   3584     [D3DRS_INDEXEDVERTEXBLENDENABLE] = NINE_STATE_FF_OTHER,
   3585     [D3DRS_COLORWRITEENABLE] = NINE_STATE_BLEND,
   3586     [D3DRS_TWEENFACTOR] = NINE_STATE_FF_OTHER,
   3587     [D3DRS_BLENDOP] = NINE_STATE_BLEND,
   3588     [D3DRS_POSITIONDEGREE] = NINE_STATE_UNHANDLED,
   3589     [D3DRS_NORMALDEGREE] = NINE_STATE_UNHANDLED,
   3590     [D3DRS_SCISSORTESTENABLE] = NINE_STATE_RASTERIZER,
   3591     [D3DRS_SLOPESCALEDEPTHBIAS] = NINE_STATE_RASTERIZER,
   3592     [D3DRS_ANTIALIASEDLINEENABLE] = NINE_STATE_RASTERIZER,
   3593     [D3DRS_MINTESSELLATIONLEVEL] = NINE_STATE_UNHANDLED,
   3594     [D3DRS_MAXTESSELLATIONLEVEL] = NINE_STATE_UNHANDLED,
   3595     [D3DRS_ADAPTIVETESS_X] = NINE_STATE_UNHANDLED,
   3596     [D3DRS_ADAPTIVETESS_Y] = NINE_STATE_UNHANDLED,
   3597     [D3DRS_ADAPTIVETESS_Z] = NINE_STATE_UNHANDLED,
   3598     [D3DRS_ADAPTIVETESS_W] = NINE_STATE_UNHANDLED,
   3599     [D3DRS_ENABLEADAPTIVETESSELLATION] = NINE_STATE_UNHANDLED,
   3600     [D3DRS_TWOSIDEDSTENCILMODE] = NINE_STATE_DSA,
   3601     [D3DRS_CCW_STENCILFAIL] = NINE_STATE_DSA,
   3602     [D3DRS_CCW_STENCILZFAIL] = NINE_STATE_DSA,
   3603     [D3DRS_CCW_STENCILPASS] = NINE_STATE_DSA,
   3604     [D3DRS_CCW_STENCILFUNC] = NINE_STATE_DSA,
   3605     [D3DRS_COLORWRITEENABLE1] = NINE_STATE_BLEND,
   3606     [D3DRS_COLORWRITEENABLE2] = NINE_STATE_BLEND,
   3607     [D3DRS_COLORWRITEENABLE3] = NINE_STATE_BLEND,
   3608     [D3DRS_BLENDFACTOR] = NINE_STATE_BLEND_COLOR,
   3609     [D3DRS_SRGBWRITEENABLE] = NINE_STATE_FB,
   3610     [D3DRS_DEPTHBIAS] = NINE_STATE_RASTERIZER,
   3611     [D3DRS_WRAP8] = NINE_STATE_UNHANDLED, /* cylwrap has to be done via GP */
   3612     [D3DRS_WRAP9] = NINE_STATE_UNHANDLED,
   3613     [D3DRS_WRAP10] = NINE_STATE_UNHANDLED,
   3614     [D3DRS_WRAP11] = NINE_STATE_UNHANDLED,
   3615     [D3DRS_WRAP12] = NINE_STATE_UNHANDLED,
   3616     [D3DRS_WRAP13] = NINE_STATE_UNHANDLED,
   3617     [D3DRS_WRAP14] = NINE_STATE_UNHANDLED,
   3618     [D3DRS_WRAP15] = NINE_STATE_UNHANDLED,
   3619     [D3DRS_SEPARATEALPHABLENDENABLE] = NINE_STATE_BLEND,
   3620     [D3DRS_SRCBLENDALPHA] = NINE_STATE_BLEND,
   3621     [D3DRS_DESTBLENDALPHA] = NINE_STATE_BLEND,
   3622     [D3DRS_BLENDOPALPHA] = NINE_STATE_BLEND
   3623 };
   3624 
   3625 /* Misc */
   3626 
   3627 D3DMATRIX *
   3628 nine_state_access_transform(struct nine_ff_state *ff_state, D3DTRANSFORMSTATETYPE t,
   3629                             boolean alloc)
   3630 {
   3631     static D3DMATRIX Identity = { .m[0] = { 1, 0, 0, 0 },
   3632                                   .m[1] = { 0, 1, 0, 0 },
   3633                                   .m[2] = { 0, 0, 1, 0 },
   3634                                   .m[3] = { 0, 0, 0, 1 } };
   3635     unsigned index;
   3636 
   3637     switch (t) {
   3638     case D3DTS_VIEW: index = 0; break;
   3639     case D3DTS_PROJECTION: index = 1; break;
   3640     case D3DTS_TEXTURE0: index = 2; break;
   3641     case D3DTS_TEXTURE1: index = 3; break;
   3642     case D3DTS_TEXTURE2: index = 4; break;
   3643     case D3DTS_TEXTURE3: index = 5; break;
   3644     case D3DTS_TEXTURE4: index = 6; break;
   3645     case D3DTS_TEXTURE5: index = 7; break;
   3646     case D3DTS_TEXTURE6: index = 8; break;
   3647     case D3DTS_TEXTURE7: index = 9; break;
   3648     default:
   3649         if (!(t >= D3DTS_WORLDMATRIX(0) && t <= D3DTS_WORLDMATRIX(255)))
   3650             return NULL;
   3651         index = 10 + (t - D3DTS_WORLDMATRIX(0));
   3652         break;
   3653     }
   3654 
   3655     if (index >= ff_state->num_transforms) {
   3656         unsigned N = index + 1;
   3657         unsigned n = ff_state->num_transforms;
   3658 
   3659         if (!alloc)
   3660             return &Identity;
   3661         ff_state->transform = REALLOC(ff_state->transform,
   3662                                       n * sizeof(D3DMATRIX),
   3663                                       N * sizeof(D3DMATRIX));
   3664         for (; n < N; ++n)
   3665             ff_state->transform[n] = Identity;
   3666         ff_state->num_transforms = N;
   3667     }
   3668     return &ff_state->transform[index];
   3669 }
   3670 
   3671 HRESULT
   3672 nine_state_set_light(struct nine_ff_state *ff_state, DWORD Index,
   3673                      const D3DLIGHT9 *pLight)
   3674 {
   3675     if (Index >= ff_state->num_lights) {
   3676         unsigned n = ff_state->num_lights;
   3677         unsigned N = Index + 1;
   3678 
   3679         ff_state->light = REALLOC(ff_state->light, n * sizeof(D3DLIGHT9),
   3680                                                    N * sizeof(D3DLIGHT9));
   3681         if (!ff_state->light)
   3682             return E_OUTOFMEMORY;
   3683         ff_state->num_lights = N;
   3684 
   3685         for (; n < Index; ++n) {
   3686             memset(&ff_state->light[n], 0, sizeof(D3DLIGHT9));
   3687             ff_state->light[n].Type = (D3DLIGHTTYPE)NINED3DLIGHT_INVALID;
   3688         }
   3689     }
   3690     ff_state->light[Index] = *pLight;
   3691 
   3692     if (pLight->Type == D3DLIGHT_SPOT && pLight->Theta >= pLight->Phi) {
   3693         DBG("Warning: clamping D3DLIGHT9.Theta\n");
   3694         ff_state->light[Index].Theta = ff_state->light[Index].Phi;
   3695     }
   3696     return D3D_OK;
   3697 }
   3698 
   3699 HRESULT
   3700 nine_state_light_enable(struct nine_ff_state *ff_state, uint32_t *change_group,
   3701                         DWORD Index, BOOL Enable)
   3702 {
   3703     unsigned i;
   3704 
   3705     user_assert(Index < ff_state->num_lights, D3DERR_INVALIDCALL);
   3706 
   3707     for (i = 0; i < ff_state->num_lights_active; ++i) {
   3708         if (ff_state->active_light[i] == Index)
   3709             break;
   3710     }
   3711 
   3712     if (Enable) {
   3713         if (i < ff_state->num_lights_active)
   3714             return D3D_OK;
   3715         /* XXX wine thinks this should still succeed:
   3716          */
   3717         user_assert(i < NINE_MAX_LIGHTS_ACTIVE, D3DERR_INVALIDCALL);
   3718 
   3719         ff_state->active_light[i] = Index;
   3720         ff_state->num_lights_active++;
   3721     } else {
   3722         if (i == ff_state->num_lights_active)
   3723             return D3D_OK;
   3724         --ff_state->num_lights_active;
   3725         for (; i < ff_state->num_lights_active; ++i)
   3726             ff_state->active_light[i] = ff_state->active_light[i + 1];
   3727     }
   3728 
   3729     *change_group |= NINE_STATE_FF_LIGHTING;
   3730 
   3731     return D3D_OK;
   3732 }
   3733 
   3734 #define D3DRS_TO_STRING_CASE(n) case D3DRS_##n: return "D3DRS_"#n
   3735 const char *nine_d3drs_to_string(DWORD State)
   3736 {
   3737     switch (State) {
   3738     D3DRS_TO_STRING_CASE(ZENABLE);
   3739     D3DRS_TO_STRING_CASE(FILLMODE);
   3740     D3DRS_TO_STRING_CASE(SHADEMODE);
   3741     D3DRS_TO_STRING_CASE(ZWRITEENABLE);
   3742     D3DRS_TO_STRING_CASE(ALPHATESTENABLE);
   3743     D3DRS_TO_STRING_CASE(LASTPIXEL);
   3744     D3DRS_TO_STRING_CASE(SRCBLEND);
   3745     D3DRS_TO_STRING_CASE(DESTBLEND);
   3746     D3DRS_TO_STRING_CASE(CULLMODE);
   3747     D3DRS_TO_STRING_CASE(ZFUNC);
   3748     D3DRS_TO_STRING_CASE(ALPHAREF);
   3749     D3DRS_TO_STRING_CASE(ALPHAFUNC);
   3750     D3DRS_TO_STRING_CASE(DITHERENABLE);
   3751     D3DRS_TO_STRING_CASE(ALPHABLENDENABLE);
   3752     D3DRS_TO_STRING_CASE(FOGENABLE);
   3753     D3DRS_TO_STRING_CASE(SPECULARENABLE);
   3754     D3DRS_TO_STRING_CASE(FOGCOLOR);
   3755     D3DRS_TO_STRING_CASE(FOGTABLEMODE);
   3756     D3DRS_TO_STRING_CASE(FOGSTART);
   3757     D3DRS_TO_STRING_CASE(FOGEND);
   3758     D3DRS_TO_STRING_CASE(FOGDENSITY);
   3759     D3DRS_TO_STRING_CASE(RANGEFOGENABLE);
   3760     D3DRS_TO_STRING_CASE(STENCILENABLE);
   3761     D3DRS_TO_STRING_CASE(STENCILFAIL);
   3762     D3DRS_TO_STRING_CASE(STENCILZFAIL);
   3763     D3DRS_TO_STRING_CASE(STENCILPASS);
   3764     D3DRS_TO_STRING_CASE(STENCILFUNC);
   3765     D3DRS_TO_STRING_CASE(STENCILREF);
   3766     D3DRS_TO_STRING_CASE(STENCILMASK);
   3767     D3DRS_TO_STRING_CASE(STENCILWRITEMASK);
   3768     D3DRS_TO_STRING_CASE(TEXTUREFACTOR);
   3769     D3DRS_TO_STRING_CASE(WRAP0);
   3770     D3DRS_TO_STRING_CASE(WRAP1);
   3771     D3DRS_TO_STRING_CASE(WRAP2);
   3772     D3DRS_TO_STRING_CASE(WRAP3);
   3773     D3DRS_TO_STRING_CASE(WRAP4);
   3774     D3DRS_TO_STRING_CASE(WRAP5);
   3775     D3DRS_TO_STRING_CASE(WRAP6);
   3776     D3DRS_TO_STRING_CASE(WRAP7);
   3777     D3DRS_TO_STRING_CASE(CLIPPING);
   3778     D3DRS_TO_STRING_CASE(LIGHTING);
   3779     D3DRS_TO_STRING_CASE(AMBIENT);
   3780     D3DRS_TO_STRING_CASE(FOGVERTEXMODE);
   3781     D3DRS_TO_STRING_CASE(COLORVERTEX);
   3782     D3DRS_TO_STRING_CASE(LOCALVIEWER);
   3783     D3DRS_TO_STRING_CASE(NORMALIZENORMALS);
   3784     D3DRS_TO_STRING_CASE(DIFFUSEMATERIALSOURCE);
   3785     D3DRS_TO_STRING_CASE(SPECULARMATERIALSOURCE);
   3786     D3DRS_TO_STRING_CASE(AMBIENTMATERIALSOURCE);
   3787     D3DRS_TO_STRING_CASE(EMISSIVEMATERIALSOURCE);
   3788     D3DRS_TO_STRING_CASE(VERTEXBLEND);
   3789     D3DRS_TO_STRING_CASE(CLIPPLANEENABLE);
   3790     D3DRS_TO_STRING_CASE(POINTSIZE);
   3791     D3DRS_TO_STRING_CASE(POINTSIZE_MIN);
   3792     D3DRS_TO_STRING_CASE(POINTSPRITEENABLE);
   3793     D3DRS_TO_STRING_CASE(POINTSCALEENABLE);
   3794     D3DRS_TO_STRING_CASE(POINTSCALE_A);
   3795     D3DRS_TO_STRING_CASE(POINTSCALE_B);
   3796     D3DRS_TO_STRING_CASE(POINTSCALE_C);
   3797     D3DRS_TO_STRING_CASE(MULTISAMPLEANTIALIAS);
   3798     D3DRS_TO_STRING_CASE(MULTISAMPLEMASK);
   3799     D3DRS_TO_STRING_CASE(PATCHEDGESTYLE);
   3800     D3DRS_TO_STRING_CASE(DEBUGMONITORTOKEN);
   3801     D3DRS_TO_STRING_CASE(POINTSIZE_MAX);
   3802     D3DRS_TO_STRING_CASE(INDEXEDVERTEXBLENDENABLE);
   3803     D3DRS_TO_STRING_CASE(COLORWRITEENABLE);
   3804     D3DRS_TO_STRING_CASE(TWEENFACTOR);
   3805     D3DRS_TO_STRING_CASE(BLENDOP);
   3806     D3DRS_TO_STRING_CASE(POSITIONDEGREE);
   3807     D3DRS_TO_STRING_CASE(NORMALDEGREE);
   3808     D3DRS_TO_STRING_CASE(SCISSORTESTENABLE);
   3809     D3DRS_TO_STRING_CASE(SLOPESCALEDEPTHBIAS);
   3810     D3DRS_TO_STRING_CASE(ANTIALIASEDLINEENABLE);
   3811     D3DRS_TO_STRING_CASE(MINTESSELLATIONLEVEL);
   3812     D3DRS_TO_STRING_CASE(MAXTESSELLATIONLEVEL);
   3813     D3DRS_TO_STRING_CASE(ADAPTIVETESS_X);
   3814     D3DRS_TO_STRING_CASE(ADAPTIVETESS_Y);
   3815     D3DRS_TO_STRING_CASE(ADAPTIVETESS_Z);
   3816     D3DRS_TO_STRING_CASE(ADAPTIVETESS_W);
   3817     D3DRS_TO_STRING_CASE(ENABLEADAPTIVETESSELLATION);
   3818     D3DRS_TO_STRING_CASE(TWOSIDEDSTENCILMODE);
   3819     D3DRS_TO_STRING_CASE(CCW_STENCILFAIL);
   3820     D3DRS_TO_STRING_CASE(CCW_STENCILZFAIL);
   3821     D3DRS_TO_STRING_CASE(CCW_STENCILPASS);
   3822     D3DRS_TO_STRING_CASE(CCW_STENCILFUNC);
   3823     D3DRS_TO_STRING_CASE(COLORWRITEENABLE1);
   3824     D3DRS_TO_STRING_CASE(COLORWRITEENABLE2);
   3825     D3DRS_TO_STRING_CASE(COLORWRITEENABLE3);
   3826     D3DRS_TO_STRING_CASE(BLENDFACTOR);
   3827     D3DRS_TO_STRING_CASE(SRGBWRITEENABLE);
   3828     D3DRS_TO_STRING_CASE(DEPTHBIAS);
   3829     D3DRS_TO_STRING_CASE(WRAP8);
   3830     D3DRS_TO_STRING_CASE(WRAP9);
   3831     D3DRS_TO_STRING_CASE(WRAP10);
   3832     D3DRS_TO_STRING_CASE(WRAP11);
   3833     D3DRS_TO_STRING_CASE(WRAP12);
   3834     D3DRS_TO_STRING_CASE(WRAP13);
   3835     D3DRS_TO_STRING_CASE(WRAP14);
   3836     D3DRS_TO_STRING_CASE(WRAP15);
   3837     D3DRS_TO_STRING_CASE(SEPARATEALPHABLENDENABLE);
   3838     D3DRS_TO_STRING_CASE(SRCBLENDALPHA);
   3839     D3DRS_TO_STRING_CASE(DESTBLENDALPHA);
   3840     D3DRS_TO_STRING_CASE(BLENDOPALPHA);
   3841     default:
   3842         return "(invalid)";
   3843     }
   3844 }
   3845