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