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 "util/u_math.h"
45 #include "util/u_inlines.h"
46 #include "util/u_hash_table.h"
47 #include "util/u_format.h"
48 #include "util/u_surface.h"
49 #include "util/u_upload_mgr.h"
50 #include "hud/hud_context.h"
52 #include "cso_cache/cso_context.h"
54 #define DBG_CHANNEL DBG_DEVICE
57 NineDevice9_SetDefaultState( struct NineDevice9
*This
, boolean is_reset
)
59 struct NineSurface9
*refSurf
= NULL
;
61 DBG("This=%p is_reset=%d\n", This
, (int) is_reset
);
63 assert(!This
->is_recording
);
65 nine_state_set_defaults(This
, &This
->caps
, is_reset
);
67 This
->state
.viewport
.X
= 0;
68 This
->state
.viewport
.Y
= 0;
69 This
->state
.viewport
.Width
= 0;
70 This
->state
.viewport
.Height
= 0;
72 This
->state
.scissor
.minx
= 0;
73 This
->state
.scissor
.miny
= 0;
74 This
->state
.scissor
.maxx
= 0xffff;
75 This
->state
.scissor
.maxy
= 0xffff;
77 if (This
->nswapchains
&& This
->swapchains
[0]->params
.BackBufferCount
)
78 refSurf
= This
->swapchains
[0]->buffers
[0];
81 This
->state
.viewport
.Width
= refSurf
->desc
.Width
;
82 This
->state
.viewport
.Height
= refSurf
->desc
.Height
;
83 This
->state
.scissor
.maxx
= refSurf
->desc
.Width
;
84 This
->state
.scissor
.maxy
= refSurf
->desc
.Height
;
87 if (This
->nswapchains
&& This
->swapchains
[0]->params
.EnableAutoDepthStencil
)
88 This
->state
.rs
[D3DRS_ZENABLE
] = TRUE
;
89 if (This
->state
.rs
[D3DRS_ZENABLE
])
90 NineDevice9_SetDepthStencilSurface(
91 This
, (IDirect3DSurface9
*)This
->swapchains
[0]->zsbuf
);
95 NineDevice9_RestoreNonCSOState( struct NineDevice9
*This
, unsigned mask
)
97 struct pipe_context
*pipe
= This
->pipe
;
99 DBG("This=%p mask=%u\n", This
, mask
);
102 struct pipe_constant_buffer cb
;
103 cb
.buffer_offset
= 0;
105 if (This
->prefer_user_constbuf
) {
107 cb
.user_buffer
= This
->state
.vs_const_f
;
109 cb
.buffer
= This
->constbuf_vs
;
110 cb
.user_buffer
= NULL
;
112 cb
.buffer_size
= This
->vs_const_size
;
113 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_VERTEX
, 0, &cb
);
115 if (This
->prefer_user_constbuf
) {
116 cb
.user_buffer
= This
->state
.ps_const_f
;
118 cb
.buffer
= This
->constbuf_ps
;
120 cb
.buffer_size
= This
->ps_const_size
;
121 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_FRAGMENT
, 0, &cb
);
125 struct pipe_poly_stipple stipple
;
126 memset(&stipple
, ~0, sizeof(stipple
));
127 pipe
->set_polygon_stipple(pipe
, &stipple
);
130 This
->state
.changed
.group
= NINE_STATE_ALL
;
131 This
->state
.changed
.vtxbuf
= (1ULL << This
->caps
.MaxStreams
) - 1;
132 This
->state
.changed
.ucp
= (1 << PIPE_MAX_CLIP_PLANES
) - 1;
133 This
->state
.changed
.texture
= NINE_PS_SAMPLERS_MASK
| NINE_VS_SAMPLERS_MASK
;
136 #define GET_PCAP(n) pScreen->get_param(pScreen, PIPE_CAP_##n)
138 NineDevice9_ctor( struct NineDevice9
*This
,
139 struct NineUnknownParams
*pParams
,
140 struct pipe_screen
*pScreen
,
141 D3DDEVICE_CREATION_PARAMETERS
*pCreationParameters
,
143 D3DPRESENT_PARAMETERS
*pPresentationParameters
,
145 ID3DPresentGroup
*pPresentationGroup
,
146 struct d3dadapter9_context
*pCTX
,
148 D3DDISPLAYMODEEX
*pFullscreenDisplayMode
)
151 HRESULT hr
= NineUnknown_ctor(&This
->base
, pParams
);
153 DBG("This=%p pParams=%p pScreen=%p pCreationParameters=%p pCaps=%p pPresentationParameters=%p "
154 "pD3D9=%p pPresentationGroup=%p pCTX=%p ex=%d pFullscreenDisplayMode=%p\n",
155 This
, pParams
, pScreen
, pCreationParameters
, pCaps
, pPresentationParameters
, pD3D9
,
156 pPresentationGroup
, pCTX
, (int) ex
, pFullscreenDisplayMode
);
158 if (FAILED(hr
)) { return hr
; }
160 list_inithead(&This
->update_textures
);
162 This
->screen
= pScreen
;
165 This
->params
= *pCreationParameters
;
167 This
->present
= pPresentationGroup
;
168 IDirect3D9_AddRef(This
->d3d9
);
169 ID3DPresentGroup_AddRef(This
->present
);
171 This
->pipe
= This
->screen
->context_create(This
->screen
, NULL
);
172 if (!This
->pipe
) { return E_OUTOFMEMORY
; } /* guess */
174 This
->cso
= cso_create_context(This
->pipe
);
175 if (!This
->cso
) { return E_OUTOFMEMORY
; } /* also a guess */
177 /* Create first, it messes up our state. */
178 This
->hud
= hud_create(This
->pipe
, This
->cso
); /* NULL result is fine */
180 /* create implicit swapchains */
181 This
->nswapchains
= ID3DPresentGroup_GetMultiheadCount(This
->present
);
182 This
->swapchains
= CALLOC(This
->nswapchains
,
183 sizeof(struct NineSwapChain9
*));
184 if (!This
->swapchains
) { return E_OUTOFMEMORY
; }
186 for (i
= 0; i
< This
->nswapchains
; ++i
) {
187 ID3DPresent
*present
;
189 hr
= ID3DPresentGroup_GetPresent(This
->present
, i
, &present
);
194 D3DDISPLAYMODEEX
*mode
= NULL
;
195 struct NineSwapChain9Ex
**ret
=
196 (struct NineSwapChain9Ex
**)&This
->swapchains
[i
];
198 if (pFullscreenDisplayMode
) mode
= &(pFullscreenDisplayMode
[i
]);
199 /* when this is a Device9Ex, it should create SwapChain9Exs */
200 hr
= NineSwapChain9Ex_new(This
, TRUE
, present
,
201 &pPresentationParameters
[i
], pCTX
,
202 This
->params
.hFocusWindow
, mode
, ret
);
204 hr
= NineSwapChain9_new(This
, TRUE
, present
,
205 &pPresentationParameters
[i
], pCTX
,
206 This
->params
.hFocusWindow
,
207 &This
->swapchains
[i
]);
210 ID3DPresent_Release(present
);
213 NineUnknown_ConvertRefToBind(NineUnknown(This
->swapchains
[i
]));
215 hr
= NineSwapChain9_GetBackBuffer(This
->swapchains
[i
], 0,
216 D3DBACKBUFFER_TYPE_MONO
,
217 (IDirect3DSurface9
**)
221 NineUnknown_ConvertRefToBind(NineUnknown(This
->state
.rt
[i
]));
224 This
->cursor
.software
= FALSE
;
225 This
->cursor
.hotspot
.x
= -1;
226 This
->cursor
.hotspot
.y
= -1;
228 struct pipe_resource tmpl
;
229 tmpl
.target
= PIPE_TEXTURE_2D
;
230 tmpl
.format
= PIPE_FORMAT_R8G8B8A8_UNORM
;
237 tmpl
.usage
= PIPE_USAGE_DEFAULT
;
238 tmpl
.bind
= PIPE_BIND_CURSOR
| PIPE_BIND_SAMPLER_VIEW
;
241 This
->cursor
.image
= pScreen
->resource_create(pScreen
, &tmpl
);
242 if (!This
->cursor
.image
)
243 return D3DERR_OUTOFVIDEOMEMORY
;
246 /* Create constant buffers. */
248 struct pipe_resource tmpl
;
249 unsigned max_const_vs
, max_const_ps
;
251 /* vs 3.0: >= 256 float constants, but for cards with exactly 256 slots,
252 * we have to take in some more slots for int and bool*/
253 max_const_vs
= _min(pScreen
->get_shader_param(pScreen
, PIPE_SHADER_VERTEX
,
254 PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE
) /
257 /* ps 3.0: 224 float constants. All cards supported support at least
258 * 256 constants for ps */
259 max_const_ps
= NINE_MAX_CONST_F_PS3
+ (NINE_MAX_CONST_I
+ NINE_MAX_CONST_B
/ 4);
261 This
->max_vs_const_f
= max_const_vs
-
262 (NINE_MAX_CONST_I
+ NINE_MAX_CONST_B
/ 4);
263 This
->max_ps_const_f
= max_const_ps
-
264 (NINE_MAX_CONST_I
+ NINE_MAX_CONST_B
/ 4);
266 This
->vs_const_size
= max_const_vs
* sizeof(float[4]);
267 This
->ps_const_size
= max_const_ps
* sizeof(float[4]);
268 /* Include space for I,B constants for user constbuf. */
269 This
->state
.vs_const_f
= CALLOC(This
->vs_const_size
, 1);
270 This
->state
.ps_const_f
= CALLOC(This
->ps_const_size
, 1);
271 This
->state
.vs_lconstf_temp
= CALLOC(This
->vs_const_size
,1);
272 if (!This
->state
.vs_const_f
|| !This
->state
.ps_const_f
||
273 !This
->state
.vs_lconstf_temp
)
274 return E_OUTOFMEMORY
;
276 if (strstr(pScreen
->get_name(pScreen
), "AMD") ||
277 strstr(pScreen
->get_name(pScreen
), "ATI"))
278 This
->prefer_user_constbuf
= TRUE
;
280 tmpl
.target
= PIPE_BUFFER
;
281 tmpl
.format
= PIPE_FORMAT_R8_UNORM
;
287 tmpl
.usage
= PIPE_USAGE_DYNAMIC
;
288 tmpl
.bind
= PIPE_BIND_CONSTANT_BUFFER
;
291 tmpl
.width0
= This
->vs_const_size
;
292 This
->constbuf_vs
= pScreen
->resource_create(pScreen
, &tmpl
);
294 tmpl
.width0
= This
->ps_const_size
;
295 This
->constbuf_ps
= pScreen
->resource_create(pScreen
, &tmpl
);
297 if (!This
->constbuf_vs
|| !This
->constbuf_ps
)
298 return E_OUTOFMEMORY
;
301 /* Allocate upload helper for drivers that suck (from st pov ;). */
305 This
->driver_caps
.user_vbufs
= GET_PCAP(USER_VERTEX_BUFFERS
);
306 This
->driver_caps
.user_ibufs
= GET_PCAP(USER_INDEX_BUFFERS
);
308 if (!This
->driver_caps
.user_vbufs
) bind
|= PIPE_BIND_VERTEX_BUFFER
;
309 if (!This
->driver_caps
.user_ibufs
) bind
|= PIPE_BIND_INDEX_BUFFER
;
311 This
->upload
= u_upload_create(This
->pipe
, 1 << 20, 4, bind
);
314 This
->driver_caps
.window_space_position_support
= GET_PCAP(TGSI_VS_WINDOW_SPACE_POSITION
);
315 This
->driver_caps
.vs_integer
= pScreen
->get_shader_param(pScreen
, PIPE_SHADER_VERTEX
, PIPE_SHADER_CAP_INTEGERS
);
316 This
->driver_caps
.ps_integer
= pScreen
->get_shader_param(pScreen
, PIPE_SHADER_FRAGMENT
, PIPE_SHADER_CAP_INTEGERS
);
318 nine_ff_init(This
); /* initialize fixed function code */
320 NineDevice9_SetDefaultState(This
, FALSE
);
321 NineDevice9_RestoreNonCSOState(This
, ~0);
323 This
->update
= &This
->state
;
324 nine_update_state(This
, ~0);
326 ID3DPresentGroup_Release(This
->present
);
333 NineDevice9_dtor( struct NineDevice9
*This
)
337 DBG("This=%p\n", This
);
339 if (This
->pipe
&& This
->cso
)
340 nine_pipe_context_clear(This
);
342 nine_state_clear(&This
->state
, TRUE
);
345 u_upload_destroy(This
->upload
);
347 nine_bind(&This
->record
, NULL
);
349 pipe_resource_reference(&This
->constbuf_vs
, NULL
);
350 pipe_resource_reference(&This
->constbuf_ps
, NULL
);
351 FREE(This
->state
.vs_const_f
);
352 FREE(This
->state
.ps_const_f
);
353 FREE(This
->state
.vs_lconstf_temp
);
355 if (This
->swapchains
) {
356 for (i
= 0; i
< This
->nswapchains
; ++i
)
357 NineUnknown_Unbind(NineUnknown(This
->swapchains
[i
]));
358 FREE(This
->swapchains
);
364 cso_destroy_context(This
->cso
);
366 if (This
->pipe
->destroy
) { This
->pipe
->destroy(This
->pipe
); }
369 if (This
->present
) { ID3DPresentGroup_Release(This
->present
); }
370 if (This
->d3d9
) { IDirect3D9_Release(This
->d3d9
); }
372 NineUnknown_dtor(&This
->base
);
376 NineDevice9_GetScreen( struct NineDevice9
*This
)
381 struct pipe_context
*
382 NineDevice9_GetPipe( struct NineDevice9
*This
)
388 NineDevice9_GetCSO( struct NineDevice9
*This
)
394 NineDevice9_GetCaps( struct NineDevice9
*This
)
400 NineDevice9_PauseRecording( struct NineDevice9
*This
)
403 This
->update
= &This
->state
;
404 This
->is_recording
= FALSE
;
409 NineDevice9_ResumeRecording( struct NineDevice9
*This
)
412 This
->update
= &This
->record
->state
;
413 This
->is_recording
= TRUE
;
418 NineDevice9_TestCooperativeLevel( struct NineDevice9
*This
)
420 return D3D_OK
; /* TODO */
424 NineDevice9_GetAvailableTextureMem( struct NineDevice9
*This
)
426 const unsigned mem
= This
->screen
->get_param(This
->screen
, PIPE_CAP_VIDEO_MEMORY
);
434 NineDevice9_EvictManagedResources( struct NineDevice9
*This
)
436 /* We don't really need to do anything here, but might want to free up
437 * the GPU virtual address space by killing pipe_resources.
443 NineDevice9_GetDirect3D( struct NineDevice9
*This
,
444 IDirect3D9
**ppD3D9
)
446 user_assert(ppD3D9
!= NULL
, E_POINTER
);
447 IDirect3D9_AddRef(This
->d3d9
);
448 *ppD3D9
= This
->d3d9
;
453 NineDevice9_GetDeviceCaps( struct NineDevice9
*This
,
456 user_assert(pCaps
!= NULL
, D3DERR_INVALIDCALL
);
462 NineDevice9_GetDisplayMode( struct NineDevice9
*This
,
464 D3DDISPLAYMODE
*pMode
)
466 DBG("This=%p iSwapChain=%u pMode=%p\n", This
, iSwapChain
, pMode
);
468 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
470 return NineSwapChain9_GetDisplayMode(This
->swapchains
[iSwapChain
], pMode
);
474 NineDevice9_GetCreationParameters( struct NineDevice9
*This
,
475 D3DDEVICE_CREATION_PARAMETERS
*pParameters
)
477 user_assert(pParameters
!= NULL
, D3DERR_INVALIDCALL
);
478 *pParameters
= This
->params
;
483 NineDevice9_SetCursorProperties( struct NineDevice9
*This
,
486 IDirect3DSurface9
*pCursorBitmap
)
488 /* TODO: hardware cursor */
489 struct NineSurface9
*surf
= NineSurface9(pCursorBitmap
);
490 struct pipe_context
*pipe
= This
->pipe
;
492 struct pipe_transfer
*transfer
;
495 DBG_FLAG(DBG_SWAPCHAIN
, "This=%p XHotSpot=%u YHotSpot=%u "
496 "pCursorBitmap=%p\n", This
, XHotSpot
, YHotSpot
, pCursorBitmap
);
498 user_assert(pCursorBitmap
, D3DERR_INVALIDCALL
);
500 This
->cursor
.w
= MIN2(surf
->desc
.Width
, This
->cursor
.image
->width0
);
501 This
->cursor
.h
= MIN2(surf
->desc
.Height
, This
->cursor
.image
->height0
);
503 u_box_origin_2d(This
->cursor
.w
, This
->cursor
.h
, &box
);
505 ptr
= pipe
->transfer_map(pipe
, This
->cursor
.image
, 0,
506 PIPE_TRANSFER_WRITE
|
507 PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
,
510 ret_err("Failed to update cursor image.\n", D3DERR_DRIVERINTERNALERROR
);
512 This
->cursor
.hotspot
.x
= XHotSpot
;
513 This
->cursor
.hotspot
.y
= YHotSpot
;
515 /* Copy cursor image to internal storage. */
519 const struct util_format_description
*sfmt
=
520 util_format_description(surf
->base
.info
.format
);
523 hr
= NineSurface9_LockRect(surf
, &lock
, NULL
, D3DLOCK_READONLY
);
525 ret_err("Failed to map cursor source image.\n",
526 D3DERR_DRIVERINTERNALERROR
);
528 sfmt
->unpack_rgba_8unorm(ptr
, transfer
->stride
,
529 lock
.pBits
, lock
.Pitch
,
530 This
->cursor
.w
, This
->cursor
.h
);
532 if (!This
->cursor
.software
&&
533 This
->cursor
.w
== 32 && This
->cursor
.h
== 32)
534 ID3DPresent_SetCursor(This
->swapchains
[0]->present
,
535 lock
.pBits
, &This
->cursor
.hotspot
,
536 This
->cursor
.visible
);
538 NineSurface9_UnlockRect(surf
);
540 pipe
->transfer_unmap(pipe
, transfer
);
546 NineDevice9_SetCursorPosition( struct NineDevice9
*This
,
551 struct NineSwapChain9
*swap
= This
->swapchains
[0];
553 DBG("This=%p X=%d Y=%d Flags=%d\n", This
, X
, Y
, Flags
);
555 This
->cursor
.pos
.x
= X
;
556 This
->cursor
.pos
.y
= Y
;
558 if (!This
->cursor
.software
)
559 ID3DPresent_SetCursorPos(swap
->present
, &This
->cursor
.pos
);
563 NineDevice9_ShowCursor( struct NineDevice9
*This
,
566 BOOL old
= This
->cursor
.visible
;
568 DBG("This=%p bShow=%d\n", This
, (int) bShow
);
570 This
->cursor
.visible
= bShow
&& (This
->cursor
.hotspot
.x
!= -1);
571 if (!This
->cursor
.software
)
572 ID3DPresent_SetCursor(This
->swapchains
[0]->present
, NULL
, NULL
, bShow
);
578 NineDevice9_CreateAdditionalSwapChain( struct NineDevice9
*This
,
579 D3DPRESENT_PARAMETERS
*pPresentationParameters
,
580 IDirect3DSwapChain9
**pSwapChain
)
582 struct NineSwapChain9
*swapchain
, *tmplt
= This
->swapchains
[0];
583 ID3DPresent
*present
;
586 DBG("This=%p pPresentationParameters=%p pSwapChain=%p\n",
587 This
, pPresentationParameters
, pSwapChain
);
589 user_assert(pPresentationParameters
, D3DERR_INVALIDCALL
);
591 hr
= ID3DPresentGroup_CreateAdditionalPresent(This
->present
, pPresentationParameters
, &present
);
596 hr
= NineSwapChain9_new(This
, FALSE
, present
, pPresentationParameters
,
598 tmplt
->params
.hDeviceWindow
,
603 *pSwapChain
= (IDirect3DSwapChain9
*)swapchain
;
608 NineDevice9_GetSwapChain( struct NineDevice9
*This
,
610 IDirect3DSwapChain9
**pSwapChain
)
612 user_assert(pSwapChain
!= NULL
, D3DERR_INVALIDCALL
);
615 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
617 NineUnknown_AddRef(NineUnknown(This
->swapchains
[iSwapChain
]));
618 *pSwapChain
= (IDirect3DSwapChain9
*)This
->swapchains
[iSwapChain
];
624 NineDevice9_GetNumberOfSwapChains( struct NineDevice9
*This
)
626 return This
->nswapchains
;
630 NineDevice9_Reset( struct NineDevice9
*This
,
631 D3DPRESENT_PARAMETERS
*pPresentationParameters
)
636 DBG("This=%p pPresentationParameters=%p\n", This
, pPresentationParameters
);
638 for (i
= 0; i
< This
->nswapchains
; ++i
) {
639 D3DPRESENT_PARAMETERS
*params
= &pPresentationParameters
[i
];
640 hr
= NineSwapChain9_Resize(This
->swapchains
[i
], params
, NULL
);
642 return (hr
== D3DERR_OUTOFVIDEOMEMORY
) ? hr
: D3DERR_DEVICELOST
;
645 nine_pipe_context_clear(This
);
646 nine_state_clear(&This
->state
, TRUE
);
648 NineDevice9_SetDefaultState(This
, TRUE
);
649 NineDevice9_SetRenderTarget(
650 This
, 0, (IDirect3DSurface9
*)This
->swapchains
[0]->buffers
[0]);
651 /* XXX: better use GetBackBuffer here ? */
657 NineDevice9_Present( struct NineDevice9
*This
,
658 const RECT
*pSourceRect
,
659 const RECT
*pDestRect
,
660 HWND hDestWindowOverride
,
661 const RGNDATA
*pDirtyRegion
)
666 DBG("This=%p pSourceRect=%p pDestRect=%p hDestWindowOverride=%p pDirtyRegion=%p\n",
667 This
, pSourceRect
, pDestRect
, hDestWindowOverride
, pDirtyRegion
);
669 /* XXX is this right? */
670 for (i
= 0; i
< This
->nswapchains
; ++i
) {
671 hr
= NineSwapChain9_Present(This
->swapchains
[i
], pSourceRect
, pDestRect
,
672 hDestWindowOverride
, pDirtyRegion
, 0);
673 if (FAILED(hr
)) { return hr
; }
680 NineDevice9_GetBackBuffer( struct NineDevice9
*This
,
683 D3DBACKBUFFER_TYPE Type
,
684 IDirect3DSurface9
**ppBackBuffer
)
686 user_assert(ppBackBuffer
!= NULL
, D3DERR_INVALIDCALL
);
687 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
689 return NineSwapChain9_GetBackBuffer(This
->swapchains
[iSwapChain
],
690 iBackBuffer
, Type
, ppBackBuffer
);
694 NineDevice9_GetRasterStatus( struct NineDevice9
*This
,
696 D3DRASTER_STATUS
*pRasterStatus
)
698 user_assert(pRasterStatus
!= NULL
, D3DERR_INVALIDCALL
);
699 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
701 return NineSwapChain9_GetRasterStatus(This
->swapchains
[iSwapChain
],
706 NineDevice9_SetDialogBoxMode( struct NineDevice9
*This
,
707 BOOL bEnableDialogs
)
709 STUB(D3DERR_INVALIDCALL
);
713 NineDevice9_SetGammaRamp( struct NineDevice9
*This
,
716 const D3DGAMMARAMP
*pRamp
)
718 DBG("This=%p iSwapChain=%u Flags=%x pRamp=%p\n", This
,
719 iSwapChain
, Flags
, pRamp
);
721 user_warn(iSwapChain
>= This
->nswapchains
);
724 if (pRamp
&& (iSwapChain
< This
->nswapchains
)) {
725 struct NineSwapChain9
*swap
= This
->swapchains
[iSwapChain
];
726 swap
->gamma
= *pRamp
;
727 ID3DPresent_SetGammaRamp(swap
->present
, pRamp
, swap
->params
.hDeviceWindow
);
732 NineDevice9_GetGammaRamp( struct NineDevice9
*This
,
734 D3DGAMMARAMP
*pRamp
)
736 DBG("This=%p iSwapChain=%u pRamp=%p\n", This
, iSwapChain
, pRamp
);
738 user_warn(iSwapChain
>= This
->nswapchains
);
741 if (pRamp
&& (iSwapChain
< This
->nswapchains
))
742 *pRamp
= This
->swapchains
[iSwapChain
]->gamma
;
746 NineDevice9_CreateTexture( struct NineDevice9
*This
,
753 IDirect3DTexture9
**ppTexture
,
754 HANDLE
*pSharedHandle
)
756 struct NineTexture9
*tex
;
759 DBG("This=%p Width=%u Height=%u Levels=%u Usage=%s Format=%s Pool=%s "
760 "ppOut=%p pSharedHandle=%p\n", This
, Width
, Height
, Levels
,
761 nine_D3DUSAGE_to_str(Usage
), d3dformat_to_string(Format
),
762 nine_D3DPOOL_to_str(Pool
), ppTexture
, pSharedHandle
);
764 Usage
&= D3DUSAGE_AUTOGENMIPMAP
| D3DUSAGE_DEPTHSTENCIL
| D3DUSAGE_DMAP
|
765 D3DUSAGE_DYNAMIC
| D3DUSAGE_NONSECURE
| D3DUSAGE_RENDERTARGET
|
766 D3DUSAGE_SOFTWAREPROCESSING
| D3DUSAGE_TEXTAPI
;
769 user_assert(Width
&& Height
, D3DERR_INVALIDCALL
);
770 user_assert(!pSharedHandle
|| This
->ex
, D3DERR_INVALIDCALL
);
771 /* When is used shared handle, Pool must be
772 * SYSTEMMEM with Levels 1 or DEFAULT with any Levels */
773 user_assert(!pSharedHandle
|| Pool
!= D3DPOOL_SYSTEMMEM
|| Levels
== 1,
775 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_SYSTEMMEM
|| Pool
== D3DPOOL_DEFAULT
,
777 user_assert((Usage
!= D3DUSAGE_AUTOGENMIPMAP
|| Levels
<= 1), D3DERR_INVALIDCALL
);
779 hr
= NineTexture9_new(This
, Width
, Height
, Levels
, Usage
, Format
, Pool
,
780 &tex
, pSharedHandle
);
782 *ppTexture
= (IDirect3DTexture9
*)tex
;
788 NineDevice9_CreateVolumeTexture( struct NineDevice9
*This
,
796 IDirect3DVolumeTexture9
**ppVolumeTexture
,
797 HANDLE
*pSharedHandle
)
799 struct NineVolumeTexture9
*tex
;
802 DBG("This=%p Width=%u Height=%u Depth=%u Levels=%u Usage=%s Format=%s Pool=%s "
803 "ppOut=%p pSharedHandle=%p\n", This
, Width
, Height
, Depth
, Levels
,
804 nine_D3DUSAGE_to_str(Usage
), d3dformat_to_string(Format
),
805 nine_D3DPOOL_to_str(Pool
), ppVolumeTexture
, pSharedHandle
);
807 Usage
&= D3DUSAGE_DYNAMIC
| D3DUSAGE_NONSECURE
|
808 D3DUSAGE_SOFTWAREPROCESSING
;
810 *ppVolumeTexture
= NULL
;
811 user_assert(Width
&& Height
&& Depth
, D3DERR_INVALIDCALL
);
812 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
814 hr
= NineVolumeTexture9_new(This
, Width
, Height
, Depth
, Levels
,
815 Usage
, Format
, Pool
, &tex
, pSharedHandle
);
817 *ppVolumeTexture
= (IDirect3DVolumeTexture9
*)tex
;
823 NineDevice9_CreateCubeTexture( struct NineDevice9
*This
,
829 IDirect3DCubeTexture9
**ppCubeTexture
,
830 HANDLE
*pSharedHandle
)
832 struct NineCubeTexture9
*tex
;
835 DBG("This=%p EdgeLength=%u Levels=%u Usage=%s Format=%s Pool=%s ppOut=%p "
836 "pSharedHandle=%p\n", This
, EdgeLength
, Levels
,
837 nine_D3DUSAGE_to_str(Usage
), d3dformat_to_string(Format
),
838 nine_D3DPOOL_to_str(Pool
), ppCubeTexture
, pSharedHandle
);
840 Usage
&= D3DUSAGE_AUTOGENMIPMAP
| D3DUSAGE_DEPTHSTENCIL
| D3DUSAGE_DYNAMIC
|
841 D3DUSAGE_NONSECURE
| D3DUSAGE_RENDERTARGET
|
842 D3DUSAGE_SOFTWAREPROCESSING
;
844 *ppCubeTexture
= NULL
;
845 user_assert(EdgeLength
, D3DERR_INVALIDCALL
);
846 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
848 hr
= NineCubeTexture9_new(This
, EdgeLength
, Levels
, Usage
, Format
, Pool
,
849 &tex
, pSharedHandle
);
851 *ppCubeTexture
= (IDirect3DCubeTexture9
*)tex
;
857 NineDevice9_CreateVertexBuffer( struct NineDevice9
*This
,
862 IDirect3DVertexBuffer9
**ppVertexBuffer
,
863 HANDLE
*pSharedHandle
)
865 struct NineVertexBuffer9
*buf
;
867 D3DVERTEXBUFFER_DESC desc
;
869 DBG("This=%p Length=%u Usage=%x FVF=%x Pool=%u ppOut=%p pSharedHandle=%p\n",
870 This
, Length
, Usage
, FVF
, Pool
, ppVertexBuffer
, pSharedHandle
);
872 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_NOTAVAILABLE
);
874 desc
.Format
= D3DFMT_VERTEXDATA
;
875 desc
.Type
= D3DRTYPE_VERTEXBUFFER
;
877 (D3DUSAGE_DONOTCLIP
| D3DUSAGE_DYNAMIC
| D3DUSAGE_NONSECURE
|
878 D3DUSAGE_NPATCHES
| D3DUSAGE_POINTS
| D3DUSAGE_RTPATCHES
|
879 D3DUSAGE_SOFTWAREPROCESSING
| D3DUSAGE_TEXTAPI
|
885 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
886 user_assert(desc
.Usage
== Usage
, D3DERR_INVALIDCALL
);
888 hr
= NineVertexBuffer9_new(This
, &desc
, &buf
);
890 *ppVertexBuffer
= (IDirect3DVertexBuffer9
*)buf
;
895 NineDevice9_CreateIndexBuffer( struct NineDevice9
*This
,
900 IDirect3DIndexBuffer9
**ppIndexBuffer
,
901 HANDLE
*pSharedHandle
)
903 struct NineIndexBuffer9
*buf
;
905 D3DINDEXBUFFER_DESC desc
;
907 DBG("This=%p Length=%u Usage=%x Format=%s Pool=%u ppOut=%p "
908 "pSharedHandle=%p\n", This
, Length
, Usage
,
909 d3dformat_to_string(Format
), Pool
, ppIndexBuffer
, pSharedHandle
);
911 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_NOTAVAILABLE
);
913 desc
.Format
= Format
;
914 desc
.Type
= D3DRTYPE_INDEXBUFFER
;
916 (D3DUSAGE_DONOTCLIP
| D3DUSAGE_DYNAMIC
| D3DUSAGE_NONSECURE
|
917 D3DUSAGE_NPATCHES
| D3DUSAGE_POINTS
| D3DUSAGE_RTPATCHES
|
918 D3DUSAGE_SOFTWAREPROCESSING
| D3DUSAGE_WRITEONLY
);
922 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
923 user_assert(desc
.Usage
== Usage
, D3DERR_INVALIDCALL
);
925 hr
= NineIndexBuffer9_new(This
, &desc
, &buf
);
927 *ppIndexBuffer
= (IDirect3DIndexBuffer9
*)buf
;
932 create_zs_or_rt_surface(struct NineDevice9
*This
,
933 unsigned type
, /* 0 = RT, 1 = ZS, 2 = plain */
935 UINT Width
, UINT Height
,
937 D3DMULTISAMPLE_TYPE MultiSample
,
938 DWORD MultisampleQuality
,
939 BOOL Discard_or_Lockable
,
940 IDirect3DSurface9
**ppSurface
,
941 HANDLE
*pSharedHandle
)
943 struct NineSurface9
*surface
;
944 struct pipe_screen
*screen
= This
->screen
;
945 struct pipe_resource
*resource
= NULL
;
947 D3DSURFACE_DESC desc
;
948 struct pipe_resource templ
;
950 DBG("This=%p type=%u Pool=%s Width=%u Height=%u Format=%s MS=%u Quality=%u "
951 "Discard_or_Lockable=%i ppSurface=%p pSharedHandle=%p\n",
952 This
, type
, nine_D3DPOOL_to_str(Pool
), Width
, Height
,
953 d3dformat_to_string(Format
), MultiSample
, MultisampleQuality
,
954 Discard_or_Lockable
, ppSurface
, pSharedHandle
);
957 DBG("FIXME Used shared handle! This option isn't probably handled correctly!\n");
959 user_assert(Width
&& Height
, D3DERR_INVALIDCALL
);
960 user_assert(Pool
!= D3DPOOL_MANAGED
, D3DERR_INVALIDCALL
);
962 templ
.target
= PIPE_TEXTURE_2D
;
963 templ
.width0
= Width
;
964 templ
.height0
= Height
;
966 templ
.array_size
= 1;
967 templ
.last_level
= 0;
968 templ
.nr_samples
= (unsigned)MultiSample
;
969 templ
.usage
= PIPE_USAGE_DEFAULT
;
971 templ
.bind
= PIPE_BIND_SAMPLER_VIEW
; /* StretchRect */
973 case 0: templ
.bind
|= PIPE_BIND_RENDER_TARGET
; break;
974 case 1: templ
.bind
= d3d9_get_pipe_depth_format_bindings(Format
); break;
979 templ
.format
= d3d9_to_pipe_format_checked(screen
, Format
, templ
.target
,
980 templ
.nr_samples
, templ
.bind
,
983 desc
.Format
= Format
;
984 desc
.Type
= D3DRTYPE_SURFACE
;
987 desc
.MultiSampleType
= MultiSample
;
988 desc
.MultiSampleQuality
= MultisampleQuality
;
990 desc
.Height
= Height
;
992 case 0: desc
.Usage
= D3DUSAGE_RENDERTARGET
; break;
993 case 1: desc
.Usage
= D3DUSAGE_DEPTHSTENCIL
; break;
997 if (Pool
== D3DPOOL_DEFAULT
&& Format
!= D3DFMT_NULL
) {
998 /* resource_create doesn't return an error code, so check format here */
999 user_assert(templ
.format
!= PIPE_FORMAT_NONE
, D3DERR_INVALIDCALL
);
1000 resource
= screen
->resource_create(screen
, &templ
);
1001 user_assert(resource
, D3DERR_OUTOFVIDEOMEMORY
);
1002 if (Discard_or_Lockable
&& (desc
.Usage
& D3DUSAGE_RENDERTARGET
))
1003 resource
->flags
|= NINE_RESOURCE_FLAG_LOCKABLE
;
1007 hr
= NineSurface9_new(This
, NULL
, resource
, NULL
, 0, 0, 0, &desc
, &surface
);
1008 pipe_resource_reference(&resource
, NULL
);
1011 *ppSurface
= (IDirect3DSurface9
*)surface
;
1016 NineDevice9_CreateRenderTarget( struct NineDevice9
*This
,
1020 D3DMULTISAMPLE_TYPE MultiSample
,
1021 DWORD MultisampleQuality
,
1023 IDirect3DSurface9
**ppSurface
,
1024 HANDLE
*pSharedHandle
)
1027 return create_zs_or_rt_surface(This
, 0, D3DPOOL_DEFAULT
,
1028 Width
, Height
, Format
,
1029 MultiSample
, MultisampleQuality
,
1030 Lockable
, ppSurface
, pSharedHandle
);
1034 NineDevice9_CreateDepthStencilSurface( struct NineDevice9
*This
,
1038 D3DMULTISAMPLE_TYPE MultiSample
,
1039 DWORD MultisampleQuality
,
1041 IDirect3DSurface9
**ppSurface
,
1042 HANDLE
*pSharedHandle
)
1045 if (!depth_stencil_format(Format
))
1046 return D3DERR_NOTAVAILABLE
;
1047 return create_zs_or_rt_surface(This
, 1, D3DPOOL_DEFAULT
,
1048 Width
, Height
, Format
,
1049 MultiSample
, MultisampleQuality
,
1050 Discard
, ppSurface
, pSharedHandle
);
1054 NineDevice9_UpdateSurface( struct NineDevice9
*This
,
1055 IDirect3DSurface9
*pSourceSurface
,
1056 const RECT
*pSourceRect
,
1057 IDirect3DSurface9
*pDestinationSurface
,
1058 const POINT
*pDestPoint
)
1060 struct NineSurface9
*dst
= NineSurface9(pDestinationSurface
);
1061 struct NineSurface9
*src
= NineSurface9(pSourceSurface
);
1063 DBG("This=%p pSourceSurface=%p pDestinationSurface=%p "
1064 "pSourceRect=%p pDestPoint=%p\n", This
,
1065 pSourceSurface
, pDestinationSurface
, pSourceRect
, pDestPoint
);
1067 DBG("pSourceRect = (%u,%u)-(%u,%u)\n",
1068 pSourceRect
->left
, pSourceRect
->top
,
1069 pSourceRect
->right
, pSourceRect
->bottom
);
1071 DBG("pDestPoint = (%u,%u)\n", pDestPoint
->x
, pDestPoint
->y
);
1073 user_assert(dst
->base
.pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1074 user_assert(src
->base
.pool
== D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
1076 user_assert(dst
->desc
.MultiSampleType
== D3DMULTISAMPLE_NONE
, D3DERR_INVALIDCALL
);
1077 user_assert(src
->desc
.MultiSampleType
== D3DMULTISAMPLE_NONE
, D3DERR_INVALIDCALL
);
1079 return NineSurface9_CopySurface(dst
, src
, pDestPoint
, pSourceRect
);
1083 NineDevice9_UpdateTexture( struct NineDevice9
*This
,
1084 IDirect3DBaseTexture9
*pSourceTexture
,
1085 IDirect3DBaseTexture9
*pDestinationTexture
)
1087 struct NineBaseTexture9
*dstb
= NineBaseTexture9(pDestinationTexture
);
1088 struct NineBaseTexture9
*srcb
= NineBaseTexture9(pSourceTexture
);
1090 unsigned last_level
= dstb
->base
.info
.last_level
;
1092 DBG("This=%p pSourceTexture=%p pDestinationTexture=%p\n", This
,
1093 pSourceTexture
, pDestinationTexture
);
1095 user_assert(pSourceTexture
!= pDestinationTexture
, D3DERR_INVALIDCALL
);
1097 user_assert(dstb
->base
.pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1098 user_assert(srcb
->base
.pool
== D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
1100 if (dstb
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
) {
1101 /* Only the first level is updated, the others regenerated. */
1104 user_assert(!(srcb
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
), D3DERR_INVALIDCALL
);
1107 user_assert(dstb
->base
.type
== srcb
->base
.type
, D3DERR_INVALIDCALL
);
1109 /* TODO: We can restrict the update to the dirty portions of the source.
1110 * Yes, this seems silly, but it's what MSDN says ...
1113 /* Find src level that matches dst level 0: */
1114 user_assert(srcb
->base
.info
.width0
>= dstb
->base
.info
.width0
&&
1115 srcb
->base
.info
.height0
>= dstb
->base
.info
.height0
&&
1116 srcb
->base
.info
.depth0
>= dstb
->base
.info
.depth0
,
1117 D3DERR_INVALIDCALL
);
1118 for (m
= 0; m
<= srcb
->base
.info
.last_level
; ++m
) {
1119 unsigned w
= u_minify(srcb
->base
.info
.width0
, m
);
1120 unsigned h
= u_minify(srcb
->base
.info
.height0
, m
);
1121 unsigned d
= u_minify(srcb
->base
.info
.depth0
, m
);
1123 if (w
== dstb
->base
.info
.width0
&&
1124 h
== dstb
->base
.info
.height0
&&
1125 d
== dstb
->base
.info
.depth0
)
1128 user_assert(m
<= srcb
->base
.info
.last_level
, D3DERR_INVALIDCALL
);
1130 last_level
= MIN2(last_level
, srcb
->base
.info
.last_level
- m
);
1132 if (dstb
->base
.type
== D3DRTYPE_TEXTURE
) {
1133 struct NineTexture9
*dst
= NineTexture9(dstb
);
1134 struct NineTexture9
*src
= NineTexture9(srcb
);
1136 for (l
= 0; l
<= last_level
; ++l
, ++m
)
1137 NineSurface9_CopySurface(dst
->surfaces
[l
],
1138 src
->surfaces
[m
], NULL
, NULL
);
1140 if (dstb
->base
.type
== D3DRTYPE_CUBETEXTURE
) {
1141 struct NineCubeTexture9
*dst
= NineCubeTexture9(dstb
);
1142 struct NineCubeTexture9
*src
= NineCubeTexture9(srcb
);
1145 /* GPUs usually have them stored as arrays of mip-mapped 2D textures. */
1146 for (z
= 0; z
< 6; ++z
) {
1147 for (l
= 0; l
<= last_level
; ++l
, ++m
) {
1148 NineSurface9_CopySurface(dst
->surfaces
[l
* 6 + z
],
1149 src
->surfaces
[m
* 6 + z
], NULL
, NULL
);
1154 if (dstb
->base
.type
== D3DRTYPE_VOLUMETEXTURE
) {
1155 struct NineVolumeTexture9
*dst
= NineVolumeTexture9(dstb
);
1156 struct NineVolumeTexture9
*src
= NineVolumeTexture9(srcb
);
1158 for (l
= 0; l
<= last_level
; ++l
, ++m
)
1159 NineVolume9_CopyVolume(dst
->volumes
[l
],
1160 src
->volumes
[m
], 0, 0, 0, NULL
);
1162 assert(!"invalid texture type");
1165 if (dstb
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
)
1166 NineBaseTexture9_GenerateMipSubLevels(dstb
);
1172 NineDevice9_GetRenderTargetData( struct NineDevice9
*This
,
1173 IDirect3DSurface9
*pRenderTarget
,
1174 IDirect3DSurface9
*pDestSurface
)
1176 struct NineSurface9
*dst
= NineSurface9(pDestSurface
);
1177 struct NineSurface9
*src
= NineSurface9(pRenderTarget
);
1179 DBG("This=%p pRenderTarget=%p pDestSurface=%p\n",
1180 This
, pRenderTarget
, pDestSurface
);
1182 user_assert(dst
->desc
.Pool
== D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
1183 user_assert(src
->desc
.Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1185 user_assert(dst
->desc
.MultiSampleType
< 2, D3DERR_INVALIDCALL
);
1186 user_assert(src
->desc
.MultiSampleType
< 2, D3DERR_INVALIDCALL
);
1188 return NineSurface9_CopySurface(dst
, src
, NULL
, NULL
);
1192 NineDevice9_GetFrontBufferData( struct NineDevice9
*This
,
1194 IDirect3DSurface9
*pDestSurface
)
1196 DBG("This=%p iSwapChain=%u pDestSurface=%p\n", This
,
1197 iSwapChain
, pDestSurface
);
1199 user_assert(pDestSurface
!= NULL
, D3DERR_INVALIDCALL
);
1200 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
1202 return NineSwapChain9_GetFrontBufferData(This
->swapchains
[iSwapChain
],
1207 NineDevice9_StretchRect( struct NineDevice9
*This
,
1208 IDirect3DSurface9
*pSourceSurface
,
1209 const RECT
*pSourceRect
,
1210 IDirect3DSurface9
*pDestSurface
,
1211 const RECT
*pDestRect
,
1212 D3DTEXTUREFILTERTYPE Filter
)
1214 struct pipe_screen
*screen
= This
->screen
;
1215 struct pipe_context
*pipe
= This
->pipe
;
1216 struct NineSurface9
*dst
= NineSurface9(pDestSurface
);
1217 struct NineSurface9
*src
= NineSurface9(pSourceSurface
);
1218 struct pipe_resource
*dst_res
= NineSurface9_GetResource(dst
);
1219 struct pipe_resource
*src_res
= NineSurface9_GetResource(src
);
1220 const boolean zs
= util_format_is_depth_or_stencil(dst_res
->format
);
1221 struct pipe_blit_info blit
;
1222 boolean scaled
, clamped
, ms
, flip_x
= FALSE
, flip_y
= FALSE
;
1224 DBG("This=%p pSourceSurface=%p pSourceRect=%p pDestSurface=%p "
1225 "pDestRect=%p Filter=%u\n",
1226 This
, pSourceSurface
, pSourceRect
, pDestSurface
, pDestRect
, Filter
);
1228 DBG("pSourceRect=(%u,%u)-(%u,%u)\n",
1229 pSourceRect
->left
, pSourceRect
->top
,
1230 pSourceRect
->right
, pSourceRect
->bottom
);
1232 DBG("pDestRect=(%u,%u)-(%u,%u)\n", pDestRect
->left
, pDestRect
->top
,
1233 pDestRect
->right
, pDestRect
->bottom
);
1235 user_assert(!zs
|| !This
->in_scene
, D3DERR_INVALIDCALL
);
1236 user_assert(!zs
|| !pSourceRect
||
1237 (pSourceRect
->left
== 0 &&
1238 pSourceRect
->top
== 0 &&
1239 pSourceRect
->right
== src
->desc
.Width
&&
1240 pSourceRect
->bottom
== src
->desc
.Height
), D3DERR_INVALIDCALL
);
1241 user_assert(!zs
|| !pDestRect
||
1242 (pDestRect
->left
== 0 &&
1243 pDestRect
->top
== 0 &&
1244 pDestRect
->right
== dst
->desc
.Width
&&
1245 pDestRect
->bottom
== dst
->desc
.Height
), D3DERR_INVALIDCALL
);
1247 (dst
->desc
.Width
== src
->desc
.Width
&&
1248 dst
->desc
.Height
== src
->desc
.Height
), D3DERR_INVALIDCALL
);
1249 user_assert(zs
|| !util_format_is_depth_or_stencil(src_res
->format
),
1250 D3DERR_INVALIDCALL
);
1251 user_assert(!zs
|| dst
->desc
.Format
== src
->desc
.Format
,
1252 D3DERR_INVALIDCALL
);
1253 user_assert(screen
->is_format_supported(screen
, src_res
->format
,
1255 src_res
->nr_samples
,
1256 PIPE_BIND_SAMPLER_VIEW
),
1257 D3DERR_INVALIDCALL
);
1258 user_assert(dst
->base
.pool
== D3DPOOL_DEFAULT
&&
1259 src
->base
.pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1261 /* We might want to permit these, but wine thinks we shouldn't. */
1262 user_assert(!pDestRect
||
1263 (pDestRect
->left
<= pDestRect
->right
&&
1264 pDestRect
->top
<= pDestRect
->bottom
), D3DERR_INVALIDCALL
);
1265 user_assert(!pSourceRect
||
1266 (pSourceRect
->left
<= pSourceRect
->right
&&
1267 pSourceRect
->top
<= pSourceRect
->bottom
), D3DERR_INVALIDCALL
);
1269 blit
.dst
.resource
= dst_res
;
1270 blit
.dst
.level
= dst
->level
;
1271 blit
.dst
.box
.z
= dst
->layer
;
1272 blit
.dst
.box
.depth
= 1;
1273 blit
.dst
.format
= dst_res
->format
;
1275 flip_x
= pDestRect
->left
> pDestRect
->right
;
1277 blit
.dst
.box
.x
= pDestRect
->right
;
1278 blit
.dst
.box
.width
= pDestRect
->left
- pDestRect
->right
;
1280 blit
.dst
.box
.x
= pDestRect
->left
;
1281 blit
.dst
.box
.width
= pDestRect
->right
- pDestRect
->left
;
1283 flip_y
= pDestRect
->top
> pDestRect
->bottom
;
1285 blit
.dst
.box
.y
= pDestRect
->bottom
;
1286 blit
.dst
.box
.height
= pDestRect
->top
- pDestRect
->bottom
;
1288 blit
.dst
.box
.y
= pDestRect
->top
;
1289 blit
.dst
.box
.height
= pDestRect
->bottom
- pDestRect
->top
;
1294 blit
.dst
.box
.width
= dst
->desc
.Width
;
1295 blit
.dst
.box
.height
= dst
->desc
.Height
;
1297 blit
.src
.resource
= src_res
;
1298 blit
.src
.level
= src
->level
;
1299 blit
.src
.box
.z
= src
->layer
;
1300 blit
.src
.box
.depth
= 1;
1301 blit
.src
.format
= src_res
->format
;
1303 if (flip_x
^ (pSourceRect
->left
> pSourceRect
->right
)) {
1304 blit
.src
.box
.x
= pSourceRect
->right
;
1305 blit
.src
.box
.width
= pSourceRect
->left
- pSourceRect
->right
;
1307 blit
.src
.box
.x
= pSourceRect
->left
;
1308 blit
.src
.box
.width
= pSourceRect
->right
- pSourceRect
->left
;
1310 if (flip_y
^ (pSourceRect
->top
> pSourceRect
->bottom
)) {
1311 blit
.src
.box
.y
= pSourceRect
->bottom
;
1312 blit
.src
.box
.height
= pSourceRect
->top
- pSourceRect
->bottom
;
1314 blit
.src
.box
.y
= pSourceRect
->top
;
1315 blit
.src
.box
.height
= pSourceRect
->bottom
- pSourceRect
->top
;
1318 blit
.src
.box
.x
= flip_x
? src
->desc
.Width
: 0;
1319 blit
.src
.box
.y
= flip_y
? src
->desc
.Height
: 0;
1320 blit
.src
.box
.width
= flip_x
? -src
->desc
.Width
: src
->desc
.Width
;
1321 blit
.src
.box
.height
= flip_y
? -src
->desc
.Height
: src
->desc
.Height
;
1323 blit
.mask
= zs
? PIPE_MASK_ZS
: PIPE_MASK_RGBA
;
1324 blit
.filter
= Filter
== D3DTEXF_LINEAR
?
1325 PIPE_TEX_FILTER_LINEAR
: PIPE_TEX_FILTER_NEAREST
;
1326 blit
.scissor_enable
= FALSE
;
1328 /* If both of a src and dst dimension are negative, flip them. */
1329 if (blit
.dst
.box
.width
< 0 && blit
.src
.box
.width
< 0) {
1330 blit
.dst
.box
.width
= -blit
.dst
.box
.width
;
1331 blit
.src
.box
.width
= -blit
.src
.box
.width
;
1333 if (blit
.dst
.box
.height
< 0 && blit
.src
.box
.height
< 0) {
1334 blit
.dst
.box
.height
= -blit
.dst
.box
.height
;
1335 blit
.src
.box
.height
= -blit
.src
.box
.height
;
1338 blit
.dst
.box
.width
!= blit
.src
.box
.width
||
1339 blit
.dst
.box
.height
!= blit
.src
.box
.height
;
1341 user_assert(!scaled
|| dst
!= src
, D3DERR_INVALIDCALL
);
1342 user_assert(!scaled
||
1343 !NineSurface9_IsOffscreenPlain(dst
) ||
1344 NineSurface9_IsOffscreenPlain(src
), D3DERR_INVALIDCALL
);
1345 user_assert(!scaled
||
1346 (!util_format_is_compressed(dst
->base
.info
.format
) &&
1347 !util_format_is_compressed(src
->base
.info
.format
)),
1348 D3DERR_INVALIDCALL
);
1350 user_warn(src
== dst
&&
1351 u_box_test_intersection_2d(&blit
.src
.box
, &blit
.dst
.box
));
1353 /* Check for clipping/clamping: */
1355 struct pipe_box box
;
1358 xy
= u_box_clip_2d(&box
, &blit
.dst
.box
,
1359 dst
->desc
.Width
, dst
->desc
.Height
);
1363 xy
= u_box_clip_2d(&box
, &blit
.src
.box
,
1364 src
->desc
.Width
, src
->desc
.Height
);
1368 ms
= (dst
->desc
.MultiSampleType
| 1) != (src
->desc
.MultiSampleType
| 1);
1370 if (clamped
|| scaled
|| (blit
.dst
.format
!= blit
.src
.format
) || ms
) {
1371 DBG("using pipe->blit()\n");
1372 /* TODO: software scaling */
1373 user_assert(screen
->is_format_supported(screen
, dst_res
->format
,
1375 dst_res
->nr_samples
,
1376 zs
? PIPE_BIND_DEPTH_STENCIL
:
1377 PIPE_BIND_RENDER_TARGET
),
1378 D3DERR_INVALIDCALL
);
1380 pipe
->blit(pipe
, &blit
);
1382 assert(blit
.dst
.box
.x
>= 0 && blit
.dst
.box
.y
>= 0 &&
1383 blit
.src
.box
.x
>= 0 && blit
.src
.box
.y
>= 0 &&
1384 blit
.dst
.box
.x
+ blit
.dst
.box
.width
<= dst
->desc
.Width
&&
1385 blit
.src
.box
.x
+ blit
.src
.box
.width
<= src
->desc
.Width
&&
1386 blit
.dst
.box
.y
+ blit
.dst
.box
.height
<= dst
->desc
.Height
&&
1387 blit
.src
.box
.y
+ blit
.src
.box
.height
<= src
->desc
.Height
);
1388 /* Or drivers might crash ... */
1389 DBG("Using resource_copy_region.\n");
1390 pipe
->resource_copy_region(pipe
,
1391 blit
.dst
.resource
, blit
.dst
.level
,
1392 blit
.dst
.box
.x
, blit
.dst
.box
.y
, blit
.dst
.box
.z
,
1393 blit
.src
.resource
, blit
.src
.level
,
1401 NineDevice9_ColorFill( struct NineDevice9
*This
,
1402 IDirect3DSurface9
*pSurface
,
1406 struct pipe_context
*pipe
= This
->pipe
;
1407 struct NineSurface9
*surf
= NineSurface9(pSurface
);
1408 struct pipe_surface
*psurf
;
1409 unsigned x
, y
, w
, h
;
1410 union pipe_color_union rgba
;
1413 DBG("This=%p pSurface=%p pRect=%p color=%08x\n", This
,
1414 pSurface
, pRect
, color
);
1416 DBG("pRect=(%u,%u)-(%u,%u)\n", pRect
->left
, pRect
->top
,
1417 pRect
->right
, pRect
->bottom
);
1419 user_assert(surf
->base
.pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1421 user_assert((surf
->base
.usage
& D3DUSAGE_RENDERTARGET
) ||
1422 NineSurface9_IsOffscreenPlain(surf
), D3DERR_INVALIDCALL
);
1427 w
= pRect
->right
- pRect
->left
;
1428 h
= pRect
->bottom
- pRect
->top
;
1432 w
= surf
->desc
.Width
;
1433 h
= surf
->desc
.Height
;
1435 d3dcolor_to_pipe_color_union(&rgba
, color
);
1438 !This
->screen
->is_format_supported(This
->screen
, surf
->base
.info
.format
,
1439 surf
->base
.info
.target
,
1440 surf
->base
.info
.nr_samples
,
1441 PIPE_BIND_RENDER_TARGET
);
1443 psurf
= NineSurface9_GetSurface(surf
, 0);
1449 pipe
->clear_render_target(pipe
, psurf
, &rgba
, x
, y
, w
, h
);
1451 D3DLOCKED_RECT lock
;
1452 union util_color uc
;
1454 /* XXX: lock pRect and fix util_fill_rect */
1455 hr
= NineSurface9_LockRect(surf
, &lock
, NULL
, 0);
1458 util_pack_color_ub(color
>> 16, color
>> 8, color
>> 0, color
>> 24,
1459 surf
->base
.info
.format
, &uc
);
1460 util_fill_rect(lock
.pBits
, surf
->base
.info
.format
,lock
.Pitch
,
1462 NineSurface9_UnlockRect(surf
);
1469 NineDevice9_CreateOffscreenPlainSurface( struct NineDevice9
*This
,
1474 IDirect3DSurface9
**ppSurface
,
1475 HANDLE
*pSharedHandle
)
1479 DBG("This=%p Width=%u Height=%u Format=%s(0x%x) Pool=%u "
1480 "ppSurface=%p pSharedHandle=%p\n", This
,
1481 Width
, Height
, d3dformat_to_string(Format
), Format
, Pool
,
1482 ppSurface
, pSharedHandle
);
1485 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
1486 || Pool
== D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
1487 user_assert(Pool
!= D3DPOOL_MANAGED
, D3DERR_INVALIDCALL
);
1489 /* Can be used with StretchRect and ColorFill. It's also always lockable.
1491 hr
= create_zs_or_rt_surface(This
, 2, Pool
, Width
, Height
,
1493 D3DMULTISAMPLE_NONE
, 0,
1495 ppSurface
, pSharedHandle
);
1497 DBG("Failed to create surface.\n");
1502 NineDevice9_SetRenderTarget( struct NineDevice9
*This
,
1503 DWORD RenderTargetIndex
,
1504 IDirect3DSurface9
*pRenderTarget
)
1506 struct NineSurface9
*rt
= NineSurface9(pRenderTarget
);
1507 const unsigned i
= RenderTargetIndex
;
1509 DBG("This=%p RenderTargetIndex=%u pRenderTarget=%p\n", This
,
1510 RenderTargetIndex
, pRenderTarget
);
1512 user_assert(i
< This
->caps
.NumSimultaneousRTs
, D3DERR_INVALIDCALL
);
1513 user_assert(i
!= 0 || pRenderTarget
, D3DERR_INVALIDCALL
);
1514 user_assert(!pRenderTarget
||
1515 rt
->desc
.Usage
& D3DUSAGE_RENDERTARGET
, D3DERR_INVALIDCALL
);
1518 This
->state
.viewport
.X
= 0;
1519 This
->state
.viewport
.Y
= 0;
1520 This
->state
.viewport
.Width
= rt
->desc
.Width
;
1521 This
->state
.viewport
.Height
= rt
->desc
.Height
;
1522 This
->state
.viewport
.MinZ
= 0.0f
;
1523 This
->state
.viewport
.MaxZ
= 1.0f
;
1525 This
->state
.scissor
.minx
= 0;
1526 This
->state
.scissor
.miny
= 0;
1527 This
->state
.scissor
.maxx
= rt
->desc
.Width
;
1528 This
->state
.scissor
.maxy
= rt
->desc
.Height
;
1530 This
->state
.changed
.group
|= NINE_STATE_VIEWPORT
| NINE_STATE_SCISSOR
;
1533 if (This
->state
.rt
[i
] != NineSurface9(pRenderTarget
)) {
1534 nine_bind(&This
->state
.rt
[i
], pRenderTarget
);
1535 This
->state
.changed
.group
|= NINE_STATE_FB
;
1541 NineDevice9_GetRenderTarget( struct NineDevice9
*This
,
1542 DWORD RenderTargetIndex
,
1543 IDirect3DSurface9
**ppRenderTarget
)
1545 const unsigned i
= RenderTargetIndex
;
1547 user_assert(i
< This
->caps
.NumSimultaneousRTs
, D3DERR_INVALIDCALL
);
1548 user_assert(ppRenderTarget
, D3DERR_INVALIDCALL
);
1550 *ppRenderTarget
= (IDirect3DSurface9
*)This
->state
.rt
[i
];
1551 if (!This
->state
.rt
[i
])
1552 return D3DERR_NOTFOUND
;
1554 NineUnknown_AddRef(NineUnknown(This
->state
.rt
[i
]));
1559 NineDevice9_SetDepthStencilSurface( struct NineDevice9
*This
,
1560 IDirect3DSurface9
*pNewZStencil
)
1562 DBG("This=%p pNewZStencil=%p\n", This
, pNewZStencil
);
1564 if (This
->state
.ds
!= NineSurface9(pNewZStencil
)) {
1565 nine_bind(&This
->state
.ds
, pNewZStencil
);
1566 This
->state
.changed
.group
|= NINE_STATE_FB
;
1572 NineDevice9_GetDepthStencilSurface( struct NineDevice9
*This
,
1573 IDirect3DSurface9
**ppZStencilSurface
)
1575 user_assert(ppZStencilSurface
, D3DERR_INVALIDCALL
);
1577 *ppZStencilSurface
= (IDirect3DSurface9
*)This
->state
.ds
;
1578 if (!This
->state
.ds
)
1579 return D3DERR_NOTFOUND
;
1581 NineUnknown_AddRef(NineUnknown(This
->state
.ds
));
1586 NineDevice9_BeginScene( struct NineDevice9
*This
)
1588 DBG("This=%p\n", This
);
1589 user_assert(!This
->in_scene
, D3DERR_INVALIDCALL
);
1590 This
->in_scene
= TRUE
;
1591 /* Do we want to do anything else here ? */
1596 NineDevice9_EndScene( struct NineDevice9
*This
)
1598 DBG("This=%p\n", This
);
1599 user_assert(This
->in_scene
, D3DERR_INVALIDCALL
);
1600 This
->in_scene
= FALSE
;
1605 NineDevice9_Clear( struct NineDevice9
*This
,
1607 const D3DRECT
*pRects
,
1613 struct pipe_context
*pipe
= This
->pipe
;
1614 struct NineSurface9
*zsbuf
= This
->state
.ds
;
1617 union pipe_color_union rgba
;
1620 DBG("This=%p Count=%u pRects=%p Flags=%x Color=%08x Z=%f Stencil=%x\n",
1621 This
, Count
, pRects
, Flags
, Color
, Z
, Stencil
);
1623 user_assert(This
->state
.ds
|| !(Flags
& NINED3DCLEAR_DEPTHSTENCIL
),
1624 D3DERR_INVALIDCALL
);
1625 user_assert(!(Flags
& D3DCLEAR_STENCIL
) ||
1627 util_format_is_depth_and_stencil(zsbuf
->base
.info
.format
)),
1628 D3DERR_INVALIDCALL
);
1630 user_assert((Count
&& pRects
) || (!Count
&& !pRects
), D3DERR_INVALIDCALL
);
1632 user_warn((pRects
&& !Count
) || (!pRects
&& Count
));
1633 if (pRects
&& !Count
)
1639 if (Flags
& D3DCLEAR_TARGET
) bufs
|= PIPE_CLEAR_COLOR
;
1640 if (Flags
& D3DCLEAR_ZBUFFER
) bufs
|= PIPE_CLEAR_DEPTH
;
1641 if (Flags
& D3DCLEAR_STENCIL
) bufs
|= PIPE_CLEAR_STENCIL
;
1644 d3dcolor_to_pipe_color_union(&rgba
, Color
);
1646 nine_update_state(This
, NINE_STATE_FB
);
1648 rect
.x1
= This
->state
.viewport
.X
;
1649 rect
.y1
= This
->state
.viewport
.Y
;
1650 rect
.x2
= This
->state
.viewport
.Width
+ rect
.x1
;
1651 rect
.y2
= This
->state
.viewport
.Height
+ rect
.y1
;
1653 /* Both rectangles apply, which is weird, but that's D3D9. */
1654 if (This
->state
.rs
[D3DRS_SCISSORTESTENABLE
]) {
1655 rect
.x1
= MAX2(rect
.x1
, This
->state
.scissor
.minx
);
1656 rect
.y1
= MAX2(rect
.y1
, This
->state
.scissor
.miny
);
1657 rect
.x2
= MIN2(rect
.x2
, This
->state
.scissor
.maxx
);
1658 rect
.y2
= MIN2(rect
.y2
, This
->state
.scissor
.maxy
);
1662 /* Maybe apps like to specify a large rect ? */
1663 if (pRects
[0].x1
<= rect
.x1
&& pRects
[0].x2
>= rect
.x2
&&
1664 pRects
[0].y1
<= rect
.y1
&& pRects
[0].y2
>= rect
.y2
) {
1665 DBG("First rect covers viewport.\n");
1671 if (rect
.x1
>= This
->state
.fb
.width
|| rect
.y1
>= This
->state
.fb
.height
)
1674 rect
.x1
== 0 && rect
.x2
>= This
->state
.fb
.width
&&
1675 rect
.y1
== 0 && rect
.y2
>= This
->state
.fb
.height
) {
1676 /* fast path, clears everything at once */
1678 pipe
->clear(pipe
, bufs
, &rgba
, Z
, Stencil
);
1681 rect
.x2
= MIN2(rect
.x2
, This
->state
.fb
.width
);
1682 rect
.y2
= MIN2(rect
.y2
, This
->state
.fb
.height
);
1689 for (i
= 0; (i
< This
->state
.fb
.nr_cbufs
); ++i
) {
1690 if (!This
->state
.fb
.cbufs
[i
] || !(Flags
& D3DCLEAR_TARGET
))
1691 continue; /* save space, compiler should hoist this */
1692 for (r
= 0; r
< Count
; ++r
) {
1693 /* Don't trust users to pass these in the right order. */
1694 unsigned x1
= MIN2(pRects
[r
].x1
, pRects
[r
].x2
);
1695 unsigned y1
= MIN2(pRects
[r
].y1
, pRects
[r
].y2
);
1696 unsigned x2
= MAX2(pRects
[r
].x1
, pRects
[r
].x2
);
1697 unsigned y2
= MAX2(pRects
[r
].y1
, pRects
[r
].y2
);
1699 /* Drop negative rectangles (like wine expects). */
1700 if (pRects
[r
].x1
> pRects
[r
].x2
) continue;
1701 if (pRects
[r
].y1
> pRects
[r
].y2
) continue;
1704 x1
= MAX2(x1
, rect
.x1
);
1705 y1
= MAX2(y1
, rect
.y1
);
1706 x2
= MIN2(x2
, rect
.x2
);
1707 y2
= MIN2(y2
, rect
.y2
);
1709 DBG("Clearing (%u..%u)x(%u..%u)\n", x1
, x2
, y1
, y2
);
1710 pipe
->clear_render_target(pipe
, This
->state
.fb
.cbufs
[i
], &rgba
,
1711 x1
, y1
, x2
- x1
, y2
- y1
);
1714 if (!(Flags
& NINED3DCLEAR_DEPTHSTENCIL
))
1717 bufs
&= PIPE_CLEAR_DEPTHSTENCIL
;
1719 for (r
= 0; r
< Count
; ++r
) {
1720 unsigned x1
= MIN2(pRects
[r
].x1
, pRects
[r
].x2
);
1721 unsigned y1
= MIN2(pRects
[r
].y1
, pRects
[r
].y2
);
1722 unsigned x2
= MAX2(pRects
[r
].x1
, pRects
[r
].x2
);
1723 unsigned y2
= MAX2(pRects
[r
].y1
, pRects
[r
].y2
);
1725 /* Drop negative rectangles. */
1726 if (pRects
[r
].x1
> pRects
[r
].x2
) continue;
1727 if (pRects
[r
].y1
> pRects
[r
].y2
) continue;
1730 x1
= MIN2(x1
, rect
.x1
);
1731 y1
= MIN2(y1
, rect
.y1
);
1732 x2
= MIN2(x2
, rect
.x2
);
1733 y2
= MIN2(y2
, rect
.y2
);
1735 pipe
->clear_depth_stencil(pipe
, This
->state
.fb
.zsbuf
, bufs
, Z
, Stencil
,
1736 x1
, y1
, x2
- x1
, y2
- y1
);
1742 NineDevice9_SetTransform( struct NineDevice9
*This
,
1743 D3DTRANSFORMSTATETYPE State
,
1744 const D3DMATRIX
*pMatrix
)
1746 struct nine_state
*state
= This
->update
;
1747 D3DMATRIX
*M
= nine_state_access_transform(state
, State
, TRUE
);
1749 DBG("This=%p State=%d pMatrix=%p\n", This
, State
, pMatrix
);
1751 user_assert(M
, D3DERR_INVALIDCALL
);
1754 state
->ff
.changed
.transform
[State
/ 32] |= 1 << (State
% 32);
1755 state
->changed
.group
|= NINE_STATE_FF
;
1761 NineDevice9_GetTransform( struct NineDevice9
*This
,
1762 D3DTRANSFORMSTATETYPE State
,
1763 D3DMATRIX
*pMatrix
)
1765 D3DMATRIX
*M
= nine_state_access_transform(&This
->state
, State
, FALSE
);
1766 user_assert(M
, D3DERR_INVALIDCALL
);
1772 NineDevice9_MultiplyTransform( struct NineDevice9
*This
,
1773 D3DTRANSFORMSTATETYPE State
,
1774 const D3DMATRIX
*pMatrix
)
1776 struct nine_state
*state
= This
->update
;
1778 D3DMATRIX
*M
= nine_state_access_transform(state
, State
, TRUE
);
1780 DBG("This=%p State=%d pMatrix=%p\n", This
, State
, pMatrix
);
1782 user_assert(M
, D3DERR_INVALIDCALL
);
1784 nine_d3d_matrix_matrix_mul(&T
, pMatrix
, M
);
1785 return NineDevice9_SetTransform(This
, State
, &T
);
1789 NineDevice9_SetViewport( struct NineDevice9
*This
,
1790 const D3DVIEWPORT9
*pViewport
)
1792 struct nine_state
*state
= This
->update
;
1794 DBG("X=%u Y=%u W=%u H=%u MinZ=%f MaxZ=%f\n",
1795 pViewport
->X
, pViewport
->Y
, pViewport
->Width
, pViewport
->Height
,
1796 pViewport
->MinZ
, pViewport
->MaxZ
);
1798 state
->viewport
= *pViewport
;
1799 state
->changed
.group
|= NINE_STATE_VIEWPORT
;
1805 NineDevice9_GetViewport( struct NineDevice9
*This
,
1806 D3DVIEWPORT9
*pViewport
)
1808 *pViewport
= This
->state
.viewport
;
1813 NineDevice9_SetMaterial( struct NineDevice9
*This
,
1814 const D3DMATERIAL9
*pMaterial
)
1816 struct nine_state
*state
= This
->update
;
1818 DBG("This=%p pMaterial=%p\n", This
, pMaterial
);
1820 nine_dump_D3DMATERIAL9(DBG_FF
, pMaterial
);
1822 user_assert(pMaterial
, E_POINTER
);
1824 state
->ff
.material
= *pMaterial
;
1825 state
->changed
.group
|= NINE_STATE_FF_MATERIAL
;
1831 NineDevice9_GetMaterial( struct NineDevice9
*This
,
1832 D3DMATERIAL9
*pMaterial
)
1834 user_assert(pMaterial
, E_POINTER
);
1835 *pMaterial
= This
->state
.ff
.material
;
1840 NineDevice9_SetLight( struct NineDevice9
*This
,
1842 const D3DLIGHT9
*pLight
)
1844 struct nine_state
*state
= This
->update
;
1846 DBG("This=%p Index=%u pLight=%p\n", This
, Index
, pLight
);
1848 nine_dump_D3DLIGHT9(DBG_FF
, pLight
);
1850 user_assert(pLight
, D3DERR_INVALIDCALL
);
1851 user_assert(pLight
->Type
< NINED3DLIGHT_INVALID
, D3DERR_INVALIDCALL
);
1853 user_assert(Index
< NINE_MAX_LIGHTS
, D3DERR_INVALIDCALL
); /* sanity */
1855 if (Index
>= state
->ff
.num_lights
) {
1856 unsigned n
= state
->ff
.num_lights
;
1857 unsigned N
= Index
+ 1;
1859 state
->ff
.light
= REALLOC(state
->ff
.light
, n
* sizeof(D3DLIGHT9
),
1860 N
* sizeof(D3DLIGHT9
));
1861 if (!state
->ff
.light
)
1862 return E_OUTOFMEMORY
;
1863 state
->ff
.num_lights
= N
;
1865 for (; n
< Index
; ++n
)
1866 state
->ff
.light
[n
].Type
= (D3DLIGHTTYPE
)NINED3DLIGHT_INVALID
;
1868 state
->ff
.light
[Index
] = *pLight
;
1870 if (pLight
->Type
== D3DLIGHT_SPOT
&& pLight
->Theta
>= pLight
->Phi
) {
1871 DBG("Warning: clamping D3DLIGHT9.Theta\n");
1872 state
->ff
.light
[Index
].Theta
= state
->ff
.light
[Index
].Phi
;
1874 if (pLight
->Type
!= D3DLIGHT_DIRECTIONAL
&&
1875 pLight
->Attenuation0
== 0.0f
&&
1876 pLight
->Attenuation1
== 0.0f
&&
1877 pLight
->Attenuation2
== 0.0f
) {
1878 DBG("Warning: all D3DLIGHT9.Attenuation[i] are 0\n");
1881 state
->changed
.group
|= NINE_STATE_FF_LIGHTING
;
1887 NineDevice9_GetLight( struct NineDevice9
*This
,
1891 const struct nine_state
*state
= &This
->state
;
1893 user_assert(pLight
, D3DERR_INVALIDCALL
);
1894 user_assert(Index
< state
->ff
.num_lights
, D3DERR_INVALIDCALL
);
1895 user_assert(state
->ff
.light
[Index
].Type
< NINED3DLIGHT_INVALID
,
1896 D3DERR_INVALIDCALL
);
1898 *pLight
= state
->ff
.light
[Index
];
1904 NineDevice9_LightEnable( struct NineDevice9
*This
,
1908 struct nine_state
*state
= This
->update
;
1911 DBG("This=%p Index=%u Enable=%i\n", This
, Index
, Enable
);
1913 if (Index
>= state
->ff
.num_lights
||
1914 state
->ff
.light
[Index
].Type
== NINED3DLIGHT_INVALID
) {
1915 /* This should create a default light. */
1917 memset(&light
, 0, sizeof(light
));
1918 light
.Type
= D3DLIGHT_DIRECTIONAL
;
1919 light
.Diffuse
.r
= 1.0f
;
1920 light
.Diffuse
.g
= 1.0f
;
1921 light
.Diffuse
.b
= 1.0f
;
1922 light
.Direction
.z
= 1.0f
;
1923 NineDevice9_SetLight(This
, Index
, &light
);
1925 user_assert(Index
< state
->ff
.num_lights
, D3DERR_INVALIDCALL
);
1927 for (i
= 0; i
< state
->ff
.num_lights_active
; ++i
) {
1928 if (state
->ff
.active_light
[i
] == Index
)
1933 if (i
< state
->ff
.num_lights_active
)
1935 /* XXX wine thinks this should still succeed:
1937 user_assert(i
< NINE_MAX_LIGHTS_ACTIVE
, D3DERR_INVALIDCALL
);
1939 state
->ff
.active_light
[i
] = Index
;
1940 state
->ff
.num_lights_active
++;
1942 if (i
== state
->ff
.num_lights_active
)
1944 --state
->ff
.num_lights_active
;
1945 for (; i
< state
->ff
.num_lights_active
; ++i
)
1946 state
->ff
.active_light
[i
] = state
->ff
.active_light
[i
+ 1];
1948 state
->changed
.group
|= NINE_STATE_FF_LIGHTING
;
1954 NineDevice9_GetLightEnable( struct NineDevice9
*This
,
1958 const struct nine_state
*state
= &This
->state
;
1961 user_assert(Index
< state
->ff
.num_lights
, D3DERR_INVALIDCALL
);
1962 user_assert(state
->ff
.light
[Index
].Type
< NINED3DLIGHT_INVALID
,
1963 D3DERR_INVALIDCALL
);
1965 for (i
= 0; i
< state
->ff
.num_lights_active
; ++i
)
1966 if (state
->ff
.active_light
[i
] == Index
)
1968 *pEnable
= i
!= state
->ff
.num_lights_active
;
1973 NineDevice9_SetClipPlane( struct NineDevice9
*This
,
1975 const float *pPlane
)
1977 struct nine_state
*state
= This
->update
;
1979 user_assert(pPlane
, D3DERR_INVALIDCALL
);
1981 DBG("This=%p Index=%u pPlane=%f %f %f %f\n", This
, Index
,
1982 pPlane
[0], pPlane
[1],
1983 pPlane
[2], pPlane
[3]);
1985 user_assert(Index
< PIPE_MAX_CLIP_PLANES
, D3DERR_INVALIDCALL
);
1987 memcpy(&state
->clip
.ucp
[Index
][0], pPlane
, sizeof(state
->clip
.ucp
[0]));
1988 state
->changed
.ucp
|= 1 << Index
;
1994 NineDevice9_GetClipPlane( struct NineDevice9
*This
,
1998 const struct nine_state
*state
= &This
->state
;
2000 user_assert(Index
< PIPE_MAX_CLIP_PLANES
, D3DERR_INVALIDCALL
);
2002 memcpy(pPlane
, &state
->clip
.ucp
[Index
][0], sizeof(state
->clip
.ucp
[0]));
2006 #define RESZ_CODE 0x7fa05000
2009 NineDevice9_ResolveZ( struct NineDevice9
*This
)
2011 struct nine_state
*state
= &This
->state
;
2012 const struct util_format_description
*desc
;
2013 struct NineSurface9
*source
= state
->ds
;
2014 struct NineBaseTexture9
*destination
= state
->texture
[0];
2015 struct pipe_resource
*src
, *dst
;
2016 struct pipe_blit_info blit
;
2018 DBG("RESZ resolve\n");
2020 user_assert(source
&& destination
&&
2021 destination
->base
.type
== D3DRTYPE_TEXTURE
, D3DERR_INVALIDCALL
);
2023 src
= source
->base
.resource
;
2024 dst
= destination
->base
.resource
;
2026 user_assert(src
&& dst
, D3DERR_INVALIDCALL
);
2028 /* check dst is depth format. we know already for src */
2029 desc
= util_format_description(dst
->format
);
2030 user_assert(desc
->colorspace
== UTIL_FORMAT_COLORSPACE_ZS
, D3DERR_INVALIDCALL
);
2032 blit
.src
.resource
= src
;
2034 blit
.src
.format
= src
->format
;
2036 blit
.src
.box
.depth
= 1;
2039 blit
.src
.box
.width
= src
->width0
;
2040 blit
.src
.box
.height
= src
->height0
;
2042 blit
.dst
.resource
= dst
;
2044 blit
.dst
.format
= dst
->format
;
2046 blit
.dst
.box
.depth
= 1;
2049 blit
.dst
.box
.width
= dst
->width0
;
2050 blit
.dst
.box
.height
= dst
->height0
;
2052 blit
.mask
= PIPE_MASK_ZS
;
2053 blit
.filter
= PIPE_TEX_FILTER_NEAREST
;
2054 blit
.scissor_enable
= FALSE
;
2056 This
->pipe
->blit(This
->pipe
, &blit
);
2060 #define ALPHA_TO_COVERAGE_ENABLE MAKEFOURCC('A', '2', 'M', '1')
2061 #define ALPHA_TO_COVERAGE_DISABLE MAKEFOURCC('A', '2', 'M', '0')
2064 NineDevice9_SetRenderState( struct NineDevice9
*This
,
2065 D3DRENDERSTATETYPE State
,
2068 struct nine_state
*state
= This
->update
;
2070 DBG("This=%p State=%u(%s) Value=%08x\n", This
,
2071 State
, nine_d3drs_to_string(State
), Value
);
2073 /* Amd hacks (equivalent to GL extensions) */
2074 if (State
== D3DRS_POINTSIZE
) {
2075 if (Value
== RESZ_CODE
)
2076 return NineDevice9_ResolveZ(This
);
2078 if (Value
== ALPHA_TO_COVERAGE_ENABLE
||
2079 Value
== ALPHA_TO_COVERAGE_DISABLE
) {
2080 state
->rs
[NINED3DRS_ALPHACOVERAGE
] = (Value
== ALPHA_TO_COVERAGE_ENABLE
);
2081 state
->changed
.group
|= NINE_STATE_BLEND
;
2087 if (State
== D3DRS_ADAPTIVETESS_Y
&&
2088 (Value
== D3DFMT_ATOC
|| (Value
== D3DFMT_UNKNOWN
&& state
->rs
[NINED3DRS_ALPHACOVERAGE
]))) {
2089 state
->rs
[NINED3DRS_ALPHACOVERAGE
] = (Value
== D3DFMT_ATOC
);
2090 state
->changed
.group
|= NINE_STATE_BLEND
;
2094 user_assert(State
< Elements(state
->rs
), D3DERR_INVALIDCALL
);
2096 if (likely(state
->rs
[State
] != Value
) || unlikely(This
->is_recording
)) {
2097 state
->rs
[State
] = Value
;
2098 state
->changed
.rs
[State
/ 32] |= 1 << (State
% 32);
2099 state
->changed
.group
|= nine_render_state_group
[State
];
2106 NineDevice9_GetRenderState( struct NineDevice9
*This
,
2107 D3DRENDERSTATETYPE State
,
2110 user_assert(State
< Elements(This
->state
.rs
), D3DERR_INVALIDCALL
);
2112 *pValue
= This
->state
.rs
[State
];
2117 NineDevice9_CreateStateBlock( struct NineDevice9
*This
,
2118 D3DSTATEBLOCKTYPE Type
,
2119 IDirect3DStateBlock9
**ppSB
)
2121 struct NineStateBlock9
*nsb
;
2122 struct nine_state
*dst
;
2124 enum nine_stateblock_type type
;
2127 DBG("This=%p Type=%u ppSB=%p\n", This
, Type
, ppSB
);
2129 user_assert(Type
== D3DSBT_ALL
||
2130 Type
== D3DSBT_VERTEXSTATE
||
2131 Type
== D3DSBT_PIXELSTATE
, D3DERR_INVALIDCALL
);
2134 case D3DSBT_VERTEXSTATE
: type
= NINESBT_VERTEXSTATE
; break;
2135 case D3DSBT_PIXELSTATE
: type
= NINESBT_PIXELSTATE
; break;
2141 hr
= NineStateBlock9_new(This
, &nsb
, type
);
2144 *ppSB
= (IDirect3DStateBlock9
*)nsb
;
2147 dst
->changed
.group
=
2148 NINE_STATE_TEXTURE
|
2151 if (Type
== D3DSBT_ALL
|| Type
== D3DSBT_VERTEXSTATE
) {
2152 dst
->changed
.group
|=
2153 NINE_STATE_FF_LIGHTING
|
2154 NINE_STATE_VS
| NINE_STATE_VS_CONST
|
2156 /* TODO: texture/sampler state */
2157 memcpy(dst
->changed
.rs
,
2158 nine_render_states_vertex
, sizeof(dst
->changed
.rs
));
2159 nine_ranges_insert(&dst
->changed
.vs_const_f
, 0, This
->max_vs_const_f
,
2161 dst
->changed
.vs_const_i
= 0xffff;
2162 dst
->changed
.vs_const_b
= 0xffff;
2163 for (s
= 0; s
< NINE_MAX_SAMPLERS
; ++s
)
2164 dst
->changed
.sampler
[s
] |= 1 << D3DSAMP_DMAPOFFSET
;
2165 if (This
->state
.ff
.num_lights
) {
2166 dst
->ff
.num_lights
= This
->state
.ff
.num_lights
;
2167 /* zero'd -> light type won't be NINED3DLIGHT_INVALID, so
2168 * all currently existing lights will be captured
2170 dst
->ff
.light
= CALLOC(This
->state
.ff
.num_lights
,
2172 if (!dst
->ff
.light
) {
2173 nine_bind(ppSB
, NULL
);
2174 return E_OUTOFMEMORY
;
2178 if (Type
== D3DSBT_ALL
|| Type
== D3DSBT_PIXELSTATE
) {
2179 dst
->changed
.group
|=
2180 NINE_STATE_PS
| NINE_STATE_PS_CONST
;
2181 /* TODO: texture/sampler state */
2182 memcpy(dst
->changed
.rs
,
2183 nine_render_states_pixel
, sizeof(dst
->changed
.rs
));
2184 nine_ranges_insert(&dst
->changed
.ps_const_f
, 0, This
->max_ps_const_f
,
2186 dst
->changed
.ps_const_i
= 0xffff;
2187 dst
->changed
.ps_const_b
= 0xffff;
2188 for (s
= 0; s
< NINE_MAX_SAMPLERS
; ++s
)
2189 dst
->changed
.sampler
[s
] |= 0x1ffe;
2191 if (Type
== D3DSBT_ALL
) {
2192 dst
->changed
.group
|=
2193 NINE_STATE_VIEWPORT
|
2194 NINE_STATE_SCISSOR
|
2195 NINE_STATE_RASTERIZER
|
2199 NINE_STATE_MATERIAL
|
2200 NINE_STATE_BLEND_COLOR
|
2201 NINE_STATE_SAMPLE_MASK
;
2202 memset(dst
->changed
.rs
, ~0, (D3DRS_COUNT
/ 32) * sizeof(uint32_t));
2203 dst
->changed
.rs
[D3DRS_LAST
/ 32] |= (1 << (D3DRS_COUNT
% 32)) - 1;
2204 dst
->changed
.vtxbuf
= (1ULL << This
->caps
.MaxStreams
) - 1;
2205 dst
->changed
.stream_freq
= dst
->changed
.vtxbuf
;
2206 dst
->changed
.ucp
= (1 << PIPE_MAX_CLIP_PLANES
) - 1;
2207 dst
->changed
.texture
= (1 << NINE_MAX_SAMPLERS
) - 1;
2209 NineStateBlock9_Capture(NineStateBlock9(*ppSB
));
2211 /* TODO: fixed function state */
2217 NineDevice9_BeginStateBlock( struct NineDevice9
*This
)
2221 DBG("This=%p\n", This
);
2223 user_assert(!This
->record
, D3DERR_INVALIDCALL
);
2225 hr
= NineStateBlock9_new(This
, &This
->record
, NINESBT_CUSTOM
);
2228 NineUnknown_ConvertRefToBind(NineUnknown(This
->record
));
2230 This
->update
= &This
->record
->state
;
2231 This
->is_recording
= TRUE
;
2237 NineDevice9_EndStateBlock( struct NineDevice9
*This
,
2238 IDirect3DStateBlock9
**ppSB
)
2240 DBG("This=%p ppSB=%p\n", This
, ppSB
);
2242 user_assert(This
->record
, D3DERR_INVALIDCALL
);
2244 This
->update
= &This
->state
;
2245 This
->is_recording
= FALSE
;
2247 NineUnknown_AddRef(NineUnknown(This
->record
));
2248 *ppSB
= (IDirect3DStateBlock9
*)This
->record
;
2249 NineUnknown_Unbind(NineUnknown(This
->record
));
2250 This
->record
= NULL
;
2256 NineDevice9_SetClipStatus( struct NineDevice9
*This
,
2257 const D3DCLIPSTATUS9
*pClipStatus
)
2259 STUB(D3DERR_INVALIDCALL
);
2263 NineDevice9_GetClipStatus( struct NineDevice9
*This
,
2264 D3DCLIPSTATUS9
*pClipStatus
)
2266 STUB(D3DERR_INVALIDCALL
);
2270 NineDevice9_GetTexture( struct NineDevice9
*This
,
2272 IDirect3DBaseTexture9
**ppTexture
)
2274 user_assert(Stage
< This
->caps
.MaxSimultaneousTextures
||
2275 Stage
== D3DDMAPSAMPLER
||
2276 (Stage
>= D3DVERTEXTEXTURESAMPLER0
&&
2277 Stage
<= D3DVERTEXTEXTURESAMPLER3
), D3DERR_INVALIDCALL
);
2278 user_assert(ppTexture
, D3DERR_INVALIDCALL
);
2280 if (Stage
>= D3DDMAPSAMPLER
)
2281 Stage
= Stage
- D3DDMAPSAMPLER
+ NINE_MAX_SAMPLERS_PS
;
2283 *ppTexture
= (IDirect3DBaseTexture9
*)This
->state
.texture
[Stage
];
2285 if (This
->state
.texture
[Stage
])
2286 NineUnknown_AddRef(NineUnknown(This
->state
.texture
[Stage
]));
2291 NineDevice9_SetTexture( struct NineDevice9
*This
,
2293 IDirect3DBaseTexture9
*pTexture
)
2295 struct nine_state
*state
= This
->update
;
2296 struct NineBaseTexture9
*tex
= NineBaseTexture9(pTexture
);
2298 DBG("This=%p Stage=%u pTexture=%p\n", This
, Stage
, pTexture
);
2300 user_assert(Stage
< This
->caps
.MaxSimultaneousTextures
||
2301 Stage
== D3DDMAPSAMPLER
||
2302 (Stage
>= D3DVERTEXTEXTURESAMPLER0
&&
2303 Stage
<= D3DVERTEXTEXTURESAMPLER3
), D3DERR_INVALIDCALL
);
2304 user_assert(!tex
|| tex
->base
.pool
!= D3DPOOL_SCRATCH
, D3DERR_INVALIDCALL
);
2306 if (unlikely(tex
&& tex
->base
.pool
== D3DPOOL_SYSTEMMEM
)) {
2307 /* TODO: Currently not implemented. Better return error
2308 * with message telling what's wrong */
2309 ERR("This=%p D3DPOOL_SYSTEMMEM not implemented for SetTexture\n", This
);
2310 user_assert(tex
->base
.pool
!= D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
2313 if (Stage
>= D3DDMAPSAMPLER
)
2314 Stage
= Stage
- D3DDMAPSAMPLER
+ NINE_MAX_SAMPLERS_PS
;
2316 if (!This
->is_recording
) {
2317 struct NineBaseTexture9
*old
= state
->texture
[Stage
];
2321 state
->samplers_shadow
&= ~(1 << Stage
);
2323 state
->samplers_shadow
|= tex
->shadow
<< Stage
;
2325 if ((tex
->dirty
| tex
->dirty_mip
) && LIST_IS_EMPTY(&tex
->list
))
2326 list_add(&tex
->list
, &This
->update_textures
);
2333 nine_bind(&state
->texture
[Stage
], pTexture
);
2335 state
->changed
.texture
|= 1 << Stage
;
2336 state
->changed
.group
|= NINE_STATE_TEXTURE
;
2342 NineDevice9_GetTextureStageState( struct NineDevice9
*This
,
2344 D3DTEXTURESTAGESTATETYPE Type
,
2347 const struct nine_state
*state
= &This
->state
;
2349 user_assert(Stage
< Elements(state
->ff
.tex_stage
), D3DERR_INVALIDCALL
);
2350 user_assert(Type
< Elements(state
->ff
.tex_stage
[0]), D3DERR_INVALIDCALL
);
2352 *pValue
= state
->ff
.tex_stage
[Stage
][Type
];
2358 NineDevice9_SetTextureStageState( struct NineDevice9
*This
,
2360 D3DTEXTURESTAGESTATETYPE Type
,
2363 struct nine_state
*state
= This
->update
;
2365 DBG("Stage=%u Type=%u Value=%08x\n", Stage
, Type
, Value
);
2366 nine_dump_D3DTSS_value(DBG_FF
, Type
, Value
);
2368 user_assert(Stage
< Elements(state
->ff
.tex_stage
), D3DERR_INVALIDCALL
);
2369 user_assert(Type
< Elements(state
->ff
.tex_stage
[0]), D3DERR_INVALIDCALL
);
2371 state
->ff
.tex_stage
[Stage
][Type
] = Value
;
2373 state
->changed
.group
|= NINE_STATE_FF_PSSTAGES
;
2374 state
->ff
.changed
.tex_stage
[Stage
][Type
/ 32] |= 1 << (Type
% 32);
2380 NineDevice9_GetSamplerState( struct NineDevice9
*This
,
2382 D3DSAMPLERSTATETYPE Type
,
2385 user_assert(Sampler
< This
->caps
.MaxSimultaneousTextures
||
2386 Sampler
== D3DDMAPSAMPLER
||
2387 (Sampler
>= D3DVERTEXTEXTURESAMPLER0
&&
2388 Sampler
<= D3DVERTEXTEXTURESAMPLER3
), D3DERR_INVALIDCALL
);
2390 if (Sampler
>= D3DDMAPSAMPLER
)
2391 Sampler
= Sampler
- D3DDMAPSAMPLER
+ NINE_MAX_SAMPLERS_PS
;
2393 *pValue
= This
->state
.samp
[Sampler
][Type
];
2398 NineDevice9_SetSamplerState( struct NineDevice9
*This
,
2400 D3DSAMPLERSTATETYPE Type
,
2403 struct nine_state
*state
= This
->update
;
2405 DBG("This=%p Sampler=%u Type=%s Value=%08x\n", This
,
2406 Sampler
, nine_D3DSAMP_to_str(Type
), Value
);
2408 user_assert(Sampler
< This
->caps
.MaxSimultaneousTextures
||
2409 Sampler
== D3DDMAPSAMPLER
||
2410 (Sampler
>= D3DVERTEXTEXTURESAMPLER0
&&
2411 Sampler
<= D3DVERTEXTEXTURESAMPLER3
), D3DERR_INVALIDCALL
);
2413 if (Sampler
>= D3DDMAPSAMPLER
)
2414 Sampler
= Sampler
- D3DDMAPSAMPLER
+ NINE_MAX_SAMPLERS_PS
;
2416 state
->samp
[Sampler
][Type
] = Value
;
2417 state
->changed
.group
|= NINE_STATE_SAMPLER
;
2418 state
->changed
.sampler
[Sampler
] |= 1 << Type
;
2420 if (Type
== D3DSAMP_SRGBTEXTURE
)
2421 state
->changed
.srgb
= TRUE
;
2427 NineDevice9_ValidateDevice( struct NineDevice9
*This
,
2430 const struct nine_state
*state
= &This
->state
;
2432 unsigned w
= 0, h
= 0;
2434 DBG("This=%p pNumPasses=%p\n", This
, pNumPasses
);
2436 for (i
= 0; i
< Elements(state
->samp
); ++i
) {
2437 if (state
->samp
[i
][D3DSAMP_MINFILTER
] == D3DTEXF_NONE
||
2438 state
->samp
[i
][D3DSAMP_MAGFILTER
] == D3DTEXF_NONE
)
2439 return D3DERR_UNSUPPORTEDTEXTUREFILTER
;
2442 for (i
= 0; i
< This
->caps
.NumSimultaneousRTs
; ++i
) {
2446 w
= state
->rt
[i
]->desc
.Width
;
2447 h
= state
->rt
[i
]->desc
.Height
;
2449 if (state
->rt
[i
]->desc
.Width
!= w
|| state
->rt
[i
]->desc
.Height
!= h
) {
2450 return D3DERR_CONFLICTINGRENDERSTATE
;
2454 (state
->rs
[D3DRS_ZENABLE
] || state
->rs
[D3DRS_STENCILENABLE
])) {
2456 (state
->ds
->desc
.Width
!= w
|| state
->ds
->desc
.Height
!= h
))
2457 return D3DERR_CONFLICTINGRENDERSTATE
;
2467 NineDevice9_SetPaletteEntries( struct NineDevice9
*This
,
2469 const PALETTEENTRY
*pEntries
)
2471 STUB(D3D_OK
); /* like wine */
2475 NineDevice9_GetPaletteEntries( struct NineDevice9
*This
,
2477 PALETTEENTRY
*pEntries
)
2479 STUB(D3DERR_INVALIDCALL
);
2483 NineDevice9_SetCurrentTexturePalette( struct NineDevice9
*This
,
2484 UINT PaletteNumber
)
2486 STUB(D3D_OK
); /* like wine */
2490 NineDevice9_GetCurrentTexturePalette( struct NineDevice9
*This
,
2491 UINT
*PaletteNumber
)
2493 STUB(D3DERR_INVALIDCALL
);
2497 NineDevice9_SetScissorRect( struct NineDevice9
*This
,
2500 struct nine_state
*state
= This
->update
;
2502 DBG("x=(%u..%u) y=(%u..%u)\n",
2503 pRect
->left
, pRect
->top
, pRect
->right
, pRect
->bottom
);
2505 state
->scissor
.minx
= pRect
->left
;
2506 state
->scissor
.miny
= pRect
->top
;
2507 state
->scissor
.maxx
= pRect
->right
;
2508 state
->scissor
.maxy
= pRect
->bottom
;
2510 state
->changed
.group
|= NINE_STATE_SCISSOR
;
2516 NineDevice9_GetScissorRect( struct NineDevice9
*This
,
2519 pRect
->left
= This
->state
.scissor
.minx
;
2520 pRect
->top
= This
->state
.scissor
.miny
;
2521 pRect
->right
= This
->state
.scissor
.maxx
;
2522 pRect
->bottom
= This
->state
.scissor
.maxy
;
2528 NineDevice9_SetSoftwareVertexProcessing( struct NineDevice9
*This
,
2531 STUB(D3DERR_INVALIDCALL
);
2535 NineDevice9_GetSoftwareVertexProcessing( struct NineDevice9
*This
)
2537 return !!(This
->params
.BehaviorFlags
& D3DCREATE_SOFTWARE_VERTEXPROCESSING
);
2541 NineDevice9_SetNPatchMode( struct NineDevice9
*This
,
2544 STUB(D3DERR_INVALIDCALL
);
2548 NineDevice9_GetNPatchMode( struct NineDevice9
*This
)
2554 init_draw_info(struct pipe_draw_info
*info
,
2555 struct NineDevice9
*dev
, D3DPRIMITIVETYPE type
, UINT count
)
2557 info
->mode
= d3dprimitivetype_to_pipe_prim(type
);
2558 info
->count
= prim_count_to_vertex_count(type
, count
);
2559 info
->start_instance
= 0;
2560 info
->instance_count
= 1;
2561 if (dev
->state
.stream_instancedata_mask
& dev
->state
.stream_usage_mask
)
2562 info
->instance_count
= MAX2(dev
->state
.stream_freq
[0] & 0x7FFFFF, 1);
2563 info
->primitive_restart
= FALSE
;
2564 info
->restart_index
= 0;
2565 info
->count_from_stream_output
= NULL
;
2566 info
->indirect
= NULL
;
2570 NineDevice9_DrawPrimitive( struct NineDevice9
*This
,
2571 D3DPRIMITIVETYPE PrimitiveType
,
2573 UINT PrimitiveCount
)
2575 struct pipe_draw_info info
;
2577 DBG("iface %p, PrimitiveType %u, StartVertex %u, PrimitiveCount %u\n",
2578 This
, PrimitiveType
, StartVertex
, PrimitiveCount
);
2580 nine_update_state(This
, ~0);
2582 init_draw_info(&info
, This
, PrimitiveType
, PrimitiveCount
);
2583 info
.indexed
= FALSE
;
2584 info
.start
= StartVertex
;
2585 info
.index_bias
= 0;
2586 info
.min_index
= info
.start
;
2587 info
.max_index
= info
.count
- 1;
2589 This
->pipe
->draw_vbo(This
->pipe
, &info
);
2595 NineDevice9_DrawIndexedPrimitive( struct NineDevice9
*This
,
2596 D3DPRIMITIVETYPE PrimitiveType
,
2597 INT BaseVertexIndex
,
2598 UINT MinVertexIndex
,
2601 UINT PrimitiveCount
)
2603 struct pipe_draw_info info
;
2605 DBG("iface %p, PrimitiveType %u, BaseVertexIndex %u, MinVertexIndex %u "
2606 "NumVertices %u, StartIndex %u, PrimitiveCount %u\n",
2607 This
, PrimitiveType
, BaseVertexIndex
, MinVertexIndex
, NumVertices
,
2608 StartIndex
, PrimitiveCount
);
2610 user_assert(This
->state
.idxbuf
, D3DERR_INVALIDCALL
);
2611 user_assert(This
->state
.vdecl
, D3DERR_INVALIDCALL
);
2613 nine_update_state(This
, ~0);
2615 init_draw_info(&info
, This
, PrimitiveType
, PrimitiveCount
);
2616 info
.indexed
= TRUE
;
2617 info
.start
= StartIndex
;
2618 info
.index_bias
= BaseVertexIndex
;
2619 /* These don't include index bias: */
2620 info
.min_index
= MinVertexIndex
;
2621 info
.max_index
= MinVertexIndex
+ NumVertices
- 1;
2623 This
->pipe
->draw_vbo(This
->pipe
, &info
);
2629 NineDevice9_DrawPrimitiveUP( struct NineDevice9
*This
,
2630 D3DPRIMITIVETYPE PrimitiveType
,
2631 UINT PrimitiveCount
,
2632 const void *pVertexStreamZeroData
,
2633 UINT VertexStreamZeroStride
)
2635 struct pipe_vertex_buffer vtxbuf
;
2636 struct pipe_draw_info info
;
2638 DBG("iface %p, PrimitiveType %u, PrimitiveCount %u, data %p, stride %u\n",
2639 This
, PrimitiveType
, PrimitiveCount
,
2640 pVertexStreamZeroData
, VertexStreamZeroStride
);
2642 user_assert(pVertexStreamZeroData
&& VertexStreamZeroStride
,
2643 D3DERR_INVALIDCALL
);
2645 nine_update_state(This
, ~0);
2647 init_draw_info(&info
, This
, PrimitiveType
, PrimitiveCount
);
2648 info
.indexed
= FALSE
;
2650 info
.index_bias
= 0;
2652 info
.max_index
= info
.count
- 1;
2654 vtxbuf
.stride
= VertexStreamZeroStride
;
2655 vtxbuf
.buffer_offset
= 0;
2656 vtxbuf
.buffer
= NULL
;
2657 vtxbuf
.user_buffer
= pVertexStreamZeroData
;
2659 if (!This
->driver_caps
.user_vbufs
)
2660 u_upload_data(This
->upload
,
2662 (info
.max_index
+ 1) * VertexStreamZeroStride
, /* XXX */
2664 &vtxbuf
.buffer_offset
,
2667 This
->pipe
->set_vertex_buffers(This
->pipe
, 0, 1, &vtxbuf
);
2669 This
->pipe
->draw_vbo(This
->pipe
, &info
);
2671 NineDevice9_PauseRecording(This
);
2672 NineDevice9_SetStreamSource(This
, 0, NULL
, 0, 0);
2673 NineDevice9_ResumeRecording(This
);
2675 pipe_resource_reference(&vtxbuf
.buffer
, NULL
);
2681 NineDevice9_DrawIndexedPrimitiveUP( struct NineDevice9
*This
,
2682 D3DPRIMITIVETYPE PrimitiveType
,
2683 UINT MinVertexIndex
,
2685 UINT PrimitiveCount
,
2686 const void *pIndexData
,
2687 D3DFORMAT IndexDataFormat
,
2688 const void *pVertexStreamZeroData
,
2689 UINT VertexStreamZeroStride
)
2691 struct pipe_draw_info info
;
2692 struct pipe_vertex_buffer vbuf
;
2693 struct pipe_index_buffer ibuf
;
2695 DBG("iface %p, PrimitiveType %u, MinVertexIndex %u, NumVertices %u "
2696 "PrimitiveCount %u, pIndexData %p, IndexDataFormat %u "
2697 "pVertexStreamZeroData %p, VertexStreamZeroStride %u\n",
2698 This
, PrimitiveType
, MinVertexIndex
, NumVertices
, PrimitiveCount
,
2699 pIndexData
, IndexDataFormat
,
2700 pVertexStreamZeroData
, VertexStreamZeroStride
);
2702 user_assert(pIndexData
&& pVertexStreamZeroData
, D3DERR_INVALIDCALL
);
2703 user_assert(VertexStreamZeroStride
, D3DERR_INVALIDCALL
);
2704 user_assert(IndexDataFormat
== D3DFMT_INDEX16
||
2705 IndexDataFormat
== D3DFMT_INDEX32
, D3DERR_INVALIDCALL
);
2707 nine_update_state(This
, ~0);
2709 init_draw_info(&info
, This
, PrimitiveType
, PrimitiveCount
);
2710 info
.indexed
= TRUE
;
2712 info
.index_bias
= 0;
2713 info
.min_index
= MinVertexIndex
;
2714 info
.max_index
= MinVertexIndex
+ NumVertices
- 1;
2716 vbuf
.stride
= VertexStreamZeroStride
;
2717 vbuf
.buffer_offset
= 0;
2719 vbuf
.user_buffer
= pVertexStreamZeroData
;
2721 ibuf
.index_size
= (IndexDataFormat
== D3DFMT_INDEX16
) ? 2 : 4;
2724 ibuf
.user_buffer
= pIndexData
;
2726 if (!This
->driver_caps
.user_vbufs
) {
2727 const unsigned base
= info
.min_index
* VertexStreamZeroStride
;
2728 u_upload_data(This
->upload
,
2731 info
.min_index
+ 1) * VertexStreamZeroStride
, /* XXX */
2732 (const uint8_t *)vbuf
.user_buffer
+ base
,
2733 &vbuf
.buffer_offset
,
2735 /* Won't be used: */
2736 vbuf
.buffer_offset
-= base
;
2738 if (!This
->driver_caps
.user_ibufs
)
2739 u_upload_data(This
->upload
,
2741 info
.count
* ibuf
.index_size
,
2746 This
->pipe
->set_vertex_buffers(This
->pipe
, 0, 1, &vbuf
);
2747 This
->pipe
->set_index_buffer(This
->pipe
, &ibuf
);
2749 This
->pipe
->draw_vbo(This
->pipe
, &info
);
2751 pipe_resource_reference(&vbuf
.buffer
, NULL
);
2752 pipe_resource_reference(&ibuf
.buffer
, NULL
);
2754 NineDevice9_PauseRecording(This
);
2755 NineDevice9_SetIndices(This
, NULL
);
2756 NineDevice9_SetStreamSource(This
, 0, NULL
, 0, 0);
2757 NineDevice9_ResumeRecording(This
);
2762 /* TODO: Write to pDestBuffer directly if vertex declaration contains
2766 NineDevice9_ProcessVertices( struct NineDevice9
*This
,
2770 IDirect3DVertexBuffer9
*pDestBuffer
,
2771 IDirect3DVertexDeclaration9
*pVertexDecl
,
2774 struct pipe_screen
*screen
= This
->screen
;
2775 struct NineVertexDeclaration9
*vdecl
= NineVertexDeclaration9(pVertexDecl
);
2776 struct NineVertexShader9
*vs
;
2777 struct pipe_resource
*resource
;
2778 struct pipe_stream_output_target
*target
;
2779 struct pipe_draw_info draw
;
2781 unsigned buffer_offset
, buffer_size
;
2783 DBG("This=%p SrcStartIndex=%u DestIndex=%u VertexCount=%u "
2784 "pDestBuffer=%p pVertexDecl=%p Flags=%d\n",
2785 This
, SrcStartIndex
, DestIndex
, VertexCount
, pDestBuffer
,
2786 pVertexDecl
, Flags
);
2788 if (!screen
->get_param(screen
, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS
))
2789 STUB(D3DERR_INVALIDCALL
);
2791 nine_update_state(This
, ~0);
2793 /* TODO: Create shader with stream output. */
2794 STUB(D3DERR_INVALIDCALL
);
2795 struct NineVertexBuffer9
*dst
= NineVertexBuffer9(pDestBuffer
);
2797 vs
= This
->state
.vs
? This
->state
.vs
: This
->ff
.vs
;
2799 buffer_size
= VertexCount
* vs
->so
->stride
[0];
2801 struct pipe_resource templ
;
2803 templ
.target
= PIPE_BUFFER
;
2804 templ
.format
= PIPE_FORMAT_R8_UNORM
;
2805 templ
.width0
= buffer_size
;
2807 templ
.bind
= PIPE_BIND_STREAM_OUTPUT
;
2808 templ
.usage
= PIPE_USAGE_STREAM
;
2809 templ
.height0
= templ
.depth0
= templ
.array_size
= 1;
2810 templ
.last_level
= templ
.nr_samples
= 0;
2812 resource
= This
->screen
->resource_create(This
->screen
, &templ
);
2814 return E_OUTOFMEMORY
;
2817 /* SO matches vertex declaration */
2818 resource
= dst
->base
.resource
;
2819 buffer_offset
= DestIndex
* vs
->so
->stride
[0];
2821 target
= This
->pipe
->create_stream_output_target(This
->pipe
, resource
,
2825 pipe_resource_reference(&resource
, NULL
);
2826 return D3DERR_DRIVERINTERNALERROR
;
2830 hr
= NineVertexDeclaration9_new_from_fvf(This
, dst
->desc
.FVF
, &vdecl
);
2835 init_draw_info(&draw
, This
, D3DPT_POINTLIST
, VertexCount
);
2836 draw
.instance_count
= 1;
2837 draw
.indexed
= FALSE
;
2838 draw
.start
= SrcStartIndex
;
2839 draw
.index_bias
= 0;
2840 draw
.min_index
= SrcStartIndex
;
2841 draw
.max_index
= SrcStartIndex
+ VertexCount
- 1;
2843 This
->pipe
->set_stream_output_targets(This
->pipe
, 1, &target
, 0);
2844 This
->pipe
->draw_vbo(This
->pipe
, &draw
);
2845 This
->pipe
->set_stream_output_targets(This
->pipe
, 0, NULL
, 0);
2846 This
->pipe
->stream_output_target_destroy(This
->pipe
, target
);
2848 hr
= NineVertexDeclaration9_ConvertStreamOutput(vdecl
,
2849 dst
, DestIndex
, VertexCount
,
2852 pipe_resource_reference(&resource
, NULL
);
2854 NineUnknown_Release(NineUnknown(vdecl
));
2859 NineDevice9_CreateVertexDeclaration( struct NineDevice9
*This
,
2860 const D3DVERTEXELEMENT9
*pVertexElements
,
2861 IDirect3DVertexDeclaration9
**ppDecl
)
2863 struct NineVertexDeclaration9
*vdecl
;
2865 DBG("This=%p pVertexElements=%p ppDecl=%p\n",
2866 This
, pVertexElements
, ppDecl
);
2868 HRESULT hr
= NineVertexDeclaration9_new(This
, pVertexElements
, &vdecl
);
2870 *ppDecl
= (IDirect3DVertexDeclaration9
*)vdecl
;
2876 NineDevice9_SetVertexDeclaration( struct NineDevice9
*This
,
2877 IDirect3DVertexDeclaration9
*pDecl
)
2879 struct nine_state
*state
= This
->update
;
2881 DBG("This=%p pDecl=%p\n", This
, pDecl
);
2883 if (likely(!This
->is_recording
) && state
->vdecl
== NineVertexDeclaration9(pDecl
))
2885 nine_bind(&state
->vdecl
, pDecl
);
2887 state
->changed
.group
|= NINE_STATE_VDECL
;
2893 NineDevice9_GetVertexDeclaration( struct NineDevice9
*This
,
2894 IDirect3DVertexDeclaration9
**ppDecl
)
2896 user_assert(ppDecl
, D3DERR_INVALIDCALL
);
2898 *ppDecl
= (IDirect3DVertexDeclaration9
*)This
->state
.vdecl
;
2900 NineUnknown_AddRef(NineUnknown(*ppDecl
));
2905 NineDevice9_SetFVF( struct NineDevice9
*This
,
2908 struct NineVertexDeclaration9
*vdecl
;
2911 DBG("FVF = %08x\n", FVF
);
2913 return D3D_OK
; /* like wine */
2915 vdecl
= util_hash_table_get(This
->ff
.ht_fvf
, &FVF
);
2917 hr
= NineVertexDeclaration9_new_from_fvf(This
, FVF
, &vdecl
);
2921 util_hash_table_set(This
->ff
.ht_fvf
, &vdecl
->fvf
, vdecl
);
2922 NineUnknown_ConvertRefToBind(NineUnknown(vdecl
));
2924 return NineDevice9_SetVertexDeclaration(
2925 This
, (IDirect3DVertexDeclaration9
*)vdecl
);
2929 NineDevice9_GetFVF( struct NineDevice9
*This
,
2932 *pFVF
= This
->state
.vdecl
? This
->state
.vdecl
->fvf
: 0;
2937 NineDevice9_CreateVertexShader( struct NineDevice9
*This
,
2938 const DWORD
*pFunction
,
2939 IDirect3DVertexShader9
**ppShader
)
2941 struct NineVertexShader9
*vs
;
2944 DBG("This=%p pFunction=%p ppShader=%p\n", This
, pFunction
, ppShader
);
2946 hr
= NineVertexShader9_new(This
, &vs
, pFunction
, NULL
);
2949 *ppShader
= (IDirect3DVertexShader9
*)vs
;
2954 NineDevice9_SetVertexShader( struct NineDevice9
*This
,
2955 IDirect3DVertexShader9
*pShader
)
2957 struct nine_state
*state
= This
->update
;
2959 DBG("This=%p pShader=%p\n", This
, pShader
);
2961 nine_bind(&state
->vs
, pShader
);
2963 state
->changed
.group
|= NINE_STATE_VS
;
2969 NineDevice9_GetVertexShader( struct NineDevice9
*This
,
2970 IDirect3DVertexShader9
**ppShader
)
2972 user_assert(ppShader
, D3DERR_INVALIDCALL
);
2973 nine_reference_set(ppShader
, This
->state
.vs
);
2978 NineDevice9_SetVertexShaderConstantF( struct NineDevice9
*This
,
2980 const float *pConstantData
,
2981 UINT Vector4fCount
)
2983 struct nine_state
*state
= This
->update
;
2985 DBG("This=%p StartRegister=%u pConstantData=%p Vector4fCount=%u\n",
2986 This
, StartRegister
, pConstantData
, Vector4fCount
);
2988 user_assert(StartRegister
< This
->caps
.MaxVertexShaderConst
, D3DERR_INVALIDCALL
);
2989 user_assert(StartRegister
+ Vector4fCount
<= This
->caps
.MaxVertexShaderConst
, D3DERR_INVALIDCALL
);
2993 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
2995 memcpy(&state
->vs_const_f
[StartRegister
* 4],
2997 Vector4fCount
* 4 * sizeof(state
->vs_const_f
[0]));
2999 nine_ranges_insert(&state
->changed
.vs_const_f
,
3000 StartRegister
, StartRegister
+ Vector4fCount
,
3003 state
->changed
.group
|= NINE_STATE_VS_CONST
;
3009 NineDevice9_GetVertexShaderConstantF( struct NineDevice9
*This
,
3011 float *pConstantData
,
3012 UINT Vector4fCount
)
3014 const struct nine_state
*state
= &This
->state
;
3016 user_assert(StartRegister
< This
->caps
.MaxVertexShaderConst
, D3DERR_INVALIDCALL
);
3017 user_assert(StartRegister
+ Vector4fCount
<= This
->caps
.MaxVertexShaderConst
, D3DERR_INVALIDCALL
);
3018 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3020 memcpy(pConstantData
,
3021 &state
->vs_const_f
[StartRegister
* 4],
3022 Vector4fCount
* 4 * sizeof(state
->vs_const_f
[0]));
3028 NineDevice9_SetVertexShaderConstantI( struct NineDevice9
*This
,
3030 const int *pConstantData
,
3031 UINT Vector4iCount
)
3033 struct nine_state
*state
= This
->update
;
3036 DBG("This=%p StartRegister=%u pConstantData=%p Vector4iCount=%u\n",
3037 This
, StartRegister
, pConstantData
, Vector4iCount
);
3039 user_assert(StartRegister
< NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3040 user_assert(StartRegister
+ Vector4iCount
<= NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3041 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3043 if (This
->driver_caps
.vs_integer
) {
3044 memcpy(&state
->vs_const_i
[StartRegister
][0],
3046 Vector4iCount
* sizeof(state
->vs_const_i
[0]));
3048 for (i
= 0; i
< Vector4iCount
; i
++) {
3049 state
->vs_const_i
[StartRegister
+i
][0] = fui((float)(pConstantData
[4*i
]));
3050 state
->vs_const_i
[StartRegister
+i
][1] = fui((float)(pConstantData
[4*i
+1]));
3051 state
->vs_const_i
[StartRegister
+i
][2] = fui((float)(pConstantData
[4*i
+2]));
3052 state
->vs_const_i
[StartRegister
+i
][3] = fui((float)(pConstantData
[4*i
+3]));
3056 state
->changed
.vs_const_i
|= ((1 << Vector4iCount
) - 1) << StartRegister
;
3057 state
->changed
.group
|= NINE_STATE_VS_CONST
;
3063 NineDevice9_GetVertexShaderConstantI( struct NineDevice9
*This
,
3066 UINT Vector4iCount
)
3068 const struct nine_state
*state
= &This
->state
;
3071 user_assert(StartRegister
< NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3072 user_assert(StartRegister
+ Vector4iCount
<= NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3073 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3075 if (This
->driver_caps
.vs_integer
) {
3076 memcpy(pConstantData
,
3077 &state
->vs_const_i
[StartRegister
][0],
3078 Vector4iCount
* sizeof(state
->vs_const_i
[0]));
3080 for (i
= 0; i
< Vector4iCount
; i
++) {
3081 pConstantData
[4*i
] = (int32_t) uif(state
->vs_const_i
[StartRegister
+i
][0]);
3082 pConstantData
[4*i
+1] = (int32_t) uif(state
->vs_const_i
[StartRegister
+i
][1]);
3083 pConstantData
[4*i
+2] = (int32_t) uif(state
->vs_const_i
[StartRegister
+i
][2]);
3084 pConstantData
[4*i
+3] = (int32_t) uif(state
->vs_const_i
[StartRegister
+i
][3]);
3092 NineDevice9_SetVertexShaderConstantB( struct NineDevice9
*This
,
3094 const BOOL
*pConstantData
,
3097 struct nine_state
*state
= This
->update
;
3099 uint32_t bool_true
= This
->driver_caps
.vs_integer
? 0xFFFFFFFF : fui(1.0f
);
3101 DBG("This=%p StartRegister=%u pConstantData=%p BoolCount=%u\n",
3102 This
, StartRegister
, pConstantData
, BoolCount
);
3104 user_assert(StartRegister
< NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3105 user_assert(StartRegister
+ BoolCount
<= NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3106 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3108 for (i
= 0; i
< BoolCount
; i
++)
3109 state
->vs_const_b
[StartRegister
+ i
] = pConstantData
[i
] ? bool_true
: 0;
3111 state
->changed
.vs_const_b
|= ((1 << BoolCount
) - 1) << StartRegister
;
3112 state
->changed
.group
|= NINE_STATE_VS_CONST
;
3118 NineDevice9_GetVertexShaderConstantB( struct NineDevice9
*This
,
3120 BOOL
*pConstantData
,
3123 const struct nine_state
*state
= &This
->state
;
3126 user_assert(StartRegister
< NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3127 user_assert(StartRegister
+ BoolCount
<= NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3128 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3130 for (i
= 0; i
< BoolCount
; i
++)
3131 pConstantData
[i
] = state
->vs_const_b
[StartRegister
+ i
] != 0 ? TRUE
: FALSE
;
3137 NineDevice9_SetStreamSource( struct NineDevice9
*This
,
3139 IDirect3DVertexBuffer9
*pStreamData
,
3143 struct nine_state
*state
= This
->update
;
3144 struct NineVertexBuffer9
*pVBuf9
= NineVertexBuffer9(pStreamData
);
3145 const unsigned i
= StreamNumber
;
3147 DBG("This=%p StreamNumber=%u pStreamData=%p OffsetInBytes=%u Stride=%u\n",
3148 This
, StreamNumber
, pStreamData
, OffsetInBytes
, Stride
);
3150 user_assert(StreamNumber
< This
->caps
.MaxStreams
, D3DERR_INVALIDCALL
);
3151 user_assert(Stride
<= This
->caps
.MaxStreamStride
, D3DERR_INVALIDCALL
);
3153 if (likely(!This
->is_recording
)) {
3154 if (state
->stream
[i
] == NineVertexBuffer9(pStreamData
) &&
3155 state
->vtxbuf
[i
].stride
== Stride
&&
3156 state
->vtxbuf
[i
].buffer_offset
== OffsetInBytes
)
3159 nine_bind(&state
->stream
[i
], pStreamData
);
3161 state
->changed
.vtxbuf
|= 1 << StreamNumber
;
3164 state
->vtxbuf
[i
].stride
= Stride
;
3165 state
->vtxbuf
[i
].buffer_offset
= OffsetInBytes
;
3167 state
->vtxbuf
[i
].buffer
= pStreamData
? pVBuf9
->base
.resource
: NULL
;
3173 NineDevice9_GetStreamSource( struct NineDevice9
*This
,
3175 IDirect3DVertexBuffer9
**ppStreamData
,
3176 UINT
*pOffsetInBytes
,
3179 const struct nine_state
*state
= &This
->state
;
3180 const unsigned i
= StreamNumber
;
3182 user_assert(StreamNumber
< This
->caps
.MaxStreams
, D3DERR_INVALIDCALL
);
3183 user_assert(ppStreamData
, D3DERR_INVALIDCALL
);
3185 nine_reference_set(ppStreamData
, state
->stream
[i
]);
3186 *pStride
= state
->vtxbuf
[i
].stride
;
3187 *pOffsetInBytes
= state
->vtxbuf
[i
].buffer_offset
;
3193 NineDevice9_SetStreamSourceFreq( struct NineDevice9
*This
,
3197 struct nine_state
*state
= This
->update
;
3198 /* const UINT freq = Setting & 0x7FFFFF; */
3200 DBG("This=%p StreamNumber=%u FrequencyParameter=0x%x\n", This
,
3201 StreamNumber
, Setting
);
3203 user_assert(StreamNumber
< This
->caps
.MaxStreams
, D3DERR_INVALIDCALL
);
3204 user_assert(StreamNumber
!= 0 || !(Setting
& D3DSTREAMSOURCE_INSTANCEDATA
),
3205 D3DERR_INVALIDCALL
);
3206 user_assert(!((Setting
& D3DSTREAMSOURCE_INSTANCEDATA
) &&
3207 (Setting
& D3DSTREAMSOURCE_INDEXEDDATA
)), D3DERR_INVALIDCALL
);
3208 user_assert(Setting
, D3DERR_INVALIDCALL
);
3210 state
->stream_freq
[StreamNumber
] = Setting
;
3212 if (Setting
& D3DSTREAMSOURCE_INSTANCEDATA
)
3213 state
->stream_instancedata_mask
|= 1 << StreamNumber
;
3215 state
->stream_instancedata_mask
&= ~(1 << StreamNumber
);
3217 state
->changed
.stream_freq
|= 1 << StreamNumber
;
3222 NineDevice9_GetStreamSourceFreq( struct NineDevice9
*This
,
3226 user_assert(StreamNumber
< This
->caps
.MaxStreams
, D3DERR_INVALIDCALL
);
3227 *pSetting
= This
->state
.stream_freq
[StreamNumber
];
3232 NineDevice9_SetIndices( struct NineDevice9
*This
,
3233 IDirect3DIndexBuffer9
*pIndexData
)
3235 struct nine_state
*state
= This
->update
;
3237 DBG("This=%p pIndexData=%p\n", This
, pIndexData
);
3239 if (likely(!This
->is_recording
))
3240 if (state
->idxbuf
== NineIndexBuffer9(pIndexData
))
3242 nine_bind(&state
->idxbuf
, pIndexData
);
3244 state
->changed
.group
|= NINE_STATE_IDXBUF
;
3249 /* XXX: wine/d3d9 doesn't have pBaseVertexIndex, and it doesn't make sense
3250 * here because it's an argument passed to the Draw calls.
3253 NineDevice9_GetIndices( struct NineDevice9
*This
,
3254 IDirect3DIndexBuffer9
**ppIndexData
/*,
3255 UINT *pBaseVertexIndex */ )
3257 user_assert(ppIndexData
, D3DERR_INVALIDCALL
);
3258 nine_reference_set(ppIndexData
, This
->state
.idxbuf
);
3263 NineDevice9_CreatePixelShader( struct NineDevice9
*This
,
3264 const DWORD
*pFunction
,
3265 IDirect3DPixelShader9
**ppShader
)
3267 struct NinePixelShader9
*ps
;
3270 DBG("This=%p pFunction=%p ppShader=%p\n", This
, pFunction
, ppShader
);
3272 hr
= NinePixelShader9_new(This
, &ps
, pFunction
, NULL
);
3275 *ppShader
= (IDirect3DPixelShader9
*)ps
;
3280 NineDevice9_SetPixelShader( struct NineDevice9
*This
,
3281 IDirect3DPixelShader9
*pShader
)
3283 struct nine_state
*state
= This
->update
;
3285 DBG("This=%p pShader=%p\n", This
, pShader
);
3287 nine_bind(&state
->ps
, pShader
);
3289 state
->changed
.group
|= NINE_STATE_PS
;
3295 NineDevice9_GetPixelShader( struct NineDevice9
*This
,
3296 IDirect3DPixelShader9
**ppShader
)
3298 user_assert(ppShader
, D3DERR_INVALIDCALL
);
3299 nine_reference_set(ppShader
, This
->state
.ps
);
3304 NineDevice9_SetPixelShaderConstantF( struct NineDevice9
*This
,
3306 const float *pConstantData
,
3307 UINT Vector4fCount
)
3309 struct nine_state
*state
= This
->update
;
3311 DBG("This=%p StartRegister=%u pConstantData=%p Vector4fCount=%u\n",
3312 This
, StartRegister
, pConstantData
, Vector4fCount
);
3314 user_assert(StartRegister
< NINE_MAX_CONST_F_PS3
, D3DERR_INVALIDCALL
);
3315 user_assert(StartRegister
+ Vector4fCount
<= NINE_MAX_CONST_F_PS3
, D3DERR_INVALIDCALL
);
3319 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3321 memcpy(&state
->ps_const_f
[StartRegister
* 4],
3323 Vector4fCount
* 4 * sizeof(state
->ps_const_f
[0]));
3325 nine_ranges_insert(&state
->changed
.ps_const_f
,
3326 StartRegister
, StartRegister
+ Vector4fCount
,
3329 state
->changed
.group
|= NINE_STATE_PS_CONST
;
3335 NineDevice9_GetPixelShaderConstantF( struct NineDevice9
*This
,
3337 float *pConstantData
,
3338 UINT Vector4fCount
)
3340 const struct nine_state
*state
= &This
->state
;
3342 user_assert(StartRegister
< NINE_MAX_CONST_F_PS3
, D3DERR_INVALIDCALL
);
3343 user_assert(StartRegister
+ Vector4fCount
<= NINE_MAX_CONST_F_PS3
, D3DERR_INVALIDCALL
);
3344 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3346 memcpy(pConstantData
,
3347 &state
->ps_const_f
[StartRegister
* 4],
3348 Vector4fCount
* 4 * sizeof(state
->ps_const_f
[0]));
3354 NineDevice9_SetPixelShaderConstantI( struct NineDevice9
*This
,
3356 const int *pConstantData
,
3357 UINT Vector4iCount
)
3359 struct nine_state
*state
= This
->update
;
3362 DBG("This=%p StartRegister=%u pConstantData=%p Vector4iCount=%u\n",
3363 This
, StartRegister
, pConstantData
, Vector4iCount
);
3365 user_assert(StartRegister
< NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3366 user_assert(StartRegister
+ Vector4iCount
<= NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3367 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3369 if (This
->driver_caps
.ps_integer
) {
3370 memcpy(&state
->ps_const_i
[StartRegister
][0],
3372 Vector4iCount
* sizeof(state
->ps_const_i
[0]));
3374 for (i
= 0; i
< Vector4iCount
; i
++) {
3375 state
->ps_const_i
[StartRegister
+i
][0] = fui((float)(pConstantData
[4*i
]));
3376 state
->ps_const_i
[StartRegister
+i
][1] = fui((float)(pConstantData
[4*i
+1]));
3377 state
->ps_const_i
[StartRegister
+i
][2] = fui((float)(pConstantData
[4*i
+2]));
3378 state
->ps_const_i
[StartRegister
+i
][3] = fui((float)(pConstantData
[4*i
+3]));
3381 state
->changed
.ps_const_i
|= ((1 << Vector4iCount
) - 1) << StartRegister
;
3382 state
->changed
.group
|= NINE_STATE_PS_CONST
;
3388 NineDevice9_GetPixelShaderConstantI( struct NineDevice9
*This
,
3391 UINT Vector4iCount
)
3393 const struct nine_state
*state
= &This
->state
;
3396 user_assert(StartRegister
< NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3397 user_assert(StartRegister
+ Vector4iCount
<= NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3398 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3400 if (This
->driver_caps
.ps_integer
) {
3401 memcpy(pConstantData
,
3402 &state
->ps_const_i
[StartRegister
][0],
3403 Vector4iCount
* sizeof(state
->ps_const_i
[0]));
3405 for (i
= 0; i
< Vector4iCount
; i
++) {
3406 pConstantData
[4*i
] = (int32_t) uif(state
->ps_const_i
[StartRegister
+i
][0]);
3407 pConstantData
[4*i
+1] = (int32_t) uif(state
->ps_const_i
[StartRegister
+i
][1]);
3408 pConstantData
[4*i
+2] = (int32_t) uif(state
->ps_const_i
[StartRegister
+i
][2]);
3409 pConstantData
[4*i
+3] = (int32_t) uif(state
->ps_const_i
[StartRegister
+i
][3]);
3417 NineDevice9_SetPixelShaderConstantB( struct NineDevice9
*This
,
3419 const BOOL
*pConstantData
,
3422 struct nine_state
*state
= This
->update
;
3424 uint32_t bool_true
= This
->driver_caps
.ps_integer
? 0xFFFFFFFF : fui(1.0f
);
3426 DBG("This=%p StartRegister=%u pConstantData=%p BoolCount=%u\n",
3427 This
, StartRegister
, pConstantData
, BoolCount
);
3429 user_assert(StartRegister
< NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3430 user_assert(StartRegister
+ BoolCount
<= NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3431 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3433 for (i
= 0; i
< BoolCount
; i
++)
3434 state
->ps_const_b
[StartRegister
+ i
] = pConstantData
[i
] ? bool_true
: 0;
3436 state
->changed
.ps_const_b
|= ((1 << BoolCount
) - 1) << StartRegister
;
3437 state
->changed
.group
|= NINE_STATE_PS_CONST
;
3443 NineDevice9_GetPixelShaderConstantB( struct NineDevice9
*This
,
3445 BOOL
*pConstantData
,
3448 const struct nine_state
*state
= &This
->state
;
3451 user_assert(StartRegister
< NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3452 user_assert(StartRegister
+ BoolCount
<= NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3453 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3455 for (i
= 0; i
< BoolCount
; i
++)
3456 pConstantData
[i
] = state
->ps_const_b
[StartRegister
+ i
] ? TRUE
: FALSE
;
3462 NineDevice9_DrawRectPatch( struct NineDevice9
*This
,
3464 const float *pNumSegs
,
3465 const D3DRECTPATCH_INFO
*pRectPatchInfo
)
3467 STUB(D3DERR_INVALIDCALL
);
3471 NineDevice9_DrawTriPatch( struct NineDevice9
*This
,
3473 const float *pNumSegs
,
3474 const D3DTRIPATCH_INFO
*pTriPatchInfo
)
3476 STUB(D3DERR_INVALIDCALL
);
3480 NineDevice9_DeletePatch( struct NineDevice9
*This
,
3483 STUB(D3DERR_INVALIDCALL
);
3487 NineDevice9_CreateQuery( struct NineDevice9
*This
,
3489 IDirect3DQuery9
**ppQuery
)
3491 struct NineQuery9
*query
;
3494 DBG("This=%p Type=%d ppQuery=%p\n", This
, Type
, ppQuery
);
3496 hr
= nine_is_query_supported(This
->screen
, Type
);
3497 if (!ppQuery
|| hr
!= D3D_OK
)
3500 hr
= NineQuery9_new(This
, &query
, Type
);
3503 *ppQuery
= (IDirect3DQuery9
*)query
;
3507 IDirect3DDevice9Vtbl NineDevice9_vtable
= {
3508 (void *)NineUnknown_QueryInterface
,
3509 (void *)NineUnknown_AddRef
,
3510 (void *)NineUnknown_Release
,
3511 (void *)NineDevice9_TestCooperativeLevel
,
3512 (void *)NineDevice9_GetAvailableTextureMem
,
3513 (void *)NineDevice9_EvictManagedResources
,
3514 (void *)NineDevice9_GetDirect3D
,
3515 (void *)NineDevice9_GetDeviceCaps
,
3516 (void *)NineDevice9_GetDisplayMode
,
3517 (void *)NineDevice9_GetCreationParameters
,
3518 (void *)NineDevice9_SetCursorProperties
,
3519 (void *)NineDevice9_SetCursorPosition
,
3520 (void *)NineDevice9_ShowCursor
,
3521 (void *)NineDevice9_CreateAdditionalSwapChain
,
3522 (void *)NineDevice9_GetSwapChain
,
3523 (void *)NineDevice9_GetNumberOfSwapChains
,
3524 (void *)NineDevice9_Reset
,
3525 (void *)NineDevice9_Present
,
3526 (void *)NineDevice9_GetBackBuffer
,
3527 (void *)NineDevice9_GetRasterStatus
,
3528 (void *)NineDevice9_SetDialogBoxMode
,
3529 (void *)NineDevice9_SetGammaRamp
,
3530 (void *)NineDevice9_GetGammaRamp
,
3531 (void *)NineDevice9_CreateTexture
,
3532 (void *)NineDevice9_CreateVolumeTexture
,
3533 (void *)NineDevice9_CreateCubeTexture
,
3534 (void *)NineDevice9_CreateVertexBuffer
,
3535 (void *)NineDevice9_CreateIndexBuffer
,
3536 (void *)NineDevice9_CreateRenderTarget
,
3537 (void *)NineDevice9_CreateDepthStencilSurface
,
3538 (void *)NineDevice9_UpdateSurface
,
3539 (void *)NineDevice9_UpdateTexture
,
3540 (void *)NineDevice9_GetRenderTargetData
,
3541 (void *)NineDevice9_GetFrontBufferData
,
3542 (void *)NineDevice9_StretchRect
,
3543 (void *)NineDevice9_ColorFill
,
3544 (void *)NineDevice9_CreateOffscreenPlainSurface
,
3545 (void *)NineDevice9_SetRenderTarget
,
3546 (void *)NineDevice9_GetRenderTarget
,
3547 (void *)NineDevice9_SetDepthStencilSurface
,
3548 (void *)NineDevice9_GetDepthStencilSurface
,
3549 (void *)NineDevice9_BeginScene
,
3550 (void *)NineDevice9_EndScene
,
3551 (void *)NineDevice9_Clear
,
3552 (void *)NineDevice9_SetTransform
,
3553 (void *)NineDevice9_GetTransform
,
3554 (void *)NineDevice9_MultiplyTransform
,
3555 (void *)NineDevice9_SetViewport
,
3556 (void *)NineDevice9_GetViewport
,
3557 (void *)NineDevice9_SetMaterial
,
3558 (void *)NineDevice9_GetMaterial
,
3559 (void *)NineDevice9_SetLight
,
3560 (void *)NineDevice9_GetLight
,
3561 (void *)NineDevice9_LightEnable
,
3562 (void *)NineDevice9_GetLightEnable
,
3563 (void *)NineDevice9_SetClipPlane
,
3564 (void *)NineDevice9_GetClipPlane
,
3565 (void *)NineDevice9_SetRenderState
,
3566 (void *)NineDevice9_GetRenderState
,
3567 (void *)NineDevice9_CreateStateBlock
,
3568 (void *)NineDevice9_BeginStateBlock
,
3569 (void *)NineDevice9_EndStateBlock
,
3570 (void *)NineDevice9_SetClipStatus
,
3571 (void *)NineDevice9_GetClipStatus
,
3572 (void *)NineDevice9_GetTexture
,
3573 (void *)NineDevice9_SetTexture
,
3574 (void *)NineDevice9_GetTextureStageState
,
3575 (void *)NineDevice9_SetTextureStageState
,
3576 (void *)NineDevice9_GetSamplerState
,
3577 (void *)NineDevice9_SetSamplerState
,
3578 (void *)NineDevice9_ValidateDevice
,
3579 (void *)NineDevice9_SetPaletteEntries
,
3580 (void *)NineDevice9_GetPaletteEntries
,
3581 (void *)NineDevice9_SetCurrentTexturePalette
,
3582 (void *)NineDevice9_GetCurrentTexturePalette
,
3583 (void *)NineDevice9_SetScissorRect
,
3584 (void *)NineDevice9_GetScissorRect
,
3585 (void *)NineDevice9_SetSoftwareVertexProcessing
,
3586 (void *)NineDevice9_GetSoftwareVertexProcessing
,
3587 (void *)NineDevice9_SetNPatchMode
,
3588 (void *)NineDevice9_GetNPatchMode
,
3589 (void *)NineDevice9_DrawPrimitive
,
3590 (void *)NineDevice9_DrawIndexedPrimitive
,
3591 (void *)NineDevice9_DrawPrimitiveUP
,
3592 (void *)NineDevice9_DrawIndexedPrimitiveUP
,
3593 (void *)NineDevice9_ProcessVertices
,
3594 (void *)NineDevice9_CreateVertexDeclaration
,
3595 (void *)NineDevice9_SetVertexDeclaration
,
3596 (void *)NineDevice9_GetVertexDeclaration
,
3597 (void *)NineDevice9_SetFVF
,
3598 (void *)NineDevice9_GetFVF
,
3599 (void *)NineDevice9_CreateVertexShader
,
3600 (void *)NineDevice9_SetVertexShader
,
3601 (void *)NineDevice9_GetVertexShader
,
3602 (void *)NineDevice9_SetVertexShaderConstantF
,
3603 (void *)NineDevice9_GetVertexShaderConstantF
,
3604 (void *)NineDevice9_SetVertexShaderConstantI
,
3605 (void *)NineDevice9_GetVertexShaderConstantI
,
3606 (void *)NineDevice9_SetVertexShaderConstantB
,
3607 (void *)NineDevice9_GetVertexShaderConstantB
,
3608 (void *)NineDevice9_SetStreamSource
,
3609 (void *)NineDevice9_GetStreamSource
,
3610 (void *)NineDevice9_SetStreamSourceFreq
,
3611 (void *)NineDevice9_GetStreamSourceFreq
,
3612 (void *)NineDevice9_SetIndices
,
3613 (void *)NineDevice9_GetIndices
,
3614 (void *)NineDevice9_CreatePixelShader
,
3615 (void *)NineDevice9_SetPixelShader
,
3616 (void *)NineDevice9_GetPixelShader
,
3617 (void *)NineDevice9_SetPixelShaderConstantF
,
3618 (void *)NineDevice9_GetPixelShaderConstantF
,
3619 (void *)NineDevice9_SetPixelShaderConstantI
,
3620 (void *)NineDevice9_GetPixelShaderConstantI
,
3621 (void *)NineDevice9_SetPixelShaderConstantB
,
3622 (void *)NineDevice9_GetPixelShaderConstantB
,
3623 (void *)NineDevice9_DrawRectPatch
,
3624 (void *)NineDevice9_DrawTriPatch
,
3625 (void *)NineDevice9_DeletePatch
,
3626 (void *)NineDevice9_CreateQuery
3629 static const GUID
*NineDevice9_IIDs
[] = {
3630 &IID_IDirect3DDevice9
,
3636 NineDevice9_new( struct pipe_screen
*pScreen
,
3637 D3DDEVICE_CREATION_PARAMETERS
*pCreationParameters
,
3639 D3DPRESENT_PARAMETERS
*pPresentationParameters
,
3641 ID3DPresentGroup
*pPresentationGroup
,
3642 struct d3dadapter9_context
*pCTX
,
3644 D3DDISPLAYMODEEX
*pFullscreenDisplayMode
,
3645 struct NineDevice9
**ppOut
)
3648 lock
= !!(pCreationParameters
->BehaviorFlags
& D3DCREATE_MULTITHREADED
);
3650 NINE_NEW(Device9
, ppOut
, lock
, /* args */
3651 pScreen
, pCreationParameters
, pCaps
,
3652 pPresentationParameters
, pD3D9
, pPresentationGroup
, pCTX
,
3653 ex
, pFullscreenDisplayMode
);