2 * Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
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:
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
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. */
24 #include "stateblock9.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"
35 #include "cubetexture9.h"
36 #include "volumetexture9.h"
37 #include "nine_helpers.h"
38 #include "nine_pipe.h"
40 #include "nine_dump.h"
42 #include "pipe/p_screen.h"
43 #include "pipe/p_context.h"
44 #include "pipe/p_config.h"
45 #include "util/u_math.h"
46 #include "util/u_inlines.h"
47 #include "util/u_hash_table.h"
48 #include "util/u_format.h"
49 #include "util/u_surface.h"
50 #include "util/u_upload_mgr.h"
51 #include "hud/hud_context.h"
53 #include "cso_cache/cso_context.h"
55 #define DBG_CHANNEL DBG_DEVICE
57 #if defined(PIPE_CC_GCC) && (defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64))
59 #include <fpu_control.h>
61 static void nine_setup_fpu()
66 /* clear the control word */
68 /* d3d9 doc/wine tests: mask all exceptions, use single-precision
69 * and round to nearest */
70 c
|= _FPU_MASK_IM
| _FPU_MASK_DM
| _FPU_MASK_ZM
| _FPU_MASK_OM
|
71 _FPU_MASK_UM
| _FPU_MASK_PM
| _FPU_SINGLE
| _FPU_RC_NEAREST
;
77 static void nine_setup_fpu(void)
79 WARN_ONCE("FPU setup not supported on non-x86 platforms\n");
85 NineDevice9_SetDefaultState( struct NineDevice9
*This
, boolean is_reset
)
87 struct NineSurface9
*refSurf
= NULL
;
89 DBG("This=%p is_reset=%d\n", This
, (int) is_reset
);
91 assert(!This
->is_recording
);
93 nine_state_set_defaults(This
, &This
->caps
, is_reset
);
95 This
->state
.viewport
.X
= 0;
96 This
->state
.viewport
.Y
= 0;
97 This
->state
.viewport
.Width
= 0;
98 This
->state
.viewport
.Height
= 0;
100 This
->state
.scissor
.minx
= 0;
101 This
->state
.scissor
.miny
= 0;
102 This
->state
.scissor
.maxx
= 0xffff;
103 This
->state
.scissor
.maxy
= 0xffff;
105 if (This
->nswapchains
&& This
->swapchains
[0]->params
.BackBufferCount
)
106 refSurf
= This
->swapchains
[0]->buffers
[0];
109 This
->state
.viewport
.Width
= refSurf
->desc
.Width
;
110 This
->state
.viewport
.Height
= refSurf
->desc
.Height
;
111 This
->state
.scissor
.maxx
= refSurf
->desc
.Width
;
112 This
->state
.scissor
.maxy
= refSurf
->desc
.Height
;
115 if (This
->nswapchains
&& This
->swapchains
[0]->params
.EnableAutoDepthStencil
)
116 This
->state
.rs
[D3DRS_ZENABLE
] = TRUE
;
117 if (This
->state
.rs
[D3DRS_ZENABLE
])
118 NineDevice9_SetDepthStencilSurface(
119 This
, (IDirect3DSurface9
*)This
->swapchains
[0]->zsbuf
);
123 NineDevice9_RestoreNonCSOState( struct NineDevice9
*This
, unsigned mask
)
125 struct pipe_context
*pipe
= This
->pipe
;
127 DBG("This=%p mask=%u\n", This
, mask
);
130 struct pipe_constant_buffer cb
;
131 cb
.buffer_offset
= 0;
133 if (This
->prefer_user_constbuf
) {
135 cb
.user_buffer
= This
->state
.vs_const_f
;
137 cb
.buffer
= This
->constbuf_vs
;
138 cb
.user_buffer
= NULL
;
140 cb
.buffer_size
= This
->vs_const_size
;
141 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_VERTEX
, 0, &cb
);
143 if (This
->prefer_user_constbuf
) {
144 cb
.user_buffer
= This
->state
.ps_const_f
;
146 cb
.buffer
= This
->constbuf_ps
;
148 cb
.buffer_size
= This
->ps_const_size
;
149 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_FRAGMENT
, 0, &cb
);
153 struct pipe_poly_stipple stipple
;
154 memset(&stipple
, ~0, sizeof(stipple
));
155 pipe
->set_polygon_stipple(pipe
, &stipple
);
158 This
->state
.changed
.group
= NINE_STATE_ALL
;
159 This
->state
.changed
.vtxbuf
= (1ULL << This
->caps
.MaxStreams
) - 1;
160 This
->state
.changed
.ucp
= (1 << PIPE_MAX_CLIP_PLANES
) - 1;
161 This
->state
.changed
.texture
= NINE_PS_SAMPLERS_MASK
| NINE_VS_SAMPLERS_MASK
;
164 #define GET_PCAP(n) pScreen->get_param(pScreen, PIPE_CAP_##n)
166 NineDevice9_ctor( struct NineDevice9
*This
,
167 struct NineUnknownParams
*pParams
,
168 struct pipe_screen
*pScreen
,
169 D3DDEVICE_CREATION_PARAMETERS
*pCreationParameters
,
171 D3DPRESENT_PARAMETERS
*pPresentationParameters
,
173 ID3DPresentGroup
*pPresentationGroup
,
174 struct d3dadapter9_context
*pCTX
,
176 D3DDISPLAYMODEEX
*pFullscreenDisplayMode
)
179 HRESULT hr
= NineUnknown_ctor(&This
->base
, pParams
);
181 DBG("This=%p pParams=%p pScreen=%p pCreationParameters=%p pCaps=%p pPresentationParameters=%p "
182 "pD3D9=%p pPresentationGroup=%p pCTX=%p ex=%d pFullscreenDisplayMode=%p\n",
183 This
, pParams
, pScreen
, pCreationParameters
, pCaps
, pPresentationParameters
, pD3D9
,
184 pPresentationGroup
, pCTX
, (int) ex
, pFullscreenDisplayMode
);
186 if (FAILED(hr
)) { return hr
; }
188 list_inithead(&This
->update_textures
);
190 This
->screen
= pScreen
;
193 This
->params
= *pCreationParameters
;
195 This
->present
= pPresentationGroup
;
196 IDirect3D9_AddRef(This
->d3d9
);
197 ID3DPresentGroup_AddRef(This
->present
);
199 if (!(This
->params
.BehaviorFlags
& D3DCREATE_FPU_PRESERVE
))
202 if (This
->params
.BehaviorFlags
& D3DCREATE_SOFTWARE_VERTEXPROCESSING
)
203 DBG("Application asked full Software Vertex Processing. Ignoring.\n");
204 if (This
->params
.BehaviorFlags
& D3DCREATE_MIXED_VERTEXPROCESSING
)
205 DBG("Application asked mixed Software Vertex Processing. Ignoring.\n");
207 This
->pipe
= This
->screen
->context_create(This
->screen
, NULL
);
208 if (!This
->pipe
) { return E_OUTOFMEMORY
; } /* guess */
210 This
->cso
= cso_create_context(This
->pipe
);
211 if (!This
->cso
) { return E_OUTOFMEMORY
; } /* also a guess */
213 /* Create first, it messes up our state. */
214 This
->hud
= hud_create(This
->pipe
, This
->cso
); /* NULL result is fine */
216 /* create implicit swapchains */
217 This
->nswapchains
= ID3DPresentGroup_GetMultiheadCount(This
->present
);
218 This
->swapchains
= CALLOC(This
->nswapchains
,
219 sizeof(struct NineSwapChain9
*));
220 if (!This
->swapchains
) { return E_OUTOFMEMORY
; }
222 for (i
= 0; i
< This
->nswapchains
; ++i
) {
223 ID3DPresent
*present
;
225 hr
= ID3DPresentGroup_GetPresent(This
->present
, i
, &present
);
230 D3DDISPLAYMODEEX
*mode
= NULL
;
231 struct NineSwapChain9Ex
**ret
=
232 (struct NineSwapChain9Ex
**)&This
->swapchains
[i
];
234 if (pFullscreenDisplayMode
) mode
= &(pFullscreenDisplayMode
[i
]);
235 /* when this is a Device9Ex, it should create SwapChain9Exs */
236 hr
= NineSwapChain9Ex_new(This
, TRUE
, present
,
237 &pPresentationParameters
[i
], pCTX
,
238 This
->params
.hFocusWindow
, mode
, ret
);
240 hr
= NineSwapChain9_new(This
, TRUE
, present
,
241 &pPresentationParameters
[i
], pCTX
,
242 This
->params
.hFocusWindow
,
243 &This
->swapchains
[i
]);
246 ID3DPresent_Release(present
);
249 NineUnknown_ConvertRefToBind(NineUnknown(This
->swapchains
[i
]));
251 hr
= NineSwapChain9_GetBackBuffer(This
->swapchains
[i
], 0,
252 D3DBACKBUFFER_TYPE_MONO
,
253 (IDirect3DSurface9
**)
257 NineUnknown_ConvertRefToBind(NineUnknown(This
->state
.rt
[i
]));
260 /* Initialize a dummy VBO to be used when a a vertex declaration does not
261 * specify all the inputs needed by vertex shader, on win default behavior
262 * is to pass 0,0,0,0 to the shader */
264 struct pipe_transfer
*transfer
;
265 struct pipe_resource tmpl
;
269 tmpl
.target
= PIPE_BUFFER
;
270 tmpl
.format
= PIPE_FORMAT_R8_UNORM
;
271 tmpl
.width0
= 16; /* 4 floats */
277 tmpl
.usage
= PIPE_USAGE_DEFAULT
;
278 tmpl
.bind
= PIPE_BIND_VERTEX_BUFFER
| PIPE_BIND_TRANSFER_WRITE
;
280 This
->dummy_vbo
= pScreen
->resource_create(pScreen
, &tmpl
);
282 if (!This
->dummy_vbo
)
283 return D3DERR_OUTOFVIDEOMEMORY
;
285 u_box_1d(0, 16, &box
);
286 data
= This
->pipe
->transfer_map(This
->pipe
, This
->dummy_vbo
, 0,
287 PIPE_TRANSFER_WRITE
|
288 PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
,
293 This
->pipe
->transfer_unmap(This
->pipe
, transfer
);
296 This
->cursor
.software
= FALSE
;
297 This
->cursor
.hotspot
.x
= -1;
298 This
->cursor
.hotspot
.y
= -1;
300 struct pipe_resource tmpl
;
301 tmpl
.target
= PIPE_TEXTURE_2D
;
302 tmpl
.format
= PIPE_FORMAT_R8G8B8A8_UNORM
;
309 tmpl
.usage
= PIPE_USAGE_DEFAULT
;
310 tmpl
.bind
= PIPE_BIND_CURSOR
| PIPE_BIND_SAMPLER_VIEW
;
313 This
->cursor
.image
= pScreen
->resource_create(pScreen
, &tmpl
);
314 if (!This
->cursor
.image
)
315 return D3DERR_OUTOFVIDEOMEMORY
;
318 /* Create constant buffers. */
320 struct pipe_resource tmpl
;
321 unsigned max_const_vs
, max_const_ps
;
323 /* vs 3.0: >= 256 float constants, but for cards with exactly 256 slots,
324 * we have to take in some more slots for int and bool*/
325 max_const_vs
= _min(pScreen
->get_shader_param(pScreen
, PIPE_SHADER_VERTEX
,
326 PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE
) /
329 /* ps 3.0: 224 float constants. All cards supported support at least
330 * 256 constants for ps */
331 max_const_ps
= NINE_MAX_CONST_F_PS3
+ (NINE_MAX_CONST_I
+ NINE_MAX_CONST_B
/ 4);
333 This
->max_vs_const_f
= max_const_vs
-
334 (NINE_MAX_CONST_I
+ NINE_MAX_CONST_B
/ 4);
335 This
->max_ps_const_f
= max_const_ps
-
336 (NINE_MAX_CONST_I
+ NINE_MAX_CONST_B
/ 4);
338 This
->vs_const_size
= max_const_vs
* sizeof(float[4]);
339 This
->ps_const_size
= max_const_ps
* sizeof(float[4]);
340 /* Include space for I,B constants for user constbuf. */
341 This
->state
.vs_const_f
= CALLOC(This
->vs_const_size
, 1);
342 This
->state
.ps_const_f
= CALLOC(This
->ps_const_size
, 1);
343 This
->state
.vs_lconstf_temp
= CALLOC(This
->vs_const_size
,1);
344 if (!This
->state
.vs_const_f
|| !This
->state
.ps_const_f
||
345 !This
->state
.vs_lconstf_temp
)
346 return E_OUTOFMEMORY
;
348 if (strstr(pScreen
->get_name(pScreen
), "AMD") ||
349 strstr(pScreen
->get_name(pScreen
), "ATI")) {
350 This
->prefer_user_constbuf
= TRUE
;
351 This
->driver_bugs
.buggy_barycentrics
= TRUE
;
354 tmpl
.target
= PIPE_BUFFER
;
355 tmpl
.format
= PIPE_FORMAT_R8_UNORM
;
361 tmpl
.usage
= PIPE_USAGE_DYNAMIC
;
362 tmpl
.bind
= PIPE_BIND_CONSTANT_BUFFER
;
365 tmpl
.width0
= This
->vs_const_size
;
366 This
->constbuf_vs
= pScreen
->resource_create(pScreen
, &tmpl
);
368 tmpl
.width0
= This
->ps_const_size
;
369 This
->constbuf_ps
= pScreen
->resource_create(pScreen
, &tmpl
);
371 if (!This
->constbuf_vs
|| !This
->constbuf_ps
)
372 return E_OUTOFMEMORY
;
375 /* allocate dummy texture/sampler for when there are missing ones bound */
377 struct pipe_resource tmplt
;
378 struct pipe_sampler_view templ
;
380 tmplt
.target
= PIPE_TEXTURE_2D
;
384 tmplt
.last_level
= 0;
385 tmplt
.array_size
= 1;
386 tmplt
.usage
= PIPE_USAGE_DEFAULT
;
388 tmplt
.format
= PIPE_FORMAT_B8G8R8A8_UNORM
;
389 tmplt
.bind
= PIPE_BIND_SAMPLER_VIEW
;
390 tmplt
.nr_samples
= 0;
392 This
->dummy_texture
= This
->screen
->resource_create(This
->screen
, &tmplt
);
393 if (!This
->dummy_texture
)
394 return D3DERR_DRIVERINTERNALERROR
;
396 templ
.format
= PIPE_FORMAT_B8G8R8A8_UNORM
;
397 templ
.u
.tex
.first_layer
= 0;
398 templ
.u
.tex
.last_layer
= 0;
399 templ
.u
.tex
.first_level
= 0;
400 templ
.u
.tex
.last_level
= 0;
401 templ
.swizzle_r
= PIPE_SWIZZLE_ZERO
;
402 templ
.swizzle_g
= PIPE_SWIZZLE_ZERO
;
403 templ
.swizzle_b
= PIPE_SWIZZLE_ZERO
;
404 templ
.swizzle_a
= PIPE_SWIZZLE_ONE
;
405 templ
.target
= This
->dummy_texture
->target
;
407 This
->dummy_sampler
= This
->pipe
->create_sampler_view(This
->pipe
, This
->dummy_texture
, &templ
);
408 if (!This
->dummy_sampler
)
409 return D3DERR_DRIVERINTERNALERROR
;
412 /* Allocate upload helper for drivers that suck (from st pov ;). */
416 This
->driver_caps
.user_vbufs
= GET_PCAP(USER_VERTEX_BUFFERS
);
417 This
->driver_caps
.user_ibufs
= GET_PCAP(USER_INDEX_BUFFERS
);
419 if (!This
->driver_caps
.user_vbufs
) bind
|= PIPE_BIND_VERTEX_BUFFER
;
420 if (!This
->driver_caps
.user_ibufs
) bind
|= PIPE_BIND_INDEX_BUFFER
;
422 This
->upload
= u_upload_create(This
->pipe
, 1 << 20, 4, bind
);
425 This
->driver_caps
.window_space_position_support
= GET_PCAP(TGSI_VS_WINDOW_SPACE_POSITION
);
426 This
->driver_caps
.vs_integer
= pScreen
->get_shader_param(pScreen
, PIPE_SHADER_VERTEX
, PIPE_SHADER_CAP_INTEGERS
);
427 This
->driver_caps
.ps_integer
= pScreen
->get_shader_param(pScreen
, PIPE_SHADER_FRAGMENT
, PIPE_SHADER_CAP_INTEGERS
);
429 nine_ff_init(This
); /* initialize fixed function code */
431 NineDevice9_SetDefaultState(This
, FALSE
);
432 NineDevice9_RestoreNonCSOState(This
, ~0);
434 This
->update
= &This
->state
;
435 nine_update_state(This
, ~0);
437 ID3DPresentGroup_Release(This
->present
);
444 NineDevice9_dtor( struct NineDevice9
*This
)
448 DBG("This=%p\n", This
);
450 if (This
->pipe
&& This
->cso
)
451 nine_pipe_context_clear(This
);
453 nine_state_clear(&This
->state
, TRUE
);
456 u_upload_destroy(This
->upload
);
458 nine_bind(&This
->record
, NULL
);
460 pipe_sampler_view_reference(&This
->dummy_sampler
, NULL
);
461 pipe_resource_reference(&This
->dummy_texture
, NULL
);
462 pipe_resource_reference(&This
->constbuf_vs
, NULL
);
463 pipe_resource_reference(&This
->constbuf_ps
, NULL
);
464 pipe_resource_reference(&This
->dummy_vbo
, NULL
);
465 FREE(This
->state
.vs_const_f
);
466 FREE(This
->state
.ps_const_f
);
467 FREE(This
->state
.vs_lconstf_temp
);
469 if (This
->swapchains
) {
470 for (i
= 0; i
< This
->nswapchains
; ++i
)
471 NineUnknown_Unbind(NineUnknown(This
->swapchains
[i
]));
472 FREE(This
->swapchains
);
478 cso_destroy_context(This
->cso
);
480 if (This
->pipe
->destroy
) { This
->pipe
->destroy(This
->pipe
); }
483 if (This
->present
) { ID3DPresentGroup_Release(This
->present
); }
484 if (This
->d3d9
) { IDirect3D9_Release(This
->d3d9
); }
486 NineUnknown_dtor(&This
->base
);
490 NineDevice9_GetScreen( struct NineDevice9
*This
)
495 struct pipe_context
*
496 NineDevice9_GetPipe( struct NineDevice9
*This
)
502 NineDevice9_GetCSO( struct NineDevice9
*This
)
508 NineDevice9_GetCaps( struct NineDevice9
*This
)
514 NineDevice9_PauseRecording( struct NineDevice9
*This
)
517 This
->update
= &This
->state
;
518 This
->is_recording
= FALSE
;
523 NineDevice9_ResumeRecording( struct NineDevice9
*This
)
526 This
->update
= &This
->record
->state
;
527 This
->is_recording
= TRUE
;
532 NineDevice9_TestCooperativeLevel( struct NineDevice9
*This
)
534 return D3D_OK
; /* TODO */
538 NineDevice9_GetAvailableTextureMem( struct NineDevice9
*This
)
540 const unsigned mem
= This
->screen
->get_param(This
->screen
, PIPE_CAP_VIDEO_MEMORY
);
548 NineDevice9_EvictManagedResources( struct NineDevice9
*This
)
550 /* We don't really need to do anything here, but might want to free up
551 * the GPU virtual address space by killing pipe_resources.
557 NineDevice9_GetDirect3D( struct NineDevice9
*This
,
558 IDirect3D9
**ppD3D9
)
560 user_assert(ppD3D9
!= NULL
, E_POINTER
);
561 IDirect3D9_AddRef(This
->d3d9
);
562 *ppD3D9
= This
->d3d9
;
567 NineDevice9_GetDeviceCaps( struct NineDevice9
*This
,
570 user_assert(pCaps
!= NULL
, D3DERR_INVALIDCALL
);
576 NineDevice9_GetDisplayMode( struct NineDevice9
*This
,
578 D3DDISPLAYMODE
*pMode
)
580 DBG("This=%p iSwapChain=%u pMode=%p\n", This
, iSwapChain
, pMode
);
582 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
584 return NineSwapChain9_GetDisplayMode(This
->swapchains
[iSwapChain
], pMode
);
588 NineDevice9_GetCreationParameters( struct NineDevice9
*This
,
589 D3DDEVICE_CREATION_PARAMETERS
*pParameters
)
591 user_assert(pParameters
!= NULL
, D3DERR_INVALIDCALL
);
592 *pParameters
= This
->params
;
597 NineDevice9_SetCursorProperties( struct NineDevice9
*This
,
600 IDirect3DSurface9
*pCursorBitmap
)
602 struct NineSurface9
*surf
= NineSurface9(pCursorBitmap
);
603 struct pipe_context
*pipe
= This
->pipe
;
605 struct pipe_transfer
*transfer
;
609 DBG_FLAG(DBG_SWAPCHAIN
, "This=%p XHotSpot=%u YHotSpot=%u "
610 "pCursorBitmap=%p\n", This
, XHotSpot
, YHotSpot
, pCursorBitmap
);
612 user_assert(pCursorBitmap
, D3DERR_INVALIDCALL
);
614 This
->cursor
.w
= MIN2(surf
->desc
.Width
, This
->cursor
.image
->width0
);
615 This
->cursor
.h
= MIN2(surf
->desc
.Height
, This
->cursor
.image
->height0
);
616 hw_cursor
= This
->cursor
.w
== 32 && This
->cursor
.h
== 32;
618 u_box_origin_2d(This
->cursor
.w
, This
->cursor
.h
, &box
);
620 ptr
= pipe
->transfer_map(pipe
, This
->cursor
.image
, 0,
621 PIPE_TRANSFER_WRITE
|
622 PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
,
625 ret_err("Failed to update cursor image.\n", D3DERR_DRIVERINTERNALERROR
);
627 This
->cursor
.hotspot
.x
= XHotSpot
;
628 This
->cursor
.hotspot
.y
= YHotSpot
;
630 /* Copy cursor image to internal storage. */
634 const struct util_format_description
*sfmt
=
635 util_format_description(surf
->base
.info
.format
);
638 hr
= NineSurface9_LockRect(surf
, &lock
, NULL
, D3DLOCK_READONLY
);
640 ret_err("Failed to map cursor source image.\n",
641 D3DERR_DRIVERINTERNALERROR
);
643 sfmt
->unpack_rgba_8unorm(ptr
, transfer
->stride
,
644 lock
.pBits
, lock
.Pitch
,
645 This
->cursor
.w
, This
->cursor
.h
);
648 hw_cursor
= ID3DPresent_SetCursor(This
->swapchains
[0]->present
,
650 &This
->cursor
.hotspot
,
651 This
->cursor
.visible
) == D3D_OK
;
653 NineSurface9_UnlockRect(surf
);
655 pipe
->transfer_unmap(pipe
, transfer
);
657 /* hide cursor if we emulate it */
659 ID3DPresent_SetCursor(This
->swapchains
[0]->present
, NULL
, NULL
, FALSE
);
660 This
->cursor
.software
= !hw_cursor
;
666 NineDevice9_SetCursorPosition( struct NineDevice9
*This
,
671 struct NineSwapChain9
*swap
= This
->swapchains
[0];
673 DBG("This=%p X=%d Y=%d Flags=%d\n", This
, X
, Y
, Flags
);
675 This
->cursor
.pos
.x
= X
;
676 This
->cursor
.pos
.y
= Y
;
678 if (!This
->cursor
.software
)
679 ID3DPresent_SetCursorPos(swap
->present
, &This
->cursor
.pos
);
683 NineDevice9_ShowCursor( struct NineDevice9
*This
,
686 BOOL old
= This
->cursor
.visible
;
688 DBG("This=%p bShow=%d\n", This
, (int) bShow
);
690 This
->cursor
.visible
= bShow
&& (This
->cursor
.hotspot
.x
!= -1);
691 if (!This
->cursor
.software
)
692 ID3DPresent_SetCursor(This
->swapchains
[0]->present
, NULL
, NULL
, bShow
);
698 NineDevice9_CreateAdditionalSwapChain( struct NineDevice9
*This
,
699 D3DPRESENT_PARAMETERS
*pPresentationParameters
,
700 IDirect3DSwapChain9
**pSwapChain
)
702 struct NineSwapChain9
*swapchain
, *tmplt
= This
->swapchains
[0];
703 ID3DPresent
*present
;
706 DBG("This=%p pPresentationParameters=%p pSwapChain=%p\n",
707 This
, pPresentationParameters
, pSwapChain
);
709 user_assert(pPresentationParameters
, D3DERR_INVALIDCALL
);
711 hr
= ID3DPresentGroup_CreateAdditionalPresent(This
->present
, pPresentationParameters
, &present
);
716 hr
= NineSwapChain9_new(This
, FALSE
, present
, pPresentationParameters
,
718 tmplt
->params
.hDeviceWindow
,
723 *pSwapChain
= (IDirect3DSwapChain9
*)swapchain
;
728 NineDevice9_GetSwapChain( struct NineDevice9
*This
,
730 IDirect3DSwapChain9
**pSwapChain
)
732 user_assert(pSwapChain
!= NULL
, D3DERR_INVALIDCALL
);
735 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
737 NineUnknown_AddRef(NineUnknown(This
->swapchains
[iSwapChain
]));
738 *pSwapChain
= (IDirect3DSwapChain9
*)This
->swapchains
[iSwapChain
];
744 NineDevice9_GetNumberOfSwapChains( struct NineDevice9
*This
)
746 return This
->nswapchains
;
750 NineDevice9_Reset( struct NineDevice9
*This
,
751 D3DPRESENT_PARAMETERS
*pPresentationParameters
)
756 DBG("This=%p pPresentationParameters=%p\n", This
, pPresentationParameters
);
758 for (i
= 0; i
< This
->nswapchains
; ++i
) {
759 D3DPRESENT_PARAMETERS
*params
= &pPresentationParameters
[i
];
760 hr
= NineSwapChain9_Resize(This
->swapchains
[i
], params
, NULL
);
762 return (hr
== D3DERR_OUTOFVIDEOMEMORY
) ? hr
: D3DERR_DEVICELOST
;
765 nine_pipe_context_clear(This
);
766 nine_state_clear(&This
->state
, TRUE
);
768 NineDevice9_SetDefaultState(This
, TRUE
);
769 NineDevice9_SetRenderTarget(
770 This
, 0, (IDirect3DSurface9
*)This
->swapchains
[0]->buffers
[0]);
771 /* XXX: better use GetBackBuffer here ? */
777 NineDevice9_Present( struct NineDevice9
*This
,
778 const RECT
*pSourceRect
,
779 const RECT
*pDestRect
,
780 HWND hDestWindowOverride
,
781 const RGNDATA
*pDirtyRegion
)
786 DBG("This=%p pSourceRect=%p pDestRect=%p hDestWindowOverride=%p pDirtyRegion=%p\n",
787 This
, pSourceRect
, pDestRect
, hDestWindowOverride
, pDirtyRegion
);
789 /* XXX is this right? */
790 for (i
= 0; i
< This
->nswapchains
; ++i
) {
791 hr
= NineSwapChain9_Present(This
->swapchains
[i
], pSourceRect
, pDestRect
,
792 hDestWindowOverride
, pDirtyRegion
, 0);
793 if (FAILED(hr
)) { return hr
; }
800 NineDevice9_GetBackBuffer( struct NineDevice9
*This
,
803 D3DBACKBUFFER_TYPE Type
,
804 IDirect3DSurface9
**ppBackBuffer
)
806 user_assert(ppBackBuffer
!= NULL
, D3DERR_INVALIDCALL
);
807 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
809 return NineSwapChain9_GetBackBuffer(This
->swapchains
[iSwapChain
],
810 iBackBuffer
, Type
, ppBackBuffer
);
814 NineDevice9_GetRasterStatus( struct NineDevice9
*This
,
816 D3DRASTER_STATUS
*pRasterStatus
)
818 user_assert(pRasterStatus
!= NULL
, D3DERR_INVALIDCALL
);
819 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
821 return NineSwapChain9_GetRasterStatus(This
->swapchains
[iSwapChain
],
826 NineDevice9_SetDialogBoxMode( struct NineDevice9
*This
,
827 BOOL bEnableDialogs
)
829 STUB(D3DERR_INVALIDCALL
);
833 NineDevice9_SetGammaRamp( struct NineDevice9
*This
,
836 const D3DGAMMARAMP
*pRamp
)
838 DBG("This=%p iSwapChain=%u Flags=%x pRamp=%p\n", This
,
839 iSwapChain
, Flags
, pRamp
);
841 user_warn(iSwapChain
>= This
->nswapchains
);
844 if (pRamp
&& (iSwapChain
< This
->nswapchains
)) {
845 struct NineSwapChain9
*swap
= This
->swapchains
[iSwapChain
];
846 swap
->gamma
= *pRamp
;
847 ID3DPresent_SetGammaRamp(swap
->present
, pRamp
, swap
->params
.hDeviceWindow
);
852 NineDevice9_GetGammaRamp( struct NineDevice9
*This
,
854 D3DGAMMARAMP
*pRamp
)
856 DBG("This=%p iSwapChain=%u pRamp=%p\n", This
, iSwapChain
, pRamp
);
858 user_warn(iSwapChain
>= This
->nswapchains
);
861 if (pRamp
&& (iSwapChain
< This
->nswapchains
))
862 *pRamp
= This
->swapchains
[iSwapChain
]->gamma
;
866 NineDevice9_CreateTexture( struct NineDevice9
*This
,
873 IDirect3DTexture9
**ppTexture
,
874 HANDLE
*pSharedHandle
)
876 struct NineTexture9
*tex
;
879 DBG("This=%p Width=%u Height=%u Levels=%u Usage=%s Format=%s Pool=%s "
880 "ppOut=%p pSharedHandle=%p\n", This
, Width
, Height
, Levels
,
881 nine_D3DUSAGE_to_str(Usage
), d3dformat_to_string(Format
),
882 nine_D3DPOOL_to_str(Pool
), ppTexture
, pSharedHandle
);
884 Usage
&= D3DUSAGE_AUTOGENMIPMAP
| D3DUSAGE_DEPTHSTENCIL
| D3DUSAGE_DMAP
|
885 D3DUSAGE_DYNAMIC
| D3DUSAGE_NONSECURE
| D3DUSAGE_RENDERTARGET
|
886 D3DUSAGE_SOFTWAREPROCESSING
| D3DUSAGE_TEXTAPI
;
889 user_assert(Width
&& Height
, D3DERR_INVALIDCALL
);
890 user_assert(!pSharedHandle
|| This
->ex
, D3DERR_INVALIDCALL
);
891 /* When is used shared handle, Pool must be
892 * SYSTEMMEM with Levels 1 or DEFAULT with any Levels */
893 user_assert(!pSharedHandle
|| Pool
!= D3DPOOL_SYSTEMMEM
|| Levels
== 1,
895 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_SYSTEMMEM
|| Pool
== D3DPOOL_DEFAULT
,
897 user_assert((Usage
!= D3DUSAGE_AUTOGENMIPMAP
|| Levels
<= 1), D3DERR_INVALIDCALL
);
899 hr
= NineTexture9_new(This
, Width
, Height
, Levels
, Usage
, Format
, Pool
,
900 &tex
, pSharedHandle
);
902 *ppTexture
= (IDirect3DTexture9
*)tex
;
908 NineDevice9_CreateVolumeTexture( struct NineDevice9
*This
,
916 IDirect3DVolumeTexture9
**ppVolumeTexture
,
917 HANDLE
*pSharedHandle
)
919 struct NineVolumeTexture9
*tex
;
922 DBG("This=%p Width=%u Height=%u Depth=%u Levels=%u Usage=%s Format=%s Pool=%s "
923 "ppOut=%p pSharedHandle=%p\n", This
, Width
, Height
, Depth
, Levels
,
924 nine_D3DUSAGE_to_str(Usage
), d3dformat_to_string(Format
),
925 nine_D3DPOOL_to_str(Pool
), ppVolumeTexture
, pSharedHandle
);
927 Usage
&= D3DUSAGE_DYNAMIC
| D3DUSAGE_NONSECURE
|
928 D3DUSAGE_SOFTWAREPROCESSING
;
930 *ppVolumeTexture
= NULL
;
931 user_assert(Width
&& Height
&& Depth
, D3DERR_INVALIDCALL
);
932 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
934 hr
= NineVolumeTexture9_new(This
, Width
, Height
, Depth
, Levels
,
935 Usage
, Format
, Pool
, &tex
, pSharedHandle
);
937 *ppVolumeTexture
= (IDirect3DVolumeTexture9
*)tex
;
943 NineDevice9_CreateCubeTexture( struct NineDevice9
*This
,
949 IDirect3DCubeTexture9
**ppCubeTexture
,
950 HANDLE
*pSharedHandle
)
952 struct NineCubeTexture9
*tex
;
955 DBG("This=%p EdgeLength=%u Levels=%u Usage=%s Format=%s Pool=%s ppOut=%p "
956 "pSharedHandle=%p\n", This
, EdgeLength
, Levels
,
957 nine_D3DUSAGE_to_str(Usage
), d3dformat_to_string(Format
),
958 nine_D3DPOOL_to_str(Pool
), ppCubeTexture
, pSharedHandle
);
960 Usage
&= D3DUSAGE_AUTOGENMIPMAP
| D3DUSAGE_DEPTHSTENCIL
| D3DUSAGE_DYNAMIC
|
961 D3DUSAGE_NONSECURE
| D3DUSAGE_RENDERTARGET
|
962 D3DUSAGE_SOFTWAREPROCESSING
;
964 *ppCubeTexture
= NULL
;
965 user_assert(EdgeLength
, D3DERR_INVALIDCALL
);
966 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
968 hr
= NineCubeTexture9_new(This
, EdgeLength
, Levels
, Usage
, Format
, Pool
,
969 &tex
, pSharedHandle
);
971 *ppCubeTexture
= (IDirect3DCubeTexture9
*)tex
;
977 NineDevice9_CreateVertexBuffer( struct NineDevice9
*This
,
982 IDirect3DVertexBuffer9
**ppVertexBuffer
,
983 HANDLE
*pSharedHandle
)
985 struct NineVertexBuffer9
*buf
;
987 D3DVERTEXBUFFER_DESC desc
;
989 DBG("This=%p Length=%u Usage=%x FVF=%x Pool=%u ppOut=%p pSharedHandle=%p\n",
990 This
, Length
, Usage
, FVF
, Pool
, ppVertexBuffer
, pSharedHandle
);
992 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_NOTAVAILABLE
);
994 desc
.Format
= D3DFMT_VERTEXDATA
;
995 desc
.Type
= D3DRTYPE_VERTEXBUFFER
;
997 (D3DUSAGE_DONOTCLIP
| D3DUSAGE_DYNAMIC
| D3DUSAGE_NONSECURE
|
998 D3DUSAGE_NPATCHES
| D3DUSAGE_POINTS
| D3DUSAGE_RTPATCHES
|
999 D3DUSAGE_SOFTWAREPROCESSING
| D3DUSAGE_TEXTAPI
|
1000 D3DUSAGE_WRITEONLY
);
1005 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1006 user_assert(desc
.Usage
== Usage
, D3DERR_INVALIDCALL
);
1008 hr
= NineVertexBuffer9_new(This
, &desc
, &buf
);
1010 *ppVertexBuffer
= (IDirect3DVertexBuffer9
*)buf
;
1015 NineDevice9_CreateIndexBuffer( struct NineDevice9
*This
,
1020 IDirect3DIndexBuffer9
**ppIndexBuffer
,
1021 HANDLE
*pSharedHandle
)
1023 struct NineIndexBuffer9
*buf
;
1025 D3DINDEXBUFFER_DESC desc
;
1027 DBG("This=%p Length=%u Usage=%x Format=%s Pool=%u ppOut=%p "
1028 "pSharedHandle=%p\n", This
, Length
, Usage
,
1029 d3dformat_to_string(Format
), Pool
, ppIndexBuffer
, pSharedHandle
);
1031 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_NOTAVAILABLE
);
1033 desc
.Format
= Format
;
1034 desc
.Type
= D3DRTYPE_INDEXBUFFER
;
1035 desc
.Usage
= Usage
&
1036 (D3DUSAGE_DONOTCLIP
| D3DUSAGE_DYNAMIC
| D3DUSAGE_NONSECURE
|
1037 D3DUSAGE_NPATCHES
| D3DUSAGE_POINTS
| D3DUSAGE_RTPATCHES
|
1038 D3DUSAGE_SOFTWAREPROCESSING
| D3DUSAGE_WRITEONLY
);
1042 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1043 user_assert(desc
.Usage
== Usage
, D3DERR_INVALIDCALL
);
1045 hr
= NineIndexBuffer9_new(This
, &desc
, &buf
);
1047 *ppIndexBuffer
= (IDirect3DIndexBuffer9
*)buf
;
1052 create_zs_or_rt_surface(struct NineDevice9
*This
,
1053 unsigned type
, /* 0 = RT, 1 = ZS, 2 = plain */
1055 UINT Width
, UINT Height
,
1057 D3DMULTISAMPLE_TYPE MultiSample
,
1058 DWORD MultisampleQuality
,
1059 BOOL Discard_or_Lockable
,
1060 IDirect3DSurface9
**ppSurface
,
1061 HANDLE
*pSharedHandle
)
1063 struct NineSurface9
*surface
;
1064 struct pipe_screen
*screen
= This
->screen
;
1065 struct pipe_resource
*resource
= NULL
;
1067 D3DSURFACE_DESC desc
;
1068 struct pipe_resource templ
;
1070 DBG("This=%p type=%u Pool=%s Width=%u Height=%u Format=%s MS=%u Quality=%u "
1071 "Discard_or_Lockable=%i ppSurface=%p pSharedHandle=%p\n",
1072 This
, type
, nine_D3DPOOL_to_str(Pool
), Width
, Height
,
1073 d3dformat_to_string(Format
), MultiSample
, MultisampleQuality
,
1074 Discard_or_Lockable
, ppSurface
, pSharedHandle
);
1077 DBG("FIXME Used shared handle! This option isn't probably handled correctly!\n");
1079 user_assert(Width
&& Height
, D3DERR_INVALIDCALL
);
1080 user_assert(Pool
!= D3DPOOL_MANAGED
, D3DERR_INVALIDCALL
);
1082 templ
.target
= PIPE_TEXTURE_2D
;
1083 templ
.width0
= Width
;
1084 templ
.height0
= Height
;
1086 templ
.array_size
= 1;
1087 templ
.last_level
= 0;
1088 templ
.nr_samples
= (unsigned)MultiSample
;
1089 templ
.usage
= PIPE_USAGE_DEFAULT
;
1091 templ
.bind
= PIPE_BIND_SAMPLER_VIEW
; /* StretchRect */
1093 case 0: templ
.bind
|= PIPE_BIND_RENDER_TARGET
; break;
1094 case 1: templ
.bind
= d3d9_get_pipe_depth_format_bindings(Format
); break;
1099 templ
.format
= d3d9_to_pipe_format_checked(screen
, Format
, templ
.target
,
1100 templ
.nr_samples
, templ
.bind
,
1103 desc
.Format
= Format
;
1104 desc
.Type
= D3DRTYPE_SURFACE
;
1107 desc
.MultiSampleType
= MultiSample
;
1108 desc
.MultiSampleQuality
= MultisampleQuality
;
1110 desc
.Height
= Height
;
1112 case 0: desc
.Usage
= D3DUSAGE_RENDERTARGET
; break;
1113 case 1: desc
.Usage
= D3DUSAGE_DEPTHSTENCIL
; break;
1117 if (Pool
== D3DPOOL_DEFAULT
&& Format
!= D3DFMT_NULL
) {
1118 /* resource_create doesn't return an error code, so check format here */
1119 user_assert(templ
.format
!= PIPE_FORMAT_NONE
, D3DERR_INVALIDCALL
);
1120 resource
= screen
->resource_create(screen
, &templ
);
1121 user_assert(resource
, D3DERR_OUTOFVIDEOMEMORY
);
1122 if (Discard_or_Lockable
&& (desc
.Usage
& D3DUSAGE_RENDERTARGET
))
1123 resource
->flags
|= NINE_RESOURCE_FLAG_LOCKABLE
;
1127 hr
= NineSurface9_new(This
, NULL
, resource
, NULL
, 0, 0, 0, &desc
, &surface
);
1128 pipe_resource_reference(&resource
, NULL
);
1131 *ppSurface
= (IDirect3DSurface9
*)surface
;
1136 NineDevice9_CreateRenderTarget( struct NineDevice9
*This
,
1140 D3DMULTISAMPLE_TYPE MultiSample
,
1141 DWORD MultisampleQuality
,
1143 IDirect3DSurface9
**ppSurface
,
1144 HANDLE
*pSharedHandle
)
1147 return create_zs_or_rt_surface(This
, 0, D3DPOOL_DEFAULT
,
1148 Width
, Height
, Format
,
1149 MultiSample
, MultisampleQuality
,
1150 Lockable
, ppSurface
, pSharedHandle
);
1154 NineDevice9_CreateDepthStencilSurface( struct NineDevice9
*This
,
1158 D3DMULTISAMPLE_TYPE MultiSample
,
1159 DWORD MultisampleQuality
,
1161 IDirect3DSurface9
**ppSurface
,
1162 HANDLE
*pSharedHandle
)
1165 if (!depth_stencil_format(Format
))
1166 return D3DERR_NOTAVAILABLE
;
1167 return create_zs_or_rt_surface(This
, 1, D3DPOOL_DEFAULT
,
1168 Width
, Height
, Format
,
1169 MultiSample
, MultisampleQuality
,
1170 Discard
, ppSurface
, pSharedHandle
);
1174 NineDevice9_UpdateSurface( struct NineDevice9
*This
,
1175 IDirect3DSurface9
*pSourceSurface
,
1176 const RECT
*pSourceRect
,
1177 IDirect3DSurface9
*pDestinationSurface
,
1178 const POINT
*pDestPoint
)
1180 struct NineSurface9
*dst
= NineSurface9(pDestinationSurface
);
1181 struct NineSurface9
*src
= NineSurface9(pSourceSurface
);
1183 DBG("This=%p pSourceSurface=%p pDestinationSurface=%p "
1184 "pSourceRect=%p pDestPoint=%p\n", This
,
1185 pSourceSurface
, pDestinationSurface
, pSourceRect
, pDestPoint
);
1187 DBG("pSourceRect = (%u,%u)-(%u,%u)\n",
1188 pSourceRect
->left
, pSourceRect
->top
,
1189 pSourceRect
->right
, pSourceRect
->bottom
);
1191 DBG("pDestPoint = (%u,%u)\n", pDestPoint
->x
, pDestPoint
->y
);
1193 user_assert(dst
->base
.pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1194 user_assert(src
->base
.pool
== D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
1196 user_assert(dst
->desc
.MultiSampleType
== D3DMULTISAMPLE_NONE
, D3DERR_INVALIDCALL
);
1197 user_assert(src
->desc
.MultiSampleType
== D3DMULTISAMPLE_NONE
, D3DERR_INVALIDCALL
);
1199 return NineSurface9_CopySurface(dst
, src
, pDestPoint
, pSourceRect
);
1203 NineDevice9_UpdateTexture( struct NineDevice9
*This
,
1204 IDirect3DBaseTexture9
*pSourceTexture
,
1205 IDirect3DBaseTexture9
*pDestinationTexture
)
1207 struct NineBaseTexture9
*dstb
= NineBaseTexture9(pDestinationTexture
);
1208 struct NineBaseTexture9
*srcb
= NineBaseTexture9(pSourceTexture
);
1210 unsigned last_level
= dstb
->base
.info
.last_level
;
1212 DBG("This=%p pSourceTexture=%p pDestinationTexture=%p\n", This
,
1213 pSourceTexture
, pDestinationTexture
);
1215 user_assert(pSourceTexture
!= pDestinationTexture
, D3DERR_INVALIDCALL
);
1217 user_assert(dstb
->base
.pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1218 user_assert(srcb
->base
.pool
== D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
1220 if (dstb
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
) {
1221 /* Only the first level is updated, the others regenerated. */
1223 /* if the source has D3DUSAGE_AUTOGENMIPMAP, we have to ignore
1224 * the sublevels, thus level 0 has to match */
1225 user_assert(!(srcb
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
) ||
1226 (srcb
->base
.info
.width0
== dstb
->base
.info
.width0
&&
1227 srcb
->base
.info
.height0
== dstb
->base
.info
.height0
&&
1228 srcb
->base
.info
.depth0
== dstb
->base
.info
.depth0
),
1229 D3DERR_INVALIDCALL
);
1231 user_assert(!(srcb
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
), D3DERR_INVALIDCALL
);
1234 user_assert(dstb
->base
.type
== srcb
->base
.type
, D3DERR_INVALIDCALL
);
1236 /* TODO: We can restrict the update to the dirty portions of the source.
1237 * Yes, this seems silly, but it's what MSDN says ...
1240 /* Find src level that matches dst level 0: */
1241 user_assert(srcb
->base
.info
.width0
>= dstb
->base
.info
.width0
&&
1242 srcb
->base
.info
.height0
>= dstb
->base
.info
.height0
&&
1243 srcb
->base
.info
.depth0
>= dstb
->base
.info
.depth0
,
1244 D3DERR_INVALIDCALL
);
1245 for (m
= 0; m
<= srcb
->base
.info
.last_level
; ++m
) {
1246 unsigned w
= u_minify(srcb
->base
.info
.width0
, m
);
1247 unsigned h
= u_minify(srcb
->base
.info
.height0
, m
);
1248 unsigned d
= u_minify(srcb
->base
.info
.depth0
, m
);
1250 if (w
== dstb
->base
.info
.width0
&&
1251 h
== dstb
->base
.info
.height0
&&
1252 d
== dstb
->base
.info
.depth0
)
1255 user_assert(m
<= srcb
->base
.info
.last_level
, D3DERR_INVALIDCALL
);
1257 last_level
= MIN2(last_level
, srcb
->base
.info
.last_level
- m
);
1259 if (dstb
->base
.type
== D3DRTYPE_TEXTURE
) {
1260 struct NineTexture9
*dst
= NineTexture9(dstb
);
1261 struct NineTexture9
*src
= NineTexture9(srcb
);
1263 for (l
= 0; l
<= last_level
; ++l
, ++m
)
1264 NineSurface9_CopySurface(dst
->surfaces
[l
],
1265 src
->surfaces
[m
], NULL
, NULL
);
1267 if (dstb
->base
.type
== D3DRTYPE_CUBETEXTURE
) {
1268 struct NineCubeTexture9
*dst
= NineCubeTexture9(dstb
);
1269 struct NineCubeTexture9
*src
= NineCubeTexture9(srcb
);
1272 /* GPUs usually have them stored as arrays of mip-mapped 2D textures. */
1273 for (z
= 0; z
< 6; ++z
) {
1274 for (l
= 0; l
<= last_level
; ++l
, ++m
) {
1275 NineSurface9_CopySurface(dst
->surfaces
[l
* 6 + z
],
1276 src
->surfaces
[m
* 6 + z
], NULL
, NULL
);
1281 if (dstb
->base
.type
== D3DRTYPE_VOLUMETEXTURE
) {
1282 struct NineVolumeTexture9
*dst
= NineVolumeTexture9(dstb
);
1283 struct NineVolumeTexture9
*src
= NineVolumeTexture9(srcb
);
1285 for (l
= 0; l
<= last_level
; ++l
, ++m
)
1286 NineVolume9_CopyVolume(dst
->volumes
[l
],
1287 src
->volumes
[m
], 0, 0, 0, NULL
);
1289 assert(!"invalid texture type");
1292 if (dstb
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
) {
1293 dstb
->dirty_mip
= TRUE
;
1294 NineBaseTexture9_GenerateMipSubLevels(dstb
);
1301 NineDevice9_GetRenderTargetData( struct NineDevice9
*This
,
1302 IDirect3DSurface9
*pRenderTarget
,
1303 IDirect3DSurface9
*pDestSurface
)
1305 struct NineSurface9
*dst
= NineSurface9(pDestSurface
);
1306 struct NineSurface9
*src
= NineSurface9(pRenderTarget
);
1308 DBG("This=%p pRenderTarget=%p pDestSurface=%p\n",
1309 This
, pRenderTarget
, pDestSurface
);
1311 user_assert(dst
->desc
.Pool
== D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
1312 user_assert(src
->desc
.Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1314 user_assert(dst
->desc
.MultiSampleType
< 2, D3DERR_INVALIDCALL
);
1315 user_assert(src
->desc
.MultiSampleType
< 2, D3DERR_INVALIDCALL
);
1317 return NineSurface9_CopySurface(dst
, src
, NULL
, NULL
);
1321 NineDevice9_GetFrontBufferData( struct NineDevice9
*This
,
1323 IDirect3DSurface9
*pDestSurface
)
1325 DBG("This=%p iSwapChain=%u pDestSurface=%p\n", This
,
1326 iSwapChain
, pDestSurface
);
1328 user_assert(pDestSurface
!= NULL
, D3DERR_INVALIDCALL
);
1329 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
1331 return NineSwapChain9_GetFrontBufferData(This
->swapchains
[iSwapChain
],
1336 NineDevice9_StretchRect( struct NineDevice9
*This
,
1337 IDirect3DSurface9
*pSourceSurface
,
1338 const RECT
*pSourceRect
,
1339 IDirect3DSurface9
*pDestSurface
,
1340 const RECT
*pDestRect
,
1341 D3DTEXTUREFILTERTYPE Filter
)
1343 struct pipe_screen
*screen
= This
->screen
;
1344 struct pipe_context
*pipe
= This
->pipe
;
1345 struct NineSurface9
*dst
= NineSurface9(pDestSurface
);
1346 struct NineSurface9
*src
= NineSurface9(pSourceSurface
);
1347 struct pipe_resource
*dst_res
= NineSurface9_GetResource(dst
);
1348 struct pipe_resource
*src_res
= NineSurface9_GetResource(src
);
1349 const boolean zs
= util_format_is_depth_or_stencil(dst_res
->format
);
1350 struct pipe_blit_info blit
;
1351 boolean scaled
, clamped
, ms
, flip_x
= FALSE
, flip_y
= FALSE
;
1353 DBG("This=%p pSourceSurface=%p pSourceRect=%p pDestSurface=%p "
1354 "pDestRect=%p Filter=%u\n",
1355 This
, pSourceSurface
, pSourceRect
, pDestSurface
, pDestRect
, Filter
);
1357 DBG("pSourceRect=(%u,%u)-(%u,%u)\n",
1358 pSourceRect
->left
, pSourceRect
->top
,
1359 pSourceRect
->right
, pSourceRect
->bottom
);
1361 DBG("pDestRect=(%u,%u)-(%u,%u)\n", pDestRect
->left
, pDestRect
->top
,
1362 pDestRect
->right
, pDestRect
->bottom
);
1364 user_assert(!zs
|| !This
->in_scene
, D3DERR_INVALIDCALL
);
1365 user_assert(!zs
|| !pSourceRect
||
1366 (pSourceRect
->left
== 0 &&
1367 pSourceRect
->top
== 0 &&
1368 pSourceRect
->right
== src
->desc
.Width
&&
1369 pSourceRect
->bottom
== src
->desc
.Height
), D3DERR_INVALIDCALL
);
1370 user_assert(!zs
|| !pDestRect
||
1371 (pDestRect
->left
== 0 &&
1372 pDestRect
->top
== 0 &&
1373 pDestRect
->right
== dst
->desc
.Width
&&
1374 pDestRect
->bottom
== dst
->desc
.Height
), D3DERR_INVALIDCALL
);
1376 (dst
->desc
.Width
== src
->desc
.Width
&&
1377 dst
->desc
.Height
== src
->desc
.Height
), D3DERR_INVALIDCALL
);
1378 user_assert(zs
|| !util_format_is_depth_or_stencil(src_res
->format
),
1379 D3DERR_INVALIDCALL
);
1380 user_assert(!zs
|| dst
->desc
.Format
== src
->desc
.Format
,
1381 D3DERR_INVALIDCALL
);
1382 user_assert(screen
->is_format_supported(screen
, src_res
->format
,
1384 src_res
->nr_samples
,
1385 PIPE_BIND_SAMPLER_VIEW
),
1386 D3DERR_INVALIDCALL
);
1387 user_assert(dst
->base
.pool
== D3DPOOL_DEFAULT
&&
1388 src
->base
.pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1390 /* We might want to permit these, but wine thinks we shouldn't. */
1391 user_assert(!pDestRect
||
1392 (pDestRect
->left
<= pDestRect
->right
&&
1393 pDestRect
->top
<= pDestRect
->bottom
), D3DERR_INVALIDCALL
);
1394 user_assert(!pSourceRect
||
1395 (pSourceRect
->left
<= pSourceRect
->right
&&
1396 pSourceRect
->top
<= pSourceRect
->bottom
), D3DERR_INVALIDCALL
);
1398 memset(&blit
, 0, sizeof(blit
));
1399 blit
.dst
.resource
= dst_res
;
1400 blit
.dst
.level
= dst
->level
;
1401 blit
.dst
.box
.z
= dst
->layer
;
1402 blit
.dst
.box
.depth
= 1;
1403 blit
.dst
.format
= dst_res
->format
;
1405 flip_x
= pDestRect
->left
> pDestRect
->right
;
1407 blit
.dst
.box
.x
= pDestRect
->right
;
1408 blit
.dst
.box
.width
= pDestRect
->left
- pDestRect
->right
;
1410 blit
.dst
.box
.x
= pDestRect
->left
;
1411 blit
.dst
.box
.width
= pDestRect
->right
- pDestRect
->left
;
1413 flip_y
= pDestRect
->top
> pDestRect
->bottom
;
1415 blit
.dst
.box
.y
= pDestRect
->bottom
;
1416 blit
.dst
.box
.height
= pDestRect
->top
- pDestRect
->bottom
;
1418 blit
.dst
.box
.y
= pDestRect
->top
;
1419 blit
.dst
.box
.height
= pDestRect
->bottom
- pDestRect
->top
;
1424 blit
.dst
.box
.width
= dst
->desc
.Width
;
1425 blit
.dst
.box
.height
= dst
->desc
.Height
;
1427 blit
.src
.resource
= src_res
;
1428 blit
.src
.level
= src
->level
;
1429 blit
.src
.box
.z
= src
->layer
;
1430 blit
.src
.box
.depth
= 1;
1431 blit
.src
.format
= src_res
->format
;
1433 if (flip_x
^ (pSourceRect
->left
> pSourceRect
->right
)) {
1434 blit
.src
.box
.x
= pSourceRect
->right
;
1435 blit
.src
.box
.width
= pSourceRect
->left
- pSourceRect
->right
;
1437 blit
.src
.box
.x
= pSourceRect
->left
;
1438 blit
.src
.box
.width
= pSourceRect
->right
- pSourceRect
->left
;
1440 if (flip_y
^ (pSourceRect
->top
> pSourceRect
->bottom
)) {
1441 blit
.src
.box
.y
= pSourceRect
->bottom
;
1442 blit
.src
.box
.height
= pSourceRect
->top
- pSourceRect
->bottom
;
1444 blit
.src
.box
.y
= pSourceRect
->top
;
1445 blit
.src
.box
.height
= pSourceRect
->bottom
- pSourceRect
->top
;
1448 blit
.src
.box
.x
= flip_x
? src
->desc
.Width
: 0;
1449 blit
.src
.box
.y
= flip_y
? src
->desc
.Height
: 0;
1450 blit
.src
.box
.width
= flip_x
? -src
->desc
.Width
: src
->desc
.Width
;
1451 blit
.src
.box
.height
= flip_y
? -src
->desc
.Height
: src
->desc
.Height
;
1453 blit
.mask
= zs
? PIPE_MASK_ZS
: PIPE_MASK_RGBA
;
1454 blit
.filter
= Filter
== D3DTEXF_LINEAR
?
1455 PIPE_TEX_FILTER_LINEAR
: PIPE_TEX_FILTER_NEAREST
;
1456 blit
.scissor_enable
= FALSE
;
1458 /* If both of a src and dst dimension are negative, flip them. */
1459 if (blit
.dst
.box
.width
< 0 && blit
.src
.box
.width
< 0) {
1460 blit
.dst
.box
.width
= -blit
.dst
.box
.width
;
1461 blit
.src
.box
.width
= -blit
.src
.box
.width
;
1463 if (blit
.dst
.box
.height
< 0 && blit
.src
.box
.height
< 0) {
1464 blit
.dst
.box
.height
= -blit
.dst
.box
.height
;
1465 blit
.src
.box
.height
= -blit
.src
.box
.height
;
1468 blit
.dst
.box
.width
!= blit
.src
.box
.width
||
1469 blit
.dst
.box
.height
!= blit
.src
.box
.height
;
1471 user_assert(!scaled
|| dst
!= src
, D3DERR_INVALIDCALL
);
1472 user_assert(!scaled
||
1473 !NineSurface9_IsOffscreenPlain(dst
) ||
1474 NineSurface9_IsOffscreenPlain(src
), D3DERR_INVALIDCALL
);
1475 user_assert(!scaled
||
1476 (!util_format_is_compressed(dst
->base
.info
.format
) &&
1477 !util_format_is_compressed(src
->base
.info
.format
)),
1478 D3DERR_INVALIDCALL
);
1480 user_warn(src
== dst
&&
1481 u_box_test_intersection_2d(&blit
.src
.box
, &blit
.dst
.box
));
1483 /* Check for clipping/clamping: */
1485 struct pipe_box box
;
1488 xy
= u_box_clip_2d(&box
, &blit
.dst
.box
,
1489 dst
->desc
.Width
, dst
->desc
.Height
);
1493 xy
= u_box_clip_2d(&box
, &blit
.src
.box
,
1494 src
->desc
.Width
, src
->desc
.Height
);
1498 ms
= (dst
->desc
.MultiSampleType
| 1) != (src
->desc
.MultiSampleType
| 1);
1500 if (clamped
|| scaled
|| (blit
.dst
.format
!= blit
.src
.format
) || ms
) {
1501 DBG("using pipe->blit()\n");
1502 /* TODO: software scaling */
1503 user_assert(screen
->is_format_supported(screen
, dst_res
->format
,
1505 dst_res
->nr_samples
,
1506 zs
? PIPE_BIND_DEPTH_STENCIL
:
1507 PIPE_BIND_RENDER_TARGET
),
1508 D3DERR_INVALIDCALL
);
1510 pipe
->blit(pipe
, &blit
);
1512 assert(blit
.dst
.box
.x
>= 0 && blit
.dst
.box
.y
>= 0 &&
1513 blit
.src
.box
.x
>= 0 && blit
.src
.box
.y
>= 0 &&
1514 blit
.dst
.box
.x
+ blit
.dst
.box
.width
<= dst
->desc
.Width
&&
1515 blit
.src
.box
.x
+ blit
.src
.box
.width
<= src
->desc
.Width
&&
1516 blit
.dst
.box
.y
+ blit
.dst
.box
.height
<= dst
->desc
.Height
&&
1517 blit
.src
.box
.y
+ blit
.src
.box
.height
<= src
->desc
.Height
);
1518 /* Or drivers might crash ... */
1519 DBG("Using resource_copy_region.\n");
1520 pipe
->resource_copy_region(pipe
,
1521 blit
.dst
.resource
, blit
.dst
.level
,
1522 blit
.dst
.box
.x
, blit
.dst
.box
.y
, blit
.dst
.box
.z
,
1523 blit
.src
.resource
, blit
.src
.level
,
1527 /* Communicate the container it needs to update sublevels - if apply */
1528 NineSurface9_MarkContainerDirty(dst
);
1534 NineDevice9_ColorFill( struct NineDevice9
*This
,
1535 IDirect3DSurface9
*pSurface
,
1539 struct pipe_context
*pipe
= This
->pipe
;
1540 struct NineSurface9
*surf
= NineSurface9(pSurface
);
1541 struct pipe_surface
*psurf
;
1542 unsigned x
, y
, w
, h
;
1543 union pipe_color_union rgba
;
1546 DBG("This=%p pSurface=%p pRect=%p color=%08x\n", This
,
1547 pSurface
, pRect
, color
);
1549 DBG("pRect=(%u,%u)-(%u,%u)\n", pRect
->left
, pRect
->top
,
1550 pRect
->right
, pRect
->bottom
);
1552 user_assert(surf
->base
.pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1554 user_assert((surf
->base
.usage
& D3DUSAGE_RENDERTARGET
) ||
1555 NineSurface9_IsOffscreenPlain(surf
), D3DERR_INVALIDCALL
);
1560 w
= pRect
->right
- pRect
->left
;
1561 h
= pRect
->bottom
- pRect
->top
;
1565 w
= surf
->desc
.Width
;
1566 h
= surf
->desc
.Height
;
1568 d3dcolor_to_pipe_color_union(&rgba
, color
);
1571 !This
->screen
->is_format_supported(This
->screen
, surf
->base
.info
.format
,
1572 surf
->base
.info
.target
,
1573 surf
->base
.info
.nr_samples
,
1574 PIPE_BIND_RENDER_TARGET
);
1576 psurf
= NineSurface9_GetSurface(surf
, 0);
1582 pipe
->clear_render_target(pipe
, psurf
, &rgba
, x
, y
, w
, h
);
1584 D3DLOCKED_RECT lock
;
1585 union util_color uc
;
1587 /* XXX: lock pRect and fix util_fill_rect */
1588 hr
= NineSurface9_LockRect(surf
, &lock
, NULL
, 0);
1591 util_pack_color_ub(color
>> 16, color
>> 8, color
>> 0, color
>> 24,
1592 surf
->base
.info
.format
, &uc
);
1593 util_fill_rect(lock
.pBits
, surf
->base
.info
.format
,lock
.Pitch
,
1595 NineSurface9_UnlockRect(surf
);
1602 NineDevice9_CreateOffscreenPlainSurface( struct NineDevice9
*This
,
1607 IDirect3DSurface9
**ppSurface
,
1608 HANDLE
*pSharedHandle
)
1612 DBG("This=%p Width=%u Height=%u Format=%s(0x%x) Pool=%u "
1613 "ppSurface=%p pSharedHandle=%p\n", This
,
1614 Width
, Height
, d3dformat_to_string(Format
), Format
, Pool
,
1615 ppSurface
, pSharedHandle
);
1618 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
1619 || Pool
== D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
1620 user_assert(Pool
!= D3DPOOL_MANAGED
, D3DERR_INVALIDCALL
);
1622 /* Can be used with StretchRect and ColorFill. It's also always lockable.
1624 hr
= create_zs_or_rt_surface(This
, 2, Pool
, Width
, Height
,
1626 D3DMULTISAMPLE_NONE
, 0,
1628 ppSurface
, pSharedHandle
);
1630 DBG("Failed to create surface.\n");
1635 NineDevice9_SetRenderTarget( struct NineDevice9
*This
,
1636 DWORD RenderTargetIndex
,
1637 IDirect3DSurface9
*pRenderTarget
)
1639 struct NineSurface9
*rt
= NineSurface9(pRenderTarget
);
1640 const unsigned i
= RenderTargetIndex
;
1642 DBG("This=%p RenderTargetIndex=%u pRenderTarget=%p\n", This
,
1643 RenderTargetIndex
, pRenderTarget
);
1645 user_assert(i
< This
->caps
.NumSimultaneousRTs
, D3DERR_INVALIDCALL
);
1646 user_assert(i
!= 0 || pRenderTarget
, D3DERR_INVALIDCALL
);
1647 user_assert(!pRenderTarget
||
1648 rt
->desc
.Usage
& D3DUSAGE_RENDERTARGET
, D3DERR_INVALIDCALL
);
1651 This
->state
.viewport
.X
= 0;
1652 This
->state
.viewport
.Y
= 0;
1653 This
->state
.viewport
.Width
= rt
->desc
.Width
;
1654 This
->state
.viewport
.Height
= rt
->desc
.Height
;
1655 This
->state
.viewport
.MinZ
= 0.0f
;
1656 This
->state
.viewport
.MaxZ
= 1.0f
;
1658 This
->state
.scissor
.minx
= 0;
1659 This
->state
.scissor
.miny
= 0;
1660 This
->state
.scissor
.maxx
= rt
->desc
.Width
;
1661 This
->state
.scissor
.maxy
= rt
->desc
.Height
;
1663 This
->state
.changed
.group
|= NINE_STATE_VIEWPORT
| NINE_STATE_SCISSOR
;
1666 if (This
->state
.rt
[i
] != NineSurface9(pRenderTarget
)) {
1667 nine_bind(&This
->state
.rt
[i
], pRenderTarget
);
1668 This
->state
.changed
.group
|= NINE_STATE_FB
;
1674 NineDevice9_GetRenderTarget( struct NineDevice9
*This
,
1675 DWORD RenderTargetIndex
,
1676 IDirect3DSurface9
**ppRenderTarget
)
1678 const unsigned i
= RenderTargetIndex
;
1680 user_assert(i
< This
->caps
.NumSimultaneousRTs
, D3DERR_INVALIDCALL
);
1681 user_assert(ppRenderTarget
, D3DERR_INVALIDCALL
);
1683 *ppRenderTarget
= (IDirect3DSurface9
*)This
->state
.rt
[i
];
1684 if (!This
->state
.rt
[i
])
1685 return D3DERR_NOTFOUND
;
1687 NineUnknown_AddRef(NineUnknown(This
->state
.rt
[i
]));
1692 NineDevice9_SetDepthStencilSurface( struct NineDevice9
*This
,
1693 IDirect3DSurface9
*pNewZStencil
)
1695 DBG("This=%p pNewZStencil=%p\n", This
, pNewZStencil
);
1697 if (This
->state
.ds
!= NineSurface9(pNewZStencil
)) {
1698 nine_bind(&This
->state
.ds
, pNewZStencil
);
1699 This
->state
.changed
.group
|= NINE_STATE_FB
;
1705 NineDevice9_GetDepthStencilSurface( struct NineDevice9
*This
,
1706 IDirect3DSurface9
**ppZStencilSurface
)
1708 user_assert(ppZStencilSurface
, D3DERR_INVALIDCALL
);
1710 *ppZStencilSurface
= (IDirect3DSurface9
*)This
->state
.ds
;
1711 if (!This
->state
.ds
)
1712 return D3DERR_NOTFOUND
;
1714 NineUnknown_AddRef(NineUnknown(This
->state
.ds
));
1719 NineDevice9_BeginScene( struct NineDevice9
*This
)
1721 DBG("This=%p\n", This
);
1722 user_assert(!This
->in_scene
, D3DERR_INVALIDCALL
);
1723 This
->in_scene
= TRUE
;
1724 /* Do we want to do anything else here ? */
1729 NineDevice9_EndScene( struct NineDevice9
*This
)
1731 DBG("This=%p\n", This
);
1732 user_assert(This
->in_scene
, D3DERR_INVALIDCALL
);
1733 This
->in_scene
= FALSE
;
1738 NineDevice9_Clear( struct NineDevice9
*This
,
1740 const D3DRECT
*pRects
,
1746 const int sRGB
= This
->state
.rs
[D3DRS_SRGBWRITEENABLE
] ? 1 : 0;
1747 struct pipe_surface
*cbuf
, *zsbuf
;
1748 struct pipe_context
*pipe
= This
->pipe
;
1749 struct NineSurface9
*zsbuf_surf
= This
->state
.ds
;
1750 struct NineSurface9
*rt
;
1753 union pipe_color_union rgba
;
1754 unsigned rt_mask
= 0;
1757 DBG("This=%p Count=%u pRects=%p Flags=%x Color=%08x Z=%f Stencil=%x\n",
1758 This
, Count
, pRects
, Flags
, Color
, Z
, Stencil
);
1760 user_assert(This
->state
.ds
|| !(Flags
& NINED3DCLEAR_DEPTHSTENCIL
),
1761 D3DERR_INVALIDCALL
);
1762 user_assert(!(Flags
& D3DCLEAR_STENCIL
) ||
1764 util_format_is_depth_and_stencil(zsbuf_surf
->base
.info
.format
)),
1765 D3DERR_INVALIDCALL
);
1767 user_assert((Count
&& pRects
) || (!Count
&& !pRects
), D3DERR_INVALIDCALL
);
1769 user_warn((pRects
&& !Count
) || (!pRects
&& Count
));
1770 if (pRects
&& !Count
)
1776 if (Flags
& D3DCLEAR_TARGET
) bufs
|= PIPE_CLEAR_COLOR
;
1777 if (Flags
& D3DCLEAR_ZBUFFER
) bufs
|= PIPE_CLEAR_DEPTH
;
1778 if (Flags
& D3DCLEAR_STENCIL
) bufs
|= PIPE_CLEAR_STENCIL
;
1781 d3dcolor_to_pipe_color_union(&rgba
, Color
);
1783 nine_update_state(This
, NINE_STATE_FB
);
1785 rect
.x1
= This
->state
.viewport
.X
;
1786 rect
.y1
= This
->state
.viewport
.Y
;
1787 rect
.x2
= This
->state
.viewport
.Width
+ rect
.x1
;
1788 rect
.y2
= This
->state
.viewport
.Height
+ rect
.y1
;
1790 /* Both rectangles apply, which is weird, but that's D3D9. */
1791 if (This
->state
.rs
[D3DRS_SCISSORTESTENABLE
]) {
1792 rect
.x1
= MAX2(rect
.x1
, This
->state
.scissor
.minx
);
1793 rect
.y1
= MAX2(rect
.y1
, This
->state
.scissor
.miny
);
1794 rect
.x2
= MIN2(rect
.x2
, This
->state
.scissor
.maxx
);
1795 rect
.y2
= MIN2(rect
.y2
, This
->state
.scissor
.maxy
);
1799 /* Maybe apps like to specify a large rect ? */
1800 if (pRects
[0].x1
<= rect
.x1
&& pRects
[0].x2
>= rect
.x2
&&
1801 pRects
[0].y1
<= rect
.y1
&& pRects
[0].y2
>= rect
.y2
) {
1802 DBG("First rect covers viewport.\n");
1808 if (rect
.x1
>= This
->state
.fb
.width
|| rect
.y1
>= This
->state
.fb
.height
)
1811 for (i
= 0; i
< This
->caps
.NumSimultaneousRTs
; ++i
) {
1812 if (This
->state
.rt
[i
] && This
->state
.rt
[i
]->desc
.Format
!= D3DFMT_NULL
)
1816 /* fast path, clears everything at once */
1818 (!(bufs
& PIPE_CLEAR_COLOR
) || (rt_mask
== This
->state
.rt_mask
)) &&
1819 rect
.x1
== 0 && rect
.y1
== 0 &&
1820 /* Case we clear only render target. Check clear region vs rt. */
1821 ((!(bufs
& (PIPE_CLEAR_DEPTH
| PIPE_CLEAR_STENCIL
)) &&
1822 rect
.x2
>= This
->state
.fb
.width
&&
1823 rect
.y2
>= This
->state
.fb
.height
) ||
1824 /* Case we clear depth buffer (and eventually rt too).
1825 * depth buffer size is always >= rt size. Compare to clear region */
1826 ((bufs
& (PIPE_CLEAR_DEPTH
| PIPE_CLEAR_STENCIL
)) &&
1827 This
->state
.fb
.zsbuf
!= NULL
&&
1828 rect
.x2
>= zsbuf_surf
->desc
.Width
&&
1829 rect
.y2
>= zsbuf_surf
->desc
.Height
))) {
1830 DBG("Clear fast path\n");
1831 pipe
->clear(pipe
, bufs
, &rgba
, Z
, Stencil
);
1840 for (i
= 0; i
< This
->caps
.NumSimultaneousRTs
; ++i
) {
1841 rt
= This
->state
.rt
[i
];
1842 if (!rt
|| rt
->desc
.Format
== D3DFMT_NULL
||
1843 !(Flags
& D3DCLEAR_TARGET
))
1844 continue; /* save space, compiler should hoist this */
1845 cbuf
= NineSurface9_GetSurface(rt
, sRGB
);
1846 for (r
= 0; r
< Count
; ++r
) {
1847 /* Don't trust users to pass these in the right order. */
1848 unsigned x1
= MIN2(pRects
[r
].x1
, pRects
[r
].x2
);
1849 unsigned y1
= MIN2(pRects
[r
].y1
, pRects
[r
].y2
);
1850 unsigned x2
= MAX2(pRects
[r
].x1
, pRects
[r
].x2
);
1851 unsigned y2
= MAX2(pRects
[r
].y1
, pRects
[r
].y2
);
1853 /* Drop negative rectangles (like wine expects). */
1854 if (pRects
[r
].x1
> pRects
[r
].x2
) continue;
1855 if (pRects
[r
].y1
> pRects
[r
].y2
) continue;
1858 x1
= MAX2(x1
, rect
.x1
);
1859 y1
= MAX2(y1
, rect
.y1
);
1860 x2
= MIN3(x2
, rect
.x2
, rt
->desc
.Width
);
1861 y2
= MIN3(y2
, rect
.y2
, rt
->desc
.Height
);
1863 DBG("Clearing (%u..%u)x(%u..%u)\n", x1
, x2
, y1
, y2
);
1864 pipe
->clear_render_target(pipe
, cbuf
, &rgba
,
1865 x1
, y1
, x2
- x1
, y2
- y1
);
1868 if (!(Flags
& NINED3DCLEAR_DEPTHSTENCIL
))
1871 bufs
&= PIPE_CLEAR_DEPTHSTENCIL
;
1873 for (r
= 0; r
< Count
; ++r
) {
1874 unsigned x1
= MIN2(pRects
[r
].x1
, pRects
[r
].x2
);
1875 unsigned y1
= MIN2(pRects
[r
].y1
, pRects
[r
].y2
);
1876 unsigned x2
= MAX2(pRects
[r
].x1
, pRects
[r
].x2
);
1877 unsigned y2
= MAX2(pRects
[r
].y1
, pRects
[r
].y2
);
1879 /* Drop negative rectangles. */
1880 if (pRects
[r
].x1
> pRects
[r
].x2
) continue;
1881 if (pRects
[r
].y1
> pRects
[r
].y2
) continue;
1884 x1
= MIN2(x1
, rect
.x1
);
1885 y1
= MIN2(y1
, rect
.y1
);
1886 x2
= MIN3(x2
, rect
.x2
, zsbuf_surf
->desc
.Width
);
1887 y2
= MIN3(y2
, rect
.y2
, zsbuf_surf
->desc
.Height
);
1889 zsbuf
= NineSurface9_GetSurface(zsbuf_surf
, 0);
1891 pipe
->clear_depth_stencil(pipe
, zsbuf
, bufs
, Z
, Stencil
,
1892 x1
, y1
, x2
- x1
, y2
- y1
);
1898 NineDevice9_SetTransform( struct NineDevice9
*This
,
1899 D3DTRANSFORMSTATETYPE State
,
1900 const D3DMATRIX
*pMatrix
)
1902 struct nine_state
*state
= This
->update
;
1903 D3DMATRIX
*M
= nine_state_access_transform(state
, State
, TRUE
);
1905 DBG("This=%p State=%d pMatrix=%p\n", This
, State
, pMatrix
);
1907 user_assert(M
, D3DERR_INVALIDCALL
);
1910 state
->ff
.changed
.transform
[State
/ 32] |= 1 << (State
% 32);
1911 state
->changed
.group
|= NINE_STATE_FF
;
1917 NineDevice9_GetTransform( struct NineDevice9
*This
,
1918 D3DTRANSFORMSTATETYPE State
,
1919 D3DMATRIX
*pMatrix
)
1921 D3DMATRIX
*M
= nine_state_access_transform(&This
->state
, State
, FALSE
);
1922 user_assert(M
, D3DERR_INVALIDCALL
);
1928 NineDevice9_MultiplyTransform( struct NineDevice9
*This
,
1929 D3DTRANSFORMSTATETYPE State
,
1930 const D3DMATRIX
*pMatrix
)
1932 struct nine_state
*state
= This
->update
;
1934 D3DMATRIX
*M
= nine_state_access_transform(state
, State
, TRUE
);
1936 DBG("This=%p State=%d pMatrix=%p\n", This
, State
, pMatrix
);
1938 user_assert(M
, D3DERR_INVALIDCALL
);
1940 nine_d3d_matrix_matrix_mul(&T
, pMatrix
, M
);
1941 return NineDevice9_SetTransform(This
, State
, &T
);
1945 NineDevice9_SetViewport( struct NineDevice9
*This
,
1946 const D3DVIEWPORT9
*pViewport
)
1948 struct nine_state
*state
= This
->update
;
1950 DBG("X=%u Y=%u W=%u H=%u MinZ=%f MaxZ=%f\n",
1951 pViewport
->X
, pViewport
->Y
, pViewport
->Width
, pViewport
->Height
,
1952 pViewport
->MinZ
, pViewport
->MaxZ
);
1954 state
->viewport
= *pViewport
;
1955 state
->changed
.group
|= NINE_STATE_VIEWPORT
;
1961 NineDevice9_GetViewport( struct NineDevice9
*This
,
1962 D3DVIEWPORT9
*pViewport
)
1964 *pViewport
= This
->state
.viewport
;
1969 NineDevice9_SetMaterial( struct NineDevice9
*This
,
1970 const D3DMATERIAL9
*pMaterial
)
1972 struct nine_state
*state
= This
->update
;
1974 DBG("This=%p pMaterial=%p\n", This
, pMaterial
);
1976 nine_dump_D3DMATERIAL9(DBG_FF
, pMaterial
);
1978 user_assert(pMaterial
, E_POINTER
);
1980 state
->ff
.material
= *pMaterial
;
1981 state
->changed
.group
|= NINE_STATE_FF_MATERIAL
;
1987 NineDevice9_GetMaterial( struct NineDevice9
*This
,
1988 D3DMATERIAL9
*pMaterial
)
1990 user_assert(pMaterial
, E_POINTER
);
1991 *pMaterial
= This
->state
.ff
.material
;
1996 NineDevice9_SetLight( struct NineDevice9
*This
,
1998 const D3DLIGHT9
*pLight
)
2000 struct nine_state
*state
= This
->update
;
2002 DBG("This=%p Index=%u pLight=%p\n", This
, Index
, pLight
);
2004 nine_dump_D3DLIGHT9(DBG_FF
, pLight
);
2006 user_assert(pLight
, D3DERR_INVALIDCALL
);
2007 user_assert(pLight
->Type
< NINED3DLIGHT_INVALID
, D3DERR_INVALIDCALL
);
2009 user_assert(Index
< NINE_MAX_LIGHTS
, D3DERR_INVALIDCALL
); /* sanity */
2011 if (Index
>= state
->ff
.num_lights
) {
2012 unsigned n
= state
->ff
.num_lights
;
2013 unsigned N
= Index
+ 1;
2015 state
->ff
.light
= REALLOC(state
->ff
.light
, n
* sizeof(D3DLIGHT9
),
2016 N
* sizeof(D3DLIGHT9
));
2017 if (!state
->ff
.light
)
2018 return E_OUTOFMEMORY
;
2019 state
->ff
.num_lights
= N
;
2021 for (; n
< Index
; ++n
)
2022 state
->ff
.light
[n
].Type
= (D3DLIGHTTYPE
)NINED3DLIGHT_INVALID
;
2024 state
->ff
.light
[Index
] = *pLight
;
2026 if (pLight
->Type
== D3DLIGHT_SPOT
&& pLight
->Theta
>= pLight
->Phi
) {
2027 DBG("Warning: clamping D3DLIGHT9.Theta\n");
2028 state
->ff
.light
[Index
].Theta
= state
->ff
.light
[Index
].Phi
;
2030 if (pLight
->Type
!= D3DLIGHT_DIRECTIONAL
&&
2031 pLight
->Attenuation0
== 0.0f
&&
2032 pLight
->Attenuation1
== 0.0f
&&
2033 pLight
->Attenuation2
== 0.0f
) {
2034 DBG("Warning: all D3DLIGHT9.Attenuation[i] are 0\n");
2037 state
->changed
.group
|= NINE_STATE_FF_LIGHTING
;
2043 NineDevice9_GetLight( struct NineDevice9
*This
,
2047 const struct nine_state
*state
= &This
->state
;
2049 user_assert(pLight
, D3DERR_INVALIDCALL
);
2050 user_assert(Index
< state
->ff
.num_lights
, D3DERR_INVALIDCALL
);
2051 user_assert(state
->ff
.light
[Index
].Type
< NINED3DLIGHT_INVALID
,
2052 D3DERR_INVALIDCALL
);
2054 *pLight
= state
->ff
.light
[Index
];
2060 NineDevice9_LightEnable( struct NineDevice9
*This
,
2064 struct nine_state
*state
= This
->update
;
2067 DBG("This=%p Index=%u Enable=%i\n", This
, Index
, Enable
);
2069 if (Index
>= state
->ff
.num_lights
||
2070 state
->ff
.light
[Index
].Type
== NINED3DLIGHT_INVALID
) {
2071 /* This should create a default light. */
2073 memset(&light
, 0, sizeof(light
));
2074 light
.Type
= D3DLIGHT_DIRECTIONAL
;
2075 light
.Diffuse
.r
= 1.0f
;
2076 light
.Diffuse
.g
= 1.0f
;
2077 light
.Diffuse
.b
= 1.0f
;
2078 light
.Direction
.z
= 1.0f
;
2079 NineDevice9_SetLight(This
, Index
, &light
);
2081 user_assert(Index
< state
->ff
.num_lights
, D3DERR_INVALIDCALL
);
2083 for (i
= 0; i
< state
->ff
.num_lights_active
; ++i
) {
2084 if (state
->ff
.active_light
[i
] == Index
)
2089 if (i
< state
->ff
.num_lights_active
)
2091 /* XXX wine thinks this should still succeed:
2093 user_assert(i
< NINE_MAX_LIGHTS_ACTIVE
, D3DERR_INVALIDCALL
);
2095 state
->ff
.active_light
[i
] = Index
;
2096 state
->ff
.num_lights_active
++;
2098 if (i
== state
->ff
.num_lights_active
)
2100 --state
->ff
.num_lights_active
;
2101 for (; i
< state
->ff
.num_lights_active
; ++i
)
2102 state
->ff
.active_light
[i
] = state
->ff
.active_light
[i
+ 1];
2104 state
->changed
.group
|= NINE_STATE_FF_LIGHTING
;
2110 NineDevice9_GetLightEnable( struct NineDevice9
*This
,
2114 const struct nine_state
*state
= &This
->state
;
2117 user_assert(Index
< state
->ff
.num_lights
, D3DERR_INVALIDCALL
);
2118 user_assert(state
->ff
.light
[Index
].Type
< NINED3DLIGHT_INVALID
,
2119 D3DERR_INVALIDCALL
);
2121 for (i
= 0; i
< state
->ff
.num_lights_active
; ++i
)
2122 if (state
->ff
.active_light
[i
] == Index
)
2125 *pEnable
= i
!= state
->ff
.num_lights_active
? 128 : 0; // Taken from wine
2131 NineDevice9_SetClipPlane( struct NineDevice9
*This
,
2133 const float *pPlane
)
2135 struct nine_state
*state
= This
->update
;
2137 user_assert(pPlane
, D3DERR_INVALIDCALL
);
2139 DBG("This=%p Index=%u pPlane=%f %f %f %f\n", This
, Index
,
2140 pPlane
[0], pPlane
[1],
2141 pPlane
[2], pPlane
[3]);
2143 user_assert(Index
< PIPE_MAX_CLIP_PLANES
, D3DERR_INVALIDCALL
);
2145 memcpy(&state
->clip
.ucp
[Index
][0], pPlane
, sizeof(state
->clip
.ucp
[0]));
2146 state
->changed
.ucp
|= 1 << Index
;
2152 NineDevice9_GetClipPlane( struct NineDevice9
*This
,
2156 const struct nine_state
*state
= &This
->state
;
2158 user_assert(Index
< PIPE_MAX_CLIP_PLANES
, D3DERR_INVALIDCALL
);
2160 memcpy(pPlane
, &state
->clip
.ucp
[Index
][0], sizeof(state
->clip
.ucp
[0]));
2164 #define RESZ_CODE 0x7fa05000
2167 NineDevice9_ResolveZ( struct NineDevice9
*This
)
2169 struct nine_state
*state
= &This
->state
;
2170 const struct util_format_description
*desc
;
2171 struct NineSurface9
*source
= state
->ds
;
2172 struct NineBaseTexture9
*destination
= state
->texture
[0];
2173 struct pipe_resource
*src
, *dst
;
2174 struct pipe_blit_info blit
;
2176 DBG("RESZ resolve\n");
2178 user_assert(source
&& destination
&&
2179 destination
->base
.type
== D3DRTYPE_TEXTURE
, D3DERR_INVALIDCALL
);
2181 src
= source
->base
.resource
;
2182 dst
= destination
->base
.resource
;
2184 user_assert(src
&& dst
, D3DERR_INVALIDCALL
);
2186 /* check dst is depth format. we know already for src */
2187 desc
= util_format_description(dst
->format
);
2188 user_assert(desc
->colorspace
== UTIL_FORMAT_COLORSPACE_ZS
, D3DERR_INVALIDCALL
);
2190 memset(&blit
, 0, sizeof(blit
));
2191 blit
.src
.resource
= src
;
2193 blit
.src
.format
= src
->format
;
2195 blit
.src
.box
.depth
= 1;
2198 blit
.src
.box
.width
= src
->width0
;
2199 blit
.src
.box
.height
= src
->height0
;
2201 blit
.dst
.resource
= dst
;
2203 blit
.dst
.format
= dst
->format
;
2205 blit
.dst
.box
.depth
= 1;
2208 blit
.dst
.box
.width
= dst
->width0
;
2209 blit
.dst
.box
.height
= dst
->height0
;
2211 blit
.mask
= PIPE_MASK_ZS
;
2212 blit
.filter
= PIPE_TEX_FILTER_NEAREST
;
2213 blit
.scissor_enable
= FALSE
;
2215 This
->pipe
->blit(This
->pipe
, &blit
);
2219 #define ALPHA_TO_COVERAGE_ENABLE MAKEFOURCC('A', '2', 'M', '1')
2220 #define ALPHA_TO_COVERAGE_DISABLE MAKEFOURCC('A', '2', 'M', '0')
2223 NineDevice9_SetRenderState( struct NineDevice9
*This
,
2224 D3DRENDERSTATETYPE State
,
2227 struct nine_state
*state
= This
->update
;
2229 DBG("This=%p State=%u(%s) Value=%08x\n", This
,
2230 State
, nine_d3drs_to_string(State
), Value
);
2232 /* Amd hacks (equivalent to GL extensions) */
2233 if (State
== D3DRS_POINTSIZE
) {
2234 if (Value
== RESZ_CODE
)
2235 return NineDevice9_ResolveZ(This
);
2237 if (Value
== ALPHA_TO_COVERAGE_ENABLE
||
2238 Value
== ALPHA_TO_COVERAGE_DISABLE
) {
2239 state
->rs
[NINED3DRS_ALPHACOVERAGE
] = (Value
== ALPHA_TO_COVERAGE_ENABLE
);
2240 state
->changed
.group
|= NINE_STATE_BLEND
;
2246 if (State
== D3DRS_ADAPTIVETESS_Y
&&
2247 (Value
== D3DFMT_ATOC
|| (Value
== D3DFMT_UNKNOWN
&& state
->rs
[NINED3DRS_ALPHACOVERAGE
]))) {
2248 state
->rs
[NINED3DRS_ALPHACOVERAGE
] = (Value
== D3DFMT_ATOC
);
2249 state
->changed
.group
|= NINE_STATE_BLEND
;
2253 user_assert(State
< Elements(state
->rs
), D3DERR_INVALIDCALL
);
2255 if (likely(state
->rs
[State
] != Value
) || unlikely(This
->is_recording
)) {
2256 state
->rs
[State
] = Value
;
2257 state
->changed
.rs
[State
/ 32] |= 1 << (State
% 32);
2258 state
->changed
.group
|= nine_render_state_group
[State
];
2265 NineDevice9_GetRenderState( struct NineDevice9
*This
,
2266 D3DRENDERSTATETYPE State
,
2269 user_assert(State
< Elements(This
->state
.rs
), D3DERR_INVALIDCALL
);
2271 *pValue
= This
->state
.rs
[State
];
2276 NineDevice9_CreateStateBlock( struct NineDevice9
*This
,
2277 D3DSTATEBLOCKTYPE Type
,
2278 IDirect3DStateBlock9
**ppSB
)
2280 struct NineStateBlock9
*nsb
;
2281 struct nine_state
*dst
;
2283 enum nine_stateblock_type type
;
2286 DBG("This=%p Type=%u ppSB=%p\n", This
, Type
, ppSB
);
2288 user_assert(Type
== D3DSBT_ALL
||
2289 Type
== D3DSBT_VERTEXSTATE
||
2290 Type
== D3DSBT_PIXELSTATE
, D3DERR_INVALIDCALL
);
2293 case D3DSBT_VERTEXSTATE
: type
= NINESBT_VERTEXSTATE
; break;
2294 case D3DSBT_PIXELSTATE
: type
= NINESBT_PIXELSTATE
; break;
2300 hr
= NineStateBlock9_new(This
, &nsb
, type
);
2303 *ppSB
= (IDirect3DStateBlock9
*)nsb
;
2306 dst
->changed
.group
=
2307 NINE_STATE_TEXTURE
|
2310 if (Type
== D3DSBT_ALL
|| Type
== D3DSBT_VERTEXSTATE
) {
2311 dst
->changed
.group
|=
2312 NINE_STATE_FF_LIGHTING
|
2313 NINE_STATE_VS
| NINE_STATE_VS_CONST
|
2315 /* TODO: texture/sampler state */
2316 memcpy(dst
->changed
.rs
,
2317 nine_render_states_vertex
, sizeof(dst
->changed
.rs
));
2318 nine_ranges_insert(&dst
->changed
.vs_const_f
, 0, This
->max_vs_const_f
,
2320 dst
->changed
.vs_const_i
= 0xffff;
2321 dst
->changed
.vs_const_b
= 0xffff;
2322 for (s
= 0; s
< NINE_MAX_SAMPLERS
; ++s
)
2323 dst
->changed
.sampler
[s
] |= 1 << D3DSAMP_DMAPOFFSET
;
2324 if (This
->state
.ff
.num_lights
) {
2325 dst
->ff
.num_lights
= This
->state
.ff
.num_lights
;
2326 /* zero'd -> light type won't be NINED3DLIGHT_INVALID, so
2327 * all currently existing lights will be captured
2329 dst
->ff
.light
= CALLOC(This
->state
.ff
.num_lights
,
2331 if (!dst
->ff
.light
) {
2332 nine_bind(ppSB
, NULL
);
2333 return E_OUTOFMEMORY
;
2337 if (Type
== D3DSBT_ALL
|| Type
== D3DSBT_PIXELSTATE
) {
2338 dst
->changed
.group
|=
2339 NINE_STATE_PS
| NINE_STATE_PS_CONST
;
2340 /* TODO: texture/sampler state */
2341 memcpy(dst
->changed
.rs
,
2342 nine_render_states_pixel
, sizeof(dst
->changed
.rs
));
2343 nine_ranges_insert(&dst
->changed
.ps_const_f
, 0, This
->max_ps_const_f
,
2345 dst
->changed
.ps_const_i
= 0xffff;
2346 dst
->changed
.ps_const_b
= 0xffff;
2347 for (s
= 0; s
< NINE_MAX_SAMPLERS
; ++s
)
2348 dst
->changed
.sampler
[s
] |= 0x1ffe;
2350 if (Type
== D3DSBT_ALL
) {
2351 dst
->changed
.group
|=
2352 NINE_STATE_VIEWPORT
|
2353 NINE_STATE_SCISSOR
|
2354 NINE_STATE_RASTERIZER
|
2358 NINE_STATE_MATERIAL
|
2359 NINE_STATE_BLEND_COLOR
|
2360 NINE_STATE_SAMPLE_MASK
;
2361 memset(dst
->changed
.rs
, ~0, (D3DRS_COUNT
/ 32) * sizeof(uint32_t));
2362 dst
->changed
.rs
[D3DRS_LAST
/ 32] |= (1 << (D3DRS_COUNT
% 32)) - 1;
2363 dst
->changed
.vtxbuf
= (1ULL << This
->caps
.MaxStreams
) - 1;
2364 dst
->changed
.stream_freq
= dst
->changed
.vtxbuf
;
2365 dst
->changed
.ucp
= (1 << PIPE_MAX_CLIP_PLANES
) - 1;
2366 dst
->changed
.texture
= (1 << NINE_MAX_SAMPLERS
) - 1;
2368 NineStateBlock9_Capture(NineStateBlock9(*ppSB
));
2370 /* TODO: fixed function state */
2376 NineDevice9_BeginStateBlock( struct NineDevice9
*This
)
2380 DBG("This=%p\n", This
);
2382 user_assert(!This
->record
, D3DERR_INVALIDCALL
);
2384 hr
= NineStateBlock9_new(This
, &This
->record
, NINESBT_CUSTOM
);
2387 NineUnknown_ConvertRefToBind(NineUnknown(This
->record
));
2389 This
->update
= &This
->record
->state
;
2390 This
->is_recording
= TRUE
;
2396 NineDevice9_EndStateBlock( struct NineDevice9
*This
,
2397 IDirect3DStateBlock9
**ppSB
)
2399 DBG("This=%p ppSB=%p\n", This
, ppSB
);
2401 user_assert(This
->record
, D3DERR_INVALIDCALL
);
2403 This
->update
= &This
->state
;
2404 This
->is_recording
= FALSE
;
2406 NineUnknown_AddRef(NineUnknown(This
->record
));
2407 *ppSB
= (IDirect3DStateBlock9
*)This
->record
;
2408 NineUnknown_Unbind(NineUnknown(This
->record
));
2409 This
->record
= NULL
;
2415 NineDevice9_SetClipStatus( struct NineDevice9
*This
,
2416 const D3DCLIPSTATUS9
*pClipStatus
)
2418 STUB(D3DERR_INVALIDCALL
);
2422 NineDevice9_GetClipStatus( struct NineDevice9
*This
,
2423 D3DCLIPSTATUS9
*pClipStatus
)
2425 STUB(D3DERR_INVALIDCALL
);
2429 NineDevice9_GetTexture( struct NineDevice9
*This
,
2431 IDirect3DBaseTexture9
**ppTexture
)
2433 user_assert(Stage
< This
->caps
.MaxSimultaneousTextures
||
2434 Stage
== D3DDMAPSAMPLER
||
2435 (Stage
>= D3DVERTEXTEXTURESAMPLER0
&&
2436 Stage
<= D3DVERTEXTEXTURESAMPLER3
), D3DERR_INVALIDCALL
);
2437 user_assert(ppTexture
, D3DERR_INVALIDCALL
);
2439 if (Stage
>= D3DDMAPSAMPLER
)
2440 Stage
= Stage
- D3DDMAPSAMPLER
+ NINE_MAX_SAMPLERS_PS
;
2442 *ppTexture
= (IDirect3DBaseTexture9
*)This
->state
.texture
[Stage
];
2444 if (This
->state
.texture
[Stage
])
2445 NineUnknown_AddRef(NineUnknown(This
->state
.texture
[Stage
]));
2450 NineDevice9_SetTexture( struct NineDevice9
*This
,
2452 IDirect3DBaseTexture9
*pTexture
)
2454 struct nine_state
*state
= This
->update
;
2455 struct NineBaseTexture9
*tex
= NineBaseTexture9(pTexture
);
2457 DBG("This=%p Stage=%u pTexture=%p\n", This
, Stage
, pTexture
);
2459 user_assert(Stage
< This
->caps
.MaxSimultaneousTextures
||
2460 Stage
== D3DDMAPSAMPLER
||
2461 (Stage
>= D3DVERTEXTEXTURESAMPLER0
&&
2462 Stage
<= D3DVERTEXTEXTURESAMPLER3
), D3DERR_INVALIDCALL
);
2463 user_assert(!tex
|| (tex
->base
.pool
!= D3DPOOL_SCRATCH
&&
2464 tex
->base
.pool
!= D3DPOOL_SYSTEMMEM
), D3DERR_INVALIDCALL
);
2466 if (Stage
>= D3DDMAPSAMPLER
)
2467 Stage
= Stage
- D3DDMAPSAMPLER
+ NINE_MAX_SAMPLERS_PS
;
2469 if (!This
->is_recording
) {
2470 struct NineBaseTexture9
*old
= state
->texture
[Stage
];
2474 state
->samplers_shadow
&= ~(1 << Stage
);
2476 state
->samplers_shadow
|= tex
->shadow
<< Stage
;
2478 if ((tex
->managed
.dirty
| tex
->dirty_mip
) && LIST_IS_EMPTY(&tex
->list
))
2479 list_add(&tex
->list
, &This
->update_textures
);
2486 nine_bind(&state
->texture
[Stage
], pTexture
);
2488 state
->changed
.texture
|= 1 << Stage
;
2489 state
->changed
.group
|= NINE_STATE_TEXTURE
;
2495 NineDevice9_GetTextureStageState( struct NineDevice9
*This
,
2497 D3DTEXTURESTAGESTATETYPE Type
,
2500 const struct nine_state
*state
= &This
->state
;
2502 user_assert(Stage
< Elements(state
->ff
.tex_stage
), D3DERR_INVALIDCALL
);
2503 user_assert(Type
< Elements(state
->ff
.tex_stage
[0]), D3DERR_INVALIDCALL
);
2505 *pValue
= state
->ff
.tex_stage
[Stage
][Type
];
2511 NineDevice9_SetTextureStageState( struct NineDevice9
*This
,
2513 D3DTEXTURESTAGESTATETYPE Type
,
2516 struct nine_state
*state
= This
->update
;
2518 DBG("Stage=%u Type=%u Value=%08x\n", Stage
, Type
, Value
);
2519 nine_dump_D3DTSS_value(DBG_FF
, Type
, Value
);
2521 user_assert(Stage
< Elements(state
->ff
.tex_stage
), D3DERR_INVALIDCALL
);
2522 user_assert(Type
< Elements(state
->ff
.tex_stage
[0]), D3DERR_INVALIDCALL
);
2524 state
->ff
.tex_stage
[Stage
][Type
] = Value
;
2526 state
->changed
.group
|= NINE_STATE_FF_PSSTAGES
;
2527 state
->ff
.changed
.tex_stage
[Stage
][Type
/ 32] |= 1 << (Type
% 32);
2533 NineDevice9_GetSamplerState( struct NineDevice9
*This
,
2535 D3DSAMPLERSTATETYPE Type
,
2538 user_assert(Sampler
< This
->caps
.MaxSimultaneousTextures
||
2539 Sampler
== D3DDMAPSAMPLER
||
2540 (Sampler
>= D3DVERTEXTEXTURESAMPLER0
&&
2541 Sampler
<= D3DVERTEXTEXTURESAMPLER3
), D3DERR_INVALIDCALL
);
2543 if (Sampler
>= D3DDMAPSAMPLER
)
2544 Sampler
= Sampler
- D3DDMAPSAMPLER
+ NINE_MAX_SAMPLERS_PS
;
2546 *pValue
= This
->state
.samp
[Sampler
][Type
];
2551 NineDevice9_SetSamplerState( struct NineDevice9
*This
,
2553 D3DSAMPLERSTATETYPE Type
,
2556 struct nine_state
*state
= This
->update
;
2558 DBG("This=%p Sampler=%u Type=%s Value=%08x\n", This
,
2559 Sampler
, nine_D3DSAMP_to_str(Type
), Value
);
2561 user_assert(Sampler
< This
->caps
.MaxSimultaneousTextures
||
2562 Sampler
== D3DDMAPSAMPLER
||
2563 (Sampler
>= D3DVERTEXTEXTURESAMPLER0
&&
2564 Sampler
<= D3DVERTEXTEXTURESAMPLER3
), D3DERR_INVALIDCALL
);
2566 if (Sampler
>= D3DDMAPSAMPLER
)
2567 Sampler
= Sampler
- D3DDMAPSAMPLER
+ NINE_MAX_SAMPLERS_PS
;
2569 state
->samp
[Sampler
][Type
] = Value
;
2570 state
->changed
.group
|= NINE_STATE_SAMPLER
;
2571 state
->changed
.sampler
[Sampler
] |= 1 << Type
;
2573 if (Type
== D3DSAMP_SRGBTEXTURE
)
2574 state
->changed
.srgb
= TRUE
;
2580 NineDevice9_ValidateDevice( struct NineDevice9
*This
,
2583 const struct nine_state
*state
= &This
->state
;
2585 unsigned w
= 0, h
= 0;
2587 DBG("This=%p pNumPasses=%p\n", This
, pNumPasses
);
2589 for (i
= 0; i
< Elements(state
->samp
); ++i
) {
2590 if (state
->samp
[i
][D3DSAMP_MINFILTER
] == D3DTEXF_NONE
||
2591 state
->samp
[i
][D3DSAMP_MAGFILTER
] == D3DTEXF_NONE
)
2592 return D3DERR_UNSUPPORTEDTEXTUREFILTER
;
2595 for (i
= 0; i
< This
->caps
.NumSimultaneousRTs
; ++i
) {
2599 w
= state
->rt
[i
]->desc
.Width
;
2600 h
= state
->rt
[i
]->desc
.Height
;
2602 if (state
->rt
[i
]->desc
.Width
!= w
|| state
->rt
[i
]->desc
.Height
!= h
) {
2603 return D3DERR_CONFLICTINGRENDERSTATE
;
2607 (state
->rs
[D3DRS_ZENABLE
] || state
->rs
[D3DRS_STENCILENABLE
])) {
2609 (state
->ds
->desc
.Width
!= w
|| state
->ds
->desc
.Height
!= h
))
2610 return D3DERR_CONFLICTINGRENDERSTATE
;
2620 NineDevice9_SetPaletteEntries( struct NineDevice9
*This
,
2622 const PALETTEENTRY
*pEntries
)
2624 STUB(D3D_OK
); /* like wine */
2628 NineDevice9_GetPaletteEntries( struct NineDevice9
*This
,
2630 PALETTEENTRY
*pEntries
)
2632 STUB(D3DERR_INVALIDCALL
);
2636 NineDevice9_SetCurrentTexturePalette( struct NineDevice9
*This
,
2637 UINT PaletteNumber
)
2639 STUB(D3D_OK
); /* like wine */
2643 NineDevice9_GetCurrentTexturePalette( struct NineDevice9
*This
,
2644 UINT
*PaletteNumber
)
2646 STUB(D3DERR_INVALIDCALL
);
2650 NineDevice9_SetScissorRect( struct NineDevice9
*This
,
2653 struct nine_state
*state
= This
->update
;
2655 DBG("x=(%u..%u) y=(%u..%u)\n",
2656 pRect
->left
, pRect
->top
, pRect
->right
, pRect
->bottom
);
2658 state
->scissor
.minx
= pRect
->left
;
2659 state
->scissor
.miny
= pRect
->top
;
2660 state
->scissor
.maxx
= pRect
->right
;
2661 state
->scissor
.maxy
= pRect
->bottom
;
2663 state
->changed
.group
|= NINE_STATE_SCISSOR
;
2669 NineDevice9_GetScissorRect( struct NineDevice9
*This
,
2672 pRect
->left
= This
->state
.scissor
.minx
;
2673 pRect
->top
= This
->state
.scissor
.miny
;
2674 pRect
->right
= This
->state
.scissor
.maxx
;
2675 pRect
->bottom
= This
->state
.scissor
.maxy
;
2681 NineDevice9_SetSoftwareVertexProcessing( struct NineDevice9
*This
,
2684 STUB(D3DERR_INVALIDCALL
);
2688 NineDevice9_GetSoftwareVertexProcessing( struct NineDevice9
*This
)
2690 return !!(This
->params
.BehaviorFlags
& D3DCREATE_SOFTWARE_VERTEXPROCESSING
);
2694 NineDevice9_SetNPatchMode( struct NineDevice9
*This
,
2697 STUB(D3DERR_INVALIDCALL
);
2701 NineDevice9_GetNPatchMode( struct NineDevice9
*This
)
2707 init_draw_info(struct pipe_draw_info
*info
,
2708 struct NineDevice9
*dev
, D3DPRIMITIVETYPE type
, UINT count
)
2710 info
->mode
= d3dprimitivetype_to_pipe_prim(type
);
2711 info
->count
= prim_count_to_vertex_count(type
, count
);
2712 info
->start_instance
= 0;
2713 info
->instance_count
= 1;
2714 if (dev
->state
.stream_instancedata_mask
& dev
->state
.stream_usage_mask
)
2715 info
->instance_count
= MAX2(dev
->state
.stream_freq
[0] & 0x7FFFFF, 1);
2716 info
->primitive_restart
= FALSE
;
2717 info
->restart_index
= 0;
2718 info
->count_from_stream_output
= NULL
;
2719 info
->indirect
= NULL
;
2723 NineDevice9_DrawPrimitive( struct NineDevice9
*This
,
2724 D3DPRIMITIVETYPE PrimitiveType
,
2726 UINT PrimitiveCount
)
2728 struct pipe_draw_info info
;
2730 DBG("iface %p, PrimitiveType %u, StartVertex %u, PrimitiveCount %u\n",
2731 This
, PrimitiveType
, StartVertex
, PrimitiveCount
);
2733 nine_update_state(This
, ~0);
2735 init_draw_info(&info
, This
, PrimitiveType
, PrimitiveCount
);
2736 info
.indexed
= FALSE
;
2737 info
.start
= StartVertex
;
2738 info
.index_bias
= 0;
2739 info
.min_index
= info
.start
;
2740 info
.max_index
= info
.count
- 1;
2742 This
->pipe
->draw_vbo(This
->pipe
, &info
);
2748 NineDevice9_DrawIndexedPrimitive( struct NineDevice9
*This
,
2749 D3DPRIMITIVETYPE PrimitiveType
,
2750 INT BaseVertexIndex
,
2751 UINT MinVertexIndex
,
2754 UINT PrimitiveCount
)
2756 struct pipe_draw_info info
;
2758 DBG("iface %p, PrimitiveType %u, BaseVertexIndex %u, MinVertexIndex %u "
2759 "NumVertices %u, StartIndex %u, PrimitiveCount %u\n",
2760 This
, PrimitiveType
, BaseVertexIndex
, MinVertexIndex
, NumVertices
,
2761 StartIndex
, PrimitiveCount
);
2763 user_assert(This
->state
.idxbuf
, D3DERR_INVALIDCALL
);
2764 user_assert(This
->state
.vdecl
, D3DERR_INVALIDCALL
);
2766 nine_update_state(This
, ~0);
2768 init_draw_info(&info
, This
, PrimitiveType
, PrimitiveCount
);
2769 info
.indexed
= TRUE
;
2770 info
.start
= StartIndex
;
2771 info
.index_bias
= BaseVertexIndex
;
2772 /* These don't include index bias: */
2773 info
.min_index
= MinVertexIndex
;
2774 info
.max_index
= MinVertexIndex
+ NumVertices
- 1;
2776 This
->pipe
->draw_vbo(This
->pipe
, &info
);
2782 NineDevice9_DrawPrimitiveUP( struct NineDevice9
*This
,
2783 D3DPRIMITIVETYPE PrimitiveType
,
2784 UINT PrimitiveCount
,
2785 const void *pVertexStreamZeroData
,
2786 UINT VertexStreamZeroStride
)
2788 struct pipe_vertex_buffer vtxbuf
;
2789 struct pipe_draw_info info
;
2791 DBG("iface %p, PrimitiveType %u, PrimitiveCount %u, data %p, stride %u\n",
2792 This
, PrimitiveType
, PrimitiveCount
,
2793 pVertexStreamZeroData
, VertexStreamZeroStride
);
2795 user_assert(pVertexStreamZeroData
&& VertexStreamZeroStride
,
2796 D3DERR_INVALIDCALL
);
2798 nine_update_state(This
, ~0);
2800 init_draw_info(&info
, This
, PrimitiveType
, PrimitiveCount
);
2801 info
.indexed
= FALSE
;
2803 info
.index_bias
= 0;
2805 info
.max_index
= info
.count
- 1;
2807 vtxbuf
.stride
= VertexStreamZeroStride
;
2808 vtxbuf
.buffer_offset
= 0;
2809 vtxbuf
.buffer
= NULL
;
2810 vtxbuf
.user_buffer
= pVertexStreamZeroData
;
2812 if (!This
->driver_caps
.user_vbufs
)
2813 u_upload_data(This
->upload
,
2815 (info
.max_index
+ 1) * VertexStreamZeroStride
, /* XXX */
2817 &vtxbuf
.buffer_offset
,
2820 This
->pipe
->set_vertex_buffers(This
->pipe
, 0, 1, &vtxbuf
);
2822 This
->pipe
->draw_vbo(This
->pipe
, &info
);
2824 NineDevice9_PauseRecording(This
);
2825 NineDevice9_SetStreamSource(This
, 0, NULL
, 0, 0);
2826 NineDevice9_ResumeRecording(This
);
2828 pipe_resource_reference(&vtxbuf
.buffer
, NULL
);
2834 NineDevice9_DrawIndexedPrimitiveUP( struct NineDevice9
*This
,
2835 D3DPRIMITIVETYPE PrimitiveType
,
2836 UINT MinVertexIndex
,
2838 UINT PrimitiveCount
,
2839 const void *pIndexData
,
2840 D3DFORMAT IndexDataFormat
,
2841 const void *pVertexStreamZeroData
,
2842 UINT VertexStreamZeroStride
)
2844 struct pipe_draw_info info
;
2845 struct pipe_vertex_buffer vbuf
;
2846 struct pipe_index_buffer ibuf
;
2848 DBG("iface %p, PrimitiveType %u, MinVertexIndex %u, NumVertices %u "
2849 "PrimitiveCount %u, pIndexData %p, IndexDataFormat %u "
2850 "pVertexStreamZeroData %p, VertexStreamZeroStride %u\n",
2851 This
, PrimitiveType
, MinVertexIndex
, NumVertices
, PrimitiveCount
,
2852 pIndexData
, IndexDataFormat
,
2853 pVertexStreamZeroData
, VertexStreamZeroStride
);
2855 user_assert(pIndexData
&& pVertexStreamZeroData
, D3DERR_INVALIDCALL
);
2856 user_assert(VertexStreamZeroStride
, D3DERR_INVALIDCALL
);
2857 user_assert(IndexDataFormat
== D3DFMT_INDEX16
||
2858 IndexDataFormat
== D3DFMT_INDEX32
, D3DERR_INVALIDCALL
);
2860 nine_update_state(This
, ~0);
2862 init_draw_info(&info
, This
, PrimitiveType
, PrimitiveCount
);
2863 info
.indexed
= TRUE
;
2865 info
.index_bias
= 0;
2866 info
.min_index
= MinVertexIndex
;
2867 info
.max_index
= MinVertexIndex
+ NumVertices
- 1;
2869 vbuf
.stride
= VertexStreamZeroStride
;
2870 vbuf
.buffer_offset
= 0;
2872 vbuf
.user_buffer
= pVertexStreamZeroData
;
2874 ibuf
.index_size
= (IndexDataFormat
== D3DFMT_INDEX16
) ? 2 : 4;
2877 ibuf
.user_buffer
= pIndexData
;
2879 if (!This
->driver_caps
.user_vbufs
) {
2880 const unsigned base
= info
.min_index
* VertexStreamZeroStride
;
2881 u_upload_data(This
->upload
,
2884 info
.min_index
+ 1) * VertexStreamZeroStride
, /* XXX */
2885 (const uint8_t *)vbuf
.user_buffer
+ base
,
2886 &vbuf
.buffer_offset
,
2888 /* Won't be used: */
2889 vbuf
.buffer_offset
-= base
;
2891 if (!This
->driver_caps
.user_ibufs
)
2892 u_upload_data(This
->upload
,
2894 info
.count
* ibuf
.index_size
,
2899 This
->pipe
->set_vertex_buffers(This
->pipe
, 0, 1, &vbuf
);
2900 This
->pipe
->set_index_buffer(This
->pipe
, &ibuf
);
2902 This
->pipe
->draw_vbo(This
->pipe
, &info
);
2904 pipe_resource_reference(&vbuf
.buffer
, NULL
);
2905 pipe_resource_reference(&ibuf
.buffer
, NULL
);
2907 NineDevice9_PauseRecording(This
);
2908 NineDevice9_SetIndices(This
, NULL
);
2909 NineDevice9_SetStreamSource(This
, 0, NULL
, 0, 0);
2910 NineDevice9_ResumeRecording(This
);
2915 /* TODO: Write to pDestBuffer directly if vertex declaration contains
2919 NineDevice9_ProcessVertices( struct NineDevice9
*This
,
2923 IDirect3DVertexBuffer9
*pDestBuffer
,
2924 IDirect3DVertexDeclaration9
*pVertexDecl
,
2927 struct pipe_screen
*screen
= This
->screen
;
2928 struct NineVertexDeclaration9
*vdecl
= NineVertexDeclaration9(pVertexDecl
);
2929 struct NineVertexShader9
*vs
;
2930 struct pipe_resource
*resource
;
2931 struct pipe_stream_output_target
*target
;
2932 struct pipe_draw_info draw
;
2934 unsigned buffer_offset
, buffer_size
;
2936 DBG("This=%p SrcStartIndex=%u DestIndex=%u VertexCount=%u "
2937 "pDestBuffer=%p pVertexDecl=%p Flags=%d\n",
2938 This
, SrcStartIndex
, DestIndex
, VertexCount
, pDestBuffer
,
2939 pVertexDecl
, Flags
);
2941 if (!screen
->get_param(screen
, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS
))
2942 STUB(D3DERR_INVALIDCALL
);
2944 nine_update_state(This
, ~0);
2946 /* TODO: Create shader with stream output. */
2947 STUB(D3DERR_INVALIDCALL
);
2948 struct NineVertexBuffer9
*dst
= NineVertexBuffer9(pDestBuffer
);
2950 vs
= This
->state
.vs
? This
->state
.vs
: This
->ff
.vs
;
2952 buffer_size
= VertexCount
* vs
->so
->stride
[0];
2954 struct pipe_resource templ
;
2956 templ
.target
= PIPE_BUFFER
;
2957 templ
.format
= PIPE_FORMAT_R8_UNORM
;
2958 templ
.width0
= buffer_size
;
2960 templ
.bind
= PIPE_BIND_STREAM_OUTPUT
;
2961 templ
.usage
= PIPE_USAGE_STREAM
;
2962 templ
.height0
= templ
.depth0
= templ
.array_size
= 1;
2963 templ
.last_level
= templ
.nr_samples
= 0;
2965 resource
= This
->screen
->resource_create(This
->screen
, &templ
);
2967 return E_OUTOFMEMORY
;
2970 /* SO matches vertex declaration */
2971 resource
= dst
->base
.resource
;
2972 buffer_offset
= DestIndex
* vs
->so
->stride
[0];
2974 target
= This
->pipe
->create_stream_output_target(This
->pipe
, resource
,
2978 pipe_resource_reference(&resource
, NULL
);
2979 return D3DERR_DRIVERINTERNALERROR
;
2983 hr
= NineVertexDeclaration9_new_from_fvf(This
, dst
->desc
.FVF
, &vdecl
);
2988 init_draw_info(&draw
, This
, D3DPT_POINTLIST
, VertexCount
);
2989 draw
.instance_count
= 1;
2990 draw
.indexed
= FALSE
;
2991 draw
.start
= SrcStartIndex
;
2992 draw
.index_bias
= 0;
2993 draw
.min_index
= SrcStartIndex
;
2994 draw
.max_index
= SrcStartIndex
+ VertexCount
- 1;
2996 This
->pipe
->set_stream_output_targets(This
->pipe
, 1, &target
, 0);
2997 This
->pipe
->draw_vbo(This
->pipe
, &draw
);
2998 This
->pipe
->set_stream_output_targets(This
->pipe
, 0, NULL
, 0);
2999 This
->pipe
->stream_output_target_destroy(This
->pipe
, target
);
3001 hr
= NineVertexDeclaration9_ConvertStreamOutput(vdecl
,
3002 dst
, DestIndex
, VertexCount
,
3005 pipe_resource_reference(&resource
, NULL
);
3007 NineUnknown_Release(NineUnknown(vdecl
));
3012 NineDevice9_CreateVertexDeclaration( struct NineDevice9
*This
,
3013 const D3DVERTEXELEMENT9
*pVertexElements
,
3014 IDirect3DVertexDeclaration9
**ppDecl
)
3016 struct NineVertexDeclaration9
*vdecl
;
3018 DBG("This=%p pVertexElements=%p ppDecl=%p\n",
3019 This
, pVertexElements
, ppDecl
);
3021 HRESULT hr
= NineVertexDeclaration9_new(This
, pVertexElements
, &vdecl
);
3023 *ppDecl
= (IDirect3DVertexDeclaration9
*)vdecl
;
3029 NineDevice9_SetVertexDeclaration( struct NineDevice9
*This
,
3030 IDirect3DVertexDeclaration9
*pDecl
)
3032 struct nine_state
*state
= This
->update
;
3034 DBG("This=%p pDecl=%p\n", This
, pDecl
);
3036 if (likely(!This
->is_recording
) && state
->vdecl
== NineVertexDeclaration9(pDecl
))
3038 nine_bind(&state
->vdecl
, pDecl
);
3040 state
->changed
.group
|= NINE_STATE_VDECL
;
3046 NineDevice9_GetVertexDeclaration( struct NineDevice9
*This
,
3047 IDirect3DVertexDeclaration9
**ppDecl
)
3049 user_assert(ppDecl
, D3DERR_INVALIDCALL
);
3051 *ppDecl
= (IDirect3DVertexDeclaration9
*)This
->state
.vdecl
;
3053 NineUnknown_AddRef(NineUnknown(*ppDecl
));
3058 NineDevice9_SetFVF( struct NineDevice9
*This
,
3061 struct NineVertexDeclaration9
*vdecl
;
3064 DBG("FVF = %08x\n", FVF
);
3066 return D3D_OK
; /* like wine */
3068 vdecl
= util_hash_table_get(This
->ff
.ht_fvf
, &FVF
);
3070 hr
= NineVertexDeclaration9_new_from_fvf(This
, FVF
, &vdecl
);
3074 util_hash_table_set(This
->ff
.ht_fvf
, &vdecl
->fvf
, vdecl
);
3075 NineUnknown_ConvertRefToBind(NineUnknown(vdecl
));
3077 return NineDevice9_SetVertexDeclaration(
3078 This
, (IDirect3DVertexDeclaration9
*)vdecl
);
3082 NineDevice9_GetFVF( struct NineDevice9
*This
,
3085 *pFVF
= This
->state
.vdecl
? This
->state
.vdecl
->fvf
: 0;
3090 NineDevice9_CreateVertexShader( struct NineDevice9
*This
,
3091 const DWORD
*pFunction
,
3092 IDirect3DVertexShader9
**ppShader
)
3094 struct NineVertexShader9
*vs
;
3097 DBG("This=%p pFunction=%p ppShader=%p\n", This
, pFunction
, ppShader
);
3099 hr
= NineVertexShader9_new(This
, &vs
, pFunction
, NULL
);
3102 *ppShader
= (IDirect3DVertexShader9
*)vs
;
3107 NineDevice9_SetVertexShader( struct NineDevice9
*This
,
3108 IDirect3DVertexShader9
*pShader
)
3110 struct nine_state
*state
= This
->update
;
3112 DBG("This=%p pShader=%p\n", This
, pShader
);
3114 nine_bind(&state
->vs
, pShader
);
3116 state
->changed
.group
|= NINE_STATE_VS
;
3122 NineDevice9_GetVertexShader( struct NineDevice9
*This
,
3123 IDirect3DVertexShader9
**ppShader
)
3125 user_assert(ppShader
, D3DERR_INVALIDCALL
);
3126 nine_reference_set(ppShader
, This
->state
.vs
);
3131 NineDevice9_SetVertexShaderConstantF( struct NineDevice9
*This
,
3133 const float *pConstantData
,
3134 UINT Vector4fCount
)
3136 struct nine_state
*state
= This
->update
;
3138 DBG("This=%p StartRegister=%u pConstantData=%p Vector4fCount=%u\n",
3139 This
, StartRegister
, pConstantData
, Vector4fCount
);
3141 user_assert(StartRegister
< This
->caps
.MaxVertexShaderConst
, D3DERR_INVALIDCALL
);
3142 user_assert(StartRegister
+ Vector4fCount
<= This
->caps
.MaxVertexShaderConst
, D3DERR_INVALIDCALL
);
3146 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3148 memcpy(&state
->vs_const_f
[StartRegister
* 4],
3150 Vector4fCount
* 4 * sizeof(state
->vs_const_f
[0]));
3152 nine_ranges_insert(&state
->changed
.vs_const_f
,
3153 StartRegister
, StartRegister
+ Vector4fCount
,
3156 state
->changed
.group
|= NINE_STATE_VS_CONST
;
3162 NineDevice9_GetVertexShaderConstantF( struct NineDevice9
*This
,
3164 float *pConstantData
,
3165 UINT Vector4fCount
)
3167 const struct nine_state
*state
= &This
->state
;
3169 user_assert(StartRegister
< This
->caps
.MaxVertexShaderConst
, D3DERR_INVALIDCALL
);
3170 user_assert(StartRegister
+ Vector4fCount
<= This
->caps
.MaxVertexShaderConst
, D3DERR_INVALIDCALL
);
3171 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3173 memcpy(pConstantData
,
3174 &state
->vs_const_f
[StartRegister
* 4],
3175 Vector4fCount
* 4 * sizeof(state
->vs_const_f
[0]));
3181 NineDevice9_SetVertexShaderConstantI( struct NineDevice9
*This
,
3183 const int *pConstantData
,
3184 UINT Vector4iCount
)
3186 struct nine_state
*state
= This
->update
;
3189 DBG("This=%p StartRegister=%u pConstantData=%p Vector4iCount=%u\n",
3190 This
, StartRegister
, pConstantData
, Vector4iCount
);
3192 user_assert(StartRegister
< NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3193 user_assert(StartRegister
+ Vector4iCount
<= NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3194 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3196 if (This
->driver_caps
.vs_integer
) {
3197 memcpy(&state
->vs_const_i
[StartRegister
][0],
3199 Vector4iCount
* sizeof(state
->vs_const_i
[0]));
3201 for (i
= 0; i
< Vector4iCount
; i
++) {
3202 state
->vs_const_i
[StartRegister
+i
][0] = fui((float)(pConstantData
[4*i
]));
3203 state
->vs_const_i
[StartRegister
+i
][1] = fui((float)(pConstantData
[4*i
+1]));
3204 state
->vs_const_i
[StartRegister
+i
][2] = fui((float)(pConstantData
[4*i
+2]));
3205 state
->vs_const_i
[StartRegister
+i
][3] = fui((float)(pConstantData
[4*i
+3]));
3209 state
->changed
.vs_const_i
|= ((1 << Vector4iCount
) - 1) << StartRegister
;
3210 state
->changed
.group
|= NINE_STATE_VS_CONST
;
3216 NineDevice9_GetVertexShaderConstantI( struct NineDevice9
*This
,
3219 UINT Vector4iCount
)
3221 const struct nine_state
*state
= &This
->state
;
3224 user_assert(StartRegister
< NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3225 user_assert(StartRegister
+ Vector4iCount
<= NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3226 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3228 if (This
->driver_caps
.vs_integer
) {
3229 memcpy(pConstantData
,
3230 &state
->vs_const_i
[StartRegister
][0],
3231 Vector4iCount
* sizeof(state
->vs_const_i
[0]));
3233 for (i
= 0; i
< Vector4iCount
; i
++) {
3234 pConstantData
[4*i
] = (int32_t) uif(state
->vs_const_i
[StartRegister
+i
][0]);
3235 pConstantData
[4*i
+1] = (int32_t) uif(state
->vs_const_i
[StartRegister
+i
][1]);
3236 pConstantData
[4*i
+2] = (int32_t) uif(state
->vs_const_i
[StartRegister
+i
][2]);
3237 pConstantData
[4*i
+3] = (int32_t) uif(state
->vs_const_i
[StartRegister
+i
][3]);
3245 NineDevice9_SetVertexShaderConstantB( struct NineDevice9
*This
,
3247 const BOOL
*pConstantData
,
3250 struct nine_state
*state
= This
->update
;
3252 uint32_t bool_true
= This
->driver_caps
.vs_integer
? 0xFFFFFFFF : fui(1.0f
);
3254 DBG("This=%p StartRegister=%u pConstantData=%p BoolCount=%u\n",
3255 This
, StartRegister
, pConstantData
, BoolCount
);
3257 user_assert(StartRegister
< NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3258 user_assert(StartRegister
+ BoolCount
<= NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3259 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3261 for (i
= 0; i
< BoolCount
; i
++)
3262 state
->vs_const_b
[StartRegister
+ i
] = pConstantData
[i
] ? bool_true
: 0;
3264 state
->changed
.vs_const_b
|= ((1 << BoolCount
) - 1) << StartRegister
;
3265 state
->changed
.group
|= NINE_STATE_VS_CONST
;
3271 NineDevice9_GetVertexShaderConstantB( struct NineDevice9
*This
,
3273 BOOL
*pConstantData
,
3276 const struct nine_state
*state
= &This
->state
;
3279 user_assert(StartRegister
< NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3280 user_assert(StartRegister
+ BoolCount
<= NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3281 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3283 for (i
= 0; i
< BoolCount
; i
++)
3284 pConstantData
[i
] = state
->vs_const_b
[StartRegister
+ i
] != 0 ? TRUE
: FALSE
;
3290 NineDevice9_SetStreamSource( struct NineDevice9
*This
,
3292 IDirect3DVertexBuffer9
*pStreamData
,
3296 struct nine_state
*state
= This
->update
;
3297 struct NineVertexBuffer9
*pVBuf9
= NineVertexBuffer9(pStreamData
);
3298 const unsigned i
= StreamNumber
;
3300 DBG("This=%p StreamNumber=%u pStreamData=%p OffsetInBytes=%u Stride=%u\n",
3301 This
, StreamNumber
, pStreamData
, OffsetInBytes
, Stride
);
3303 user_assert(StreamNumber
< This
->caps
.MaxStreams
, D3DERR_INVALIDCALL
);
3304 user_assert(Stride
<= This
->caps
.MaxStreamStride
, D3DERR_INVALIDCALL
);
3306 if (likely(!This
->is_recording
)) {
3307 if (state
->stream
[i
] == NineVertexBuffer9(pStreamData
) &&
3308 state
->vtxbuf
[i
].stride
== Stride
&&
3309 state
->vtxbuf
[i
].buffer_offset
== OffsetInBytes
)
3312 nine_bind(&state
->stream
[i
], pStreamData
);
3314 state
->changed
.vtxbuf
|= 1 << StreamNumber
;
3317 state
->vtxbuf
[i
].stride
= Stride
;
3318 state
->vtxbuf
[i
].buffer_offset
= OffsetInBytes
;
3320 state
->vtxbuf
[i
].buffer
= pStreamData
? pVBuf9
->base
.resource
: NULL
;
3326 NineDevice9_GetStreamSource( struct NineDevice9
*This
,
3328 IDirect3DVertexBuffer9
**ppStreamData
,
3329 UINT
*pOffsetInBytes
,
3332 const struct nine_state
*state
= &This
->state
;
3333 const unsigned i
= StreamNumber
;
3335 user_assert(StreamNumber
< This
->caps
.MaxStreams
, D3DERR_INVALIDCALL
);
3336 user_assert(ppStreamData
, D3DERR_INVALIDCALL
);
3338 nine_reference_set(ppStreamData
, state
->stream
[i
]);
3339 *pStride
= state
->vtxbuf
[i
].stride
;
3340 *pOffsetInBytes
= state
->vtxbuf
[i
].buffer_offset
;
3346 NineDevice9_SetStreamSourceFreq( struct NineDevice9
*This
,
3350 struct nine_state
*state
= This
->update
;
3351 /* const UINT freq = Setting & 0x7FFFFF; */
3353 DBG("This=%p StreamNumber=%u FrequencyParameter=0x%x\n", This
,
3354 StreamNumber
, Setting
);
3356 user_assert(StreamNumber
< This
->caps
.MaxStreams
, D3DERR_INVALIDCALL
);
3357 user_assert(StreamNumber
!= 0 || !(Setting
& D3DSTREAMSOURCE_INSTANCEDATA
),
3358 D3DERR_INVALIDCALL
);
3359 user_assert(!((Setting
& D3DSTREAMSOURCE_INSTANCEDATA
) &&
3360 (Setting
& D3DSTREAMSOURCE_INDEXEDDATA
)), D3DERR_INVALIDCALL
);
3361 user_assert(Setting
, D3DERR_INVALIDCALL
);
3363 state
->stream_freq
[StreamNumber
] = Setting
;
3365 if (Setting
& D3DSTREAMSOURCE_INSTANCEDATA
)
3366 state
->stream_instancedata_mask
|= 1 << StreamNumber
;
3368 state
->stream_instancedata_mask
&= ~(1 << StreamNumber
);
3370 state
->changed
.stream_freq
|= 1 << StreamNumber
;
3375 NineDevice9_GetStreamSourceFreq( struct NineDevice9
*This
,
3379 user_assert(StreamNumber
< This
->caps
.MaxStreams
, D3DERR_INVALIDCALL
);
3380 *pSetting
= This
->state
.stream_freq
[StreamNumber
];
3385 NineDevice9_SetIndices( struct NineDevice9
*This
,
3386 IDirect3DIndexBuffer9
*pIndexData
)
3388 struct nine_state
*state
= This
->update
;
3390 DBG("This=%p pIndexData=%p\n", This
, pIndexData
);
3392 if (likely(!This
->is_recording
))
3393 if (state
->idxbuf
== NineIndexBuffer9(pIndexData
))
3395 nine_bind(&state
->idxbuf
, pIndexData
);
3397 state
->changed
.group
|= NINE_STATE_IDXBUF
;
3402 /* XXX: wine/d3d9 doesn't have pBaseVertexIndex, and it doesn't make sense
3403 * here because it's an argument passed to the Draw calls.
3406 NineDevice9_GetIndices( struct NineDevice9
*This
,
3407 IDirect3DIndexBuffer9
**ppIndexData
/*,
3408 UINT *pBaseVertexIndex */ )
3410 user_assert(ppIndexData
, D3DERR_INVALIDCALL
);
3411 nine_reference_set(ppIndexData
, This
->state
.idxbuf
);
3416 NineDevice9_CreatePixelShader( struct NineDevice9
*This
,
3417 const DWORD
*pFunction
,
3418 IDirect3DPixelShader9
**ppShader
)
3420 struct NinePixelShader9
*ps
;
3423 DBG("This=%p pFunction=%p ppShader=%p\n", This
, pFunction
, ppShader
);
3425 hr
= NinePixelShader9_new(This
, &ps
, pFunction
, NULL
);
3428 *ppShader
= (IDirect3DPixelShader9
*)ps
;
3433 NineDevice9_SetPixelShader( struct NineDevice9
*This
,
3434 IDirect3DPixelShader9
*pShader
)
3436 struct nine_state
*state
= This
->update
;
3437 unsigned old_mask
= state
->ps
? state
->ps
->rt_mask
: 1;
3440 DBG("This=%p pShader=%p\n", This
, pShader
);
3442 nine_bind(&state
->ps
, pShader
);
3444 state
->changed
.group
|= NINE_STATE_PS
;
3446 mask
= state
->ps
? state
->ps
->rt_mask
: 1;
3447 /* We need to update cbufs if the pixel shader would
3448 * write to different render targets */
3449 if (mask
!= old_mask
)
3450 state
->changed
.group
|= NINE_STATE_FB
;
3456 NineDevice9_GetPixelShader( struct NineDevice9
*This
,
3457 IDirect3DPixelShader9
**ppShader
)
3459 user_assert(ppShader
, D3DERR_INVALIDCALL
);
3460 nine_reference_set(ppShader
, This
->state
.ps
);
3465 NineDevice9_SetPixelShaderConstantF( struct NineDevice9
*This
,
3467 const float *pConstantData
,
3468 UINT Vector4fCount
)
3470 struct nine_state
*state
= This
->update
;
3472 DBG("This=%p StartRegister=%u pConstantData=%p Vector4fCount=%u\n",
3473 This
, StartRegister
, pConstantData
, Vector4fCount
);
3475 user_assert(StartRegister
< NINE_MAX_CONST_F_PS3
, D3DERR_INVALIDCALL
);
3476 user_assert(StartRegister
+ Vector4fCount
<= NINE_MAX_CONST_F_PS3
, D3DERR_INVALIDCALL
);
3480 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3482 memcpy(&state
->ps_const_f
[StartRegister
* 4],
3484 Vector4fCount
* 4 * sizeof(state
->ps_const_f
[0]));
3486 nine_ranges_insert(&state
->changed
.ps_const_f
,
3487 StartRegister
, StartRegister
+ Vector4fCount
,
3490 state
->changed
.group
|= NINE_STATE_PS_CONST
;
3496 NineDevice9_GetPixelShaderConstantF( struct NineDevice9
*This
,
3498 float *pConstantData
,
3499 UINT Vector4fCount
)
3501 const struct nine_state
*state
= &This
->state
;
3503 user_assert(StartRegister
< NINE_MAX_CONST_F_PS3
, D3DERR_INVALIDCALL
);
3504 user_assert(StartRegister
+ Vector4fCount
<= NINE_MAX_CONST_F_PS3
, D3DERR_INVALIDCALL
);
3505 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3507 memcpy(pConstantData
,
3508 &state
->ps_const_f
[StartRegister
* 4],
3509 Vector4fCount
* 4 * sizeof(state
->ps_const_f
[0]));
3515 NineDevice9_SetPixelShaderConstantI( struct NineDevice9
*This
,
3517 const int *pConstantData
,
3518 UINT Vector4iCount
)
3520 struct nine_state
*state
= This
->update
;
3523 DBG("This=%p StartRegister=%u pConstantData=%p Vector4iCount=%u\n",
3524 This
, StartRegister
, pConstantData
, Vector4iCount
);
3526 user_assert(StartRegister
< NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3527 user_assert(StartRegister
+ Vector4iCount
<= NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3528 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3530 if (This
->driver_caps
.ps_integer
) {
3531 memcpy(&state
->ps_const_i
[StartRegister
][0],
3533 Vector4iCount
* sizeof(state
->ps_const_i
[0]));
3535 for (i
= 0; i
< Vector4iCount
; i
++) {
3536 state
->ps_const_i
[StartRegister
+i
][0] = fui((float)(pConstantData
[4*i
]));
3537 state
->ps_const_i
[StartRegister
+i
][1] = fui((float)(pConstantData
[4*i
+1]));
3538 state
->ps_const_i
[StartRegister
+i
][2] = fui((float)(pConstantData
[4*i
+2]));
3539 state
->ps_const_i
[StartRegister
+i
][3] = fui((float)(pConstantData
[4*i
+3]));
3542 state
->changed
.ps_const_i
|= ((1 << Vector4iCount
) - 1) << StartRegister
;
3543 state
->changed
.group
|= NINE_STATE_PS_CONST
;
3549 NineDevice9_GetPixelShaderConstantI( struct NineDevice9
*This
,
3552 UINT Vector4iCount
)
3554 const struct nine_state
*state
= &This
->state
;
3557 user_assert(StartRegister
< NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3558 user_assert(StartRegister
+ Vector4iCount
<= NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3559 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3561 if (This
->driver_caps
.ps_integer
) {
3562 memcpy(pConstantData
,
3563 &state
->ps_const_i
[StartRegister
][0],
3564 Vector4iCount
* sizeof(state
->ps_const_i
[0]));
3566 for (i
= 0; i
< Vector4iCount
; i
++) {
3567 pConstantData
[4*i
] = (int32_t) uif(state
->ps_const_i
[StartRegister
+i
][0]);
3568 pConstantData
[4*i
+1] = (int32_t) uif(state
->ps_const_i
[StartRegister
+i
][1]);
3569 pConstantData
[4*i
+2] = (int32_t) uif(state
->ps_const_i
[StartRegister
+i
][2]);
3570 pConstantData
[4*i
+3] = (int32_t) uif(state
->ps_const_i
[StartRegister
+i
][3]);
3578 NineDevice9_SetPixelShaderConstantB( struct NineDevice9
*This
,
3580 const BOOL
*pConstantData
,
3583 struct nine_state
*state
= This
->update
;
3585 uint32_t bool_true
= This
->driver_caps
.ps_integer
? 0xFFFFFFFF : fui(1.0f
);
3587 DBG("This=%p StartRegister=%u pConstantData=%p BoolCount=%u\n",
3588 This
, StartRegister
, pConstantData
, BoolCount
);
3590 user_assert(StartRegister
< NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3591 user_assert(StartRegister
+ BoolCount
<= NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3592 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3594 for (i
= 0; i
< BoolCount
; i
++)
3595 state
->ps_const_b
[StartRegister
+ i
] = pConstantData
[i
] ? bool_true
: 0;
3597 state
->changed
.ps_const_b
|= ((1 << BoolCount
) - 1) << StartRegister
;
3598 state
->changed
.group
|= NINE_STATE_PS_CONST
;
3604 NineDevice9_GetPixelShaderConstantB( struct NineDevice9
*This
,
3606 BOOL
*pConstantData
,
3609 const struct nine_state
*state
= &This
->state
;
3612 user_assert(StartRegister
< NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3613 user_assert(StartRegister
+ BoolCount
<= NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3614 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3616 for (i
= 0; i
< BoolCount
; i
++)
3617 pConstantData
[i
] = state
->ps_const_b
[StartRegister
+ i
] ? TRUE
: FALSE
;
3623 NineDevice9_DrawRectPatch( struct NineDevice9
*This
,
3625 const float *pNumSegs
,
3626 const D3DRECTPATCH_INFO
*pRectPatchInfo
)
3628 STUB(D3DERR_INVALIDCALL
);
3632 NineDevice9_DrawTriPatch( struct NineDevice9
*This
,
3634 const float *pNumSegs
,
3635 const D3DTRIPATCH_INFO
*pTriPatchInfo
)
3637 STUB(D3DERR_INVALIDCALL
);
3641 NineDevice9_DeletePatch( struct NineDevice9
*This
,
3644 STUB(D3DERR_INVALIDCALL
);
3648 NineDevice9_CreateQuery( struct NineDevice9
*This
,
3650 IDirect3DQuery9
**ppQuery
)
3652 struct NineQuery9
*query
;
3655 DBG("This=%p Type=%d ppQuery=%p\n", This
, Type
, ppQuery
);
3657 hr
= nine_is_query_supported(This
->screen
, Type
);
3658 if (!ppQuery
|| hr
!= D3D_OK
)
3661 hr
= NineQuery9_new(This
, &query
, Type
);
3664 *ppQuery
= (IDirect3DQuery9
*)query
;
3668 IDirect3DDevice9Vtbl NineDevice9_vtable
= {
3669 (void *)NineUnknown_QueryInterface
,
3670 (void *)NineUnknown_AddRef
,
3671 (void *)NineUnknown_Release
,
3672 (void *)NineDevice9_TestCooperativeLevel
,
3673 (void *)NineDevice9_GetAvailableTextureMem
,
3674 (void *)NineDevice9_EvictManagedResources
,
3675 (void *)NineDevice9_GetDirect3D
,
3676 (void *)NineDevice9_GetDeviceCaps
,
3677 (void *)NineDevice9_GetDisplayMode
,
3678 (void *)NineDevice9_GetCreationParameters
,
3679 (void *)NineDevice9_SetCursorProperties
,
3680 (void *)NineDevice9_SetCursorPosition
,
3681 (void *)NineDevice9_ShowCursor
,
3682 (void *)NineDevice9_CreateAdditionalSwapChain
,
3683 (void *)NineDevice9_GetSwapChain
,
3684 (void *)NineDevice9_GetNumberOfSwapChains
,
3685 (void *)NineDevice9_Reset
,
3686 (void *)NineDevice9_Present
,
3687 (void *)NineDevice9_GetBackBuffer
,
3688 (void *)NineDevice9_GetRasterStatus
,
3689 (void *)NineDevice9_SetDialogBoxMode
,
3690 (void *)NineDevice9_SetGammaRamp
,
3691 (void *)NineDevice9_GetGammaRamp
,
3692 (void *)NineDevice9_CreateTexture
,
3693 (void *)NineDevice9_CreateVolumeTexture
,
3694 (void *)NineDevice9_CreateCubeTexture
,
3695 (void *)NineDevice9_CreateVertexBuffer
,
3696 (void *)NineDevice9_CreateIndexBuffer
,
3697 (void *)NineDevice9_CreateRenderTarget
,
3698 (void *)NineDevice9_CreateDepthStencilSurface
,
3699 (void *)NineDevice9_UpdateSurface
,
3700 (void *)NineDevice9_UpdateTexture
,
3701 (void *)NineDevice9_GetRenderTargetData
,
3702 (void *)NineDevice9_GetFrontBufferData
,
3703 (void *)NineDevice9_StretchRect
,
3704 (void *)NineDevice9_ColorFill
,
3705 (void *)NineDevice9_CreateOffscreenPlainSurface
,
3706 (void *)NineDevice9_SetRenderTarget
,
3707 (void *)NineDevice9_GetRenderTarget
,
3708 (void *)NineDevice9_SetDepthStencilSurface
,
3709 (void *)NineDevice9_GetDepthStencilSurface
,
3710 (void *)NineDevice9_BeginScene
,
3711 (void *)NineDevice9_EndScene
,
3712 (void *)NineDevice9_Clear
,
3713 (void *)NineDevice9_SetTransform
,
3714 (void *)NineDevice9_GetTransform
,
3715 (void *)NineDevice9_MultiplyTransform
,
3716 (void *)NineDevice9_SetViewport
,
3717 (void *)NineDevice9_GetViewport
,
3718 (void *)NineDevice9_SetMaterial
,
3719 (void *)NineDevice9_GetMaterial
,
3720 (void *)NineDevice9_SetLight
,
3721 (void *)NineDevice9_GetLight
,
3722 (void *)NineDevice9_LightEnable
,
3723 (void *)NineDevice9_GetLightEnable
,
3724 (void *)NineDevice9_SetClipPlane
,
3725 (void *)NineDevice9_GetClipPlane
,
3726 (void *)NineDevice9_SetRenderState
,
3727 (void *)NineDevice9_GetRenderState
,
3728 (void *)NineDevice9_CreateStateBlock
,
3729 (void *)NineDevice9_BeginStateBlock
,
3730 (void *)NineDevice9_EndStateBlock
,
3731 (void *)NineDevice9_SetClipStatus
,
3732 (void *)NineDevice9_GetClipStatus
,
3733 (void *)NineDevice9_GetTexture
,
3734 (void *)NineDevice9_SetTexture
,
3735 (void *)NineDevice9_GetTextureStageState
,
3736 (void *)NineDevice9_SetTextureStageState
,
3737 (void *)NineDevice9_GetSamplerState
,
3738 (void *)NineDevice9_SetSamplerState
,
3739 (void *)NineDevice9_ValidateDevice
,
3740 (void *)NineDevice9_SetPaletteEntries
,
3741 (void *)NineDevice9_GetPaletteEntries
,
3742 (void *)NineDevice9_SetCurrentTexturePalette
,
3743 (void *)NineDevice9_GetCurrentTexturePalette
,
3744 (void *)NineDevice9_SetScissorRect
,
3745 (void *)NineDevice9_GetScissorRect
,
3746 (void *)NineDevice9_SetSoftwareVertexProcessing
,
3747 (void *)NineDevice9_GetSoftwareVertexProcessing
,
3748 (void *)NineDevice9_SetNPatchMode
,
3749 (void *)NineDevice9_GetNPatchMode
,
3750 (void *)NineDevice9_DrawPrimitive
,
3751 (void *)NineDevice9_DrawIndexedPrimitive
,
3752 (void *)NineDevice9_DrawPrimitiveUP
,
3753 (void *)NineDevice9_DrawIndexedPrimitiveUP
,
3754 (void *)NineDevice9_ProcessVertices
,
3755 (void *)NineDevice9_CreateVertexDeclaration
,
3756 (void *)NineDevice9_SetVertexDeclaration
,
3757 (void *)NineDevice9_GetVertexDeclaration
,
3758 (void *)NineDevice9_SetFVF
,
3759 (void *)NineDevice9_GetFVF
,
3760 (void *)NineDevice9_CreateVertexShader
,
3761 (void *)NineDevice9_SetVertexShader
,
3762 (void *)NineDevice9_GetVertexShader
,
3763 (void *)NineDevice9_SetVertexShaderConstantF
,
3764 (void *)NineDevice9_GetVertexShaderConstantF
,
3765 (void *)NineDevice9_SetVertexShaderConstantI
,
3766 (void *)NineDevice9_GetVertexShaderConstantI
,
3767 (void *)NineDevice9_SetVertexShaderConstantB
,
3768 (void *)NineDevice9_GetVertexShaderConstantB
,
3769 (void *)NineDevice9_SetStreamSource
,
3770 (void *)NineDevice9_GetStreamSource
,
3771 (void *)NineDevice9_SetStreamSourceFreq
,
3772 (void *)NineDevice9_GetStreamSourceFreq
,
3773 (void *)NineDevice9_SetIndices
,
3774 (void *)NineDevice9_GetIndices
,
3775 (void *)NineDevice9_CreatePixelShader
,
3776 (void *)NineDevice9_SetPixelShader
,
3777 (void *)NineDevice9_GetPixelShader
,
3778 (void *)NineDevice9_SetPixelShaderConstantF
,
3779 (void *)NineDevice9_GetPixelShaderConstantF
,
3780 (void *)NineDevice9_SetPixelShaderConstantI
,
3781 (void *)NineDevice9_GetPixelShaderConstantI
,
3782 (void *)NineDevice9_SetPixelShaderConstantB
,
3783 (void *)NineDevice9_GetPixelShaderConstantB
,
3784 (void *)NineDevice9_DrawRectPatch
,
3785 (void *)NineDevice9_DrawTriPatch
,
3786 (void *)NineDevice9_DeletePatch
,
3787 (void *)NineDevice9_CreateQuery
3790 static const GUID
*NineDevice9_IIDs
[] = {
3791 &IID_IDirect3DDevice9
,
3797 NineDevice9_new( struct pipe_screen
*pScreen
,
3798 D3DDEVICE_CREATION_PARAMETERS
*pCreationParameters
,
3800 D3DPRESENT_PARAMETERS
*pPresentationParameters
,
3802 ID3DPresentGroup
*pPresentationGroup
,
3803 struct d3dadapter9_context
*pCTX
,
3805 D3DDISPLAYMODEEX
*pFullscreenDisplayMode
,
3806 struct NineDevice9
**ppOut
)
3809 lock
= !!(pCreationParameters
->BehaviorFlags
& D3DCREATE_MULTITHREADED
);
3811 NINE_NEW(Device9
, ppOut
, lock
, /* args */
3812 pScreen
, pCreationParameters
, pCaps
,
3813 pPresentationParameters
, pD3D9
, pPresentationGroup
, pCTX
,
3814 ex
, pFullscreenDisplayMode
);