device9.c revision d9d18fe39f7b4f628af23b78576e961fd452921f
1/* 2 * Copyright 2011 Joakim Sindholt <opensource@zhasha.com> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22 23#include "device9.h" 24#include "stateblock9.h" 25#include "surface9.h" 26#include "swapchain9.h" 27#include "swapchain9ex.h" 28#include "indexbuffer9.h" 29#include "vertexbuffer9.h" 30#include "vertexdeclaration9.h" 31#include "vertexshader9.h" 32#include "pixelshader9.h" 33#include "query9.h" 34#include "texture9.h" 35#include "cubetexture9.h" 36#include "volumetexture9.h" 37#include "nine_helpers.h" 38#include "nine_pipe.h" 39#include "nine_ff.h" 40#include "nine_dump.h" 41 42#include "pipe/p_screen.h" 43#include "pipe/p_context.h" 44#include "util/u_math.h" 45#include "util/u_inlines.h" 46#include "util/u_hash_table.h" 47#include "util/u_format.h" 48#include "util/u_surface.h" 49#include "util/u_upload_mgr.h" 50#include "hud/hud_context.h" 51 52#include "cso_cache/cso_context.h" 53 54#define DBG_CHANNEL DBG_DEVICE 55 56static void 57NineDevice9_SetDefaultState( struct NineDevice9 *This, boolean is_reset ) 58{ 59 struct NineSurface9 *refSurf = NULL; 60 61 DBG("This=%p is_reset=%d\n", This, (int) is_reset); 62 63 assert(!This->is_recording); 64 65 nine_state_set_defaults(&This->state, &This->caps, is_reset); 66 67 This->state.viewport.X = 0; 68 This->state.viewport.Y = 0; 69 This->state.viewport.Width = 0; 70 This->state.viewport.Height = 0; 71 72 This->state.scissor.minx = 0; 73 This->state.scissor.miny = 0; 74 This->state.scissor.maxx = 0xffff; 75 This->state.scissor.maxy = 0xffff; 76 77 if (This->nswapchains && This->swapchains[0]->params.BackBufferCount) 78 refSurf = This->swapchains[0]->buffers[0]; 79 80 if (refSurf) { 81 This->state.viewport.Width = refSurf->desc.Width; 82 This->state.viewport.Height = refSurf->desc.Height; 83 This->state.scissor.maxx = refSurf->desc.Width; 84 This->state.scissor.maxy = refSurf->desc.Height; 85 } 86 87 if (This->nswapchains && This->swapchains[0]->params.EnableAutoDepthStencil) 88 This->state.rs[D3DRS_ZENABLE] = TRUE; 89 if (This->state.rs[D3DRS_ZENABLE]) 90 NineDevice9_SetDepthStencilSurface( 91 This, (IDirect3DSurface9 *)This->swapchains[0]->zsbuf); 92} 93 94void 95NineDevice9_RestoreNonCSOState( struct NineDevice9 *This, unsigned mask ) 96{ 97 struct pipe_context *pipe = This->pipe; 98 99 DBG("This=%p mask=%u\n", This, mask); 100 101 if (mask & 0x1) { 102 struct pipe_constant_buffer cb; 103 cb.buffer_offset = 0; 104 105 if (This->prefer_user_constbuf) { 106 cb.buffer = NULL; 107 cb.user_buffer = This->state.vs_const_f; 108 } else { 109 cb.buffer = This->constbuf_vs; 110 cb.user_buffer = NULL; 111 } 112 cb.buffer_size = This->constbuf_vs->width0; 113 pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &cb); 114 115 if (This->prefer_user_constbuf) { 116 cb.user_buffer = This->state.ps_const_f; 117 } else { 118 cb.buffer = This->constbuf_ps; 119 } 120 cb.buffer_size = This->constbuf_ps->width0; 121 pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &cb); 122 } 123 124 if (mask & 0x2) { 125 struct pipe_poly_stipple stipple; 126 memset(&stipple, ~0, sizeof(stipple)); 127 pipe->set_polygon_stipple(pipe, &stipple); 128 } 129 130 This->state.changed.group = NINE_STATE_ALL; 131 This->state.changed.vtxbuf = (1ULL << This->caps.MaxStreams) - 1; 132 This->state.changed.ucp = (1 << PIPE_MAX_CLIP_PLANES) - 1; 133 This->state.changed.texture = NINE_PS_SAMPLERS_MASK | NINE_VS_SAMPLERS_MASK; 134} 135 136#define GET_PCAP(n) pScreen->get_param(pScreen, PIPE_CAP_##n) 137HRESULT 138NineDevice9_ctor( struct NineDevice9 *This, 139 struct NineUnknownParams *pParams, 140 struct pipe_screen *pScreen, 141 D3DDEVICE_CREATION_PARAMETERS *pCreationParameters, 142 D3DCAPS9 *pCaps, 143 D3DPRESENT_PARAMETERS *pPresentationParameters, 144 IDirect3D9 *pD3D9, 145 ID3DPresentGroup *pPresentationGroup, 146 struct d3dadapter9_context *pCTX, 147 boolean ex, 148 D3DDISPLAYMODEEX *pFullscreenDisplayMode ) 149{ 150 unsigned i; 151 HRESULT hr = NineUnknown_ctor(&This->base, pParams); 152 153 DBG("This=%p pParams=%p pScreen=%p pCreationParameters=%p pCaps=%p pPresentationParameters=%p " 154 "pD3D9=%p pPresentationGroup=%p pCTX=%p ex=%d pFullscreenDisplayMode=%p\n", 155 This, pParams, pScreen, pCreationParameters, pCaps, pPresentationParameters, pD3D9, 156 pPresentationGroup, pCTX, (int) ex, pFullscreenDisplayMode); 157 158 if (FAILED(hr)) { return hr; } 159 160 list_inithead(&This->update_textures); 161 162 This->screen = pScreen; 163 This->caps = *pCaps; 164 This->d3d9 = pD3D9; 165 This->params = *pCreationParameters; 166 This->ex = ex; 167 This->present = pPresentationGroup; 168 IDirect3D9_AddRef(This->d3d9); 169 ID3DPresentGroup_AddRef(This->present); 170 171 This->pipe = This->screen->context_create(This->screen, NULL); 172 if (!This->pipe) { return E_OUTOFMEMORY; } /* guess */ 173 174 This->cso = cso_create_context(This->pipe); 175 if (!This->cso) { return E_OUTOFMEMORY; } /* also a guess */ 176 177 /* Create first, it messes up our state. */ 178 This->hud = hud_create(This->pipe, This->cso); /* NULL result is fine */ 179 180 /* create implicit swapchains */ 181 This->nswapchains = ID3DPresentGroup_GetMultiheadCount(This->present); 182 This->swapchains = CALLOC(This->nswapchains, 183 sizeof(struct NineSwapChain9 *)); 184 if (!This->swapchains) { return E_OUTOFMEMORY; } 185 186 for (i = 0; i < This->nswapchains; ++i) { 187 ID3DPresent *present; 188 189 hr = ID3DPresentGroup_GetPresent(This->present, i, &present); 190 if (FAILED(hr)) 191 return hr; 192 193 if (ex) { 194 D3DDISPLAYMODEEX *mode = NULL; 195 struct NineSwapChain9Ex **ret = 196 (struct NineSwapChain9Ex **)&This->swapchains[i]; 197 198 if (pFullscreenDisplayMode) mode = &(pFullscreenDisplayMode[i]); 199 /* when this is a Device9Ex, it should create SwapChain9Exs */ 200 hr = NineSwapChain9Ex_new(This, TRUE, present, 201 &pPresentationParameters[i], pCTX, 202 This->params.hFocusWindow, mode, ret); 203 } else { 204 hr = NineSwapChain9_new(This, TRUE, present, 205 &pPresentationParameters[i], pCTX, 206 This->params.hFocusWindow, 207 &This->swapchains[i]); 208 } 209 210 ID3DPresent_Release(present); 211 if (FAILED(hr)) 212 return hr; 213 NineUnknown_ConvertRefToBind(NineUnknown(This->swapchains[i])); 214 215 hr = NineSwapChain9_GetBackBuffer(This->swapchains[i], 0, 216 D3DBACKBUFFER_TYPE_MONO, 217 (IDirect3DSurface9 **) 218 &This->state.rt[i]); 219 if (FAILED(hr)) 220 return hr; 221 NineUnknown_ConvertRefToBind(NineUnknown(This->state.rt[i])); 222 } 223 224 This->cursor.software = FALSE; 225 This->cursor.hotspot.x = -1; 226 This->cursor.hotspot.y = -1; 227 { 228 struct pipe_resource tmpl; 229 tmpl.target = PIPE_TEXTURE_2D; 230 tmpl.format = PIPE_FORMAT_R8G8B8A8_UNORM; 231 tmpl.width0 = 64; 232 tmpl.height0 = 64; 233 tmpl.depth0 = 1; 234 tmpl.array_size = 1; 235 tmpl.last_level = 0; 236 tmpl.nr_samples = 0; 237 tmpl.usage = PIPE_USAGE_DEFAULT; 238 tmpl.bind = PIPE_BIND_CURSOR | PIPE_BIND_SAMPLER_VIEW; 239 tmpl.flags = 0; 240 241 This->cursor.image = pScreen->resource_create(pScreen, &tmpl); 242 if (!This->cursor.image) 243 return D3DERR_OUTOFVIDEOMEMORY; 244 } 245 246 /* Create constant buffers. */ 247 { 248 struct pipe_resource tmpl; 249 unsigned max_const_vs, max_const_ps; 250 251 max_const_vs = _min(pScreen->get_shader_param(pScreen, PIPE_SHADER_VERTEX, 252 PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE) / 253 sizeof(float[4]), 254 NINE_MAX_CONST_ALL); 255 max_const_ps = _min(pScreen->get_shader_param(pScreen, PIPE_SHADER_FRAGMENT, 256 PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE) / 257 sizeof(float[4]), 258 NINE_MAX_CONST_ALL); 259 260 This->max_vs_const_f = max_const_vs - 261 (NINE_MAX_CONST_I + NINE_MAX_CONST_B / 4); 262 This->max_ps_const_f = max_const_ps - 263 (NINE_MAX_CONST_I + NINE_MAX_CONST_B / 4); 264 265 /* Include space for I,B constants for user constbuf. */ 266 This->state.vs_const_f = CALLOC(NINE_MAX_CONST_ALL, sizeof(float[4])); 267 This->state.ps_const_f = CALLOC(NINE_MAX_CONST_ALL, sizeof(float[4])); 268 if (!This->state.vs_const_f || !This->state.ps_const_f) 269 return E_OUTOFMEMORY; 270 271 if (strstr(pScreen->get_name(pScreen), "AMD") || 272 strstr(pScreen->get_name(pScreen), "ATI")) 273 This->prefer_user_constbuf = TRUE; 274 275 tmpl.target = PIPE_BUFFER; 276 tmpl.format = PIPE_FORMAT_R8_UNORM; 277 tmpl.height0 = 1; 278 tmpl.depth0 = 1; 279 tmpl.array_size = 1; 280 tmpl.last_level = 0; 281 tmpl.nr_samples = 0; 282 tmpl.usage = PIPE_USAGE_DYNAMIC; 283 tmpl.bind = PIPE_BIND_CONSTANT_BUFFER; 284 tmpl.flags = 0; 285 286 tmpl.width0 = max_const_vs * sizeof(float[4]); 287 This->constbuf_vs = pScreen->resource_create(pScreen, &tmpl); 288 289 tmpl.width0 = max_const_ps * sizeof(float[4]); 290 This->constbuf_ps = pScreen->resource_create(pScreen, &tmpl); 291 292 if (!This->constbuf_vs || !This->constbuf_ps) 293 return E_OUTOFMEMORY; 294 } 295 296 /* Allocate upload helper for drivers that suck (from st pov ;). */ 297 { 298 unsigned bind = 0; 299 300 This->driver_caps.user_vbufs = GET_PCAP(USER_VERTEX_BUFFERS); 301 This->driver_caps.user_ibufs = GET_PCAP(USER_INDEX_BUFFERS); 302 303 if (!This->driver_caps.user_vbufs) bind |= PIPE_BIND_VERTEX_BUFFER; 304 if (!This->driver_caps.user_ibufs) bind |= PIPE_BIND_INDEX_BUFFER; 305 if (bind) 306 This->upload = u_upload_create(This->pipe, 1 << 20, 4, bind); 307 } 308 309 This->driver_caps.window_space_position_support = GET_PCAP(TGSI_VS_WINDOW_SPACE_POSITION); 310 This->driver_caps.vs_integer = pScreen->get_shader_param(pScreen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_INTEGERS); 311 This->driver_caps.ps_integer = pScreen->get_shader_param(pScreen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_INTEGERS); 312 313 nine_ff_init(This); /* initialize fixed function code */ 314 315 NineDevice9_SetDefaultState(This, FALSE); 316 NineDevice9_RestoreNonCSOState(This, ~0); 317 318 This->update = &This->state; 319 nine_update_state(This, ~0); 320 321 ID3DPresentGroup_Release(This->present); 322 323 return D3D_OK; 324} 325#undef GET_PCAP 326 327void 328NineDevice9_dtor( struct NineDevice9 *This ) 329{ 330 unsigned i; 331 332 DBG("This=%p\n", This); 333 334 if (This->pipe && This->cso) 335 nine_pipe_context_clear(This); 336 nine_ff_fini(This); 337 nine_state_clear(&This->state, TRUE); 338 339 if (This->upload) 340 u_upload_destroy(This->upload); 341 342 nine_bind(&This->record, NULL); 343 344 pipe_resource_reference(&This->constbuf_vs, NULL); 345 pipe_resource_reference(&This->constbuf_ps, NULL); 346 FREE(This->state.vs_const_f); 347 FREE(This->state.ps_const_f); 348 349 if (This->swapchains) { 350 for (i = 0; i < This->nswapchains; ++i) 351 NineUnknown_Unbind(NineUnknown(This->swapchains[i])); 352 FREE(This->swapchains); 353 } 354 355 /* state stuff */ 356 if (This->pipe) { 357 if (This->cso) { 358 cso_destroy_context(This->cso); 359 } 360 if (This->pipe->destroy) { This->pipe->destroy(This->pipe); } 361 } 362 363 if (This->present) { ID3DPresentGroup_Release(This->present); } 364 if (This->d3d9) { IDirect3D9_Release(This->d3d9); } 365 366 NineUnknown_dtor(&This->base); 367} 368 369struct pipe_screen * 370NineDevice9_GetScreen( struct NineDevice9 *This ) 371{ 372 return This->screen; 373} 374 375struct pipe_context * 376NineDevice9_GetPipe( struct NineDevice9 *This ) 377{ 378 return This->pipe; 379} 380 381struct cso_context * 382NineDevice9_GetCSO( struct NineDevice9 *This ) 383{ 384 return This->cso; 385} 386 387const D3DCAPS9 * 388NineDevice9_GetCaps( struct NineDevice9 *This ) 389{ 390 return &This->caps; 391} 392 393static INLINE void 394NineDevice9_PauseRecording( struct NineDevice9 *This ) 395{ 396 if (This->record) { 397 This->update = &This->state; 398 This->is_recording = FALSE; 399 } 400} 401 402static INLINE void 403NineDevice9_ResumeRecording( struct NineDevice9 *This ) 404{ 405 if (This->record) { 406 This->update = &This->record->state; 407 This->is_recording = TRUE; 408 } 409} 410 411HRESULT WINAPI 412NineDevice9_TestCooperativeLevel( struct NineDevice9 *This ) 413{ 414 return D3D_OK; /* TODO */ 415} 416 417UINT WINAPI 418NineDevice9_GetAvailableTextureMem( struct NineDevice9 *This ) 419{ 420 const unsigned mem = This->screen->get_param(This->screen, PIPE_CAP_VIDEO_MEMORY); 421 if (mem < 4096) 422 return mem << 20; 423 else 424 return UINT_MAX; 425} 426 427HRESULT WINAPI 428NineDevice9_EvictManagedResources( struct NineDevice9 *This ) 429{ 430 /* We don't really need to do anything here, but might want to free up 431 * the GPU virtual address space by killing pipe_resources. 432 */ 433 STUB(D3D_OK); 434} 435 436HRESULT WINAPI 437NineDevice9_GetDirect3D( struct NineDevice9 *This, 438 IDirect3D9 **ppD3D9 ) 439{ 440 user_assert(ppD3D9 != NULL, E_POINTER); 441 IDirect3D9_AddRef(This->d3d9); 442 *ppD3D9 = This->d3d9; 443 return D3D_OK; 444} 445 446HRESULT WINAPI 447NineDevice9_GetDeviceCaps( struct NineDevice9 *This, 448 D3DCAPS9 *pCaps ) 449{ 450 user_assert(pCaps != NULL, D3DERR_INVALIDCALL); 451 *pCaps = This->caps; 452 return D3D_OK; 453} 454 455HRESULT WINAPI 456NineDevice9_GetDisplayMode( struct NineDevice9 *This, 457 UINT iSwapChain, 458 D3DDISPLAYMODE *pMode ) 459{ 460 DBG("This=%p iSwapChain=%u pMode=%p\n", This, iSwapChain, pMode); 461 462 user_assert(iSwapChain < This->nswapchains, D3DERR_INVALIDCALL); 463 464 return NineSwapChain9_GetDisplayMode(This->swapchains[iSwapChain], pMode); 465} 466 467HRESULT WINAPI 468NineDevice9_GetCreationParameters( struct NineDevice9 *This, 469 D3DDEVICE_CREATION_PARAMETERS *pParameters ) 470{ 471 user_assert(pParameters != NULL, D3DERR_INVALIDCALL); 472 *pParameters = This->params; 473 return D3D_OK; 474} 475 476HRESULT WINAPI 477NineDevice9_SetCursorProperties( struct NineDevice9 *This, 478 UINT XHotSpot, 479 UINT YHotSpot, 480 IDirect3DSurface9 *pCursorBitmap ) 481{ 482 /* TODO: hardware cursor */ 483 struct NineSurface9 *surf = NineSurface9(pCursorBitmap); 484 struct pipe_context *pipe = This->pipe; 485 struct pipe_box box; 486 struct pipe_transfer *transfer; 487 void *ptr; 488 489 DBG_FLAG(DBG_SWAPCHAIN, "This=%p XHotSpot=%u YHotSpot=%u " 490 "pCursorBitmap=%p\n", This, XHotSpot, YHotSpot, pCursorBitmap); 491 492 user_assert(pCursorBitmap, D3DERR_INVALIDCALL); 493 494 This->cursor.w = MIN2(surf->desc.Width, This->cursor.image->width0); 495 This->cursor.h = MIN2(surf->desc.Height, This->cursor.image->height0); 496 497 u_box_origin_2d(This->cursor.w, This->cursor.h, &box); 498 499 ptr = pipe->transfer_map(pipe, This->cursor.image, 0, 500 PIPE_TRANSFER_WRITE | 501 PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE, 502 &box, &transfer); 503 if (!ptr) 504 ret_err("Failed to update cursor image.\n", D3DERR_DRIVERINTERNALERROR); 505 506 This->cursor.hotspot.x = XHotSpot; 507 This->cursor.hotspot.y = YHotSpot; 508 509 /* Copy cursor image to internal storage. */ 510 { 511 D3DLOCKED_RECT lock; 512 HRESULT hr; 513 const struct util_format_description *sfmt = 514 util_format_description(surf->base.info.format); 515 assert(sfmt); 516 517 hr = NineSurface9_LockRect(surf, &lock, NULL, D3DLOCK_READONLY); 518 if (FAILED(hr)) 519 ret_err("Failed to map cursor source image.\n", 520 D3DERR_DRIVERINTERNALERROR); 521 522 sfmt->unpack_rgba_8unorm(ptr, transfer->stride, 523 lock.pBits, lock.Pitch, 524 This->cursor.w, This->cursor.h); 525 526 if (!This->cursor.software && 527 This->cursor.w == 32 && This->cursor.h == 32) 528 ID3DPresent_SetCursor(This->swapchains[0]->present, 529 lock.pBits, &This->cursor.hotspot, 530 This->cursor.visible); 531 532 NineSurface9_UnlockRect(surf); 533 } 534 pipe->transfer_unmap(pipe, transfer); 535 536 return D3D_OK; 537} 538 539void WINAPI 540NineDevice9_SetCursorPosition( struct NineDevice9 *This, 541 int X, 542 int Y, 543 DWORD Flags ) 544{ 545 struct NineSwapChain9 *swap = This->swapchains[0]; 546 547 DBG("This=%p X=%d Y=%d Flags=%d\n", This, X, Y, Flags); 548 549 This->cursor.pos.x = X; 550 This->cursor.pos.y = Y; 551 552 if (!This->cursor.software) 553 ID3DPresent_SetCursorPos(swap->present, &This->cursor.pos); 554} 555 556BOOL WINAPI 557NineDevice9_ShowCursor( struct NineDevice9 *This, 558 BOOL bShow ) 559{ 560 BOOL old = This->cursor.visible; 561 562 DBG("This=%p bShow=%d\n", This, (int) bShow); 563 564 This->cursor.visible = bShow && (This->cursor.hotspot.x != -1); 565 if (!This->cursor.software) 566 ID3DPresent_SetCursor(This->swapchains[0]->present, NULL, NULL, bShow); 567 568 return old; 569} 570 571HRESULT WINAPI 572NineDevice9_CreateAdditionalSwapChain( struct NineDevice9 *This, 573 D3DPRESENT_PARAMETERS *pPresentationParameters, 574 IDirect3DSwapChain9 **pSwapChain ) 575{ 576 struct NineSwapChain9 *swapchain, *tmplt = This->swapchains[0]; 577 ID3DPresent *present; 578 HRESULT hr; 579 580 DBG("This=%p pPresentationParameters=%p pSwapChain=%p\n", 581 This, pPresentationParameters, pSwapChain); 582 583 user_assert(pPresentationParameters, D3DERR_INVALIDCALL); 584 585 hr = ID3DPresentGroup_CreateAdditionalPresent(This->present, pPresentationParameters, &present); 586 587 if (FAILED(hr)) 588 return hr; 589 590 hr = NineSwapChain9_new(This, FALSE, present, pPresentationParameters, 591 tmplt->actx, 592 tmplt->params.hDeviceWindow, 593 &swapchain); 594 if (FAILED(hr)) 595 return hr; 596 597 *pSwapChain = (IDirect3DSwapChain9 *)swapchain; 598 return D3D_OK; 599} 600 601HRESULT WINAPI 602NineDevice9_GetSwapChain( struct NineDevice9 *This, 603 UINT iSwapChain, 604 IDirect3DSwapChain9 **pSwapChain ) 605{ 606 user_assert(pSwapChain != NULL, D3DERR_INVALIDCALL); 607 608 *pSwapChain = NULL; 609 user_assert(iSwapChain < This->nswapchains, D3DERR_INVALIDCALL); 610 611 NineUnknown_AddRef(NineUnknown(This->swapchains[iSwapChain])); 612 *pSwapChain = (IDirect3DSwapChain9 *)This->swapchains[iSwapChain]; 613 614 return D3D_OK; 615} 616 617UINT WINAPI 618NineDevice9_GetNumberOfSwapChains( struct NineDevice9 *This ) 619{ 620 return This->nswapchains; 621} 622 623HRESULT WINAPI 624NineDevice9_Reset( struct NineDevice9 *This, 625 D3DPRESENT_PARAMETERS *pPresentationParameters ) 626{ 627 HRESULT hr = D3D_OK; 628 unsigned i; 629 630 DBG("This=%p pPresentationParameters=%p\n", This, pPresentationParameters); 631 632 for (i = 0; i < This->nswapchains; ++i) { 633 D3DPRESENT_PARAMETERS *params = &pPresentationParameters[i]; 634 hr = NineSwapChain9_Resize(This->swapchains[i], params, NULL); 635 if (FAILED(hr)) 636 return (hr == D3DERR_OUTOFVIDEOMEMORY) ? hr : D3DERR_DEVICELOST; 637 } 638 639 nine_pipe_context_clear(This); 640 nine_state_clear(&This->state, TRUE); 641 642 NineDevice9_SetDefaultState(This, TRUE); 643 NineDevice9_SetRenderTarget( 644 This, 0, (IDirect3DSurface9 *)This->swapchains[0]->buffers[0]); 645 /* XXX: better use GetBackBuffer here ? */ 646 647 return hr; 648} 649 650HRESULT WINAPI 651NineDevice9_Present( struct NineDevice9 *This, 652 const RECT *pSourceRect, 653 const RECT *pDestRect, 654 HWND hDestWindowOverride, 655 const RGNDATA *pDirtyRegion ) 656{ 657 unsigned i; 658 HRESULT hr; 659 660 DBG("This=%p pSourceRect=%p pDestRect=%p hDestWindowOverride=%p pDirtyRegion=%p\n", 661 This, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); 662 663 /* XXX is this right? */ 664 for (i = 0; i < This->nswapchains; ++i) { 665 hr = NineSwapChain9_Present(This->swapchains[i], pSourceRect, pDestRect, 666 hDestWindowOverride, pDirtyRegion, 0); 667 if (FAILED(hr)) { return hr; } 668 } 669 670 return D3D_OK; 671} 672 673HRESULT WINAPI 674NineDevice9_GetBackBuffer( struct NineDevice9 *This, 675 UINT iSwapChain, 676 UINT iBackBuffer, 677 D3DBACKBUFFER_TYPE Type, 678 IDirect3DSurface9 **ppBackBuffer ) 679{ 680 user_assert(ppBackBuffer != NULL, D3DERR_INVALIDCALL); 681 user_assert(iSwapChain < This->nswapchains, D3DERR_INVALIDCALL); 682 683 return NineSwapChain9_GetBackBuffer(This->swapchains[iSwapChain], 684 iBackBuffer, Type, ppBackBuffer); 685} 686 687HRESULT WINAPI 688NineDevice9_GetRasterStatus( struct NineDevice9 *This, 689 UINT iSwapChain, 690 D3DRASTER_STATUS *pRasterStatus ) 691{ 692 user_assert(pRasterStatus != NULL, D3DERR_INVALIDCALL); 693 user_assert(iSwapChain < This->nswapchains, D3DERR_INVALIDCALL); 694 695 return NineSwapChain9_GetRasterStatus(This->swapchains[iSwapChain], 696 pRasterStatus); 697} 698 699HRESULT WINAPI 700NineDevice9_SetDialogBoxMode( struct NineDevice9 *This, 701 BOOL bEnableDialogs ) 702{ 703 STUB(D3DERR_INVALIDCALL); 704} 705 706void WINAPI 707NineDevice9_SetGammaRamp( struct NineDevice9 *This, 708 UINT iSwapChain, 709 DWORD Flags, 710 const D3DGAMMARAMP *pRamp ) 711{ 712 DBG("This=%p iSwapChain=%u Flags=%x pRamp=%p\n", This, 713 iSwapChain, Flags, pRamp); 714 715 user_warn(iSwapChain >= This->nswapchains); 716 user_warn(!pRamp); 717 718 if (pRamp && (iSwapChain < This->nswapchains)) { 719 struct NineSwapChain9 *swap = This->swapchains[iSwapChain]; 720 swap->gamma = *pRamp; 721 ID3DPresent_SetGammaRamp(swap->present, pRamp, swap->params.hDeviceWindow); 722 } 723} 724 725void WINAPI 726NineDevice9_GetGammaRamp( struct NineDevice9 *This, 727 UINT iSwapChain, 728 D3DGAMMARAMP *pRamp ) 729{ 730 DBG("This=%p iSwapChain=%u pRamp=%p\n", This, iSwapChain, pRamp); 731 732 user_warn(iSwapChain >= This->nswapchains); 733 user_warn(!pRamp); 734 735 if (pRamp && (iSwapChain < This->nswapchains)) 736 *pRamp = This->swapchains[iSwapChain]->gamma; 737} 738 739HRESULT WINAPI 740NineDevice9_CreateTexture( struct NineDevice9 *This, 741 UINT Width, 742 UINT Height, 743 UINT Levels, 744 DWORD Usage, 745 D3DFORMAT Format, 746 D3DPOOL Pool, 747 IDirect3DTexture9 **ppTexture, 748 HANDLE *pSharedHandle ) 749{ 750 struct NineTexture9 *tex; 751 HRESULT hr; 752 753 DBG("This=%p Width=%u Height=%u Levels=%u Usage=%s Format=%s Pool=%s " 754 "ppOut=%p pSharedHandle=%p\n", This, Width, Height, Levels, 755 nine_D3DUSAGE_to_str(Usage), d3dformat_to_string(Format), 756 nine_D3DPOOL_to_str(Pool), ppTexture, pSharedHandle); 757 758 Usage &= D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_DMAP | 759 D3DUSAGE_DYNAMIC | D3DUSAGE_NONSECURE | D3DUSAGE_RENDERTARGET | 760 D3DUSAGE_SOFTWAREPROCESSING | D3DUSAGE_TEXTAPI; 761 762 user_assert(Width && Height, D3DERR_INVALIDCALL); 763 user_assert(!pSharedHandle || This->ex, D3DERR_INVALIDCALL); 764 /* When is used shared handle, Pool must be 765 * SYSTEMMEM with Levels 1 or DEFAULT with any Levels */ 766 user_assert(!pSharedHandle || Pool != D3DPOOL_SYSTEMMEM || Levels == 1, 767 D3DERR_INVALIDCALL); 768 user_assert(!pSharedHandle || Pool == D3DPOOL_SYSTEMMEM || Pool == D3DPOOL_DEFAULT, 769 D3DERR_INVALIDCALL); 770 user_assert((Usage != D3DUSAGE_AUTOGENMIPMAP || Levels <= 1), D3DERR_INVALIDCALL); 771 772 hr = NineTexture9_new(This, Width, Height, Levels, Usage, Format, Pool, 773 &tex, pSharedHandle); 774 if (SUCCEEDED(hr)) 775 *ppTexture = (IDirect3DTexture9 *)tex; 776 777 return hr; 778} 779 780HRESULT WINAPI 781NineDevice9_CreateVolumeTexture( struct NineDevice9 *This, 782 UINT Width, 783 UINT Height, 784 UINT Depth, 785 UINT Levels, 786 DWORD Usage, 787 D3DFORMAT Format, 788 D3DPOOL Pool, 789 IDirect3DVolumeTexture9 **ppVolumeTexture, 790 HANDLE *pSharedHandle ) 791{ 792 struct NineVolumeTexture9 *tex; 793 HRESULT hr; 794 795 DBG("This=%p Width=%u Height=%u Depth=%u Levels=%u Usage=%s Format=%s Pool=%s " 796 "ppOut=%p pSharedHandle=%p\n", This, Width, Height, Depth, Levels, 797 nine_D3DUSAGE_to_str(Usage), d3dformat_to_string(Format), 798 nine_D3DPOOL_to_str(Pool), ppVolumeTexture, pSharedHandle); 799 800 Usage &= D3DUSAGE_DYNAMIC | D3DUSAGE_NONSECURE | 801 D3DUSAGE_SOFTWAREPROCESSING; 802 803 user_assert(Width && Height && Depth, D3DERR_INVALIDCALL); 804 user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 805 806 hr = NineVolumeTexture9_new(This, Width, Height, Depth, Levels, 807 Usage, Format, Pool, &tex, pSharedHandle); 808 if (SUCCEEDED(hr)) 809 *ppVolumeTexture = (IDirect3DVolumeTexture9 *)tex; 810 811 return hr; 812} 813 814HRESULT WINAPI 815NineDevice9_CreateCubeTexture( struct NineDevice9 *This, 816 UINT EdgeLength, 817 UINT Levels, 818 DWORD Usage, 819 D3DFORMAT Format, 820 D3DPOOL Pool, 821 IDirect3DCubeTexture9 **ppCubeTexture, 822 HANDLE *pSharedHandle ) 823{ 824 struct NineCubeTexture9 *tex; 825 HRESULT hr; 826 827 DBG("This=%p EdgeLength=%u Levels=%u Usage=%s Format=%s Pool=%s ppOut=%p " 828 "pSharedHandle=%p\n", This, EdgeLength, Levels, 829 nine_D3DUSAGE_to_str(Usage), d3dformat_to_string(Format), 830 nine_D3DPOOL_to_str(Pool), ppCubeTexture, pSharedHandle); 831 832 Usage &= D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_DYNAMIC | 833 D3DUSAGE_NONSECURE | D3DUSAGE_RENDERTARGET | 834 D3DUSAGE_SOFTWAREPROCESSING; 835 836 user_assert(EdgeLength, D3DERR_INVALIDCALL); 837 user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 838 839 hr = NineCubeTexture9_new(This, EdgeLength, Levels, Usage, Format, Pool, 840 &tex, pSharedHandle); 841 if (SUCCEEDED(hr)) 842 *ppCubeTexture = (IDirect3DCubeTexture9 *)tex; 843 844 return hr; 845} 846 847HRESULT WINAPI 848NineDevice9_CreateVertexBuffer( struct NineDevice9 *This, 849 UINT Length, 850 DWORD Usage, 851 DWORD FVF, 852 D3DPOOL Pool, 853 IDirect3DVertexBuffer9 **ppVertexBuffer, 854 HANDLE *pSharedHandle ) 855{ 856 struct NineVertexBuffer9 *buf; 857 HRESULT hr; 858 D3DVERTEXBUFFER_DESC desc; 859 860 DBG("This=%p Length=%u Usage=%x FVF=%x Pool=%u ppOut=%p pSharedHandle=%p\n", 861 This, Length, Usage, FVF, Pool, ppVertexBuffer, pSharedHandle); 862 863 user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT, D3DERR_NOTAVAILABLE); 864 865 desc.Format = D3DFMT_VERTEXDATA; 866 desc.Type = D3DRTYPE_VERTEXBUFFER; 867 desc.Usage = Usage & 868 (D3DUSAGE_DONOTCLIP | D3DUSAGE_DYNAMIC | D3DUSAGE_NONSECURE | 869 D3DUSAGE_NPATCHES | D3DUSAGE_POINTS | D3DUSAGE_RTPATCHES | 870 D3DUSAGE_SOFTWAREPROCESSING | D3DUSAGE_TEXTAPI | 871 D3DUSAGE_WRITEONLY); 872 desc.Pool = Pool; 873 desc.Size = Length; 874 desc.FVF = FVF; 875 876 user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 877 user_assert(desc.Usage == Usage, D3DERR_INVALIDCALL); 878 879 hr = NineVertexBuffer9_new(This, &desc, &buf); 880 if (SUCCEEDED(hr)) 881 *ppVertexBuffer = (IDirect3DVertexBuffer9 *)buf; 882 return hr; 883} 884 885HRESULT WINAPI 886NineDevice9_CreateIndexBuffer( struct NineDevice9 *This, 887 UINT Length, 888 DWORD Usage, 889 D3DFORMAT Format, 890 D3DPOOL Pool, 891 IDirect3DIndexBuffer9 **ppIndexBuffer, 892 HANDLE *pSharedHandle ) 893{ 894 struct NineIndexBuffer9 *buf; 895 HRESULT hr; 896 D3DINDEXBUFFER_DESC desc; 897 898 DBG("This=%p Length=%u Usage=%x Format=%s Pool=%u ppOut=%p " 899 "pSharedHandle=%p\n", This, Length, Usage, 900 d3dformat_to_string(Format), Pool, ppIndexBuffer, pSharedHandle); 901 902 user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT, D3DERR_NOTAVAILABLE); 903 904 desc.Format = Format; 905 desc.Type = D3DRTYPE_INDEXBUFFER; 906 desc.Usage = Usage & 907 (D3DUSAGE_DONOTCLIP | D3DUSAGE_DYNAMIC | D3DUSAGE_NONSECURE | 908 D3DUSAGE_NPATCHES | D3DUSAGE_POINTS | D3DUSAGE_RTPATCHES | 909 D3DUSAGE_SOFTWAREPROCESSING | D3DUSAGE_WRITEONLY); 910 desc.Pool = Pool; 911 desc.Size = Length; 912 913 user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 914 user_assert(desc.Usage == Usage, D3DERR_INVALIDCALL); 915 916 hr = NineIndexBuffer9_new(This, &desc, &buf); 917 if (SUCCEEDED(hr)) 918 *ppIndexBuffer = (IDirect3DIndexBuffer9 *)buf; 919 return hr; 920} 921 922static HRESULT 923create_zs_or_rt_surface(struct NineDevice9 *This, 924 unsigned type, /* 0 = RT, 1 = ZS, 2 = plain */ 925 D3DPOOL Pool, 926 UINT Width, UINT Height, 927 D3DFORMAT Format, 928 D3DMULTISAMPLE_TYPE MultiSample, 929 DWORD MultisampleQuality, 930 BOOL Discard_or_Lockable, 931 IDirect3DSurface9 **ppSurface, 932 HANDLE *pSharedHandle) 933{ 934 struct NineSurface9 *surface; 935 struct pipe_screen *screen = This->screen; 936 struct pipe_resource *resource = NULL; 937 HRESULT hr; 938 D3DSURFACE_DESC desc; 939 struct pipe_resource templ; 940 941 DBG("This=%p type=%u Pool=%s Width=%u Height=%u Format=%s MS=%u Quality=%u " 942 "Discard_or_Lockable=%i ppSurface=%p pSharedHandle=%p\n", 943 This, type, nine_D3DPOOL_to_str(Pool), Width, Height, 944 d3dformat_to_string(Format), MultiSample, MultisampleQuality, 945 Discard_or_Lockable, ppSurface, pSharedHandle); 946 947 if (pSharedHandle) 948 DBG("FIXME Used shared handle! This option isn't probably handled correctly!\n"); 949 950 user_assert(Width && Height, D3DERR_INVALIDCALL); 951 user_assert(Pool != D3DPOOL_MANAGED, D3DERR_INVALIDCALL); 952 953 templ.target = PIPE_TEXTURE_2D; 954 templ.format = d3d9_to_pipe_format(Format); 955 templ.width0 = Width; 956 templ.height0 = Height; 957 templ.depth0 = 1; 958 templ.array_size = 1; 959 templ.last_level = 0; 960 templ.nr_samples = (unsigned)MultiSample; 961 templ.usage = PIPE_USAGE_DEFAULT; 962 templ.flags = 0; 963 templ.bind = PIPE_BIND_SAMPLER_VIEW; /* StretchRect */ 964 switch (type) { 965 case 0: templ.bind |= PIPE_BIND_RENDER_TARGET; break; 966 case 1: templ.bind |= PIPE_BIND_DEPTH_STENCIL; break; 967 default: 968 assert(type == 2); 969 break; 970 } 971 972 desc.Format = Format; 973 desc.Type = D3DRTYPE_SURFACE; 974 desc.Usage = 0; 975 desc.Pool = Pool; 976 desc.MultiSampleType = MultiSample; 977 desc.MultiSampleQuality = MultisampleQuality; 978 desc.Width = Width; 979 desc.Height = Height; 980 switch (type) { 981 case 0: desc.Usage = D3DUSAGE_RENDERTARGET; break; 982 case 1: desc.Usage = D3DUSAGE_DEPTHSTENCIL; break; 983 default: break; 984 } 985 986 if (Pool == D3DPOOL_DEFAULT && Format != D3DFMT_NULL) { 987 /* resource_create doesn't return an error code, so check format here */ 988 user_assert(CHECK_PIPE_RESOURCE_TEMPLATE(templ), D3DERR_INVALIDCALL); 989 resource = screen->resource_create(screen, &templ); 990 user_assert(resource, D3DERR_OUTOFVIDEOMEMORY); 991 if (Discard_or_Lockable && (desc.Usage & D3DUSAGE_RENDERTARGET)) 992 resource->flags |= NINE_RESOURCE_FLAG_LOCKABLE; 993 } else { 994 resource = NULL; 995 } 996 hr = NineSurface9_new(This, NULL, resource, NULL, 0, 0, 0, &desc, &surface); 997 pipe_resource_reference(&resource, NULL); 998 999 if (SUCCEEDED(hr)) 1000 *ppSurface = (IDirect3DSurface9 *)surface; 1001 return hr; 1002} 1003 1004HRESULT WINAPI 1005NineDevice9_CreateRenderTarget( struct NineDevice9 *This, 1006 UINT Width, 1007 UINT Height, 1008 D3DFORMAT Format, 1009 D3DMULTISAMPLE_TYPE MultiSample, 1010 DWORD MultisampleQuality, 1011 BOOL Lockable, 1012 IDirect3DSurface9 **ppSurface, 1013 HANDLE *pSharedHandle ) 1014{ 1015 return create_zs_or_rt_surface(This, 0, D3DPOOL_DEFAULT, 1016 Width, Height, Format, 1017 MultiSample, MultisampleQuality, 1018 Lockable, ppSurface, pSharedHandle); 1019} 1020 1021HRESULT WINAPI 1022NineDevice9_CreateDepthStencilSurface( struct NineDevice9 *This, 1023 UINT Width, 1024 UINT Height, 1025 D3DFORMAT Format, 1026 D3DMULTISAMPLE_TYPE MultiSample, 1027 DWORD MultisampleQuality, 1028 BOOL Discard, 1029 IDirect3DSurface9 **ppSurface, 1030 HANDLE *pSharedHandle ) 1031{ 1032 return create_zs_or_rt_surface(This, 1, D3DPOOL_DEFAULT, 1033 Width, Height, Format, 1034 MultiSample, MultisampleQuality, 1035 Discard, ppSurface, pSharedHandle); 1036} 1037 1038HRESULT WINAPI 1039NineDevice9_UpdateSurface( struct NineDevice9 *This, 1040 IDirect3DSurface9 *pSourceSurface, 1041 const RECT *pSourceRect, 1042 IDirect3DSurface9 *pDestinationSurface, 1043 const POINT *pDestPoint ) 1044{ 1045 struct NineSurface9 *dst = NineSurface9(pDestinationSurface); 1046 struct NineSurface9 *src = NineSurface9(pSourceSurface); 1047 1048 DBG("This=%p pSourceSurface=%p pDestinationSurface=%p " 1049 "pSourceRect=%p pDestPoint=%p\n", This, 1050 pSourceSurface, pDestinationSurface, pSourceRect, pDestPoint); 1051 if (pSourceRect) 1052 DBG("pSourceRect = (%u,%u)-(%u,%u)\n", 1053 pSourceRect->left, pSourceRect->top, 1054 pSourceRect->right, pSourceRect->bottom); 1055 if (pDestPoint) 1056 DBG("pDestPoint = (%u,%u)\n", pDestPoint->x, pDestPoint->y); 1057 1058 user_assert(dst->base.pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 1059 user_assert(src->base.pool == D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL); 1060 1061 user_assert(dst->desc.MultiSampleType == D3DMULTISAMPLE_NONE, D3DERR_INVALIDCALL); 1062 user_assert(src->desc.MultiSampleType == D3DMULTISAMPLE_NONE, D3DERR_INVALIDCALL); 1063 1064 return NineSurface9_CopySurface(dst, src, pDestPoint, pSourceRect); 1065} 1066 1067HRESULT WINAPI 1068NineDevice9_UpdateTexture( struct NineDevice9 *This, 1069 IDirect3DBaseTexture9 *pSourceTexture, 1070 IDirect3DBaseTexture9 *pDestinationTexture ) 1071{ 1072 struct NineBaseTexture9 *dstb = NineBaseTexture9(pDestinationTexture); 1073 struct NineBaseTexture9 *srcb = NineBaseTexture9(pSourceTexture); 1074 unsigned l, m; 1075 unsigned last_level = dstb->base.info.last_level; 1076 1077 DBG("This=%p pSourceTexture=%p pDestinationTexture=%p\n", This, 1078 pSourceTexture, pDestinationTexture); 1079 1080 user_assert(pSourceTexture != pDestinationTexture, D3DERR_INVALIDCALL); 1081 1082 user_assert(dstb->base.pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 1083 user_assert(srcb->base.pool == D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL); 1084 1085 if (dstb->base.usage & D3DUSAGE_AUTOGENMIPMAP) { 1086 /* Only the first level is updated, the others regenerated. */ 1087 last_level = 0; 1088 } else { 1089 user_assert(!(srcb->base.usage & D3DUSAGE_AUTOGENMIPMAP), D3DERR_INVALIDCALL); 1090 } 1091 1092 user_assert(dstb->base.type == srcb->base.type, D3DERR_INVALIDCALL); 1093 1094 /* TODO: We can restrict the update to the dirty portions of the source. 1095 * Yes, this seems silly, but it's what MSDN says ... 1096 */ 1097 1098 /* Find src level that matches dst level 0: */ 1099 user_assert(srcb->base.info.width0 >= dstb->base.info.width0 && 1100 srcb->base.info.height0 >= dstb->base.info.height0 && 1101 srcb->base.info.depth0 >= dstb->base.info.depth0, 1102 D3DERR_INVALIDCALL); 1103 for (m = 0; m <= srcb->base.info.last_level; ++m) { 1104 unsigned w = u_minify(srcb->base.info.width0, m); 1105 unsigned h = u_minify(srcb->base.info.height0, m); 1106 unsigned d = u_minify(srcb->base.info.depth0, m); 1107 1108 if (w == dstb->base.info.width0 && 1109 h == dstb->base.info.height0 && 1110 d == dstb->base.info.depth0) 1111 break; 1112 } 1113 user_assert(m <= srcb->base.info.last_level, D3DERR_INVALIDCALL); 1114 1115 last_level = MIN2(last_level, srcb->base.info.last_level - m); 1116 1117 if (dstb->base.type == D3DRTYPE_TEXTURE) { 1118 struct NineTexture9 *dst = NineTexture9(dstb); 1119 struct NineTexture9 *src = NineTexture9(srcb); 1120 1121 for (l = 0; l <= last_level; ++l, ++m) 1122 NineSurface9_CopySurface(dst->surfaces[l], 1123 src->surfaces[m], NULL, NULL); 1124 } else 1125 if (dstb->base.type == D3DRTYPE_CUBETEXTURE) { 1126 struct NineCubeTexture9 *dst = NineCubeTexture9(dstb); 1127 struct NineCubeTexture9 *src = NineCubeTexture9(srcb); 1128 unsigned z; 1129 1130 /* GPUs usually have them stored as arrays of mip-mapped 2D textures. */ 1131 for (z = 0; z < 6; ++z) { 1132 for (l = 0; l <= last_level; ++l, ++m) { 1133 NineSurface9_CopySurface(dst->surfaces[l * 6 + z], 1134 src->surfaces[m * 6 + z], NULL, NULL); 1135 } 1136 m -= l; 1137 } 1138 } else 1139 if (dstb->base.type == D3DRTYPE_VOLUMETEXTURE) { 1140 struct NineVolumeTexture9 *dst = NineVolumeTexture9(dstb); 1141 struct NineVolumeTexture9 *src = NineVolumeTexture9(srcb); 1142 1143 for (l = 0; l <= last_level; ++l, ++m) 1144 NineVolume9_CopyVolume(dst->volumes[l], 1145 src->volumes[m], 0, 0, 0, NULL); 1146 } else{ 1147 assert(!"invalid texture type"); 1148 } 1149 1150 if (dstb->base.usage & D3DUSAGE_AUTOGENMIPMAP) 1151 NineBaseTexture9_GenerateMipSubLevels(dstb); 1152 1153 return D3D_OK; 1154} 1155 1156HRESULT WINAPI 1157NineDevice9_GetRenderTargetData( struct NineDevice9 *This, 1158 IDirect3DSurface9 *pRenderTarget, 1159 IDirect3DSurface9 *pDestSurface ) 1160{ 1161 struct NineSurface9 *dst = NineSurface9(pDestSurface); 1162 struct NineSurface9 *src = NineSurface9(pRenderTarget); 1163 1164 DBG("This=%p pRenderTarget=%p pDestSurface=%p\n", 1165 This, pRenderTarget, pDestSurface); 1166 1167 user_assert(dst->desc.Pool == D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL); 1168 user_assert(src->desc.Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 1169 1170 user_assert(dst->desc.MultiSampleType < 2, D3DERR_INVALIDCALL); 1171 user_assert(src->desc.MultiSampleType < 2, D3DERR_INVALIDCALL); 1172 1173 return NineSurface9_CopySurface(dst, src, NULL, NULL); 1174} 1175 1176HRESULT WINAPI 1177NineDevice9_GetFrontBufferData( struct NineDevice9 *This, 1178 UINT iSwapChain, 1179 IDirect3DSurface9 *pDestSurface ) 1180{ 1181 DBG("This=%p iSwapChain=%u pDestSurface=%p\n", This, 1182 iSwapChain, pDestSurface); 1183 1184 user_assert(pDestSurface != NULL, D3DERR_INVALIDCALL); 1185 user_assert(iSwapChain < This->nswapchains, D3DERR_INVALIDCALL); 1186 1187 return NineSwapChain9_GetFrontBufferData(This->swapchains[iSwapChain], 1188 pDestSurface); 1189} 1190 1191HRESULT WINAPI 1192NineDevice9_StretchRect( struct NineDevice9 *This, 1193 IDirect3DSurface9 *pSourceSurface, 1194 const RECT *pSourceRect, 1195 IDirect3DSurface9 *pDestSurface, 1196 const RECT *pDestRect, 1197 D3DTEXTUREFILTERTYPE Filter ) 1198{ 1199 struct pipe_screen *screen = This->screen; 1200 struct pipe_context *pipe = This->pipe; 1201 struct NineSurface9 *dst = NineSurface9(pDestSurface); 1202 struct NineSurface9 *src = NineSurface9(pSourceSurface); 1203 struct pipe_resource *dst_res = NineSurface9_GetResource(dst); 1204 struct pipe_resource *src_res = NineSurface9_GetResource(src); 1205 const boolean zs = util_format_is_depth_or_stencil(dst_res->format); 1206 struct pipe_blit_info blit; 1207 boolean scaled, clamped, ms, flip_x = FALSE, flip_y = FALSE; 1208 1209 DBG("This=%p pSourceSurface=%p pSourceRect=%p pDestSurface=%p " 1210 "pDestRect=%p Filter=%u\n", 1211 This, pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter); 1212 if (pSourceRect) 1213 DBG("pSourceRect=(%u,%u)-(%u,%u)\n", 1214 pSourceRect->left, pSourceRect->top, 1215 pSourceRect->right, pSourceRect->bottom); 1216 if (pDestRect) 1217 DBG("pDestRect=(%u,%u)-(%u,%u)\n", pDestRect->left, pDestRect->top, 1218 pDestRect->right, pDestRect->bottom); 1219 1220 user_assert(!zs || !This->in_scene, D3DERR_INVALIDCALL); 1221 user_assert(!zs || !pSourceRect || 1222 (pSourceRect->left == 0 && 1223 pSourceRect->top == 0 && 1224 pSourceRect->right == src->desc.Width && 1225 pSourceRect->bottom == src->desc.Height), D3DERR_INVALIDCALL); 1226 user_assert(!zs || !pDestRect || 1227 (pDestRect->left == 0 && 1228 pDestRect->top == 0 && 1229 pDestRect->right == dst->desc.Width && 1230 pDestRect->bottom == dst->desc.Height), D3DERR_INVALIDCALL); 1231 user_assert(!zs || 1232 (dst->desc.Width == src->desc.Width && 1233 dst->desc.Height == src->desc.Height), D3DERR_INVALIDCALL); 1234 user_assert(zs || !util_format_is_depth_or_stencil(src_res->format), 1235 D3DERR_INVALIDCALL); 1236 user_assert(!zs || dst->desc.Format == src->desc.Format, 1237 D3DERR_INVALIDCALL); 1238 user_assert(screen->is_format_supported(screen, src_res->format, 1239 src_res->target, 1240 src_res->nr_samples, 1241 PIPE_BIND_SAMPLER_VIEW), 1242 D3DERR_INVALIDCALL); 1243 user_assert(dst->base.pool == D3DPOOL_DEFAULT && 1244 src->base.pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 1245 1246 /* We might want to permit these, but wine thinks we shouldn't. */ 1247 user_assert(!pDestRect || 1248 (pDestRect->left <= pDestRect->right && 1249 pDestRect->top <= pDestRect->bottom), D3DERR_INVALIDCALL); 1250 user_assert(!pSourceRect || 1251 (pSourceRect->left <= pSourceRect->right && 1252 pSourceRect->top <= pSourceRect->bottom), D3DERR_INVALIDCALL); 1253 1254 blit.dst.resource = dst_res; 1255 blit.dst.level = dst->level; 1256 blit.dst.box.z = dst->layer; 1257 blit.dst.box.depth = 1; 1258 blit.dst.format = dst_res->format; 1259 if (pDestRect) { 1260 flip_x = pDestRect->left > pDestRect->right; 1261 if (flip_x) { 1262 blit.dst.box.x = pDestRect->right; 1263 blit.dst.box.width = pDestRect->left - pDestRect->right; 1264 } else { 1265 blit.dst.box.x = pDestRect->left; 1266 blit.dst.box.width = pDestRect->right - pDestRect->left; 1267 } 1268 flip_y = pDestRect->top > pDestRect->bottom; 1269 if (flip_y) { 1270 blit.dst.box.y = pDestRect->bottom; 1271 blit.dst.box.height = pDestRect->top - pDestRect->bottom; 1272 } else { 1273 blit.dst.box.y = pDestRect->top; 1274 blit.dst.box.height = pDestRect->bottom - pDestRect->top; 1275 } 1276 } else { 1277 blit.dst.box.x = 0; 1278 blit.dst.box.y = 0; 1279 blit.dst.box.width = dst->desc.Width; 1280 blit.dst.box.height = dst->desc.Height; 1281 } 1282 blit.src.resource = src_res; 1283 blit.src.level = src->level; 1284 blit.src.box.z = src->layer; 1285 blit.src.box.depth = 1; 1286 blit.src.format = src_res->format; 1287 if (pSourceRect) { 1288 if (flip_x ^ (pSourceRect->left > pSourceRect->right)) { 1289 blit.src.box.x = pSourceRect->right; 1290 blit.src.box.width = pSourceRect->left - pSourceRect->right; 1291 } else { 1292 blit.src.box.x = pSourceRect->left; 1293 blit.src.box.width = pSourceRect->right - pSourceRect->left; 1294 } 1295 if (flip_y ^ (pSourceRect->top > pSourceRect->bottom)) { 1296 blit.src.box.y = pSourceRect->bottom; 1297 blit.src.box.height = pSourceRect->top - pSourceRect->bottom; 1298 } else { 1299 blit.src.box.y = pSourceRect->top; 1300 blit.src.box.height = pSourceRect->bottom - pSourceRect->top; 1301 } 1302 } else { 1303 blit.src.box.x = flip_x ? src->desc.Width : 0; 1304 blit.src.box.y = flip_y ? src->desc.Height : 0; 1305 blit.src.box.width = flip_x ? -src->desc.Width : src->desc.Width; 1306 blit.src.box.height = flip_y ? -src->desc.Height : src->desc.Height; 1307 } 1308 blit.mask = zs ? PIPE_MASK_ZS : PIPE_MASK_RGBA; 1309 blit.filter = Filter == D3DTEXF_LINEAR ? 1310 PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST; 1311 blit.scissor_enable = FALSE; 1312 1313 /* If both of a src and dst dimension are negative, flip them. */ 1314 if (blit.dst.box.width < 0 && blit.src.box.width < 0) { 1315 blit.dst.box.width = -blit.dst.box.width; 1316 blit.src.box.width = -blit.src.box.width; 1317 } 1318 if (blit.dst.box.height < 0 && blit.src.box.height < 0) { 1319 blit.dst.box.height = -blit.dst.box.height; 1320 blit.src.box.height = -blit.src.box.height; 1321 } 1322 scaled = 1323 blit.dst.box.width != blit.src.box.width || 1324 blit.dst.box.height != blit.src.box.height; 1325 1326 user_assert(!scaled || dst != src, D3DERR_INVALIDCALL); 1327 user_assert(!scaled || 1328 !NineSurface9_IsOffscreenPlain(dst) || 1329 NineSurface9_IsOffscreenPlain(src), D3DERR_INVALIDCALL); 1330 user_assert(!scaled || 1331 (!util_format_is_compressed(dst->base.info.format) && 1332 !util_format_is_compressed(src->base.info.format)), 1333 D3DERR_INVALIDCALL); 1334 1335 user_warn(src == dst && 1336 u_box_test_intersection_2d(&blit.src.box, &blit.dst.box)); 1337 1338 /* Check for clipping/clamping: */ 1339 { 1340 struct pipe_box box; 1341 int xy; 1342 1343 xy = u_box_clip_2d(&box, &blit.dst.box, 1344 dst->desc.Width, dst->desc.Height); 1345 if (xy < 0) 1346 return D3D_OK; 1347 if (xy == 0) 1348 xy = u_box_clip_2d(&box, &blit.src.box, 1349 src->desc.Width, src->desc.Height); 1350 clamped = !!xy; 1351 } 1352 1353 ms = (dst->desc.MultiSampleType | 1) != (src->desc.MultiSampleType | 1); 1354 1355 if (clamped || scaled || (blit.dst.format != blit.src.format) || ms) { 1356 DBG("using pipe->blit()\n"); 1357 /* TODO: software scaling */ 1358 user_assert(screen->is_format_supported(screen, dst_res->format, 1359 dst_res->target, 1360 dst_res->nr_samples, 1361 zs ? PIPE_BIND_DEPTH_STENCIL : 1362 PIPE_BIND_RENDER_TARGET), 1363 D3DERR_INVALIDCALL); 1364 1365 pipe->blit(pipe, &blit); 1366 } else { 1367 assert(blit.dst.box.x >= 0 && blit.dst.box.y >= 0 && 1368 blit.src.box.x >= 0 && blit.src.box.y >= 0 && 1369 blit.dst.box.x + blit.dst.box.width <= dst->desc.Width && 1370 blit.src.box.x + blit.src.box.width <= src->desc.Width && 1371 blit.dst.box.y + blit.dst.box.height <= dst->desc.Height && 1372 blit.src.box.y + blit.src.box.height <= src->desc.Height); 1373 /* Or drivers might crash ... */ 1374 DBG("Using resource_copy_region.\n"); 1375 pipe->resource_copy_region(pipe, 1376 blit.dst.resource, blit.dst.level, 1377 blit.dst.box.x, blit.dst.box.y, blit.dst.box.z, 1378 blit.src.resource, blit.src.level, 1379 &blit.src.box); 1380 } 1381 1382 return D3D_OK; 1383} 1384 1385HRESULT WINAPI 1386NineDevice9_ColorFill( struct NineDevice9 *This, 1387 IDirect3DSurface9 *pSurface, 1388 const RECT *pRect, 1389 D3DCOLOR color ) 1390{ 1391 struct pipe_context *pipe = This->pipe; 1392 struct NineSurface9 *surf = NineSurface9(pSurface); 1393 struct pipe_surface *psurf; 1394 unsigned x, y, w, h; 1395 union pipe_color_union rgba; 1396 boolean fallback; 1397 1398 DBG("This=%p pSurface=%p pRect=%p color=%08x\n", This, 1399 pSurface, pRect, color); 1400 if (pRect) 1401 DBG("pRect=(%u,%u)-(%u,%u)\n", pRect->left, pRect->top, 1402 pRect->right, pRect->bottom); 1403 1404 user_assert(surf->base.pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 1405 1406 user_assert((surf->base.usage & D3DUSAGE_RENDERTARGET) || 1407 NineSurface9_IsOffscreenPlain(surf), D3DERR_INVALIDCALL); 1408 1409 if (pRect) { 1410 x = pRect->left; 1411 y = pRect->top; 1412 w = pRect->right - pRect->left; 1413 h = pRect->bottom - pRect->top; 1414 } else{ 1415 x = 0; 1416 y = 0; 1417 w = surf->desc.Width; 1418 h = surf->desc.Height; 1419 } 1420 d3dcolor_to_pipe_color_union(&rgba, color); 1421 1422 fallback = 1423 !This->screen->is_format_supported(This->screen, surf->base.info.format, 1424 surf->base.info.target, 1425 surf->base.info.nr_samples, 1426 PIPE_BIND_RENDER_TARGET); 1427 if (!fallback) { 1428 psurf = NineSurface9_GetSurface(surf, 0); 1429 if (!psurf) 1430 fallback = TRUE; 1431 } 1432 1433 if (!fallback) { 1434 pipe->clear_render_target(pipe, psurf, &rgba, x, y, w, h); 1435 } else { 1436 D3DLOCKED_RECT lock; 1437 union util_color uc; 1438 HRESULT hr; 1439 /* XXX: lock pRect and fix util_fill_rect */ 1440 hr = NineSurface9_LockRect(surf, &lock, NULL, 0); 1441 if (FAILED(hr)) 1442 return hr; 1443 util_pack_color_ub(color >> 16, color >> 8, color >> 0, color >> 24, 1444 surf->base.info.format, &uc); 1445 util_fill_rect(lock.pBits, surf->base.info.format,lock.Pitch, 1446 x, y, w, h, &uc); 1447 NineSurface9_UnlockRect(surf); 1448 } 1449 1450 return D3D_OK; 1451} 1452 1453HRESULT WINAPI 1454NineDevice9_CreateOffscreenPlainSurface( struct NineDevice9 *This, 1455 UINT Width, 1456 UINT Height, 1457 D3DFORMAT Format, 1458 D3DPOOL Pool, 1459 IDirect3DSurface9 **ppSurface, 1460 HANDLE *pSharedHandle ) 1461{ 1462 HRESULT hr; 1463 1464 DBG("This=%p Width=%u Height=%u Format=%s(0x%x) Pool=%u " 1465 "ppSurface=%p pSharedHandle=%p\n", This, 1466 Width, Height, d3dformat_to_string(Format), Format, Pool, 1467 ppSurface, pSharedHandle); 1468 1469 user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT 1470 || Pool == D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL); 1471 user_assert(Pool != D3DPOOL_MANAGED, D3DERR_INVALIDCALL); 1472 1473 /* Can be used with StretchRect and ColorFill. It's also always lockable. 1474 */ 1475 hr = create_zs_or_rt_surface(This, 2, Pool, Width, Height, 1476 Format, 1477 D3DMULTISAMPLE_NONE, 0, 1478 TRUE, 1479 ppSurface, pSharedHandle); 1480 if (FAILED(hr)) 1481 DBG("Failed to create surface.\n"); 1482 return hr; 1483} 1484 1485HRESULT WINAPI 1486NineDevice9_SetRenderTarget( struct NineDevice9 *This, 1487 DWORD RenderTargetIndex, 1488 IDirect3DSurface9 *pRenderTarget ) 1489{ 1490 struct NineSurface9 *rt = NineSurface9(pRenderTarget); 1491 const unsigned i = RenderTargetIndex; 1492 1493 DBG("This=%p RenderTargetIndex=%u pRenderTarget=%p\n", This, 1494 RenderTargetIndex, pRenderTarget); 1495 1496 user_assert(i < This->caps.NumSimultaneousRTs, D3DERR_INVALIDCALL); 1497 user_assert(i != 0 || pRenderTarget, D3DERR_INVALIDCALL); 1498 user_assert(!pRenderTarget || 1499 rt->desc.Usage & D3DUSAGE_RENDERTARGET, D3DERR_INVALIDCALL); 1500 1501 if (i == 0) { 1502 This->state.viewport.X = 0; 1503 This->state.viewport.Y = 0; 1504 This->state.viewport.Width = rt->desc.Width; 1505 This->state.viewport.Height = rt->desc.Height; 1506 This->state.viewport.MinZ = 0.0f; 1507 This->state.viewport.MaxZ = 1.0f; 1508 1509 This->state.scissor.minx = 0; 1510 This->state.scissor.miny = 0; 1511 This->state.scissor.maxx = rt->desc.Width; 1512 This->state.scissor.maxy = rt->desc.Height; 1513 1514 This->state.changed.group |= NINE_STATE_VIEWPORT | NINE_STATE_SCISSOR; 1515 } 1516 1517 if (This->state.rt[i] != NineSurface9(pRenderTarget)) { 1518 nine_bind(&This->state.rt[i], pRenderTarget); 1519 This->state.changed.group |= NINE_STATE_FB; 1520 } 1521 return D3D_OK; 1522} 1523 1524HRESULT WINAPI 1525NineDevice9_GetRenderTarget( struct NineDevice9 *This, 1526 DWORD RenderTargetIndex, 1527 IDirect3DSurface9 **ppRenderTarget ) 1528{ 1529 const unsigned i = RenderTargetIndex; 1530 1531 user_assert(i < This->caps.NumSimultaneousRTs, D3DERR_INVALIDCALL); 1532 user_assert(ppRenderTarget, D3DERR_INVALIDCALL); 1533 1534 *ppRenderTarget = (IDirect3DSurface9 *)This->state.rt[i]; 1535 if (!This->state.rt[i]) 1536 return D3DERR_NOTFOUND; 1537 1538 NineUnknown_AddRef(NineUnknown(This->state.rt[i])); 1539 return D3D_OK; 1540} 1541 1542HRESULT WINAPI 1543NineDevice9_SetDepthStencilSurface( struct NineDevice9 *This, 1544 IDirect3DSurface9 *pNewZStencil ) 1545{ 1546 DBG("This=%p pNewZStencil=%p\n", This, pNewZStencil); 1547 1548 if (This->state.ds != NineSurface9(pNewZStencil)) { 1549 nine_bind(&This->state.ds, pNewZStencil); 1550 This->state.changed.group |= NINE_STATE_FB; 1551 } 1552 return D3D_OK; 1553} 1554 1555HRESULT WINAPI 1556NineDevice9_GetDepthStencilSurface( struct NineDevice9 *This, 1557 IDirect3DSurface9 **ppZStencilSurface ) 1558{ 1559 user_assert(ppZStencilSurface, D3DERR_INVALIDCALL); 1560 1561 *ppZStencilSurface = (IDirect3DSurface9 *)This->state.ds; 1562 if (!This->state.ds) 1563 return D3DERR_NOTFOUND; 1564 1565 NineUnknown_AddRef(NineUnknown(This->state.ds)); 1566 return D3D_OK; 1567} 1568 1569HRESULT WINAPI 1570NineDevice9_BeginScene( struct NineDevice9 *This ) 1571{ 1572 DBG("This=%p\n", This); 1573 user_assert(!This->in_scene, D3DERR_INVALIDCALL); 1574 This->in_scene = TRUE; 1575 /* Do we want to do anything else here ? */ 1576 return D3D_OK; 1577} 1578 1579HRESULT WINAPI 1580NineDevice9_EndScene( struct NineDevice9 *This ) 1581{ 1582 DBG("This=%p\n", This); 1583 user_assert(This->in_scene, D3DERR_INVALIDCALL); 1584 This->in_scene = FALSE; 1585 return D3D_OK; 1586} 1587 1588HRESULT WINAPI 1589NineDevice9_Clear( struct NineDevice9 *This, 1590 DWORD Count, 1591 const D3DRECT *pRects, 1592 DWORD Flags, 1593 D3DCOLOR Color, 1594 float Z, 1595 DWORD Stencil ) 1596{ 1597 struct pipe_context *pipe = This->pipe; 1598 struct NineSurface9 *zsbuf = This->state.ds; 1599 unsigned bufs = 0; 1600 unsigned r, i; 1601 union pipe_color_union rgba; 1602 D3DRECT rect; 1603 1604 DBG("This=%p Count=%u pRects=%p Flags=%x Color=%08x Z=%f Stencil=%x\n", 1605 This, Count, pRects, Flags, Color, Z, Stencil); 1606 1607 user_assert(This->state.ds || !(Flags & NINED3DCLEAR_DEPTHSTENCIL), 1608 D3DERR_INVALIDCALL); 1609 user_assert(!(Flags & D3DCLEAR_STENCIL) || 1610 (zsbuf && 1611 util_format_is_depth_and_stencil(zsbuf->base.info.format)), 1612 D3DERR_INVALIDCALL); 1613#ifdef NINE_STRICT 1614 user_assert((Count && pRects) || (!Count && !pRects), D3DERR_INVALIDCALL); 1615#else 1616 user_warn((pRects && !Count) || (!pRects && Count)); 1617 if (pRects && !Count) 1618 return D3D_OK; 1619 if (!pRects) 1620 Count = 0; 1621#endif 1622 1623 if (Flags & D3DCLEAR_TARGET) bufs |= PIPE_CLEAR_COLOR; 1624 if (Flags & D3DCLEAR_ZBUFFER) bufs |= PIPE_CLEAR_DEPTH; 1625 if (Flags & D3DCLEAR_STENCIL) bufs |= PIPE_CLEAR_STENCIL; 1626 if (!bufs) 1627 return D3D_OK; 1628 d3dcolor_to_pipe_color_union(&rgba, Color); 1629 1630 nine_update_state(This, NINE_STATE_FB); 1631 1632 rect.x1 = This->state.viewport.X; 1633 rect.y1 = This->state.viewport.Y; 1634 rect.x2 = This->state.viewport.Width + rect.x1; 1635 rect.y2 = This->state.viewport.Height + rect.y1; 1636 1637 /* Both rectangles apply, which is weird, but that's D3D9. */ 1638 if (This->state.rs[D3DRS_SCISSORTESTENABLE]) { 1639 rect.x1 = MAX2(rect.x1, This->state.scissor.minx); 1640 rect.y1 = MAX2(rect.y1, This->state.scissor.miny); 1641 rect.x2 = MIN2(rect.x2, This->state.scissor.maxx); 1642 rect.y2 = MIN2(rect.y2, This->state.scissor.maxy); 1643 } 1644 1645 if (Count) { 1646 /* Maybe apps like to specify a large rect ? */ 1647 if (pRects[0].x1 <= rect.x1 && pRects[0].x2 >= rect.x2 && 1648 pRects[0].y1 <= rect.y1 && pRects[0].y2 >= rect.y2) { 1649 DBG("First rect covers viewport.\n"); 1650 Count = 0; 1651 pRects = NULL; 1652 } 1653 } 1654 1655 if (rect.x1 >= This->state.fb.width || rect.y1 >= This->state.fb.height) 1656 return D3D_OK; 1657 if (!Count && 1658 rect.x1 == 0 && rect.x2 >= This->state.fb.width && 1659 rect.y1 == 0 && rect.y2 >= This->state.fb.height) { 1660 /* fast path, clears everything at once */ 1661 DBG("fast path\n"); 1662 pipe->clear(pipe, bufs, &rgba, Z, Stencil); 1663 return D3D_OK; 1664 } 1665 rect.x2 = MIN2(rect.x2, This->state.fb.width); 1666 rect.y2 = MIN2(rect.y2, This->state.fb.height); 1667 1668 if (!Count) { 1669 Count = 1; 1670 pRects = ▭ 1671 } 1672 1673 for (i = 0; (i < This->state.fb.nr_cbufs); ++i) { 1674 if (!This->state.fb.cbufs[i] || !(Flags & D3DCLEAR_TARGET)) 1675 continue; /* save space, compiler should hoist this */ 1676 for (r = 0; r < Count; ++r) { 1677 /* Don't trust users to pass these in the right order. */ 1678 unsigned x1 = MIN2(pRects[r].x1, pRects[r].x2); 1679 unsigned y1 = MIN2(pRects[r].y1, pRects[r].y2); 1680 unsigned x2 = MAX2(pRects[r].x1, pRects[r].x2); 1681 unsigned y2 = MAX2(pRects[r].y1, pRects[r].y2); 1682#ifndef NINE_LAX 1683 /* Drop negative rectangles (like wine expects). */ 1684 if (pRects[r].x1 > pRects[r].x2) continue; 1685 if (pRects[r].y1 > pRects[r].y2) continue; 1686#endif 1687 1688 x1 = MAX2(x1, rect.x1); 1689 y1 = MAX2(y1, rect.y1); 1690 x2 = MIN2(x2, rect.x2); 1691 y2 = MIN2(y2, rect.y2); 1692 1693 DBG("Clearing (%u..%u)x(%u..%u)\n", x1, x2, y1, y2); 1694 pipe->clear_render_target(pipe, This->state.fb.cbufs[i], &rgba, 1695 x1, y1, x2 - x1, y2 - y1); 1696 } 1697 } 1698 if (!(Flags & NINED3DCLEAR_DEPTHSTENCIL)) 1699 return D3D_OK; 1700 1701 bufs &= PIPE_CLEAR_DEPTHSTENCIL; 1702 1703 for (r = 0; r < Count; ++r) { 1704 unsigned x1 = MIN2(pRects[r].x1, pRects[r].x2); 1705 unsigned y1 = MIN2(pRects[r].y1, pRects[r].y2); 1706 unsigned x2 = MAX2(pRects[r].x1, pRects[r].x2); 1707 unsigned y2 = MAX2(pRects[r].y1, pRects[r].y2); 1708#ifndef NINE_LAX 1709 /* Drop negative rectangles. */ 1710 if (pRects[r].x1 > pRects[r].x2) continue; 1711 if (pRects[r].y1 > pRects[r].y2) continue; 1712#endif 1713 1714 x1 = MIN2(x1, rect.x1); 1715 y1 = MIN2(y1, rect.y1); 1716 x2 = MIN2(x2, rect.x2); 1717 y2 = MIN2(y2, rect.y2); 1718 1719 pipe->clear_depth_stencil(pipe, This->state.fb.zsbuf, bufs, Z, Stencil, 1720 x1, y1, x2 - x1, y2 - y1); 1721 } 1722 return D3D_OK; 1723} 1724 1725HRESULT WINAPI 1726NineDevice9_SetTransform( struct NineDevice9 *This, 1727 D3DTRANSFORMSTATETYPE State, 1728 const D3DMATRIX *pMatrix ) 1729{ 1730 struct nine_state *state = This->update; 1731 D3DMATRIX *M = nine_state_access_transform(state, State, TRUE); 1732 1733 DBG("This=%p State=%d pMatrix=%p\n", This, State, pMatrix); 1734 1735 user_assert(M, D3DERR_INVALIDCALL); 1736 1737 *M = *pMatrix; 1738 state->ff.changed.transform[State / 32] |= 1 << (State % 32); 1739 state->changed.group |= NINE_STATE_FF; 1740 1741 return D3D_OK; 1742} 1743 1744HRESULT WINAPI 1745NineDevice9_GetTransform( struct NineDevice9 *This, 1746 D3DTRANSFORMSTATETYPE State, 1747 D3DMATRIX *pMatrix ) 1748{ 1749 D3DMATRIX *M = nine_state_access_transform(&This->state, State, FALSE); 1750 user_assert(M, D3DERR_INVALIDCALL); 1751 *pMatrix = *M; 1752 return D3D_OK; 1753} 1754 1755HRESULT WINAPI 1756NineDevice9_MultiplyTransform( struct NineDevice9 *This, 1757 D3DTRANSFORMSTATETYPE State, 1758 const D3DMATRIX *pMatrix ) 1759{ 1760 struct nine_state *state = This->update; 1761 D3DMATRIX T; 1762 D3DMATRIX *M = nine_state_access_transform(state, State, TRUE); 1763 1764 DBG("This=%p State=%d pMatrix=%p\n", This, State, pMatrix); 1765 1766 user_assert(M, D3DERR_INVALIDCALL); 1767 1768 nine_d3d_matrix_matrix_mul(&T, pMatrix, M); 1769 return NineDevice9_SetTransform(This, State, &T); 1770} 1771 1772HRESULT WINAPI 1773NineDevice9_SetViewport( struct NineDevice9 *This, 1774 const D3DVIEWPORT9 *pViewport ) 1775{ 1776 struct nine_state *state = This->update; 1777 1778 DBG("X=%u Y=%u W=%u H=%u MinZ=%f MaxZ=%f\n", 1779 pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, 1780 pViewport->MinZ, pViewport->MaxZ); 1781 1782 state->viewport = *pViewport; 1783 state->changed.group |= NINE_STATE_VIEWPORT; 1784 1785 return D3D_OK; 1786} 1787 1788HRESULT WINAPI 1789NineDevice9_GetViewport( struct NineDevice9 *This, 1790 D3DVIEWPORT9 *pViewport ) 1791{ 1792 *pViewport = This->state.viewport; 1793 return D3D_OK; 1794} 1795 1796HRESULT WINAPI 1797NineDevice9_SetMaterial( struct NineDevice9 *This, 1798 const D3DMATERIAL9 *pMaterial ) 1799{ 1800 struct nine_state *state = This->update; 1801 1802 DBG("This=%p pMaterial=%p\n", This, pMaterial); 1803 if (pMaterial) 1804 nine_dump_D3DMATERIAL9(DBG_FF, pMaterial); 1805 1806 user_assert(pMaterial, E_POINTER); 1807 1808 state->ff.material = *pMaterial; 1809 state->changed.group |= NINE_STATE_FF_MATERIAL; 1810 1811 return D3D_OK; 1812} 1813 1814HRESULT WINAPI 1815NineDevice9_GetMaterial( struct NineDevice9 *This, 1816 D3DMATERIAL9 *pMaterial ) 1817{ 1818 user_assert(pMaterial, E_POINTER); 1819 *pMaterial = This->state.ff.material; 1820 return D3D_OK; 1821} 1822 1823HRESULT WINAPI 1824NineDevice9_SetLight( struct NineDevice9 *This, 1825 DWORD Index, 1826 const D3DLIGHT9 *pLight ) 1827{ 1828 struct nine_state *state = This->update; 1829 1830 DBG("This=%p Index=%u pLight=%p\n", This, Index, pLight); 1831 if (pLight) 1832 nine_dump_D3DLIGHT9(DBG_FF, pLight); 1833 1834 user_assert(pLight, D3DERR_INVALIDCALL); 1835 user_assert(pLight->Type < NINED3DLIGHT_INVALID, D3DERR_INVALIDCALL); 1836 1837 user_assert(Index < NINE_MAX_LIGHTS, D3DERR_INVALIDCALL); /* sanity */ 1838 1839 if (Index >= state->ff.num_lights) { 1840 unsigned n = state->ff.num_lights; 1841 unsigned N = Index + 1; 1842 1843 state->ff.light = REALLOC(state->ff.light, n * sizeof(D3DLIGHT9), 1844 N * sizeof(D3DLIGHT9)); 1845 if (!state->ff.light) 1846 return E_OUTOFMEMORY; 1847 state->ff.num_lights = N; 1848 1849 for (; n < Index; ++n) 1850 state->ff.light[n].Type = (D3DLIGHTTYPE)NINED3DLIGHT_INVALID; 1851 } 1852 state->ff.light[Index] = *pLight; 1853 1854 if (pLight->Type == D3DLIGHT_SPOT && pLight->Theta >= pLight->Phi) { 1855 DBG("Warning: clamping D3DLIGHT9.Theta\n"); 1856 state->ff.light[Index].Theta = state->ff.light[Index].Phi; 1857 } 1858 if (pLight->Type != D3DLIGHT_DIRECTIONAL && 1859 pLight->Attenuation0 == 0.0f && 1860 pLight->Attenuation1 == 0.0f && 1861 pLight->Attenuation2 == 0.0f) { 1862 DBG("Warning: all D3DLIGHT9.Attenuation[i] are 0\n"); 1863 } 1864 1865 state->changed.group |= NINE_STATE_FF_LIGHTING; 1866 1867 return D3D_OK; 1868} 1869 1870HRESULT WINAPI 1871NineDevice9_GetLight( struct NineDevice9 *This, 1872 DWORD Index, 1873 D3DLIGHT9 *pLight ) 1874{ 1875 const struct nine_state *state = &This->state; 1876 1877 user_assert(pLight, D3DERR_INVALIDCALL); 1878 user_assert(Index < state->ff.num_lights, D3DERR_INVALIDCALL); 1879 user_assert(state->ff.light[Index].Type < NINED3DLIGHT_INVALID, 1880 D3DERR_INVALIDCALL); 1881 1882 *pLight = state->ff.light[Index]; 1883 1884 return D3D_OK; 1885} 1886 1887HRESULT WINAPI 1888NineDevice9_LightEnable( struct NineDevice9 *This, 1889 DWORD Index, 1890 BOOL Enable ) 1891{ 1892 struct nine_state *state = This->update; 1893 unsigned i; 1894 1895 DBG("This=%p Index=%u Enable=%i\n", This, Index, Enable); 1896 1897 if (Index >= state->ff.num_lights || 1898 state->ff.light[Index].Type == NINED3DLIGHT_INVALID) { 1899 /* This should create a default light. */ 1900 D3DLIGHT9 light; 1901 memset(&light, 0, sizeof(light)); 1902 light.Type = D3DLIGHT_DIRECTIONAL; 1903 light.Diffuse.r = 1.0f; 1904 light.Diffuse.g = 1.0f; 1905 light.Diffuse.b = 1.0f; 1906 light.Direction.z = 1.0f; 1907 NineDevice9_SetLight(This, Index, &light); 1908 } 1909 user_assert(Index < state->ff.num_lights, D3DERR_INVALIDCALL); 1910 1911 for (i = 0; i < state->ff.num_lights_active; ++i) { 1912 if (state->ff.active_light[i] == Index) 1913 break; 1914 } 1915 1916 if (Enable) { 1917 if (i < state->ff.num_lights_active) 1918 return D3D_OK; 1919 /* XXX wine thinks this should still succeed: 1920 */ 1921 user_assert(i < NINE_MAX_LIGHTS_ACTIVE, D3DERR_INVALIDCALL); 1922 1923 state->ff.active_light[i] = Index; 1924 state->ff.num_lights_active++; 1925 } else { 1926 if (i == state->ff.num_lights_active) 1927 return D3D_OK; 1928 --state->ff.num_lights_active; 1929 for (; i < state->ff.num_lights_active; ++i) 1930 state->ff.active_light[i] = state->ff.active_light[i + 1]; 1931 } 1932 state->changed.group |= NINE_STATE_FF_LIGHTING; 1933 1934 return D3D_OK; 1935} 1936 1937HRESULT WINAPI 1938NineDevice9_GetLightEnable( struct NineDevice9 *This, 1939 DWORD Index, 1940 BOOL *pEnable ) 1941{ 1942 const struct nine_state *state = &This->state; 1943 unsigned i; 1944 1945 user_assert(Index < state->ff.num_lights, D3DERR_INVALIDCALL); 1946 user_assert(state->ff.light[Index].Type < NINED3DLIGHT_INVALID, 1947 D3DERR_INVALIDCALL); 1948 1949 for (i = 0; i < state->ff.num_lights_active; ++i) 1950 if (state->ff.active_light[i] == Index) 1951 break; 1952 *pEnable = i != state->ff.num_lights_active; 1953 return D3D_OK; 1954} 1955 1956HRESULT WINAPI 1957NineDevice9_SetClipPlane( struct NineDevice9 *This, 1958 DWORD Index, 1959 const float *pPlane ) 1960{ 1961 struct nine_state *state = This->update; 1962 1963 DBG("This=%p Index=%u pPlane=%p(%f %f %f %f)\n", This, Index, pPlane, 1964 pPlane ? pPlane[0] : 0.0f, pPlane ? pPlane[1] : 0.0f, 1965 pPlane ? pPlane[2] : 0.0f, pPlane ? pPlane[3] : 0.0f); 1966 1967 user_assert(Index < PIPE_MAX_CLIP_PLANES, D3DERR_INVALIDCALL); 1968 1969 memcpy(&state->clip.ucp[Index][0], pPlane, sizeof(state->clip.ucp[0])); 1970 state->changed.ucp |= 1 << Index; 1971 1972 return D3D_OK; 1973} 1974 1975HRESULT WINAPI 1976NineDevice9_GetClipPlane( struct NineDevice9 *This, 1977 DWORD Index, 1978 float *pPlane ) 1979{ 1980 const struct nine_state *state = &This->state; 1981 1982 user_assert(Index < PIPE_MAX_CLIP_PLANES, D3DERR_INVALIDCALL); 1983 1984 memcpy(pPlane, &state->clip.ucp[Index][0], sizeof(state->clip.ucp[0])); 1985 return D3D_OK; 1986} 1987 1988HRESULT WINAPI 1989NineDevice9_SetRenderState( struct NineDevice9 *This, 1990 D3DRENDERSTATETYPE State, 1991 DWORD Value ) 1992{ 1993 struct nine_state *state = This->update; 1994 1995 DBG("This=%p State=%u(%s) Value=%08x\n", This, 1996 State, nine_d3drs_to_string(State), Value); 1997 1998 user_assert(State < Elements(state->rs), D3DERR_INVALIDCALL); 1999 2000 if (likely(state->rs[State] != Value) || unlikely(This->is_recording)) { 2001 state->rs[State] = Value; 2002 state->changed.rs[State / 32] |= 1 << (State % 32); 2003 state->changed.group |= nine_render_state_group[State]; 2004 } 2005 2006 return D3D_OK; 2007} 2008 2009HRESULT WINAPI 2010NineDevice9_GetRenderState( struct NineDevice9 *This, 2011 D3DRENDERSTATETYPE State, 2012 DWORD *pValue ) 2013{ 2014 user_assert(State < Elements(This->state.rs), D3DERR_INVALIDCALL); 2015 2016 *pValue = This->state.rs[State]; 2017 return D3D_OK; 2018} 2019 2020HRESULT WINAPI 2021NineDevice9_CreateStateBlock( struct NineDevice9 *This, 2022 D3DSTATEBLOCKTYPE Type, 2023 IDirect3DStateBlock9 **ppSB ) 2024{ 2025 struct NineStateBlock9 *nsb; 2026 struct nine_state *dst; 2027 HRESULT hr; 2028 enum nine_stateblock_type type; 2029 unsigned s; 2030 2031 DBG("This=%p Type=%u ppSB=%p\n", This, Type, ppSB); 2032 2033 user_assert(Type == D3DSBT_ALL || 2034 Type == D3DSBT_VERTEXSTATE || 2035 Type == D3DSBT_PIXELSTATE, D3DERR_INVALIDCALL); 2036 2037 switch (Type) { 2038 case D3DSBT_VERTEXSTATE: type = NINESBT_VERTEXSTATE; break; 2039 case D3DSBT_PIXELSTATE: type = NINESBT_PIXELSTATE; break; 2040 default: 2041 type = NINESBT_ALL; 2042 break; 2043 } 2044 2045 hr = NineStateBlock9_new(This, &nsb, type); 2046 if (FAILED(hr)) 2047 return hr; 2048 *ppSB = (IDirect3DStateBlock9 *)nsb; 2049 dst = &nsb->state; 2050 2051 dst->changed.group = 2052 NINE_STATE_TEXTURE | 2053 NINE_STATE_SAMPLER; 2054 2055 if (Type == D3DSBT_ALL || Type == D3DSBT_VERTEXSTATE) { 2056 dst->changed.group |= 2057 NINE_STATE_FF_LIGHTING | 2058 NINE_STATE_VS | NINE_STATE_VS_CONST | 2059 NINE_STATE_VDECL; 2060 /* TODO: texture/sampler state */ 2061 memcpy(dst->changed.rs, 2062 nine_render_states_vertex, sizeof(dst->changed.rs)); 2063 nine_ranges_insert(&dst->changed.vs_const_f, 0, This->max_vs_const_f, 2064 &This->range_pool); 2065 dst->changed.vs_const_i = 0xffff; 2066 dst->changed.vs_const_b = 0xffff; 2067 for (s = 0; s < NINE_MAX_SAMPLERS; ++s) 2068 dst->changed.sampler[s] |= 1 << D3DSAMP_DMAPOFFSET; 2069 if (This->state.ff.num_lights) { 2070 dst->ff.num_lights = This->state.ff.num_lights; 2071 /* zero'd -> light type won't be NINED3DLIGHT_INVALID, so 2072 * all currently existing lights will be captured 2073 */ 2074 dst->ff.light = CALLOC(This->state.ff.num_lights, 2075 sizeof(D3DLIGHT9)); 2076 if (!dst->ff.light) { 2077 nine_bind(ppSB, NULL); 2078 return E_OUTOFMEMORY; 2079 } 2080 } 2081 } 2082 if (Type == D3DSBT_ALL || Type == D3DSBT_PIXELSTATE) { 2083 dst->changed.group |= 2084 NINE_STATE_PS | NINE_STATE_PS_CONST; 2085 /* TODO: texture/sampler state */ 2086 memcpy(dst->changed.rs, 2087 nine_render_states_pixel, sizeof(dst->changed.rs)); 2088 nine_ranges_insert(&dst->changed.ps_const_f, 0, This->max_ps_const_f, 2089 &This->range_pool); 2090 dst->changed.ps_const_i = 0xffff; 2091 dst->changed.ps_const_b = 0xffff; 2092 for (s = 0; s < NINE_MAX_SAMPLERS; ++s) 2093 dst->changed.sampler[s] |= 0x1ffe; 2094 } 2095 if (Type == D3DSBT_ALL) { 2096 dst->changed.group |= 2097 NINE_STATE_VIEWPORT | 2098 NINE_STATE_SCISSOR | 2099 NINE_STATE_RASTERIZER | 2100 NINE_STATE_BLEND | 2101 NINE_STATE_DSA | 2102 NINE_STATE_IDXBUF | 2103 NINE_STATE_MATERIAL | 2104 NINE_STATE_BLEND_COLOR | 2105 NINE_STATE_SAMPLE_MASK; 2106 memset(dst->changed.rs, ~0, (D3DRS_COUNT / 32) * sizeof(uint32_t)); 2107 dst->changed.rs[D3DRS_LAST / 32] |= (1 << (D3DRS_COUNT % 32)) - 1; 2108 dst->changed.vtxbuf = (1ULL << This->caps.MaxStreams) - 1; 2109 dst->changed.stream_freq = dst->changed.vtxbuf; 2110 dst->changed.ucp = (1 << PIPE_MAX_CLIP_PLANES) - 1; 2111 dst->changed.texture = (1 << NINE_MAX_SAMPLERS) - 1; 2112 } 2113 NineStateBlock9_Capture(NineStateBlock9(*ppSB)); 2114 2115 /* TODO: fixed function state */ 2116 2117 return D3D_OK; 2118} 2119 2120HRESULT WINAPI 2121NineDevice9_BeginStateBlock( struct NineDevice9 *This ) 2122{ 2123 HRESULT hr; 2124 2125 DBG("This=%p\n", This); 2126 2127 user_assert(!This->record, D3DERR_INVALIDCALL); 2128 2129 hr = NineStateBlock9_new(This, &This->record, NINESBT_CUSTOM); 2130 if (FAILED(hr)) 2131 return hr; 2132 NineUnknown_ConvertRefToBind(NineUnknown(This->record)); 2133 2134 This->update = &This->record->state; 2135 This->is_recording = TRUE; 2136 2137 return D3D_OK; 2138} 2139 2140HRESULT WINAPI 2141NineDevice9_EndStateBlock( struct NineDevice9 *This, 2142 IDirect3DStateBlock9 **ppSB ) 2143{ 2144 DBG("This=%p ppSB=%p\n", This, ppSB); 2145 2146 user_assert(This->record, D3DERR_INVALIDCALL); 2147 2148 This->update = &This->state; 2149 This->is_recording = FALSE; 2150 2151 NineUnknown_AddRef(NineUnknown(This->record)); 2152 *ppSB = (IDirect3DStateBlock9 *)This->record; 2153 NineUnknown_Unbind(NineUnknown(This->record)); 2154 This->record = NULL; 2155 2156 return D3D_OK; 2157} 2158 2159HRESULT WINAPI 2160NineDevice9_SetClipStatus( struct NineDevice9 *This, 2161 const D3DCLIPSTATUS9 *pClipStatus ) 2162{ 2163 STUB(D3DERR_INVALIDCALL); 2164} 2165 2166HRESULT WINAPI 2167NineDevice9_GetClipStatus( struct NineDevice9 *This, 2168 D3DCLIPSTATUS9 *pClipStatus ) 2169{ 2170 STUB(D3DERR_INVALIDCALL); 2171} 2172 2173HRESULT WINAPI 2174NineDevice9_GetTexture( struct NineDevice9 *This, 2175 DWORD Stage, 2176 IDirect3DBaseTexture9 **ppTexture ) 2177{ 2178 user_assert(Stage < This->caps.MaxSimultaneousTextures || 2179 Stage == D3DDMAPSAMPLER || 2180 (Stage >= D3DVERTEXTEXTURESAMPLER0 && 2181 Stage <= D3DVERTEXTEXTURESAMPLER3), D3DERR_INVALIDCALL); 2182 user_assert(ppTexture, D3DERR_INVALIDCALL); 2183 2184 if (Stage >= D3DDMAPSAMPLER) 2185 Stage = Stage - D3DDMAPSAMPLER + NINE_MAX_SAMPLERS_PS; 2186 2187 *ppTexture = (IDirect3DBaseTexture9 *)This->state.texture[Stage]; 2188 2189 if (This->state.texture[Stage]) 2190 NineUnknown_AddRef(NineUnknown(This->state.texture[Stage])); 2191 return D3D_OK; 2192} 2193 2194HRESULT WINAPI 2195NineDevice9_SetTexture( struct NineDevice9 *This, 2196 DWORD Stage, 2197 IDirect3DBaseTexture9 *pTexture ) 2198{ 2199 struct nine_state *state = This->update; 2200 struct NineBaseTexture9 *tex = NineBaseTexture9(pTexture); 2201 2202 DBG("This=%p Stage=%u pTexture=%p\n", This, Stage, pTexture); 2203 2204 user_assert(Stage < This->caps.MaxSimultaneousTextures || 2205 Stage == D3DDMAPSAMPLER || 2206 (Stage >= D3DVERTEXTEXTURESAMPLER0 && 2207 Stage <= D3DVERTEXTEXTURESAMPLER3), D3DERR_INVALIDCALL); 2208 user_assert(!tex || tex->base.pool != D3DPOOL_SCRATCH, D3DERR_INVALIDCALL); 2209 2210 if (unlikely(tex && tex->base.pool == D3DPOOL_SYSTEMMEM)) { 2211 /* TODO: Currently not implemented. Better return error 2212 * with message telling what's wrong */ 2213 ERR("This=%p D3DPOOL_SYSTEMMEM not implemented for SetTexture\n", This); 2214 user_assert(tex->base.pool != D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL); 2215 } 2216 2217 if (Stage >= D3DDMAPSAMPLER) 2218 Stage = Stage - D3DDMAPSAMPLER + NINE_MAX_SAMPLERS_PS; 2219 2220 if (!This->is_recording) { 2221 struct NineBaseTexture9 *old = state->texture[Stage]; 2222 if (old == tex) 2223 return D3D_OK; 2224 2225 state->samplers_shadow &= ~(1 << Stage); 2226 if (tex) { 2227 state->samplers_shadow |= tex->shadow << Stage; 2228 2229 if ((tex->dirty | tex->dirty_mip) && LIST_IS_EMPTY(&tex->list)) 2230 list_add(&tex->list, &This->update_textures); 2231 2232 tex->bind_count++; 2233 } 2234 if (old) 2235 old->bind_count--; 2236 } 2237 nine_bind(&state->texture[Stage], pTexture); 2238 2239 state->changed.texture |= 1 << Stage; 2240 state->changed.group |= NINE_STATE_TEXTURE; 2241 2242 return D3D_OK; 2243} 2244 2245HRESULT WINAPI 2246NineDevice9_GetTextureStageState( struct NineDevice9 *This, 2247 DWORD Stage, 2248 D3DTEXTURESTAGESTATETYPE Type, 2249 DWORD *pValue ) 2250{ 2251 const struct nine_state *state = &This->state; 2252 2253 user_assert(Stage < Elements(state->ff.tex_stage), D3DERR_INVALIDCALL); 2254 user_assert(Type < Elements(state->ff.tex_stage[0]), D3DERR_INVALIDCALL); 2255 2256 *pValue = state->ff.tex_stage[Stage][Type]; 2257 2258 return D3D_OK; 2259} 2260 2261HRESULT WINAPI 2262NineDevice9_SetTextureStageState( struct NineDevice9 *This, 2263 DWORD Stage, 2264 D3DTEXTURESTAGESTATETYPE Type, 2265 DWORD Value ) 2266{ 2267 struct nine_state *state = This->update; 2268 2269 DBG("Stage=%u Type=%u Value=%08x\n", Stage, Type, Value); 2270 nine_dump_D3DTSS_value(DBG_FF, Type, Value); 2271 2272 user_assert(Stage < Elements(state->ff.tex_stage), D3DERR_INVALIDCALL); 2273 user_assert(Type < Elements(state->ff.tex_stage[0]), D3DERR_INVALIDCALL); 2274 2275 state->ff.tex_stage[Stage][Type] = Value; 2276 2277 state->changed.group |= NINE_STATE_FF_PSSTAGES; 2278 state->ff.changed.tex_stage[Stage][Type / 32] |= 1 << (Type % 32); 2279 2280 return D3D_OK; 2281} 2282 2283HRESULT WINAPI 2284NineDevice9_GetSamplerState( struct NineDevice9 *This, 2285 DWORD Sampler, 2286 D3DSAMPLERSTATETYPE Type, 2287 DWORD *pValue ) 2288{ 2289 user_assert(Sampler < This->caps.MaxSimultaneousTextures || 2290 Sampler == D3DDMAPSAMPLER || 2291 (Sampler >= D3DVERTEXTEXTURESAMPLER0 && 2292 Sampler <= D3DVERTEXTEXTURESAMPLER3), D3DERR_INVALIDCALL); 2293 2294 if (Sampler >= D3DDMAPSAMPLER) 2295 Sampler = Sampler - D3DDMAPSAMPLER + NINE_MAX_SAMPLERS_PS; 2296 2297 *pValue = This->state.samp[Sampler][Type]; 2298 return D3D_OK; 2299} 2300 2301HRESULT WINAPI 2302NineDevice9_SetSamplerState( struct NineDevice9 *This, 2303 DWORD Sampler, 2304 D3DSAMPLERSTATETYPE Type, 2305 DWORD Value ) 2306{ 2307 struct nine_state *state = This->update; 2308 2309 DBG("This=%p Sampler=%u Type=%s Value=%08x\n", This, 2310 Sampler, nine_D3DSAMP_to_str(Type), Value); 2311 2312 user_assert(Sampler < This->caps.MaxSimultaneousTextures || 2313 Sampler == D3DDMAPSAMPLER || 2314 (Sampler >= D3DVERTEXTEXTURESAMPLER0 && 2315 Sampler <= D3DVERTEXTEXTURESAMPLER3), D3DERR_INVALIDCALL); 2316 2317 if (Sampler >= D3DDMAPSAMPLER) 2318 Sampler = Sampler - D3DDMAPSAMPLER + NINE_MAX_SAMPLERS_PS; 2319 2320 state->samp[Sampler][Type] = Value; 2321 state->changed.group |= NINE_STATE_SAMPLER; 2322 state->changed.sampler[Sampler] |= 1 << Type; 2323 2324 return D3D_OK; 2325} 2326 2327HRESULT WINAPI 2328NineDevice9_ValidateDevice( struct NineDevice9 *This, 2329 DWORD *pNumPasses ) 2330{ 2331 const struct nine_state *state = &This->state; 2332 unsigned i; 2333 unsigned w = 0, h = 0; 2334 2335 DBG("This=%p pNumPasses=%p\n", This, pNumPasses); 2336 2337 for (i = 0; i < Elements(state->samp); ++i) { 2338 if (state->samp[i][D3DSAMP_MINFILTER] == D3DTEXF_NONE || 2339 state->samp[i][D3DSAMP_MAGFILTER] == D3DTEXF_NONE) 2340 return D3DERR_UNSUPPORTEDTEXTUREFILTER; 2341 } 2342 2343 for (i = 0; i < This->caps.NumSimultaneousRTs; ++i) { 2344 if (!state->rt[i]) 2345 continue; 2346 if (w == 0) { 2347 w = state->rt[i]->desc.Width; 2348 h = state->rt[i]->desc.Height; 2349 } else 2350 if (state->rt[i]->desc.Width != w || state->rt[i]->desc.Height != h) { 2351 return D3DERR_CONFLICTINGRENDERSTATE; 2352 } 2353 } 2354 if (state->ds && 2355 (state->rs[D3DRS_ZENABLE] || state->rs[D3DRS_STENCILENABLE])) { 2356 if (w != 0 && 2357 (state->ds->desc.Width != w || state->ds->desc.Height != h)) 2358 return D3DERR_CONFLICTINGRENDERSTATE; 2359 } 2360 2361 if (pNumPasses) 2362 *pNumPasses = 1; 2363 2364 return D3D_OK; 2365} 2366 2367HRESULT WINAPI 2368NineDevice9_SetPaletteEntries( struct NineDevice9 *This, 2369 UINT PaletteNumber, 2370 const PALETTEENTRY *pEntries ) 2371{ 2372 STUB(D3D_OK); /* like wine */ 2373} 2374 2375HRESULT WINAPI 2376NineDevice9_GetPaletteEntries( struct NineDevice9 *This, 2377 UINT PaletteNumber, 2378 PALETTEENTRY *pEntries ) 2379{ 2380 STUB(D3DERR_INVALIDCALL); 2381} 2382 2383HRESULT WINAPI 2384NineDevice9_SetCurrentTexturePalette( struct NineDevice9 *This, 2385 UINT PaletteNumber ) 2386{ 2387 STUB(D3D_OK); /* like wine */ 2388} 2389 2390HRESULT WINAPI 2391NineDevice9_GetCurrentTexturePalette( struct NineDevice9 *This, 2392 UINT *PaletteNumber ) 2393{ 2394 STUB(D3DERR_INVALIDCALL); 2395} 2396 2397HRESULT WINAPI 2398NineDevice9_SetScissorRect( struct NineDevice9 *This, 2399 const RECT *pRect ) 2400{ 2401 struct nine_state *state = This->update; 2402 2403 DBG("x=(%u..%u) y=(%u..%u)\n", 2404 pRect->left, pRect->top, pRect->right, pRect->bottom); 2405 2406 state->scissor.minx = pRect->left; 2407 state->scissor.miny = pRect->top; 2408 state->scissor.maxx = pRect->right; 2409 state->scissor.maxy = pRect->bottom; 2410 2411 state->changed.group |= NINE_STATE_SCISSOR; 2412 2413 return D3D_OK; 2414} 2415 2416HRESULT WINAPI 2417NineDevice9_GetScissorRect( struct NineDevice9 *This, 2418 RECT *pRect ) 2419{ 2420 pRect->left = This->state.scissor.minx; 2421 pRect->top = This->state.scissor.miny; 2422 pRect->right = This->state.scissor.maxx; 2423 pRect->bottom = This->state.scissor.maxy; 2424 2425 return D3D_OK; 2426} 2427 2428HRESULT WINAPI 2429NineDevice9_SetSoftwareVertexProcessing( struct NineDevice9 *This, 2430 BOOL bSoftware ) 2431{ 2432 STUB(D3DERR_INVALIDCALL); 2433} 2434 2435BOOL WINAPI 2436NineDevice9_GetSoftwareVertexProcessing( struct NineDevice9 *This ) 2437{ 2438 return !!(This->params.BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING); 2439} 2440 2441HRESULT WINAPI 2442NineDevice9_SetNPatchMode( struct NineDevice9 *This, 2443 float nSegments ) 2444{ 2445 STUB(D3DERR_INVALIDCALL); 2446} 2447 2448float WINAPI 2449NineDevice9_GetNPatchMode( struct NineDevice9 *This ) 2450{ 2451 STUB(0); 2452} 2453 2454static INLINE void 2455init_draw_info(struct pipe_draw_info *info, 2456 struct NineDevice9 *dev, D3DPRIMITIVETYPE type, UINT count) 2457{ 2458 info->mode = d3dprimitivetype_to_pipe_prim(type); 2459 info->count = prim_count_to_vertex_count(type, count); 2460 info->start_instance = 0; 2461 info->instance_count = 1; 2462 if (dev->state.stream_instancedata_mask & dev->state.stream_usage_mask) 2463 info->instance_count = MAX2(dev->state.stream_freq[0] & 0x7FFFFF, 1); 2464 info->primitive_restart = FALSE; 2465 info->restart_index = 0; 2466 info->count_from_stream_output = NULL; 2467 info->indirect = NULL; 2468} 2469 2470HRESULT WINAPI 2471NineDevice9_DrawPrimitive( struct NineDevice9 *This, 2472 D3DPRIMITIVETYPE PrimitiveType, 2473 UINT StartVertex, 2474 UINT PrimitiveCount ) 2475{ 2476 struct pipe_draw_info info; 2477 2478 DBG("iface %p, PrimitiveType %u, StartVertex %u, PrimitiveCount %u\n", 2479 This, PrimitiveType, StartVertex, PrimitiveCount); 2480 2481 nine_update_state(This, ~0); 2482 2483 init_draw_info(&info, This, PrimitiveType, PrimitiveCount); 2484 info.indexed = FALSE; 2485 info.start = StartVertex; 2486 info.index_bias = 0; 2487 info.min_index = info.start; 2488 info.max_index = info.count - 1; 2489 2490 This->pipe->draw_vbo(This->pipe, &info); 2491 2492 return D3D_OK; 2493} 2494 2495HRESULT WINAPI 2496NineDevice9_DrawIndexedPrimitive( struct NineDevice9 *This, 2497 D3DPRIMITIVETYPE PrimitiveType, 2498 INT BaseVertexIndex, 2499 UINT MinVertexIndex, 2500 UINT NumVertices, 2501 UINT StartIndex, 2502 UINT PrimitiveCount ) 2503{ 2504 struct pipe_draw_info info; 2505 2506 DBG("iface %p, PrimitiveType %u, BaseVertexIndex %u, MinVertexIndex %u " 2507 "NumVertices %u, StartIndex %u, PrimitiveCount %u\n", 2508 This, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, 2509 StartIndex, PrimitiveCount); 2510 2511 user_assert(This->state.idxbuf, D3DERR_INVALIDCALL); 2512 user_assert(This->state.vdecl, D3DERR_INVALIDCALL); 2513 2514 nine_update_state(This, ~0); 2515 2516 init_draw_info(&info, This, PrimitiveType, PrimitiveCount); 2517 info.indexed = TRUE; 2518 info.start = StartIndex; 2519 info.index_bias = BaseVertexIndex; 2520 /* These don't include index bias: */ 2521 info.min_index = MinVertexIndex; 2522 info.max_index = MinVertexIndex + NumVertices - 1; 2523 2524 This->pipe->draw_vbo(This->pipe, &info); 2525 2526 return D3D_OK; 2527} 2528 2529HRESULT WINAPI 2530NineDevice9_DrawPrimitiveUP( struct NineDevice9 *This, 2531 D3DPRIMITIVETYPE PrimitiveType, 2532 UINT PrimitiveCount, 2533 const void *pVertexStreamZeroData, 2534 UINT VertexStreamZeroStride ) 2535{ 2536 struct pipe_vertex_buffer vtxbuf; 2537 struct pipe_draw_info info; 2538 2539 DBG("iface %p, PrimitiveType %u, PrimitiveCount %u, data %p, stride %u\n", 2540 This, PrimitiveType, PrimitiveCount, 2541 pVertexStreamZeroData, VertexStreamZeroStride); 2542 2543 user_assert(pVertexStreamZeroData && VertexStreamZeroStride, 2544 D3DERR_INVALIDCALL); 2545 2546 nine_update_state(This, ~0); 2547 2548 init_draw_info(&info, This, PrimitiveType, PrimitiveCount); 2549 info.indexed = FALSE; 2550 info.start = 0; 2551 info.index_bias = 0; 2552 info.min_index = 0; 2553 info.max_index = info.count - 1; 2554 2555 vtxbuf.stride = VertexStreamZeroStride; 2556 vtxbuf.buffer_offset = 0; 2557 vtxbuf.buffer = NULL; 2558 vtxbuf.user_buffer = pVertexStreamZeroData; 2559 2560 if (!This->driver_caps.user_vbufs) 2561 u_upload_data(This->upload, 2562 0, 2563 (info.max_index + 1) * VertexStreamZeroStride, /* XXX */ 2564 vtxbuf.user_buffer, 2565 &vtxbuf.buffer_offset, 2566 &vtxbuf.buffer); 2567 2568 This->pipe->set_vertex_buffers(This->pipe, 0, 1, &vtxbuf); 2569 2570 This->pipe->draw_vbo(This->pipe, &info); 2571 2572 NineDevice9_PauseRecording(This); 2573 NineDevice9_SetStreamSource(This, 0, NULL, 0, 0); 2574 NineDevice9_ResumeRecording(This); 2575 2576 pipe_resource_reference(&vtxbuf.buffer, NULL); 2577 2578 return D3D_OK; 2579} 2580 2581HRESULT WINAPI 2582NineDevice9_DrawIndexedPrimitiveUP( struct NineDevice9 *This, 2583 D3DPRIMITIVETYPE PrimitiveType, 2584 UINT MinVertexIndex, 2585 UINT NumVertices, 2586 UINT PrimitiveCount, 2587 const void *pIndexData, 2588 D3DFORMAT IndexDataFormat, 2589 const void *pVertexStreamZeroData, 2590 UINT VertexStreamZeroStride ) 2591{ 2592 struct pipe_draw_info info; 2593 struct pipe_vertex_buffer vbuf; 2594 struct pipe_index_buffer ibuf; 2595 2596 DBG("iface %p, PrimitiveType %u, MinVertexIndex %u, NumVertices %u " 2597 "PrimitiveCount %u, pIndexData %p, IndexDataFormat %u " 2598 "pVertexStreamZeroData %p, VertexStreamZeroStride %u\n", 2599 This, PrimitiveType, MinVertexIndex, NumVertices, PrimitiveCount, 2600 pIndexData, IndexDataFormat, 2601 pVertexStreamZeroData, VertexStreamZeroStride); 2602 2603 user_assert(pIndexData && pVertexStreamZeroData, D3DERR_INVALIDCALL); 2604 user_assert(VertexStreamZeroStride, D3DERR_INVALIDCALL); 2605 user_assert(IndexDataFormat == D3DFMT_INDEX16 || 2606 IndexDataFormat == D3DFMT_INDEX32, D3DERR_INVALIDCALL); 2607 2608 nine_update_state(This, ~0); 2609 2610 init_draw_info(&info, This, PrimitiveType, PrimitiveCount); 2611 info.indexed = TRUE; 2612 info.start = 0; 2613 info.index_bias = 0; 2614 info.min_index = MinVertexIndex; 2615 info.max_index = MinVertexIndex + NumVertices - 1; 2616 2617 vbuf.stride = VertexStreamZeroStride; 2618 vbuf.buffer_offset = 0; 2619 vbuf.buffer = NULL; 2620 vbuf.user_buffer = pVertexStreamZeroData; 2621 2622 ibuf.index_size = (IndexDataFormat == D3DFMT_INDEX16) ? 2 : 4; 2623 ibuf.offset = 0; 2624 ibuf.buffer = NULL; 2625 ibuf.user_buffer = pIndexData; 2626 2627 if (!This->driver_caps.user_vbufs) { 2628 const unsigned base = info.min_index * VertexStreamZeroStride; 2629 u_upload_data(This->upload, 2630 base, 2631 (info.max_index - 2632 info.min_index + 1) * VertexStreamZeroStride, /* XXX */ 2633 (const uint8_t *)vbuf.user_buffer + base, 2634 &vbuf.buffer_offset, 2635 &vbuf.buffer); 2636 /* Won't be used: */ 2637 vbuf.buffer_offset -= base; 2638 } 2639 if (!This->driver_caps.user_ibufs) 2640 u_upload_data(This->upload, 2641 0, 2642 info.count * ibuf.index_size, 2643 ibuf.user_buffer, 2644 &ibuf.offset, 2645 &ibuf.buffer); 2646 2647 This->pipe->set_vertex_buffers(This->pipe, 0, 1, &vbuf); 2648 This->pipe->set_index_buffer(This->pipe, &ibuf); 2649 2650 This->pipe->draw_vbo(This->pipe, &info); 2651 2652 pipe_resource_reference(&vbuf.buffer, NULL); 2653 pipe_resource_reference(&ibuf.buffer, NULL); 2654 2655 NineDevice9_PauseRecording(This); 2656 NineDevice9_SetIndices(This, NULL); 2657 NineDevice9_SetStreamSource(This, 0, NULL, 0, 0); 2658 NineDevice9_ResumeRecording(This); 2659 2660 return D3D_OK; 2661} 2662 2663/* TODO: Write to pDestBuffer directly if vertex declaration contains 2664 * only f32 formats. 2665 */ 2666HRESULT WINAPI 2667NineDevice9_ProcessVertices( struct NineDevice9 *This, 2668 UINT SrcStartIndex, 2669 UINT DestIndex, 2670 UINT VertexCount, 2671 IDirect3DVertexBuffer9 *pDestBuffer, 2672 IDirect3DVertexDeclaration9 *pVertexDecl, 2673 DWORD Flags ) 2674{ 2675 struct pipe_screen *screen = This->screen; 2676 struct NineVertexDeclaration9 *vdecl = NineVertexDeclaration9(pVertexDecl); 2677 struct NineVertexShader9 *vs; 2678 struct pipe_resource *resource; 2679 struct pipe_stream_output_target *target; 2680 struct pipe_draw_info draw; 2681 HRESULT hr; 2682 unsigned buffer_offset, buffer_size; 2683 2684 DBG("This=%p SrcStartIndex=%u DestIndex=%u VertexCount=%u " 2685 "pDestBuffer=%p pVertexDecl=%p Flags=%d\n", 2686 This, SrcStartIndex, DestIndex, VertexCount, pDestBuffer, 2687 pVertexDecl, Flags); 2688 2689 if (!screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS)) 2690 STUB(D3DERR_INVALIDCALL); 2691 2692 nine_update_state(This, ~0); 2693 2694 /* TODO: Create shader with stream output. */ 2695 STUB(D3DERR_INVALIDCALL); 2696 struct NineVertexBuffer9 *dst = NineVertexBuffer9(pDestBuffer); 2697 2698 vs = This->state.vs ? This->state.vs : This->ff.vs; 2699 2700 buffer_size = VertexCount * vs->so->stride[0]; 2701 if (1) { 2702 struct pipe_resource templ; 2703 2704 templ.target = PIPE_BUFFER; 2705 templ.format = PIPE_FORMAT_R8_UNORM; 2706 templ.width0 = buffer_size; 2707 templ.flags = 0; 2708 templ.bind = PIPE_BIND_STREAM_OUTPUT; 2709 templ.usage = PIPE_USAGE_STREAM; 2710 templ.height0 = templ.depth0 = templ.array_size = 1; 2711 templ.last_level = templ.nr_samples = 0; 2712 2713 resource = This->screen->resource_create(This->screen, &templ); 2714 if (!resource) 2715 return E_OUTOFMEMORY; 2716 buffer_offset = 0; 2717 } else { 2718 /* SO matches vertex declaration */ 2719 resource = dst->base.resource; 2720 buffer_offset = DestIndex * vs->so->stride[0]; 2721 } 2722 target = This->pipe->create_stream_output_target(This->pipe, resource, 2723 buffer_offset, 2724 buffer_size); 2725 if (!target) { 2726 pipe_resource_reference(&resource, NULL); 2727 return D3DERR_DRIVERINTERNALERROR; 2728 } 2729 2730 if (!vdecl) { 2731 hr = NineVertexDeclaration9_new_from_fvf(This, dst->desc.FVF, &vdecl); 2732 if (FAILED(hr)) 2733 goto out; 2734 } 2735 2736 init_draw_info(&draw, This, D3DPT_POINTLIST, VertexCount); 2737 draw.instance_count = 1; 2738 draw.indexed = FALSE; 2739 draw.start = SrcStartIndex; 2740 draw.index_bias = 0; 2741 draw.min_index = SrcStartIndex; 2742 draw.max_index = SrcStartIndex + VertexCount - 1; 2743 2744 This->pipe->set_stream_output_targets(This->pipe, 1, &target, 0); 2745 This->pipe->draw_vbo(This->pipe, &draw); 2746 This->pipe->set_stream_output_targets(This->pipe, 0, NULL, 0); 2747 This->pipe->stream_output_target_destroy(This->pipe, target); 2748 2749 hr = NineVertexDeclaration9_ConvertStreamOutput(vdecl, 2750 dst, DestIndex, VertexCount, 2751 resource, vs->so); 2752out: 2753 pipe_resource_reference(&resource, NULL); 2754 if (!pVertexDecl) 2755 NineUnknown_Release(NineUnknown(vdecl)); 2756 return hr; 2757} 2758 2759HRESULT WINAPI 2760NineDevice9_CreateVertexDeclaration( struct NineDevice9 *This, 2761 const D3DVERTEXELEMENT9 *pVertexElements, 2762 IDirect3DVertexDeclaration9 **ppDecl ) 2763{ 2764 struct NineVertexDeclaration9 *vdecl; 2765 2766 DBG("This=%p pVertexElements=%p ppDecl=%p\n", 2767 This, pVertexElements, ppDecl); 2768 2769 HRESULT hr = NineVertexDeclaration9_new(This, pVertexElements, &vdecl); 2770 if (SUCCEEDED(hr)) 2771 *ppDecl = (IDirect3DVertexDeclaration9 *)vdecl; 2772 2773 return hr; 2774} 2775 2776HRESULT WINAPI 2777NineDevice9_SetVertexDeclaration( struct NineDevice9 *This, 2778 IDirect3DVertexDeclaration9 *pDecl ) 2779{ 2780 struct nine_state *state = This->update; 2781 2782 DBG("This=%p pDecl=%p\n", This, pDecl); 2783 2784 if (likely(!This->is_recording) && state->vdecl == NineVertexDeclaration9(pDecl)) 2785 return D3D_OK; 2786 nine_bind(&state->vdecl, pDecl); 2787 2788 state->changed.group |= NINE_STATE_VDECL; 2789 2790 return D3D_OK; 2791} 2792 2793HRESULT WINAPI 2794NineDevice9_GetVertexDeclaration( struct NineDevice9 *This, 2795 IDirect3DVertexDeclaration9 **ppDecl ) 2796{ 2797 user_assert(ppDecl, D3DERR_INVALIDCALL); 2798 2799 *ppDecl = (IDirect3DVertexDeclaration9 *)This->state.vdecl; 2800 if (*ppDecl) 2801 NineUnknown_AddRef(NineUnknown(*ppDecl)); 2802 return D3D_OK; 2803} 2804 2805HRESULT WINAPI 2806NineDevice9_SetFVF( struct NineDevice9 *This, 2807 DWORD FVF ) 2808{ 2809 struct NineVertexDeclaration9 *vdecl; 2810 HRESULT hr; 2811 2812 DBG("FVF = %08x\n", FVF); 2813 if (!FVF) 2814 return D3D_OK; /* like wine */ 2815 2816 vdecl = util_hash_table_get(This->ff.ht_fvf, &FVF); 2817 if (!vdecl) { 2818 hr = NineVertexDeclaration9_new_from_fvf(This, FVF, &vdecl); 2819 if (FAILED(hr)) 2820 return hr; 2821 vdecl->fvf = FVF; 2822 util_hash_table_set(This->ff.ht_fvf, &vdecl->fvf, vdecl); 2823 NineUnknown_ConvertRefToBind(NineUnknown(vdecl)); 2824 } 2825 return NineDevice9_SetVertexDeclaration( 2826 This, (IDirect3DVertexDeclaration9 *)vdecl); 2827} 2828 2829HRESULT WINAPI 2830NineDevice9_GetFVF( struct NineDevice9 *This, 2831 DWORD *pFVF ) 2832{ 2833 *pFVF = This->state.vdecl ? This->state.vdecl->fvf : 0; 2834 return D3D_OK; 2835} 2836 2837HRESULT WINAPI 2838NineDevice9_CreateVertexShader( struct NineDevice9 *This, 2839 const DWORD *pFunction, 2840 IDirect3DVertexShader9 **ppShader ) 2841{ 2842 struct NineVertexShader9 *vs; 2843 HRESULT hr; 2844 2845 DBG("This=%p pFunction=%p ppShader=%p\n", This, pFunction, ppShader); 2846 2847 hr = NineVertexShader9_new(This, &vs, pFunction, NULL); 2848 if (FAILED(hr)) 2849 return hr; 2850 *ppShader = (IDirect3DVertexShader9 *)vs; 2851 return D3D_OK; 2852} 2853 2854HRESULT WINAPI 2855NineDevice9_SetVertexShader( struct NineDevice9 *This, 2856 IDirect3DVertexShader9 *pShader ) 2857{ 2858 struct nine_state *state = This->update; 2859 2860 DBG("This=%p pShader=%p\n", This, pShader); 2861 2862 nine_bind(&state->vs, pShader); 2863 2864 state->changed.group |= NINE_STATE_VS; 2865 2866 return D3D_OK; 2867} 2868 2869HRESULT WINAPI 2870NineDevice9_GetVertexShader( struct NineDevice9 *This, 2871 IDirect3DVertexShader9 **ppShader ) 2872{ 2873 user_assert(ppShader, D3DERR_INVALIDCALL); 2874 nine_reference_set(ppShader, This->state.vs); 2875 return D3D_OK; 2876} 2877 2878HRESULT WINAPI 2879NineDevice9_SetVertexShaderConstantF( struct NineDevice9 *This, 2880 UINT StartRegister, 2881 const float *pConstantData, 2882 UINT Vector4fCount ) 2883{ 2884 struct nine_state *state = This->update; 2885 2886 DBG("This=%p StartRegister=%u pConstantData=%p Vector4fCount=%u\n", 2887 This, StartRegister, pConstantData, Vector4fCount); 2888 2889 user_assert(StartRegister < This->caps.MaxVertexShaderConst, D3DERR_INVALIDCALL); 2890 user_assert(StartRegister + Vector4fCount <= This->caps.MaxVertexShaderConst, D3DERR_INVALIDCALL); 2891 2892 if (!Vector4fCount) 2893 return D3D_OK; 2894 user_assert(pConstantData, D3DERR_INVALIDCALL); 2895 2896 memcpy(&state->vs_const_f[StartRegister * 4], 2897 pConstantData, 2898 Vector4fCount * 4 * sizeof(state->vs_const_f[0])); 2899 2900 nine_ranges_insert(&state->changed.vs_const_f, 2901 StartRegister, StartRegister + Vector4fCount, 2902 &This->range_pool); 2903 2904 state->changed.group |= NINE_STATE_VS_CONST; 2905 2906 return D3D_OK; 2907} 2908 2909HRESULT WINAPI 2910NineDevice9_GetVertexShaderConstantF( struct NineDevice9 *This, 2911 UINT StartRegister, 2912 float *pConstantData, 2913 UINT Vector4fCount ) 2914{ 2915 const struct nine_state *state = &This->state; 2916 2917 user_assert(StartRegister < This->caps.MaxVertexShaderConst, D3DERR_INVALIDCALL); 2918 user_assert(StartRegister + Vector4fCount <= This->caps.MaxVertexShaderConst, D3DERR_INVALIDCALL); 2919 user_assert(pConstantData, D3DERR_INVALIDCALL); 2920 2921 memcpy(pConstantData, 2922 &state->vs_const_f[StartRegister * 4], 2923 Vector4fCount * 4 * sizeof(state->vs_const_f[0])); 2924 2925 return D3D_OK; 2926} 2927 2928HRESULT WINAPI 2929NineDevice9_SetVertexShaderConstantI( struct NineDevice9 *This, 2930 UINT StartRegister, 2931 const int *pConstantData, 2932 UINT Vector4iCount ) 2933{ 2934 struct nine_state *state = This->update; 2935 2936 DBG("This=%p StartRegister=%u pConstantData=%p Vector4iCount=%u\n", 2937 This, StartRegister, pConstantData, Vector4iCount); 2938 2939 user_assert(StartRegister < NINE_MAX_CONST_I, D3DERR_INVALIDCALL); 2940 user_assert(StartRegister + Vector4iCount <= NINE_MAX_CONST_I, D3DERR_INVALIDCALL); 2941 user_assert(pConstantData, D3DERR_INVALIDCALL); 2942 2943 memcpy(&state->vs_const_i[StartRegister][0], 2944 pConstantData, 2945 Vector4iCount * sizeof(state->vs_const_i[0])); 2946 2947 state->changed.vs_const_i |= ((1 << Vector4iCount) - 1) << StartRegister; 2948 state->changed.group |= NINE_STATE_VS_CONST; 2949 2950 return D3D_OK; 2951} 2952 2953HRESULT WINAPI 2954NineDevice9_GetVertexShaderConstantI( struct NineDevice9 *This, 2955 UINT StartRegister, 2956 int *pConstantData, 2957 UINT Vector4iCount ) 2958{ 2959 const struct nine_state *state = &This->state; 2960 2961 user_assert(StartRegister < NINE_MAX_CONST_I, D3DERR_INVALIDCALL); 2962 user_assert(StartRegister + Vector4iCount <= NINE_MAX_CONST_I, D3DERR_INVALIDCALL); 2963 user_assert(pConstantData, D3DERR_INVALIDCALL); 2964 2965 memcpy(pConstantData, 2966 &state->vs_const_i[StartRegister][0], 2967 Vector4iCount * sizeof(state->vs_const_i[0])); 2968 2969 return D3D_OK; 2970} 2971 2972HRESULT WINAPI 2973NineDevice9_SetVertexShaderConstantB( struct NineDevice9 *This, 2974 UINT StartRegister, 2975 const BOOL *pConstantData, 2976 UINT BoolCount ) 2977{ 2978 struct nine_state *state = This->update; 2979 int i; 2980 uint32_t bool_true = This->driver_caps.vs_integer ? 0xFFFFFFFF : fui(1.0f); 2981 2982 DBG("This=%p StartRegister=%u pConstantData=%p BoolCount=%u\n", 2983 This, StartRegister, pConstantData, BoolCount); 2984 2985 user_assert(StartRegister < NINE_MAX_CONST_B, D3DERR_INVALIDCALL); 2986 user_assert(StartRegister + BoolCount <= NINE_MAX_CONST_B, D3DERR_INVALIDCALL); 2987 user_assert(pConstantData, D3DERR_INVALIDCALL); 2988 2989 for (i = 0; i < BoolCount; i++) 2990 state->vs_const_b[StartRegister + i] = pConstantData[i] ? bool_true : 0; 2991 2992 state->changed.vs_const_b |= ((1 << BoolCount) - 1) << StartRegister; 2993 state->changed.group |= NINE_STATE_VS_CONST; 2994 2995 return D3D_OK; 2996} 2997 2998HRESULT WINAPI 2999NineDevice9_GetVertexShaderConstantB( struct NineDevice9 *This, 3000 UINT StartRegister, 3001 BOOL *pConstantData, 3002 UINT BoolCount ) 3003{ 3004 const struct nine_state *state = &This->state; 3005 int i; 3006 3007 user_assert(StartRegister < NINE_MAX_CONST_B, D3DERR_INVALIDCALL); 3008 user_assert(StartRegister + BoolCount <= NINE_MAX_CONST_B, D3DERR_INVALIDCALL); 3009 user_assert(pConstantData, D3DERR_INVALIDCALL); 3010 3011 for (i = 0; i < BoolCount; i++) 3012 pConstantData[i] = state->vs_const_b[StartRegister + i] != 0 ? TRUE : FALSE; 3013 3014 return D3D_OK; 3015} 3016 3017HRESULT WINAPI 3018NineDevice9_SetStreamSource( struct NineDevice9 *This, 3019 UINT StreamNumber, 3020 IDirect3DVertexBuffer9 *pStreamData, 3021 UINT OffsetInBytes, 3022 UINT Stride ) 3023{ 3024 struct nine_state *state = This->update; 3025 struct NineVertexBuffer9 *pVBuf9 = NineVertexBuffer9(pStreamData); 3026 const unsigned i = StreamNumber; 3027 3028 DBG("This=%p StreamNumber=%u pStreamData=%p OffsetInBytes=%u Stride=%u\n", 3029 This, StreamNumber, pStreamData, OffsetInBytes, Stride); 3030 3031 user_assert(StreamNumber < This->caps.MaxStreams, D3DERR_INVALIDCALL); 3032 user_assert(Stride <= This->caps.MaxStreamStride, D3DERR_INVALIDCALL); 3033 3034 if (likely(!This->is_recording)) { 3035 if (state->stream[i] == NineVertexBuffer9(pStreamData) && 3036 state->vtxbuf[i].stride == Stride && 3037 state->vtxbuf[i].buffer_offset == OffsetInBytes) 3038 return D3D_OK; 3039 } 3040 nine_bind(&state->stream[i], pStreamData); 3041 3042 state->changed.vtxbuf |= 1 << StreamNumber; 3043 3044 if (pStreamData) { 3045 state->vtxbuf[i].stride = Stride; 3046 state->vtxbuf[i].buffer_offset = OffsetInBytes; 3047 } 3048 state->vtxbuf[i].buffer = pStreamData ? pVBuf9->base.resource : NULL; 3049 3050 return D3D_OK; 3051} 3052 3053HRESULT WINAPI 3054NineDevice9_GetStreamSource( struct NineDevice9 *This, 3055 UINT StreamNumber, 3056 IDirect3DVertexBuffer9 **ppStreamData, 3057 UINT *pOffsetInBytes, 3058 UINT *pStride ) 3059{ 3060 const struct nine_state *state = &This->state; 3061 const unsigned i = StreamNumber; 3062 3063 user_assert(StreamNumber < This->caps.MaxStreams, D3DERR_INVALIDCALL); 3064 user_assert(ppStreamData, D3DERR_INVALIDCALL); 3065 3066 nine_reference_set(ppStreamData, state->stream[i]); 3067 *pStride = state->vtxbuf[i].stride; 3068 *pOffsetInBytes = state->vtxbuf[i].buffer_offset; 3069 3070 return D3D_OK; 3071} 3072 3073HRESULT WINAPI 3074NineDevice9_SetStreamSourceFreq( struct NineDevice9 *This, 3075 UINT StreamNumber, 3076 UINT Setting ) 3077{ 3078 struct nine_state *state = This->update; 3079 /* const UINT freq = Setting & 0x7FFFFF; */ 3080 3081 DBG("This=%p StreamNumber=%u FrequencyParameter=0x%x\n", This, 3082 StreamNumber, Setting); 3083 3084 user_assert(StreamNumber < This->caps.MaxStreams, D3DERR_INVALIDCALL); 3085 user_assert(StreamNumber != 0 || !(Setting & D3DSTREAMSOURCE_INSTANCEDATA), 3086 D3DERR_INVALIDCALL); 3087 user_assert(!((Setting & D3DSTREAMSOURCE_INSTANCEDATA) && 3088 (Setting & D3DSTREAMSOURCE_INDEXEDDATA)), D3DERR_INVALIDCALL); 3089 user_assert(Setting, D3DERR_INVALIDCALL); 3090 3091 state->stream_freq[StreamNumber] = Setting; 3092 3093 if (Setting & D3DSTREAMSOURCE_INSTANCEDATA) 3094 state->stream_instancedata_mask |= 1 << StreamNumber; 3095 else 3096 state->stream_instancedata_mask &= ~(1 << StreamNumber); 3097 3098 state->changed.stream_freq |= 1 << StreamNumber; 3099 return D3D_OK; 3100} 3101 3102HRESULT WINAPI 3103NineDevice9_GetStreamSourceFreq( struct NineDevice9 *This, 3104 UINT StreamNumber, 3105 UINT *pSetting ) 3106{ 3107 user_assert(StreamNumber < This->caps.MaxStreams, D3DERR_INVALIDCALL); 3108 *pSetting = This->state.stream_freq[StreamNumber]; 3109 return D3D_OK; 3110} 3111 3112HRESULT WINAPI 3113NineDevice9_SetIndices( struct NineDevice9 *This, 3114 IDirect3DIndexBuffer9 *pIndexData ) 3115{ 3116 struct nine_state *state = This->update; 3117 3118 DBG("This=%p pIndexData=%p\n", This, pIndexData); 3119 3120 if (likely(!This->is_recording)) 3121 if (state->idxbuf == NineIndexBuffer9(pIndexData)) 3122 return D3D_OK; 3123 nine_bind(&state->idxbuf, pIndexData); 3124 3125 state->changed.group |= NINE_STATE_IDXBUF; 3126 3127 return D3D_OK; 3128} 3129 3130/* XXX: wine/d3d9 doesn't have pBaseVertexIndex, and it doesn't make sense 3131 * here because it's an argument passed to the Draw calls. 3132 */ 3133HRESULT WINAPI 3134NineDevice9_GetIndices( struct NineDevice9 *This, 3135 IDirect3DIndexBuffer9 **ppIndexData /*, 3136 UINT *pBaseVertexIndex */ ) 3137{ 3138 user_assert(ppIndexData, D3DERR_INVALIDCALL); 3139 nine_reference_set(ppIndexData, This->state.idxbuf); 3140 return D3D_OK; 3141} 3142 3143HRESULT WINAPI 3144NineDevice9_CreatePixelShader( struct NineDevice9 *This, 3145 const DWORD *pFunction, 3146 IDirect3DPixelShader9 **ppShader ) 3147{ 3148 struct NinePixelShader9 *ps; 3149 HRESULT hr; 3150 3151 DBG("This=%p pFunction=%p ppShader=%p\n", This, pFunction, ppShader); 3152 3153 hr = NinePixelShader9_new(This, &ps, pFunction, NULL); 3154 if (FAILED(hr)) 3155 return hr; 3156 *ppShader = (IDirect3DPixelShader9 *)ps; 3157 return D3D_OK; 3158} 3159 3160HRESULT WINAPI 3161NineDevice9_SetPixelShader( struct NineDevice9 *This, 3162 IDirect3DPixelShader9 *pShader ) 3163{ 3164 struct nine_state *state = This->update; 3165 3166 DBG("This=%p pShader=%p\n", This, pShader); 3167 3168 nine_bind(&state->ps, pShader); 3169 3170 state->changed.group |= NINE_STATE_PS; 3171 3172 return D3D_OK; 3173} 3174 3175HRESULT WINAPI 3176NineDevice9_GetPixelShader( struct NineDevice9 *This, 3177 IDirect3DPixelShader9 **ppShader ) 3178{ 3179 user_assert(ppShader, D3DERR_INVALIDCALL); 3180 nine_reference_set(ppShader, This->state.ps); 3181 return D3D_OK; 3182} 3183 3184HRESULT WINAPI 3185NineDevice9_SetPixelShaderConstantF( struct NineDevice9 *This, 3186 UINT StartRegister, 3187 const float *pConstantData, 3188 UINT Vector4fCount ) 3189{ 3190 struct nine_state *state = This->update; 3191 3192 DBG("This=%p StartRegister=%u pConstantData=%p Vector4fCount=%u\n", 3193 This, StartRegister, pConstantData, Vector4fCount); 3194 3195 user_assert(StartRegister < NINE_MAX_CONST_F, D3DERR_INVALIDCALL); 3196 user_assert(StartRegister + Vector4fCount <= NINE_MAX_CONST_F, D3DERR_INVALIDCALL); 3197 3198 if (!Vector4fCount) 3199 return D3D_OK; 3200 user_assert(pConstantData, D3DERR_INVALIDCALL); 3201 3202 memcpy(&state->ps_const_f[StartRegister * 4], 3203 pConstantData, 3204 Vector4fCount * 4 * sizeof(state->ps_const_f[0])); 3205 3206 nine_ranges_insert(&state->changed.ps_const_f, 3207 StartRegister, StartRegister + Vector4fCount, 3208 &This->range_pool); 3209 3210 state->changed.group |= NINE_STATE_PS_CONST; 3211 3212 return D3D_OK; 3213} 3214 3215HRESULT WINAPI 3216NineDevice9_GetPixelShaderConstantF( struct NineDevice9 *This, 3217 UINT StartRegister, 3218 float *pConstantData, 3219 UINT Vector4fCount ) 3220{ 3221 const struct nine_state *state = &This->state; 3222 3223 user_assert(StartRegister < NINE_MAX_CONST_F, D3DERR_INVALIDCALL); 3224 user_assert(StartRegister + Vector4fCount <= NINE_MAX_CONST_F, D3DERR_INVALIDCALL); 3225 user_assert(pConstantData, D3DERR_INVALIDCALL); 3226 3227 memcpy(pConstantData, 3228 &state->ps_const_f[StartRegister * 4], 3229 Vector4fCount * 4 * sizeof(state->ps_const_f[0])); 3230 3231 return D3D_OK; 3232} 3233 3234HRESULT WINAPI 3235NineDevice9_SetPixelShaderConstantI( struct NineDevice9 *This, 3236 UINT StartRegister, 3237 const int *pConstantData, 3238 UINT Vector4iCount ) 3239{ 3240 struct nine_state *state = This->update; 3241 3242 DBG("This=%p StartRegister=%u pConstantData=%p Vector4iCount=%u\n", 3243 This, StartRegister, pConstantData, Vector4iCount); 3244 3245 user_assert(StartRegister < NINE_MAX_CONST_I, D3DERR_INVALIDCALL); 3246 user_assert(StartRegister + Vector4iCount <= NINE_MAX_CONST_I, D3DERR_INVALIDCALL); 3247 user_assert(pConstantData, D3DERR_INVALIDCALL); 3248 3249 memcpy(&state->ps_const_i[StartRegister][0], 3250 pConstantData, 3251 Vector4iCount * sizeof(state->ps_const_i[0])); 3252 3253 state->changed.ps_const_i |= ((1 << Vector4iCount) - 1) << StartRegister; 3254 state->changed.group |= NINE_STATE_PS_CONST; 3255 3256 return D3D_OK; 3257} 3258 3259HRESULT WINAPI 3260NineDevice9_GetPixelShaderConstantI( struct NineDevice9 *This, 3261 UINT StartRegister, 3262 int *pConstantData, 3263 UINT Vector4iCount ) 3264{ 3265 const struct nine_state *state = &This->state; 3266 3267 user_assert(StartRegister < NINE_MAX_CONST_I, D3DERR_INVALIDCALL); 3268 user_assert(StartRegister + Vector4iCount <= NINE_MAX_CONST_I, D3DERR_INVALIDCALL); 3269 user_assert(pConstantData, D3DERR_INVALIDCALL); 3270 3271 memcpy(pConstantData, 3272 &state->ps_const_i[StartRegister][0], 3273 Vector4iCount * sizeof(state->ps_const_i[0])); 3274 3275 return D3D_OK; 3276} 3277 3278HRESULT WINAPI 3279NineDevice9_SetPixelShaderConstantB( struct NineDevice9 *This, 3280 UINT StartRegister, 3281 const BOOL *pConstantData, 3282 UINT BoolCount ) 3283{ 3284 struct nine_state *state = This->update; 3285 int i; 3286 uint32_t bool_true = This->driver_caps.ps_integer ? 0xFFFFFFFF : fui(1.0f); 3287 3288 DBG("This=%p StartRegister=%u pConstantData=%p BoolCount=%u\n", 3289 This, StartRegister, pConstantData, BoolCount); 3290 3291 user_assert(StartRegister < NINE_MAX_CONST_B, D3DERR_INVALIDCALL); 3292 user_assert(StartRegister + BoolCount <= NINE_MAX_CONST_B, D3DERR_INVALIDCALL); 3293 user_assert(pConstantData, D3DERR_INVALIDCALL); 3294 3295 for (i = 0; i < BoolCount; i++) 3296 state->ps_const_b[StartRegister + i] = pConstantData[i] ? bool_true : 0; 3297 3298 state->changed.ps_const_b |= ((1 << BoolCount) - 1) << StartRegister; 3299 state->changed.group |= NINE_STATE_PS_CONST; 3300 3301 return D3D_OK; 3302} 3303 3304HRESULT WINAPI 3305NineDevice9_GetPixelShaderConstantB( struct NineDevice9 *This, 3306 UINT StartRegister, 3307 BOOL *pConstantData, 3308 UINT BoolCount ) 3309{ 3310 const struct nine_state *state = &This->state; 3311 int i; 3312 3313 user_assert(StartRegister < NINE_MAX_CONST_B, D3DERR_INVALIDCALL); 3314 user_assert(StartRegister + BoolCount <= NINE_MAX_CONST_B, D3DERR_INVALIDCALL); 3315 user_assert(pConstantData, D3DERR_INVALIDCALL); 3316 3317 for (i = 0; i < BoolCount; i++) 3318 pConstantData[i] = state->ps_const_b[StartRegister + i] ? TRUE : FALSE; 3319 3320 return D3D_OK; 3321} 3322 3323HRESULT WINAPI 3324NineDevice9_DrawRectPatch( struct NineDevice9 *This, 3325 UINT Handle, 3326 const float *pNumSegs, 3327 const D3DRECTPATCH_INFO *pRectPatchInfo ) 3328{ 3329 STUB(D3DERR_INVALIDCALL); 3330} 3331 3332HRESULT WINAPI 3333NineDevice9_DrawTriPatch( struct NineDevice9 *This, 3334 UINT Handle, 3335 const float *pNumSegs, 3336 const D3DTRIPATCH_INFO *pTriPatchInfo ) 3337{ 3338 STUB(D3DERR_INVALIDCALL); 3339} 3340 3341HRESULT WINAPI 3342NineDevice9_DeletePatch( struct NineDevice9 *This, 3343 UINT Handle ) 3344{ 3345 STUB(D3DERR_INVALIDCALL); 3346} 3347 3348HRESULT WINAPI 3349NineDevice9_CreateQuery( struct NineDevice9 *This, 3350 D3DQUERYTYPE Type, 3351 IDirect3DQuery9 **ppQuery ) 3352{ 3353 struct NineQuery9 *query; 3354 HRESULT hr; 3355 3356 DBG("This=%p Type=%d ppQuery=%p\n", This, Type, ppQuery); 3357 3358 hr = nine_is_query_supported(This->screen, Type); 3359 if (!ppQuery || hr != D3D_OK) 3360 return hr; 3361 3362 hr = NineQuery9_new(This, &query, Type); 3363 if (FAILED(hr)) 3364 return hr; 3365 *ppQuery = (IDirect3DQuery9 *)query; 3366 return D3D_OK; 3367} 3368 3369IDirect3DDevice9Vtbl NineDevice9_vtable = { 3370 (void *)NineUnknown_QueryInterface, 3371 (void *)NineUnknown_AddRef, 3372 (void *)NineUnknown_Release, 3373 (void *)NineDevice9_TestCooperativeLevel, 3374 (void *)NineDevice9_GetAvailableTextureMem, 3375 (void *)NineDevice9_EvictManagedResources, 3376 (void *)NineDevice9_GetDirect3D, 3377 (void *)NineDevice9_GetDeviceCaps, 3378 (void *)NineDevice9_GetDisplayMode, 3379 (void *)NineDevice9_GetCreationParameters, 3380 (void *)NineDevice9_SetCursorProperties, 3381 (void *)NineDevice9_SetCursorPosition, 3382 (void *)NineDevice9_ShowCursor, 3383 (void *)NineDevice9_CreateAdditionalSwapChain, 3384 (void *)NineDevice9_GetSwapChain, 3385 (void *)NineDevice9_GetNumberOfSwapChains, 3386 (void *)NineDevice9_Reset, 3387 (void *)NineDevice9_Present, 3388 (void *)NineDevice9_GetBackBuffer, 3389 (void *)NineDevice9_GetRasterStatus, 3390 (void *)NineDevice9_SetDialogBoxMode, 3391 (void *)NineDevice9_SetGammaRamp, 3392 (void *)NineDevice9_GetGammaRamp, 3393 (void *)NineDevice9_CreateTexture, 3394 (void *)NineDevice9_CreateVolumeTexture, 3395 (void *)NineDevice9_CreateCubeTexture, 3396 (void *)NineDevice9_CreateVertexBuffer, 3397 (void *)NineDevice9_CreateIndexBuffer, 3398 (void *)NineDevice9_CreateRenderTarget, 3399 (void *)NineDevice9_CreateDepthStencilSurface, 3400 (void *)NineDevice9_UpdateSurface, 3401 (void *)NineDevice9_UpdateTexture, 3402 (void *)NineDevice9_GetRenderTargetData, 3403 (void *)NineDevice9_GetFrontBufferData, 3404 (void *)NineDevice9_StretchRect, 3405 (void *)NineDevice9_ColorFill, 3406 (void *)NineDevice9_CreateOffscreenPlainSurface, 3407 (void *)NineDevice9_SetRenderTarget, 3408 (void *)NineDevice9_GetRenderTarget, 3409 (void *)NineDevice9_SetDepthStencilSurface, 3410 (void *)NineDevice9_GetDepthStencilSurface, 3411 (void *)NineDevice9_BeginScene, 3412 (void *)NineDevice9_EndScene, 3413 (void *)NineDevice9_Clear, 3414 (void *)NineDevice9_SetTransform, 3415 (void *)NineDevice9_GetTransform, 3416 (void *)NineDevice9_MultiplyTransform, 3417 (void *)NineDevice9_SetViewport, 3418 (void *)NineDevice9_GetViewport, 3419 (void *)NineDevice9_SetMaterial, 3420 (void *)NineDevice9_GetMaterial, 3421 (void *)NineDevice9_SetLight, 3422 (void *)NineDevice9_GetLight, 3423 (void *)NineDevice9_LightEnable, 3424 (void *)NineDevice9_GetLightEnable, 3425 (void *)NineDevice9_SetClipPlane, 3426 (void *)NineDevice9_GetClipPlane, 3427 (void *)NineDevice9_SetRenderState, 3428 (void *)NineDevice9_GetRenderState, 3429 (void *)NineDevice9_CreateStateBlock, 3430 (void *)NineDevice9_BeginStateBlock, 3431 (void *)NineDevice9_EndStateBlock, 3432 (void *)NineDevice9_SetClipStatus, 3433 (void *)NineDevice9_GetClipStatus, 3434 (void *)NineDevice9_GetTexture, 3435 (void *)NineDevice9_SetTexture, 3436 (void *)NineDevice9_GetTextureStageState, 3437 (void *)NineDevice9_SetTextureStageState, 3438 (void *)NineDevice9_GetSamplerState, 3439 (void *)NineDevice9_SetSamplerState, 3440 (void *)NineDevice9_ValidateDevice, 3441 (void *)NineDevice9_SetPaletteEntries, 3442 (void *)NineDevice9_GetPaletteEntries, 3443 (void *)NineDevice9_SetCurrentTexturePalette, 3444 (void *)NineDevice9_GetCurrentTexturePalette, 3445 (void *)NineDevice9_SetScissorRect, 3446 (void *)NineDevice9_GetScissorRect, 3447 (void *)NineDevice9_SetSoftwareVertexProcessing, 3448 (void *)NineDevice9_GetSoftwareVertexProcessing, 3449 (void *)NineDevice9_SetNPatchMode, 3450 (void *)NineDevice9_GetNPatchMode, 3451 (void *)NineDevice9_DrawPrimitive, 3452 (void *)NineDevice9_DrawIndexedPrimitive, 3453 (void *)NineDevice9_DrawPrimitiveUP, 3454 (void *)NineDevice9_DrawIndexedPrimitiveUP, 3455 (void *)NineDevice9_ProcessVertices, 3456 (void *)NineDevice9_CreateVertexDeclaration, 3457 (void *)NineDevice9_SetVertexDeclaration, 3458 (void *)NineDevice9_GetVertexDeclaration, 3459 (void *)NineDevice9_SetFVF, 3460 (void *)NineDevice9_GetFVF, 3461 (void *)NineDevice9_CreateVertexShader, 3462 (void *)NineDevice9_SetVertexShader, 3463 (void *)NineDevice9_GetVertexShader, 3464 (void *)NineDevice9_SetVertexShaderConstantF, 3465 (void *)NineDevice9_GetVertexShaderConstantF, 3466 (void *)NineDevice9_SetVertexShaderConstantI, 3467 (void *)NineDevice9_GetVertexShaderConstantI, 3468 (void *)NineDevice9_SetVertexShaderConstantB, 3469 (void *)NineDevice9_GetVertexShaderConstantB, 3470 (void *)NineDevice9_SetStreamSource, 3471 (void *)NineDevice9_GetStreamSource, 3472 (void *)NineDevice9_SetStreamSourceFreq, 3473 (void *)NineDevice9_GetStreamSourceFreq, 3474 (void *)NineDevice9_SetIndices, 3475 (void *)NineDevice9_GetIndices, 3476 (void *)NineDevice9_CreatePixelShader, 3477 (void *)NineDevice9_SetPixelShader, 3478 (void *)NineDevice9_GetPixelShader, 3479 (void *)NineDevice9_SetPixelShaderConstantF, 3480 (void *)NineDevice9_GetPixelShaderConstantF, 3481 (void *)NineDevice9_SetPixelShaderConstantI, 3482 (void *)NineDevice9_GetPixelShaderConstantI, 3483 (void *)NineDevice9_SetPixelShaderConstantB, 3484 (void *)NineDevice9_GetPixelShaderConstantB, 3485 (void *)NineDevice9_DrawRectPatch, 3486 (void *)NineDevice9_DrawTriPatch, 3487 (void *)NineDevice9_DeletePatch, 3488 (void *)NineDevice9_CreateQuery 3489}; 3490 3491static const GUID *NineDevice9_IIDs[] = { 3492 &IID_IDirect3DDevice9, 3493 &IID_IUnknown, 3494 NULL 3495}; 3496 3497HRESULT 3498NineDevice9_new( struct pipe_screen *pScreen, 3499 D3DDEVICE_CREATION_PARAMETERS *pCreationParameters, 3500 D3DCAPS9 *pCaps, 3501 D3DPRESENT_PARAMETERS *pPresentationParameters, 3502 IDirect3D9 *pD3D9, 3503 ID3DPresentGroup *pPresentationGroup, 3504 struct d3dadapter9_context *pCTX, 3505 boolean ex, 3506 D3DDISPLAYMODEEX *pFullscreenDisplayMode, 3507 struct NineDevice9 **ppOut ) 3508{ 3509 BOOL lock; 3510 lock = !!(pCreationParameters->BehaviorFlags & D3DCREATE_MULTITHREADED); 3511 3512 NINE_NEW(Device9, ppOut, lock, /* args */ 3513 pScreen, pCreationParameters, pCaps, 3514 pPresentationParameters, pD3D9, pPresentationGroup, pCTX, 3515 ex, pFullscreenDisplayMode); 3516} 3517