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 assert(!This
->is_recording
);
63 nine_state_set_defaults(&This
->state
, &This
->caps
, is_reset
);
65 This
->state
.viewport
.X
= 0;
66 This
->state
.viewport
.Y
= 0;
67 This
->state
.viewport
.Width
= 0;
68 This
->state
.viewport
.Height
= 0;
70 This
->state
.scissor
.minx
= 0;
71 This
->state
.scissor
.miny
= 0;
72 This
->state
.scissor
.maxx
= 0xffff;
73 This
->state
.scissor
.maxy
= 0xffff;
75 if (This
->nswapchains
&& This
->swapchains
[0]->params
.BackBufferCount
)
76 refSurf
= This
->swapchains
[0]->buffers
[0];
79 This
->state
.viewport
.Width
= refSurf
->desc
.Width
;
80 This
->state
.viewport
.Height
= refSurf
->desc
.Height
;
81 This
->state
.scissor
.maxx
= refSurf
->desc
.Width
;
82 This
->state
.scissor
.maxy
= refSurf
->desc
.Height
;
85 if (This
->nswapchains
&& This
->swapchains
[0]->params
.EnableAutoDepthStencil
)
86 This
->state
.rs
[D3DRS_ZENABLE
] = TRUE
;
87 if (This
->state
.rs
[D3DRS_ZENABLE
])
88 NineDevice9_SetDepthStencilSurface(
89 This
, (IDirect3DSurface9
*)This
->swapchains
[0]->zsbuf
);
93 NineDevice9_RestoreNonCSOState( struct NineDevice9
*This
, unsigned mask
)
95 struct pipe_context
*pipe
= This
->pipe
;
98 struct pipe_constant_buffer cb
;
101 if (This
->prefer_user_constbuf
) {
103 cb
.user_buffer
= This
->state
.vs_const_f
;
105 cb
.buffer
= This
->constbuf_vs
;
106 cb
.user_buffer
= NULL
;
108 cb
.buffer_size
= This
->constbuf_vs
->width0
;
109 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_VERTEX
, 0, &cb
);
111 if (This
->prefer_user_constbuf
) {
112 cb
.user_buffer
= This
->state
.ps_const_f
;
114 cb
.buffer
= This
->constbuf_ps
;
116 cb
.buffer_size
= This
->constbuf_ps
->width0
;
117 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_FRAGMENT
, 0, &cb
);
121 struct pipe_poly_stipple stipple
;
122 memset(&stipple
, ~0, sizeof(stipple
));
123 pipe
->set_polygon_stipple(pipe
, &stipple
);
126 This
->state
.changed
.group
= NINE_STATE_ALL
;
127 This
->state
.changed
.vtxbuf
= (1ULL << This
->caps
.MaxStreams
) - 1;
128 This
->state
.changed
.ucp
= (1 << PIPE_MAX_CLIP_PLANES
) - 1;
129 This
->state
.changed
.texture
= NINE_PS_SAMPLERS_MASK
| NINE_VS_SAMPLERS_MASK
;
132 #define GET_PCAP(n) pScreen->get_param(pScreen, PIPE_CAP_##n)
134 NineDevice9_ctor( struct NineDevice9
*This
,
135 struct NineUnknownParams
*pParams
,
136 struct pipe_screen
*pScreen
,
137 D3DDEVICE_CREATION_PARAMETERS
*pCreationParameters
,
139 D3DPRESENT_PARAMETERS
*pPresentationParameters
,
141 ID3DPresentGroup
*pPresentationGroup
,
142 struct d3dadapter9_context
*pCTX
,
144 D3DDISPLAYMODEEX
*pFullscreenDisplayMode
)
147 HRESULT hr
= NineUnknown_ctor(&This
->base
, pParams
);
148 if (FAILED(hr
)) { return hr
; }
150 list_inithead(&This
->update_textures
);
152 This
->screen
= pScreen
;
155 This
->params
= *pCreationParameters
;
157 This
->present
= pPresentationGroup
;
158 IDirect3D9_AddRef(This
->d3d9
);
159 ID3DPresentGroup_AddRef(This
->present
);
161 This
->pipe
= This
->screen
->context_create(This
->screen
, NULL
);
162 if (!This
->pipe
) { return E_OUTOFMEMORY
; } /* guess */
164 This
->cso
= cso_create_context(This
->pipe
);
165 if (!This
->cso
) { return E_OUTOFMEMORY
; } /* also a guess */
167 /* Create first, it messes up our state. */
168 This
->hud
= hud_create(This
->pipe
, This
->cso
); /* NULL result is fine */
170 /* create implicit swapchains */
171 This
->nswapchains
= ID3DPresentGroup_GetMultiheadCount(This
->present
);
172 This
->swapchains
= CALLOC(This
->nswapchains
,
173 sizeof(struct NineSwapChain9
*));
174 if (!This
->swapchains
) { return E_OUTOFMEMORY
; }
176 for (i
= 0; i
< This
->nswapchains
; ++i
) {
177 ID3DPresent
*present
;
179 hr
= ID3DPresentGroup_GetPresent(This
->present
, i
, &present
);
184 D3DDISPLAYMODEEX
*mode
= NULL
;
185 struct NineSwapChain9Ex
**ret
=
186 (struct NineSwapChain9Ex
**)&This
->swapchains
[i
];
188 if (pFullscreenDisplayMode
) mode
= &(pFullscreenDisplayMode
[i
]);
189 /* when this is a Device9Ex, it should create SwapChain9Exs */
190 hr
= NineSwapChain9Ex_new(This
, TRUE
, present
,
191 &pPresentationParameters
[i
], pCTX
,
192 This
->params
.hFocusWindow
, mode
, ret
);
194 hr
= NineSwapChain9_new(This
, TRUE
, present
,
195 &pPresentationParameters
[i
], pCTX
,
196 This
->params
.hFocusWindow
,
197 &This
->swapchains
[i
]);
200 ID3DPresent_Release(present
);
203 NineUnknown_ConvertRefToBind(NineUnknown(This
->swapchains
[i
]));
205 hr
= NineSwapChain9_GetBackBuffer(This
->swapchains
[i
], 0,
206 D3DBACKBUFFER_TYPE_MONO
,
207 (IDirect3DSurface9
**)
211 NineUnknown_ConvertRefToBind(NineUnknown(This
->state
.rt
[i
]));
214 This
->cursor
.software
= FALSE
;
215 This
->cursor
.hotspot
.x
= -1;
216 This
->cursor
.hotspot
.y
= -1;
218 struct pipe_resource tmpl
;
219 tmpl
.target
= PIPE_TEXTURE_2D
;
220 tmpl
.format
= PIPE_FORMAT_R8G8B8A8_UNORM
;
227 tmpl
.usage
= PIPE_USAGE_DEFAULT
;
228 tmpl
.bind
= PIPE_BIND_CURSOR
| PIPE_BIND_SAMPLER_VIEW
;
231 This
->cursor
.image
= pScreen
->resource_create(pScreen
, &tmpl
);
232 if (!This
->cursor
.image
)
233 return D3DERR_OUTOFVIDEOMEMORY
;
236 /* Create constant buffers. */
238 struct pipe_resource tmpl
;
239 unsigned max_const_vs
, max_const_ps
;
241 max_const_vs
= _min(pScreen
->get_shader_param(pScreen
, PIPE_SHADER_VERTEX
,
242 PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE
) /
245 max_const_ps
= _min(pScreen
->get_shader_param(pScreen
, PIPE_SHADER_FRAGMENT
,
246 PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE
) /
250 This
->max_vs_const_f
= max_const_vs
-
251 (NINE_MAX_CONST_I
+ NINE_MAX_CONST_B
/ 4);
252 This
->max_ps_const_f
= max_const_ps
-
253 (NINE_MAX_CONST_I
+ NINE_MAX_CONST_B
/ 4);
255 /* Include space for I,B constants for user constbuf. */
256 This
->state
.vs_const_f
= CALLOC(NINE_MAX_CONST_ALL
, sizeof(float[4]));
257 This
->state
.ps_const_f
= CALLOC(NINE_MAX_CONST_ALL
, sizeof(float[4]));
258 if (!This
->state
.vs_const_f
|| !This
->state
.ps_const_f
)
259 return E_OUTOFMEMORY
;
261 if (strstr(pScreen
->get_name(pScreen
), "AMD") ||
262 strstr(pScreen
->get_name(pScreen
), "ATI"))
263 This
->prefer_user_constbuf
= TRUE
;
265 tmpl
.target
= PIPE_BUFFER
;
266 tmpl
.format
= PIPE_FORMAT_R8_UNORM
;
272 tmpl
.usage
= PIPE_USAGE_DYNAMIC
;
273 tmpl
.bind
= PIPE_BIND_CONSTANT_BUFFER
;
276 tmpl
.width0
= max_const_vs
* sizeof(float[4]);
277 This
->constbuf_vs
= pScreen
->resource_create(pScreen
, &tmpl
);
279 tmpl
.width0
= max_const_ps
* sizeof(float[4]);
280 This
->constbuf_ps
= pScreen
->resource_create(pScreen
, &tmpl
);
282 if (!This
->constbuf_vs
|| !This
->constbuf_ps
)
283 return E_OUTOFMEMORY
;
286 This
->vs_bool_true
= pScreen
->get_shader_param(pScreen
,
288 PIPE_SHADER_CAP_INTEGERS
) ? 0xFFFFFFFF : fui(1.0f
);
289 This
->ps_bool_true
= pScreen
->get_shader_param(pScreen
,
290 PIPE_SHADER_FRAGMENT
,
291 PIPE_SHADER_CAP_INTEGERS
) ? 0xFFFFFFFF : fui(1.0f
);
293 /* Allocate upload helper for drivers that suck (from st pov ;). */
297 This
->driver_caps
.user_vbufs
= GET_PCAP(USER_VERTEX_BUFFERS
);
298 This
->driver_caps
.user_ibufs
= GET_PCAP(USER_INDEX_BUFFERS
);
300 if (!This
->driver_caps
.user_vbufs
) bind
|= PIPE_BIND_VERTEX_BUFFER
;
301 if (!This
->driver_caps
.user_ibufs
) bind
|= PIPE_BIND_INDEX_BUFFER
;
303 This
->upload
= u_upload_create(This
->pipe
, 1 << 20, 4, bind
);
306 This
->driver_caps
.window_space_position_support
= GET_PCAP(TGSI_VS_WINDOW_SPACE_POSITION
);
308 nine_ff_init(This
); /* initialize fixed function code */
310 NineDevice9_SetDefaultState(This
, FALSE
);
311 NineDevice9_RestoreNonCSOState(This
, ~0);
313 This
->update
= &This
->state
;
314 nine_update_state(This
, ~0);
316 ID3DPresentGroup_Release(This
->present
);
323 NineDevice9_dtor( struct NineDevice9
*This
)
327 DBG("This=%p\n", This
);
329 if (This
->pipe
&& This
->cso
)
330 nine_pipe_context_clear(This
);
332 nine_state_clear(&This
->state
, TRUE
);
335 u_upload_destroy(This
->upload
);
337 nine_bind(&This
->record
, NULL
);
339 pipe_resource_reference(&This
->constbuf_vs
, NULL
);
340 pipe_resource_reference(&This
->constbuf_ps
, NULL
);
341 FREE(This
->state
.vs_const_f
);
342 FREE(This
->state
.ps_const_f
);
344 if (This
->swapchains
) {
345 for (i
= 0; i
< This
->nswapchains
; ++i
)
346 NineUnknown_Unbind(NineUnknown(This
->swapchains
[i
]));
347 FREE(This
->swapchains
);
353 cso_release_all(This
->cso
);
354 cso_destroy_context(This
->cso
);
356 if (This
->pipe
->destroy
) { This
->pipe
->destroy(This
->pipe
); }
359 if (This
->present
) { ID3DPresentGroup_Release(This
->present
); }
360 if (This
->d3d9
) { IDirect3D9_Release(This
->d3d9
); }
362 NineUnknown_dtor(&This
->base
);
366 NineDevice9_GetScreen( struct NineDevice9
*This
)
371 struct pipe_context
*
372 NineDevice9_GetPipe( struct NineDevice9
*This
)
378 NineDevice9_GetCSO( struct NineDevice9
*This
)
384 NineDevice9_GetCaps( struct NineDevice9
*This
)
390 NineDevice9_PauseRecording( struct NineDevice9
*This
)
393 This
->update
= &This
->state
;
394 This
->is_recording
= FALSE
;
399 NineDevice9_ResumeRecording( struct NineDevice9
*This
)
402 This
->update
= &This
->record
->state
;
403 This
->is_recording
= TRUE
;
408 NineDevice9_TestCooperativeLevel( struct NineDevice9
*This
)
410 return D3D_OK
; /* TODO */
414 NineDevice9_GetAvailableTextureMem( struct NineDevice9
*This
)
416 return This
->screen
->get_param(This
->screen
, PIPE_CAP_VIDEO_MEMORY
);
420 NineDevice9_EvictManagedResources( struct NineDevice9
*This
)
422 /* We don't really need to do anything here, but might want to free up
423 * the GPU virtual address space by killing pipe_resources.
429 NineDevice9_GetDirect3D( struct NineDevice9
*This
,
430 IDirect3D9
**ppD3D9
)
432 user_assert(ppD3D9
!= NULL
, E_POINTER
);
433 IDirect3D9_AddRef(This
->d3d9
);
434 *ppD3D9
= This
->d3d9
;
439 NineDevice9_GetDeviceCaps( struct NineDevice9
*This
,
442 user_assert(pCaps
!= NULL
, D3DERR_INVALIDCALL
);
448 NineDevice9_GetDisplayMode( struct NineDevice9
*This
,
450 D3DDISPLAYMODE
*pMode
)
452 DBG("This=%p iSwapChain=%u pMode=%p\n", This
, iSwapChain
, pMode
);
454 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
456 return NineSwapChain9_GetDisplayMode(This
->swapchains
[iSwapChain
], pMode
);
460 NineDevice9_GetCreationParameters( struct NineDevice9
*This
,
461 D3DDEVICE_CREATION_PARAMETERS
*pParameters
)
463 user_assert(pParameters
!= NULL
, D3DERR_INVALIDCALL
);
464 *pParameters
= This
->params
;
469 NineDevice9_SetCursorProperties( struct NineDevice9
*This
,
472 IDirect3DSurface9
*pCursorBitmap
)
474 /* TODO: hardware cursor */
475 struct NineSurface9
*surf
= NineSurface9(pCursorBitmap
);
476 struct pipe_context
*pipe
= This
->pipe
;
478 struct pipe_transfer
*transfer
;
481 DBG_FLAG(DBG_SWAPCHAIN
, "This=%p XHotSpot=%u YHotSpot=%u "
482 "pCursorBitmap=%p\n", This
, XHotSpot
, YHotSpot
, pCursorBitmap
);
484 user_assert(pCursorBitmap
, D3DERR_INVALIDCALL
);
486 This
->cursor
.w
= MIN2(surf
->desc
.Width
, This
->cursor
.image
->width0
);
487 This
->cursor
.h
= MIN2(surf
->desc
.Height
, This
->cursor
.image
->height0
);
489 u_box_origin_2d(This
->cursor
.w
, This
->cursor
.h
, &box
);
491 ptr
= pipe
->transfer_map(pipe
, This
->cursor
.image
, 0,
492 PIPE_TRANSFER_WRITE
|
493 PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
,
496 ret_err("Failed to update cursor image.\n", D3DERR_DRIVERINTERNALERROR
);
498 This
->cursor
.hotspot
.x
= XHotSpot
;
499 This
->cursor
.hotspot
.y
= YHotSpot
;
501 /* Copy cursor image to internal storage. */
505 const struct util_format_description
*sfmt
=
506 util_format_description(surf
->base
.info
.format
);
509 hr
= NineSurface9_LockRect(surf
, &lock
, NULL
, D3DLOCK_READONLY
);
511 ret_err("Failed to map cursor source image.\n",
512 D3DERR_DRIVERINTERNALERROR
);
514 sfmt
->unpack_rgba_8unorm(ptr
, transfer
->stride
,
515 lock
.pBits
, lock
.Pitch
,
516 This
->cursor
.w
, This
->cursor
.h
);
518 if (!This
->cursor
.software
&&
519 This
->cursor
.w
== 32 && This
->cursor
.h
== 32)
520 ID3DPresent_SetCursor(This
->swapchains
[0]->present
,
521 lock
.pBits
, &This
->cursor
.hotspot
,
522 This
->cursor
.visible
);
524 NineSurface9_UnlockRect(surf
);
526 pipe
->transfer_unmap(pipe
, transfer
);
532 NineDevice9_SetCursorPosition( struct NineDevice9
*This
,
537 struct NineSwapChain9
*swap
= This
->swapchains
[0];
539 This
->cursor
.pos
.x
= X
;
540 This
->cursor
.pos
.y
= Y
;
542 if (!This
->cursor
.software
)
543 ID3DPresent_SetCursorPos(swap
->present
, &This
->cursor
.pos
);
547 NineDevice9_ShowCursor( struct NineDevice9
*This
,
550 BOOL old
= This
->cursor
.visible
;
551 This
->cursor
.visible
= bShow
&& (This
->cursor
.hotspot
.x
!= -1);
552 if (!This
->cursor
.software
)
553 ID3DPresent_SetCursor(This
->swapchains
[0]->present
, NULL
, NULL
, bShow
);
559 NineDevice9_CreateAdditionalSwapChain( struct NineDevice9
*This
,
560 D3DPRESENT_PARAMETERS
*pPresentationParameters
,
561 IDirect3DSwapChain9
**pSwapChain
)
563 struct NineSwapChain9
*swapchain
, *tmplt
= This
->swapchains
[0];
564 ID3DPresent
*present
;
567 user_assert(pPresentationParameters
, D3DERR_INVALIDCALL
);
569 hr
= ID3DPresentGroup_CreateAdditionalPresent(This
->present
, pPresentationParameters
, &present
);
574 hr
= NineSwapChain9_new(This
, FALSE
, present
, pPresentationParameters
,
576 tmplt
->params
.hDeviceWindow
,
581 *pSwapChain
= (IDirect3DSwapChain9
*)swapchain
;
586 NineDevice9_GetSwapChain( struct NineDevice9
*This
,
588 IDirect3DSwapChain9
**pSwapChain
)
590 user_assert(pSwapChain
!= NULL
, D3DERR_INVALIDCALL
);
593 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
595 NineUnknown_AddRef(NineUnknown(This
->swapchains
[iSwapChain
]));
596 *pSwapChain
= (IDirect3DSwapChain9
*)This
->swapchains
[iSwapChain
];
602 NineDevice9_GetNumberOfSwapChains( struct NineDevice9
*This
)
604 return This
->nswapchains
;
608 NineDevice9_Reset( struct NineDevice9
*This
,
609 D3DPRESENT_PARAMETERS
*pPresentationParameters
)
614 DBG("This=%p pPresentationParameters=%p\n", This
, pPresentationParameters
);
616 for (i
= 0; i
< This
->nswapchains
; ++i
) {
617 D3DPRESENT_PARAMETERS
*params
= &pPresentationParameters
[i
];
618 hr
= NineSwapChain9_Resize(This
->swapchains
[i
], params
, NULL
);
620 return (hr
== D3DERR_OUTOFVIDEOMEMORY
) ? hr
: D3DERR_DEVICELOST
;
623 nine_pipe_context_clear(This
);
624 nine_state_clear(&This
->state
, TRUE
);
626 NineDevice9_SetDefaultState(This
, TRUE
);
627 NineDevice9_SetRenderTarget(
628 This
, 0, (IDirect3DSurface9
*)This
->swapchains
[0]->buffers
[0]);
629 /* XXX: better use GetBackBuffer here ? */
635 NineDevice9_Present( struct NineDevice9
*This
,
636 const RECT
*pSourceRect
,
637 const RECT
*pDestRect
,
638 HWND hDestWindowOverride
,
639 const RGNDATA
*pDirtyRegion
)
644 /* XXX is this right? */
645 for (i
= 0; i
< This
->nswapchains
; ++i
) {
646 hr
= NineSwapChain9_Present(This
->swapchains
[i
], pSourceRect
, pDestRect
,
647 hDestWindowOverride
, pDirtyRegion
, 0);
648 if (FAILED(hr
)) { return hr
; }
655 NineDevice9_GetBackBuffer( struct NineDevice9
*This
,
658 D3DBACKBUFFER_TYPE Type
,
659 IDirect3DSurface9
**ppBackBuffer
)
661 user_assert(ppBackBuffer
!= NULL
, D3DERR_INVALIDCALL
);
662 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
664 return NineSwapChain9_GetBackBuffer(This
->swapchains
[iSwapChain
],
665 iBackBuffer
, Type
, ppBackBuffer
);
669 NineDevice9_GetRasterStatus( struct NineDevice9
*This
,
671 D3DRASTER_STATUS
*pRasterStatus
)
673 user_assert(pRasterStatus
!= NULL
, D3DERR_INVALIDCALL
);
674 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
676 return NineSwapChain9_GetRasterStatus(This
->swapchains
[iSwapChain
],
681 NineDevice9_SetDialogBoxMode( struct NineDevice9
*This
,
682 BOOL bEnableDialogs
)
684 STUB(D3DERR_INVALIDCALL
);
688 NineDevice9_SetGammaRamp( struct NineDevice9
*This
,
691 const D3DGAMMARAMP
*pRamp
)
693 DBG("This=%p iSwapChain=%u Flags=%x pRamp=%p\n", This
,
694 iSwapChain
, Flags
, pRamp
);
696 user_warn(iSwapChain
>= This
->nswapchains
);
699 if (pRamp
&& (iSwapChain
< This
->nswapchains
)) {
700 struct NineSwapChain9
*swap
= This
->swapchains
[iSwapChain
];
701 swap
->gamma
= *pRamp
;
702 ID3DPresent_SetGammaRamp(swap
->present
, pRamp
, swap
->params
.hDeviceWindow
);
707 NineDevice9_GetGammaRamp( struct NineDevice9
*This
,
709 D3DGAMMARAMP
*pRamp
)
711 DBG("This=%p iSwapChain=%u pRamp=%p\n", This
, iSwapChain
, pRamp
);
713 user_warn(iSwapChain
>= This
->nswapchains
);
716 if (pRamp
&& (iSwapChain
< This
->nswapchains
))
717 *pRamp
= This
->swapchains
[iSwapChain
]->gamma
;
721 NineDevice9_CreateTexture( struct NineDevice9
*This
,
728 IDirect3DTexture9
**ppTexture
,
729 HANDLE
*pSharedHandle
)
731 struct NineTexture9
*tex
;
734 DBG("This=%p Width=%u Height=%u Levels=%u Usage=%s Format=%s Pool=%s "
735 "ppOut=%p pSharedHandle=%p\n", This
, Width
, Height
, Levels
,
736 nine_D3DUSAGE_to_str(Usage
), d3dformat_to_string(Format
),
737 nine_D3DPOOL_to_str(Pool
), ppTexture
, pSharedHandle
);
739 Usage
&= D3DUSAGE_AUTOGENMIPMAP
| D3DUSAGE_DEPTHSTENCIL
| D3DUSAGE_DMAP
|
740 D3DUSAGE_DYNAMIC
| D3DUSAGE_NONSECURE
| D3DUSAGE_RENDERTARGET
|
741 D3DUSAGE_SOFTWAREPROCESSING
| D3DUSAGE_TEXTAPI
;
743 user_assert(Width
&& Height
, D3DERR_INVALIDCALL
);
744 user_assert(!pSharedHandle
|| This
->ex
, D3DERR_INVALIDCALL
);
745 /* When is used shared handle, Pool must be
746 * SYSTEMMEM with Levels 1 or DEFAULT with any Levels */
747 user_assert(!pSharedHandle
|| Pool
!= D3DPOOL_SYSTEMMEM
|| Levels
== 1,
749 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_SYSTEMMEM
|| Pool
== D3DPOOL_DEFAULT
,
751 user_assert((Usage
!= D3DUSAGE_AUTOGENMIPMAP
|| Levels
<= 1), D3DERR_INVALIDCALL
);
753 hr
= NineTexture9_new(This
, Width
, Height
, Levels
, Usage
, Format
, Pool
,
754 &tex
, pSharedHandle
);
756 *ppTexture
= (IDirect3DTexture9
*)tex
;
762 NineDevice9_CreateVolumeTexture( struct NineDevice9
*This
,
770 IDirect3DVolumeTexture9
**ppVolumeTexture
,
771 HANDLE
*pSharedHandle
)
773 struct NineVolumeTexture9
*tex
;
776 DBG("This=%p Width=%u Height=%u Depth=%u Levels=%u Usage=%s Format=%s Pool=%s "
777 "ppOut=%p pSharedHandle=%p\n", This
, Width
, Height
, Depth
, Levels
,
778 nine_D3DUSAGE_to_str(Usage
), d3dformat_to_string(Format
),
779 nine_D3DPOOL_to_str(Pool
), ppVolumeTexture
, pSharedHandle
);
781 Usage
&= D3DUSAGE_DYNAMIC
| D3DUSAGE_NONSECURE
|
782 D3DUSAGE_SOFTWAREPROCESSING
;
784 user_assert(Width
&& Height
&& Depth
, D3DERR_INVALIDCALL
);
785 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
787 hr
= NineVolumeTexture9_new(This
, Width
, Height
, Depth
, Levels
,
788 Usage
, Format
, Pool
, &tex
, pSharedHandle
);
790 *ppVolumeTexture
= (IDirect3DVolumeTexture9
*)tex
;
796 NineDevice9_CreateCubeTexture( struct NineDevice9
*This
,
802 IDirect3DCubeTexture9
**ppCubeTexture
,
803 HANDLE
*pSharedHandle
)
805 struct NineCubeTexture9
*tex
;
808 DBG("This=%p EdgeLength=%u Levels=%u Usage=%s Format=%s Pool=%s ppOut=%p "
809 "pSharedHandle=%p\n", This
, EdgeLength
, Levels
,
810 nine_D3DUSAGE_to_str(Usage
), d3dformat_to_string(Format
),
811 nine_D3DPOOL_to_str(Pool
), ppCubeTexture
, pSharedHandle
);
813 Usage
&= D3DUSAGE_AUTOGENMIPMAP
| D3DUSAGE_DEPTHSTENCIL
| D3DUSAGE_DYNAMIC
|
814 D3DUSAGE_NONSECURE
| D3DUSAGE_RENDERTARGET
|
815 D3DUSAGE_SOFTWAREPROCESSING
;
817 user_assert(EdgeLength
, D3DERR_INVALIDCALL
);
818 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
820 hr
= NineCubeTexture9_new(This
, EdgeLength
, Levels
, Usage
, Format
, Pool
,
821 &tex
, pSharedHandle
);
823 *ppCubeTexture
= (IDirect3DCubeTexture9
*)tex
;
829 NineDevice9_CreateVertexBuffer( struct NineDevice9
*This
,
834 IDirect3DVertexBuffer9
**ppVertexBuffer
,
835 HANDLE
*pSharedHandle
)
837 struct NineVertexBuffer9
*buf
;
839 D3DVERTEXBUFFER_DESC desc
;
841 DBG("This=%p Length=%u Usage=%x FVF=%x Pool=%u ppOut=%p pSharedHandle=%p\n",
842 This
, Length
, Usage
, FVF
, Pool
, ppVertexBuffer
, pSharedHandle
);
844 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_NOTAVAILABLE
);
846 desc
.Format
= D3DFMT_VERTEXDATA
;
847 desc
.Type
= D3DRTYPE_VERTEXBUFFER
;
849 (D3DUSAGE_DONOTCLIP
| D3DUSAGE_DYNAMIC
| D3DUSAGE_NONSECURE
|
850 D3DUSAGE_NPATCHES
| D3DUSAGE_POINTS
| D3DUSAGE_RTPATCHES
|
851 D3DUSAGE_SOFTWAREPROCESSING
| D3DUSAGE_TEXTAPI
|
857 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
858 user_assert(desc
.Usage
== Usage
, D3DERR_INVALIDCALL
);
860 hr
= NineVertexBuffer9_new(This
, &desc
, &buf
);
862 *ppVertexBuffer
= (IDirect3DVertexBuffer9
*)buf
;
867 NineDevice9_CreateIndexBuffer( struct NineDevice9
*This
,
872 IDirect3DIndexBuffer9
**ppIndexBuffer
,
873 HANDLE
*pSharedHandle
)
875 struct NineIndexBuffer9
*buf
;
877 D3DINDEXBUFFER_DESC desc
;
879 DBG("This=%p Length=%u Usage=%x Format=%s Pool=%u ppOut=%p "
880 "pSharedHandle=%p\n", This
, Length
, Usage
,
881 d3dformat_to_string(Format
), Pool
, ppIndexBuffer
, pSharedHandle
);
883 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_NOTAVAILABLE
);
885 desc
.Format
= Format
;
886 desc
.Type
= D3DRTYPE_INDEXBUFFER
;
888 (D3DUSAGE_DONOTCLIP
| D3DUSAGE_DYNAMIC
| D3DUSAGE_NONSECURE
|
889 D3DUSAGE_NPATCHES
| D3DUSAGE_POINTS
| D3DUSAGE_RTPATCHES
|
890 D3DUSAGE_SOFTWAREPROCESSING
| D3DUSAGE_WRITEONLY
);
894 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
895 user_assert(desc
.Usage
== Usage
, D3DERR_INVALIDCALL
);
897 hr
= NineIndexBuffer9_new(This
, &desc
, &buf
);
899 *ppIndexBuffer
= (IDirect3DIndexBuffer9
*)buf
;
904 create_zs_or_rt_surface(struct NineDevice9
*This
,
905 unsigned type
, /* 0 = RT, 1 = ZS, 2 = plain */
907 UINT Width
, UINT Height
,
909 D3DMULTISAMPLE_TYPE MultiSample
,
910 DWORD MultisampleQuality
,
911 BOOL Discard_or_Lockable
,
912 IDirect3DSurface9
**ppSurface
,
913 HANDLE
*pSharedHandle
)
915 struct NineSurface9
*surface
;
916 struct pipe_screen
*screen
= This
->screen
;
917 struct pipe_resource
*resource
= NULL
;
919 D3DSURFACE_DESC desc
;
920 struct pipe_resource templ
;
922 DBG("This=%p type=%u Pool=%s Width=%u Height=%u Format=%s MS=%u Quality=%u "
923 "Discard_or_Lockable=%i ppSurface=%p pSharedHandle=%p\n",
924 This
, type
, nine_D3DPOOL_to_str(Pool
), Width
, Height
,
925 d3dformat_to_string(Format
), MultiSample
, MultisampleQuality
,
926 Discard_or_Lockable
, ppSurface
, pSharedHandle
);
929 DBG("FIXME Used shared handle! This option isn't probably handled correctly!\n");
931 user_assert(Width
&& Height
, D3DERR_INVALIDCALL
);
932 user_assert(Pool
!= D3DPOOL_MANAGED
, D3DERR_INVALIDCALL
);
934 templ
.target
= PIPE_TEXTURE_2D
;
935 templ
.format
= d3d9_to_pipe_format(Format
);
936 templ
.width0
= Width
;
937 templ
.height0
= Height
;
939 templ
.array_size
= 1;
940 templ
.last_level
= 0;
941 templ
.nr_samples
= (unsigned)MultiSample
;
942 templ
.usage
= PIPE_USAGE_DEFAULT
;
944 templ
.bind
= PIPE_BIND_SAMPLER_VIEW
; /* StretchRect */
946 case 0: templ
.bind
|= PIPE_BIND_RENDER_TARGET
; break;
947 case 1: templ
.bind
|= PIPE_BIND_DEPTH_STENCIL
; break;
953 desc
.Format
= Format
;
954 desc
.Type
= D3DRTYPE_SURFACE
;
957 desc
.MultiSampleType
= MultiSample
;
958 desc
.MultiSampleQuality
= MultisampleQuality
;
960 desc
.Height
= Height
;
962 case 0: desc
.Usage
= D3DUSAGE_RENDERTARGET
; break;
963 case 1: desc
.Usage
= D3DUSAGE_DEPTHSTENCIL
; break;
967 if (Pool
== D3DPOOL_DEFAULT
&& Format
!= D3DFMT_NULL
) {
968 /* resource_create doesn't return an error code, so check format here */
969 user_assert(CHECK_PIPE_RESOURCE_TEMPLATE(templ
), D3DERR_INVALIDCALL
);
970 resource
= screen
->resource_create(screen
, &templ
);
971 user_assert(resource
, D3DERR_OUTOFVIDEOMEMORY
);
972 if (Discard_or_Lockable
&& (desc
.Usage
& D3DUSAGE_RENDERTARGET
))
973 resource
->flags
|= NINE_RESOURCE_FLAG_LOCKABLE
;
977 hr
= NineSurface9_new(This
, NULL
, resource
, NULL
, 0, 0, 0, &desc
, &surface
);
978 pipe_resource_reference(&resource
, NULL
);
981 *ppSurface
= (IDirect3DSurface9
*)surface
;
986 NineDevice9_CreateRenderTarget( struct NineDevice9
*This
,
990 D3DMULTISAMPLE_TYPE MultiSample
,
991 DWORD MultisampleQuality
,
993 IDirect3DSurface9
**ppSurface
,
994 HANDLE
*pSharedHandle
)
996 return create_zs_or_rt_surface(This
, 0, D3DPOOL_DEFAULT
,
997 Width
, Height
, Format
,
998 MultiSample
, MultisampleQuality
,
999 Lockable
, ppSurface
, pSharedHandle
);
1003 NineDevice9_CreateDepthStencilSurface( struct NineDevice9
*This
,
1007 D3DMULTISAMPLE_TYPE MultiSample
,
1008 DWORD MultisampleQuality
,
1010 IDirect3DSurface9
**ppSurface
,
1011 HANDLE
*pSharedHandle
)
1013 return create_zs_or_rt_surface(This
, 1, D3DPOOL_DEFAULT
,
1014 Width
, Height
, Format
,
1015 MultiSample
, MultisampleQuality
,
1016 Discard
, ppSurface
, pSharedHandle
);
1020 NineDevice9_UpdateSurface( struct NineDevice9
*This
,
1021 IDirect3DSurface9
*pSourceSurface
,
1022 const RECT
*pSourceRect
,
1023 IDirect3DSurface9
*pDestinationSurface
,
1024 const POINT
*pDestPoint
)
1026 struct NineSurface9
*dst
= NineSurface9(pDestinationSurface
);
1027 struct NineSurface9
*src
= NineSurface9(pSourceSurface
);
1029 DBG("This=%p pSourceSurface=%p pDestinationSurface=%p "
1030 "pSourceRect=%p pDestPoint=%p\n", This
,
1031 pSourceSurface
, pDestinationSurface
, pSourceRect
, pDestPoint
);
1033 DBG("pSourceRect = (%u,%u)-(%u,%u)\n",
1034 pSourceRect
->left
, pSourceRect
->top
,
1035 pSourceRect
->right
, pSourceRect
->bottom
);
1037 DBG("pDestPoint = (%u,%u)\n", pDestPoint
->x
, pDestPoint
->y
);
1039 user_assert(dst
->base
.pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1040 user_assert(src
->base
.pool
== D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
1042 user_assert(dst
->desc
.MultiSampleType
== D3DMULTISAMPLE_NONE
, D3DERR_INVALIDCALL
);
1043 user_assert(src
->desc
.MultiSampleType
== D3DMULTISAMPLE_NONE
, D3DERR_INVALIDCALL
);
1045 return NineSurface9_CopySurface(dst
, src
, pDestPoint
, pSourceRect
);
1049 NineDevice9_UpdateTexture( struct NineDevice9
*This
,
1050 IDirect3DBaseTexture9
*pSourceTexture
,
1051 IDirect3DBaseTexture9
*pDestinationTexture
)
1053 struct NineBaseTexture9
*dstb
= NineBaseTexture9(pDestinationTexture
);
1054 struct NineBaseTexture9
*srcb
= NineBaseTexture9(pSourceTexture
);
1056 unsigned last_level
= dstb
->base
.info
.last_level
;
1058 DBG("This=%p pSourceTexture=%p pDestinationTexture=%p\n", This
,
1059 pSourceTexture
, pDestinationTexture
);
1061 user_assert(pSourceTexture
!= pDestinationTexture
, D3DERR_INVALIDCALL
);
1063 user_assert(dstb
->base
.pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1064 user_assert(srcb
->base
.pool
== D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
1066 if (dstb
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
) {
1067 /* Only the first level is updated, the others regenerated. */
1070 user_assert(!(srcb
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
), D3DERR_INVALIDCALL
);
1073 user_assert(dstb
->base
.type
== srcb
->base
.type
, D3DERR_INVALIDCALL
);
1075 /* TODO: We can restrict the update to the dirty portions of the source.
1076 * Yes, this seems silly, but it's what MSDN says ...
1079 /* Find src level that matches dst level 0: */
1080 user_assert(srcb
->base
.info
.width0
>= dstb
->base
.info
.width0
&&
1081 srcb
->base
.info
.height0
>= dstb
->base
.info
.height0
&&
1082 srcb
->base
.info
.depth0
>= dstb
->base
.info
.depth0
,
1083 D3DERR_INVALIDCALL
);
1084 for (m
= 0; m
<= srcb
->base
.info
.last_level
; ++m
) {
1085 unsigned w
= u_minify(srcb
->base
.info
.width0
, m
);
1086 unsigned h
= u_minify(srcb
->base
.info
.height0
, m
);
1087 unsigned d
= u_minify(srcb
->base
.info
.depth0
, m
);
1089 if (w
== dstb
->base
.info
.width0
&&
1090 h
== dstb
->base
.info
.height0
&&
1091 d
== dstb
->base
.info
.depth0
)
1094 user_assert(m
<= srcb
->base
.info
.last_level
, D3DERR_INVALIDCALL
);
1096 last_level
= MIN2(last_level
, srcb
->base
.info
.last_level
- m
);
1098 if (dstb
->base
.type
== D3DRTYPE_TEXTURE
) {
1099 struct NineTexture9
*dst
= NineTexture9(dstb
);
1100 struct NineTexture9
*src
= NineTexture9(srcb
);
1102 for (l
= 0; l
<= last_level
; ++l
, ++m
)
1103 NineSurface9_CopySurface(dst
->surfaces
[l
],
1104 src
->surfaces
[m
], NULL
, NULL
);
1106 if (dstb
->base
.type
== D3DRTYPE_CUBETEXTURE
) {
1107 struct NineCubeTexture9
*dst
= NineCubeTexture9(dstb
);
1108 struct NineCubeTexture9
*src
= NineCubeTexture9(srcb
);
1111 /* GPUs usually have them stored as arrays of mip-mapped 2D textures. */
1112 for (z
= 0; z
< 6; ++z
) {
1113 for (l
= 0; l
<= last_level
; ++l
, ++m
) {
1114 NineSurface9_CopySurface(dst
->surfaces
[l
* 6 + z
],
1115 src
->surfaces
[m
* 6 + z
], NULL
, NULL
);
1120 if (dstb
->base
.type
== D3DRTYPE_VOLUMETEXTURE
) {
1121 struct NineVolumeTexture9
*dst
= NineVolumeTexture9(dstb
);
1122 struct NineVolumeTexture9
*src
= NineVolumeTexture9(srcb
);
1124 for (l
= 0; l
<= last_level
; ++l
, ++m
)
1125 NineVolume9_CopyVolume(dst
->volumes
[l
],
1126 src
->volumes
[m
], 0, 0, 0, NULL
);
1128 assert(!"invalid texture type");
1131 if (dstb
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
)
1132 NineBaseTexture9_GenerateMipSubLevels(dstb
);
1138 NineDevice9_GetRenderTargetData( struct NineDevice9
*This
,
1139 IDirect3DSurface9
*pRenderTarget
,
1140 IDirect3DSurface9
*pDestSurface
)
1142 struct NineSurface9
*dst
= NineSurface9(pDestSurface
);
1143 struct NineSurface9
*src
= NineSurface9(pRenderTarget
);
1145 DBG("This=%p pRenderTarget=%p pDestSurface=%p\n",
1146 This
, pRenderTarget
, pDestSurface
);
1148 user_assert(dst
->desc
.Pool
== D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
1149 user_assert(src
->desc
.Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1151 user_assert(dst
->desc
.MultiSampleType
< 2, D3DERR_INVALIDCALL
);
1152 user_assert(src
->desc
.MultiSampleType
< 2, D3DERR_INVALIDCALL
);
1154 return NineSurface9_CopySurface(dst
, src
, NULL
, NULL
);
1158 NineDevice9_GetFrontBufferData( struct NineDevice9
*This
,
1160 IDirect3DSurface9
*pDestSurface
)
1162 DBG("This=%p iSwapChain=%u pDestSurface=%p\n", This
,
1163 iSwapChain
, pDestSurface
);
1165 user_assert(pDestSurface
!= NULL
, D3DERR_INVALIDCALL
);
1166 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
1168 return NineSwapChain9_GetFrontBufferData(This
->swapchains
[iSwapChain
],
1173 NineDevice9_StretchRect( struct NineDevice9
*This
,
1174 IDirect3DSurface9
*pSourceSurface
,
1175 const RECT
*pSourceRect
,
1176 IDirect3DSurface9
*pDestSurface
,
1177 const RECT
*pDestRect
,
1178 D3DTEXTUREFILTERTYPE Filter
)
1180 struct pipe_screen
*screen
= This
->screen
;
1181 struct pipe_context
*pipe
= This
->pipe
;
1182 struct NineSurface9
*dst
= NineSurface9(pDestSurface
);
1183 struct NineSurface9
*src
= NineSurface9(pSourceSurface
);
1184 struct pipe_resource
*dst_res
= NineSurface9_GetResource(dst
);
1185 struct pipe_resource
*src_res
= NineSurface9_GetResource(src
);
1186 const boolean zs
= util_format_is_depth_or_stencil(dst_res
->format
);
1187 struct pipe_blit_info blit
;
1188 boolean scaled
, clamped
, ms
, flip_x
= FALSE
, flip_y
= FALSE
;
1190 DBG("This=%p pSourceSurface=%p pSourceRect=%p pDestSurface=%p "
1191 "pDestRect=%p Filter=%u\n",
1192 This
, pSourceSurface
, pSourceRect
, pDestSurface
, pDestRect
, Filter
);
1194 DBG("pSourceRect=(%u,%u)-(%u,%u)\n",
1195 pSourceRect
->left
, pSourceRect
->top
,
1196 pSourceRect
->right
, pSourceRect
->bottom
);
1198 DBG("pSourceRect=(%u,%u)-(%u,%u)\n", pDestRect
->left
, pDestRect
->top
,
1199 pDestRect
->right
, pDestRect
->bottom
);
1201 user_assert(!zs
|| !This
->in_scene
, D3DERR_INVALIDCALL
);
1202 user_assert(!zs
|| !pSourceRect
||
1203 (pSourceRect
->left
== 0 &&
1204 pSourceRect
->top
== 0 &&
1205 pSourceRect
->right
== src
->desc
.Width
&&
1206 pSourceRect
->bottom
== src
->desc
.Height
), D3DERR_INVALIDCALL
);
1207 user_assert(!zs
|| !pDestRect
||
1208 (pDestRect
->left
== 0 &&
1209 pDestRect
->top
== 0 &&
1210 pDestRect
->right
== dst
->desc
.Width
&&
1211 pDestRect
->bottom
== dst
->desc
.Height
), D3DERR_INVALIDCALL
);
1213 (dst
->desc
.Width
== src
->desc
.Width
&&
1214 dst
->desc
.Height
== src
->desc
.Height
), D3DERR_INVALIDCALL
);
1215 user_assert(zs
|| !util_format_is_depth_or_stencil(src_res
->format
),
1216 D3DERR_INVALIDCALL
);
1217 user_assert(!zs
|| dst
->desc
.Format
== src
->desc
.Format
,
1218 D3DERR_INVALIDCALL
);
1219 user_assert(screen
->is_format_supported(screen
, src_res
->format
,
1221 src_res
->nr_samples
,
1222 PIPE_BIND_SAMPLER_VIEW
),
1223 D3DERR_INVALIDCALL
);
1224 user_assert(dst
->base
.pool
== D3DPOOL_DEFAULT
&&
1225 src
->base
.pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1227 /* We might want to permit these, but wine thinks we shouldn't. */
1228 user_assert(!pDestRect
||
1229 (pDestRect
->left
<= pDestRect
->right
&&
1230 pDestRect
->top
<= pDestRect
->bottom
), D3DERR_INVALIDCALL
);
1231 user_assert(!pSourceRect
||
1232 (pSourceRect
->left
<= pSourceRect
->right
&&
1233 pSourceRect
->top
<= pSourceRect
->bottom
), D3DERR_INVALIDCALL
);
1235 blit
.dst
.resource
= dst_res
;
1236 blit
.dst
.level
= dst
->level
;
1237 blit
.dst
.box
.z
= dst
->layer
;
1238 blit
.dst
.box
.depth
= 1;
1239 blit
.dst
.format
= dst_res
->format
;
1241 flip_x
= pDestRect
->left
> pDestRect
->right
;
1243 blit
.dst
.box
.x
= pDestRect
->right
;
1244 blit
.dst
.box
.width
= pDestRect
->left
- pDestRect
->right
;
1246 blit
.dst
.box
.x
= pDestRect
->left
;
1247 blit
.dst
.box
.width
= pDestRect
->right
- pDestRect
->left
;
1249 flip_y
= pDestRect
->top
> pDestRect
->bottom
;
1251 blit
.dst
.box
.y
= pDestRect
->bottom
;
1252 blit
.dst
.box
.height
= pDestRect
->top
- pDestRect
->bottom
;
1254 blit
.dst
.box
.y
= pDestRect
->top
;
1255 blit
.dst
.box
.height
= pDestRect
->bottom
- pDestRect
->top
;
1260 blit
.dst
.box
.width
= dst
->desc
.Width
;
1261 blit
.dst
.box
.height
= dst
->desc
.Height
;
1263 blit
.src
.resource
= src_res
;
1264 blit
.src
.level
= src
->level
;
1265 blit
.src
.box
.z
= src
->layer
;
1266 blit
.src
.box
.depth
= 1;
1267 blit
.src
.format
= src_res
->format
;
1269 if (flip_x
^ (pSourceRect
->left
> pSourceRect
->right
)) {
1270 blit
.src
.box
.x
= pSourceRect
->right
;
1271 blit
.src
.box
.width
= pSourceRect
->left
- pSourceRect
->right
;
1273 blit
.src
.box
.x
= pSourceRect
->left
;
1274 blit
.src
.box
.width
= pSourceRect
->right
- pSourceRect
->left
;
1276 if (flip_y
^ (pSourceRect
->top
> pSourceRect
->bottom
)) {
1277 blit
.src
.box
.y
= pSourceRect
->bottom
;
1278 blit
.src
.box
.height
= pSourceRect
->top
- pSourceRect
->bottom
;
1280 blit
.src
.box
.y
= pSourceRect
->top
;
1281 blit
.src
.box
.height
= pSourceRect
->bottom
- pSourceRect
->top
;
1284 blit
.src
.box
.x
= flip_x
? src
->desc
.Width
: 0;
1285 blit
.src
.box
.y
= flip_y
? src
->desc
.Height
: 0;
1286 blit
.src
.box
.width
= flip_x
? -src
->desc
.Width
: src
->desc
.Width
;
1287 blit
.src
.box
.height
= flip_y
? -src
->desc
.Height
: src
->desc
.Height
;
1289 blit
.mask
= zs
? PIPE_MASK_ZS
: PIPE_MASK_RGBA
;
1290 blit
.filter
= Filter
== D3DTEXF_LINEAR
?
1291 PIPE_TEX_FILTER_LINEAR
: PIPE_TEX_FILTER_NEAREST
;
1292 blit
.scissor_enable
= FALSE
;
1294 /* If both of a src and dst dimension are negative, flip them. */
1295 if (blit
.dst
.box
.width
< 0 && blit
.src
.box
.width
< 0) {
1296 blit
.dst
.box
.width
= -blit
.dst
.box
.width
;
1297 blit
.src
.box
.width
= -blit
.src
.box
.width
;
1299 if (blit
.dst
.box
.height
< 0 && blit
.src
.box
.height
< 0) {
1300 blit
.dst
.box
.height
= -blit
.dst
.box
.height
;
1301 blit
.src
.box
.height
= -blit
.src
.box
.height
;
1304 blit
.dst
.box
.width
!= blit
.src
.box
.width
||
1305 blit
.dst
.box
.height
!= blit
.src
.box
.height
;
1307 user_assert(!scaled
|| dst
!= src
, D3DERR_INVALIDCALL
);
1308 user_assert(!scaled
||
1309 !NineSurface9_IsOffscreenPlain(dst
) ||
1310 NineSurface9_IsOffscreenPlain(src
), D3DERR_INVALIDCALL
);
1311 user_assert(!scaled
||
1312 (!util_format_is_compressed(dst
->base
.info
.format
) &&
1313 !util_format_is_compressed(src
->base
.info
.format
)),
1314 D3DERR_INVALIDCALL
);
1316 user_warn(src
== dst
&&
1317 u_box_test_intersection_2d(&blit
.src
.box
, &blit
.dst
.box
));
1319 /* Check for clipping/clamping: */
1321 struct pipe_box box
;
1324 xy
= u_box_clip_2d(&box
, &blit
.dst
.box
,
1325 dst
->desc
.Width
, dst
->desc
.Height
);
1329 xy
= u_box_clip_2d(&box
, &blit
.src
.box
,
1330 src
->desc
.Width
, src
->desc
.Height
);
1334 ms
= (dst
->desc
.MultiSampleType
| 1) != (src
->desc
.MultiSampleType
| 1);
1336 if (clamped
|| scaled
|| (blit
.dst
.format
!= blit
.src
.format
) || ms
) {
1337 DBG("using pipe->blit()\n");
1338 /* TODO: software scaling */
1339 user_assert(screen
->is_format_supported(screen
, dst_res
->format
,
1341 dst_res
->nr_samples
,
1342 zs
? PIPE_BIND_DEPTH_STENCIL
:
1343 PIPE_BIND_RENDER_TARGET
),
1344 D3DERR_INVALIDCALL
);
1346 pipe
->blit(pipe
, &blit
);
1348 assert(blit
.dst
.box
.x
>= 0 && blit
.dst
.box
.y
>= 0 &&
1349 blit
.src
.box
.x
>= 0 && blit
.src
.box
.y
>= 0 &&
1350 blit
.dst
.box
.x
+ blit
.dst
.box
.width
<= dst
->desc
.Width
&&
1351 blit
.src
.box
.x
+ blit
.src
.box
.width
<= src
->desc
.Width
&&
1352 blit
.dst
.box
.y
+ blit
.dst
.box
.height
<= dst
->desc
.Height
&&
1353 blit
.src
.box
.y
+ blit
.src
.box
.height
<= src
->desc
.Height
);
1354 /* Or drivers might crash ... */
1355 DBG("Using resource_copy_region.\n");
1356 pipe
->resource_copy_region(pipe
,
1357 blit
.dst
.resource
, blit
.dst
.level
,
1358 blit
.dst
.box
.x
, blit
.dst
.box
.y
, blit
.dst
.box
.z
,
1359 blit
.src
.resource
, blit
.src
.level
,
1367 NineDevice9_ColorFill( struct NineDevice9
*This
,
1368 IDirect3DSurface9
*pSurface
,
1372 struct pipe_context
*pipe
= This
->pipe
;
1373 struct NineSurface9
*surf
= NineSurface9(pSurface
);
1374 struct pipe_surface
*psurf
;
1375 unsigned x
, y
, w
, h
;
1376 union pipe_color_union rgba
;
1379 DBG("This=%p pSurface=%p pRect=%p color=%08x\n", This
,
1380 pSurface
, pRect
, color
);
1382 DBG("pRect=(%u,%u)-(%u,%u)\n", pRect
->left
, pRect
->top
,
1383 pRect
->right
, pRect
->bottom
);
1385 user_assert(surf
->base
.pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1387 user_assert((surf
->base
.usage
& D3DUSAGE_RENDERTARGET
) ||
1388 NineSurface9_IsOffscreenPlain(surf
), D3DERR_INVALIDCALL
);
1393 w
= pRect
->right
- pRect
->left
;
1394 h
= pRect
->bottom
- pRect
->top
;
1398 w
= surf
->desc
.Width
;
1399 h
= surf
->desc
.Height
;
1401 d3dcolor_to_pipe_color_union(&rgba
, color
);
1404 !This
->screen
->is_format_supported(This
->screen
, surf
->base
.info
.format
,
1405 surf
->base
.info
.target
,
1406 surf
->base
.info
.nr_samples
,
1407 PIPE_BIND_RENDER_TARGET
);
1409 psurf
= NineSurface9_GetSurface(surf
, 0);
1415 pipe
->clear_render_target(pipe
, psurf
, &rgba
, x
, y
, w
, h
);
1417 D3DLOCKED_RECT lock
;
1418 union util_color uc
;
1420 /* XXX: lock pRect and fix util_fill_rect */
1421 hr
= NineSurface9_LockRect(surf
, &lock
, NULL
, 0);
1424 util_pack_color_ub(color
>> 16, color
>> 8, color
>> 0, color
>> 24,
1425 surf
->base
.info
.format
, &uc
);
1426 util_fill_rect(lock
.pBits
, surf
->base
.info
.format
,lock
.Pitch
,
1428 NineSurface9_UnlockRect(surf
);
1435 NineDevice9_CreateOffscreenPlainSurface( struct NineDevice9
*This
,
1440 IDirect3DSurface9
**ppSurface
,
1441 HANDLE
*pSharedHandle
)
1445 DBG("This=%p Width=%u Height=%u Format=%s(0x%x) Pool=%u "
1446 "ppSurface=%p pSharedHandle=%p\n", This
,
1447 Width
, Height
, d3dformat_to_string(Format
), Format
, Pool
,
1448 ppSurface
, pSharedHandle
);
1450 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
1451 || Pool
== D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
1452 user_assert(Pool
!= D3DPOOL_MANAGED
, D3DERR_INVALIDCALL
);
1454 /* Can be used with StretchRect and ColorFill. It's also always lockable.
1456 hr
= create_zs_or_rt_surface(This
, 2, Pool
, Width
, Height
,
1458 D3DMULTISAMPLE_NONE
, 0,
1460 ppSurface
, pSharedHandle
);
1462 DBG("Failed to create surface.\n");
1467 NineDevice9_SetRenderTarget( struct NineDevice9
*This
,
1468 DWORD RenderTargetIndex
,
1469 IDirect3DSurface9
*pRenderTarget
)
1471 struct NineSurface9
*rt
= NineSurface9(pRenderTarget
);
1472 const unsigned i
= RenderTargetIndex
;
1474 DBG("This=%p RenderTargetIndex=%u pRenderTarget=%p\n", This
,
1475 RenderTargetIndex
, pRenderTarget
);
1477 user_assert(i
< This
->caps
.NumSimultaneousRTs
, D3DERR_INVALIDCALL
);
1478 user_assert(i
!= 0 || pRenderTarget
, D3DERR_INVALIDCALL
);
1479 user_assert(!pRenderTarget
||
1480 rt
->desc
.Usage
& D3DUSAGE_RENDERTARGET
, D3DERR_INVALIDCALL
);
1483 This
->state
.viewport
.X
= 0;
1484 This
->state
.viewport
.Y
= 0;
1485 This
->state
.viewport
.Width
= rt
->desc
.Width
;
1486 This
->state
.viewport
.Height
= rt
->desc
.Height
;
1487 This
->state
.viewport
.MinZ
= 0.0f
;
1488 This
->state
.viewport
.MaxZ
= 1.0f
;
1490 This
->state
.scissor
.minx
= 0;
1491 This
->state
.scissor
.miny
= 0;
1492 This
->state
.scissor
.maxx
= rt
->desc
.Width
;
1493 This
->state
.scissor
.maxy
= rt
->desc
.Height
;
1495 This
->state
.changed
.group
|= NINE_STATE_VIEWPORT
| NINE_STATE_SCISSOR
;
1498 if (This
->state
.rt
[i
] != NineSurface9(pRenderTarget
)) {
1499 nine_bind(&This
->state
.rt
[i
], pRenderTarget
);
1500 This
->state
.changed
.group
|= NINE_STATE_FB
;
1506 NineDevice9_GetRenderTarget( struct NineDevice9
*This
,
1507 DWORD RenderTargetIndex
,
1508 IDirect3DSurface9
**ppRenderTarget
)
1510 const unsigned i
= RenderTargetIndex
;
1512 user_assert(i
< This
->caps
.NumSimultaneousRTs
, D3DERR_INVALIDCALL
);
1513 user_assert(ppRenderTarget
, D3DERR_INVALIDCALL
);
1515 *ppRenderTarget
= (IDirect3DSurface9
*)This
->state
.rt
[i
];
1516 if (!This
->state
.rt
[i
])
1517 return D3DERR_NOTFOUND
;
1519 NineUnknown_AddRef(NineUnknown(This
->state
.rt
[i
]));
1524 NineDevice9_SetDepthStencilSurface( struct NineDevice9
*This
,
1525 IDirect3DSurface9
*pNewZStencil
)
1527 DBG("This=%p pNewZStencil=%p\n", This
, pNewZStencil
);
1529 if (This
->state
.ds
!= NineSurface9(pNewZStencil
)) {
1530 nine_bind(&This
->state
.ds
, pNewZStencil
);
1531 This
->state
.changed
.group
|= NINE_STATE_FB
;
1537 NineDevice9_GetDepthStencilSurface( struct NineDevice9
*This
,
1538 IDirect3DSurface9
**ppZStencilSurface
)
1540 user_assert(ppZStencilSurface
, D3DERR_INVALIDCALL
);
1542 *ppZStencilSurface
= (IDirect3DSurface9
*)This
->state
.ds
;
1543 if (!This
->state
.ds
)
1544 return D3DERR_NOTFOUND
;
1546 NineUnknown_AddRef(NineUnknown(This
->state
.ds
));
1551 NineDevice9_BeginScene( struct NineDevice9
*This
)
1553 DBG("This=%p\n", This
);
1554 user_assert(!This
->in_scene
, D3DERR_INVALIDCALL
);
1555 This
->in_scene
= TRUE
;
1556 /* Do we want to do anything else here ? */
1561 NineDevice9_EndScene( struct NineDevice9
*This
)
1563 DBG("This=%p\n", This
);
1564 user_assert(This
->in_scene
, D3DERR_INVALIDCALL
);
1565 This
->in_scene
= FALSE
;
1570 NineDevice9_Clear( struct NineDevice9
*This
,
1572 const D3DRECT
*pRects
,
1578 struct pipe_context
*pipe
= This
->pipe
;
1579 struct NineSurface9
*zsbuf
= This
->state
.ds
;
1582 union pipe_color_union rgba
;
1585 DBG("This=%p Count=%u pRects=%p Flags=%x Color=%08x Z=%f Stencil=%x\n",
1586 This
, Count
, pRects
, Flags
, Color
, Z
, Stencil
);
1588 user_assert(This
->state
.ds
|| !(Flags
& NINED3DCLEAR_DEPTHSTENCIL
),
1589 D3DERR_INVALIDCALL
);
1590 user_assert(!(Flags
& D3DCLEAR_STENCIL
) ||
1592 util_format_is_depth_and_stencil(zsbuf
->base
.info
.format
)),
1593 D3DERR_INVALIDCALL
);
1595 user_assert((Count
&& pRects
) || (!Count
&& !pRects
), D3DERR_INVALIDCALL
);
1597 user_warn((pRects
&& !Count
) || (!pRects
&& Count
));
1598 if (pRects
&& !Count
)
1604 if (Flags
& D3DCLEAR_TARGET
) bufs
|= PIPE_CLEAR_COLOR
;
1605 if (Flags
& D3DCLEAR_ZBUFFER
) bufs
|= PIPE_CLEAR_DEPTH
;
1606 if (Flags
& D3DCLEAR_STENCIL
) bufs
|= PIPE_CLEAR_STENCIL
;
1609 d3dcolor_to_pipe_color_union(&rgba
, Color
);
1611 nine_update_state(This
, NINE_STATE_FB
);
1613 rect
.x1
= This
->state
.viewport
.X
;
1614 rect
.y1
= This
->state
.viewport
.Y
;
1615 rect
.x2
= This
->state
.viewport
.Width
+ rect
.x1
;
1616 rect
.y2
= This
->state
.viewport
.Height
+ rect
.y1
;
1618 /* Both rectangles apply, which is weird, but that's D3D9. */
1619 if (This
->state
.rs
[D3DRS_SCISSORTESTENABLE
]) {
1620 rect
.x1
= MAX2(rect
.x1
, This
->state
.scissor
.minx
);
1621 rect
.y1
= MAX2(rect
.y1
, This
->state
.scissor
.miny
);
1622 rect
.x2
= MIN2(rect
.x2
, This
->state
.scissor
.maxx
);
1623 rect
.y2
= MIN2(rect
.y2
, This
->state
.scissor
.maxy
);
1627 /* Maybe apps like to specify a large rect ? */
1628 if (pRects
[0].x1
<= rect
.x1
&& pRects
[0].x2
>= rect
.x2
&&
1629 pRects
[0].y1
<= rect
.y1
&& pRects
[0].y2
>= rect
.y2
) {
1630 DBG("First rect covers viewport.\n");
1636 if (rect
.x1
>= This
->state
.fb
.width
|| rect
.y1
>= This
->state
.fb
.height
)
1639 rect
.x1
== 0 && rect
.x2
>= This
->state
.fb
.width
&&
1640 rect
.y1
== 0 && rect
.y2
>= This
->state
.fb
.height
) {
1641 /* fast path, clears everything at once */
1643 pipe
->clear(pipe
, bufs
, &rgba
, Z
, Stencil
);
1646 rect
.x2
= MIN2(rect
.x2
, This
->state
.fb
.width
);
1647 rect
.y2
= MIN2(rect
.y2
, This
->state
.fb
.height
);
1654 for (i
= 0; (i
< This
->state
.fb
.nr_cbufs
); ++i
) {
1655 if (!This
->state
.fb
.cbufs
[i
] || !(Flags
& D3DCLEAR_TARGET
))
1656 continue; /* save space, compiler should hoist this */
1657 for (r
= 0; r
< Count
; ++r
) {
1658 /* Don't trust users to pass these in the right order. */
1659 unsigned x1
= MIN2(pRects
[r
].x1
, pRects
[r
].x2
);
1660 unsigned y1
= MIN2(pRects
[r
].y1
, pRects
[r
].y2
);
1661 unsigned x2
= MAX2(pRects
[r
].x1
, pRects
[r
].x2
);
1662 unsigned y2
= MAX2(pRects
[r
].y1
, pRects
[r
].y2
);
1664 /* Drop negative rectangles (like wine expects). */
1665 if (pRects
[r
].x1
> pRects
[r
].x2
) continue;
1666 if (pRects
[r
].y1
> pRects
[r
].y2
) continue;
1669 x1
= MAX2(x1
, rect
.x1
);
1670 y1
= MAX2(y1
, rect
.y1
);
1671 x2
= MIN2(x2
, rect
.x2
);
1672 y2
= MIN2(y2
, rect
.y2
);
1674 DBG("Clearing (%u..%u)x(%u..%u)\n", x1
, x2
, y1
, y2
);
1675 pipe
->clear_render_target(pipe
, This
->state
.fb
.cbufs
[i
], &rgba
,
1676 x1
, y1
, x2
- x1
, y2
- y1
);
1679 if (!(Flags
& NINED3DCLEAR_DEPTHSTENCIL
))
1682 bufs
&= PIPE_CLEAR_DEPTHSTENCIL
;
1684 for (r
= 0; r
< Count
; ++r
) {
1685 unsigned x1
= MIN2(pRects
[r
].x1
, pRects
[r
].x2
);
1686 unsigned y1
= MIN2(pRects
[r
].y1
, pRects
[r
].y2
);
1687 unsigned x2
= MAX2(pRects
[r
].x1
, pRects
[r
].x2
);
1688 unsigned y2
= MAX2(pRects
[r
].y1
, pRects
[r
].y2
);
1690 /* Drop negative rectangles. */
1691 if (pRects
[r
].x1
> pRects
[r
].x2
) continue;
1692 if (pRects
[r
].y1
> pRects
[r
].y2
) continue;
1695 x1
= MIN2(x1
, rect
.x1
);
1696 y1
= MIN2(y1
, rect
.y1
);
1697 x2
= MIN2(x2
, rect
.x2
);
1698 y2
= MIN2(y2
, rect
.y2
);
1700 pipe
->clear_depth_stencil(pipe
, This
->state
.fb
.zsbuf
, bufs
, Z
, Stencil
,
1701 x1
, y1
, x2
- x1
, y2
- y1
);
1707 NineDevice9_SetTransform( struct NineDevice9
*This
,
1708 D3DTRANSFORMSTATETYPE State
,
1709 const D3DMATRIX
*pMatrix
)
1711 struct nine_state
*state
= This
->update
;
1712 D3DMATRIX
*M
= nine_state_access_transform(state
, State
, TRUE
);
1713 user_assert(M
, D3DERR_INVALIDCALL
);
1716 state
->ff
.changed
.transform
[State
/ 32] |= 1 << (State
% 32);
1717 state
->changed
.group
|= NINE_STATE_FF
;
1723 NineDevice9_GetTransform( struct NineDevice9
*This
,
1724 D3DTRANSFORMSTATETYPE State
,
1725 D3DMATRIX
*pMatrix
)
1727 D3DMATRIX
*M
= nine_state_access_transform(&This
->state
, State
, FALSE
);
1728 user_assert(M
, D3DERR_INVALIDCALL
);
1734 NineDevice9_MultiplyTransform( struct NineDevice9
*This
,
1735 D3DTRANSFORMSTATETYPE State
,
1736 const D3DMATRIX
*pMatrix
)
1738 struct nine_state
*state
= This
->update
;
1740 D3DMATRIX
*M
= nine_state_access_transform(state
, State
, TRUE
);
1741 user_assert(M
, D3DERR_INVALIDCALL
);
1743 nine_d3d_matrix_matrix_mul(&T
, pMatrix
, M
);
1744 return NineDevice9_SetTransform(This
, State
, &T
);
1748 NineDevice9_SetViewport( struct NineDevice9
*This
,
1749 const D3DVIEWPORT9
*pViewport
)
1751 struct nine_state
*state
= This
->update
;
1753 DBG("X=%u Y=%u W=%u H=%u MinZ=%f MaxZ=%f\n",
1754 pViewport
->X
, pViewport
->Y
, pViewport
->Width
, pViewport
->Height
,
1755 pViewport
->MinZ
, pViewport
->MaxZ
);
1757 state
->viewport
= *pViewport
;
1758 state
->changed
.group
|= NINE_STATE_VIEWPORT
;
1764 NineDevice9_GetViewport( struct NineDevice9
*This
,
1765 D3DVIEWPORT9
*pViewport
)
1767 *pViewport
= This
->state
.viewport
;
1772 NineDevice9_SetMaterial( struct NineDevice9
*This
,
1773 const D3DMATERIAL9
*pMaterial
)
1775 struct nine_state
*state
= This
->update
;
1777 DBG("This=%p pMaterial=%p\n", This
, pMaterial
);
1779 nine_dump_D3DMATERIAL9(DBG_FF
, pMaterial
);
1781 user_assert(pMaterial
, E_POINTER
);
1783 state
->ff
.material
= *pMaterial
;
1784 state
->changed
.group
|= NINE_STATE_FF_MATERIAL
;
1790 NineDevice9_GetMaterial( struct NineDevice9
*This
,
1791 D3DMATERIAL9
*pMaterial
)
1793 user_assert(pMaterial
, E_POINTER
);
1794 *pMaterial
= This
->state
.ff
.material
;
1799 NineDevice9_SetLight( struct NineDevice9
*This
,
1801 const D3DLIGHT9
*pLight
)
1803 struct nine_state
*state
= This
->update
;
1805 DBG("This=%p Index=%u pLight=%p\n", This
, Index
, pLight
);
1807 nine_dump_D3DLIGHT9(DBG_FF
, pLight
);
1809 user_assert(pLight
, D3DERR_INVALIDCALL
);
1810 user_assert(pLight
->Type
< NINED3DLIGHT_INVALID
, D3DERR_INVALIDCALL
);
1812 user_assert(Index
< NINE_MAX_LIGHTS
, D3DERR_INVALIDCALL
); /* sanity */
1814 if (Index
>= state
->ff
.num_lights
) {
1815 unsigned n
= state
->ff
.num_lights
;
1816 unsigned N
= Index
+ 1;
1818 state
->ff
.light
= REALLOC(state
->ff
.light
, n
* sizeof(D3DLIGHT9
),
1819 N
* sizeof(D3DLIGHT9
));
1820 if (!state
->ff
.light
)
1821 return E_OUTOFMEMORY
;
1822 state
->ff
.num_lights
= N
;
1824 for (; n
< Index
; ++n
)
1825 state
->ff
.light
[n
].Type
= (D3DLIGHTTYPE
)NINED3DLIGHT_INVALID
;
1827 state
->ff
.light
[Index
] = *pLight
;
1829 if (pLight
->Type
== D3DLIGHT_SPOT
&& pLight
->Theta
>= pLight
->Phi
) {
1830 DBG("Warning: clamping D3DLIGHT9.Theta\n");
1831 state
->ff
.light
[Index
].Theta
= state
->ff
.light
[Index
].Phi
;
1833 if (pLight
->Type
!= D3DLIGHT_DIRECTIONAL
&&
1834 pLight
->Attenuation0
== 0.0f
&&
1835 pLight
->Attenuation1
== 0.0f
&&
1836 pLight
->Attenuation2
== 0.0f
) {
1837 DBG("Warning: all D3DLIGHT9.Attenuation[i] are 0\n");
1840 state
->changed
.group
|= NINE_STATE_FF_LIGHTING
;
1846 NineDevice9_GetLight( struct NineDevice9
*This
,
1850 const struct nine_state
*state
= &This
->state
;
1852 user_assert(pLight
, D3DERR_INVALIDCALL
);
1853 user_assert(Index
< state
->ff
.num_lights
, D3DERR_INVALIDCALL
);
1854 user_assert(state
->ff
.light
[Index
].Type
< NINED3DLIGHT_INVALID
,
1855 D3DERR_INVALIDCALL
);
1857 *pLight
= state
->ff
.light
[Index
];
1863 NineDevice9_LightEnable( struct NineDevice9
*This
,
1867 struct nine_state
*state
= This
->update
;
1870 DBG("This=%p Index=%u Enable=%i\n", This
, Index
, Enable
);
1872 if (Index
>= state
->ff
.num_lights
||
1873 state
->ff
.light
[Index
].Type
== NINED3DLIGHT_INVALID
) {
1874 /* This should create a default light. */
1876 memset(&light
, 0, sizeof(light
));
1877 light
.Type
= D3DLIGHT_DIRECTIONAL
;
1878 light
.Diffuse
.r
= 1.0f
;
1879 light
.Diffuse
.g
= 1.0f
;
1880 light
.Diffuse
.b
= 1.0f
;
1881 light
.Direction
.z
= 1.0f
;
1882 NineDevice9_SetLight(This
, Index
, &light
);
1884 user_assert(Index
< state
->ff
.num_lights
, D3DERR_INVALIDCALL
);
1886 for (i
= 0; i
< state
->ff
.num_lights_active
; ++i
) {
1887 if (state
->ff
.active_light
[i
] == Index
)
1892 if (i
< state
->ff
.num_lights_active
)
1894 /* XXX wine thinks this should still succeed:
1896 user_assert(i
< NINE_MAX_LIGHTS_ACTIVE
, D3DERR_INVALIDCALL
);
1898 state
->ff
.active_light
[i
] = Index
;
1899 state
->ff
.num_lights_active
++;
1901 if (i
== state
->ff
.num_lights_active
)
1903 --state
->ff
.num_lights_active
;
1904 for (; i
< state
->ff
.num_lights_active
; ++i
)
1905 state
->ff
.active_light
[i
] = state
->ff
.active_light
[i
+ 1];
1907 state
->changed
.group
|= NINE_STATE_FF_LIGHTING
;
1913 NineDevice9_GetLightEnable( struct NineDevice9
*This
,
1917 const struct nine_state
*state
= &This
->state
;
1920 user_assert(Index
< state
->ff
.num_lights
, D3DERR_INVALIDCALL
);
1921 user_assert(state
->ff
.light
[Index
].Type
< NINED3DLIGHT_INVALID
,
1922 D3DERR_INVALIDCALL
);
1924 for (i
= 0; i
< state
->ff
.num_lights_active
; ++i
)
1925 if (state
->ff
.active_light
[i
] == Index
)
1927 *pEnable
= i
!= state
->ff
.num_lights_active
;
1932 NineDevice9_SetClipPlane( struct NineDevice9
*This
,
1934 const float *pPlane
)
1936 struct nine_state
*state
= This
->update
;
1938 DBG("This=%p Index=%u pPlane=%p(%f %f %f %f)\n", This
, Index
, pPlane
,
1939 pPlane
? pPlane
[0] : 0.0f
, pPlane
? pPlane
[1] : 0.0f
,
1940 pPlane
? pPlane
[2] : 0.0f
, pPlane
? pPlane
[3] : 0.0f
);
1942 user_assert(Index
< PIPE_MAX_CLIP_PLANES
, D3DERR_INVALIDCALL
);
1944 memcpy(&state
->clip
.ucp
[Index
][0], pPlane
, sizeof(state
->clip
.ucp
[0]));
1945 state
->changed
.ucp
|= 1 << Index
;
1951 NineDevice9_GetClipPlane( struct NineDevice9
*This
,
1955 const struct nine_state
*state
= &This
->state
;
1957 user_assert(Index
< PIPE_MAX_CLIP_PLANES
, D3DERR_INVALIDCALL
);
1959 memcpy(pPlane
, &state
->clip
.ucp
[Index
][0], sizeof(state
->clip
.ucp
[0]));
1964 NineDevice9_SetRenderState( struct NineDevice9
*This
,
1965 D3DRENDERSTATETYPE State
,
1968 struct nine_state
*state
= This
->update
;
1970 DBG("This=%p State=%u(%s) Value=%08x\n", This
,
1971 State
, nine_d3drs_to_string(State
), Value
);
1973 user_assert(State
< Elements(state
->rs
), D3DERR_INVALIDCALL
);
1975 if (likely(state
->rs
[State
] != Value
) || unlikely(This
->is_recording
)) {
1976 state
->rs
[State
] = Value
;
1977 state
->changed
.rs
[State
/ 32] |= 1 << (State
% 32);
1978 state
->changed
.group
|= nine_render_state_group
[State
];
1985 NineDevice9_GetRenderState( struct NineDevice9
*This
,
1986 D3DRENDERSTATETYPE State
,
1989 user_assert(State
< Elements(This
->state
.rs
), D3DERR_INVALIDCALL
);
1991 *pValue
= This
->state
.rs
[State
];
1996 NineDevice9_CreateStateBlock( struct NineDevice9
*This
,
1997 D3DSTATEBLOCKTYPE Type
,
1998 IDirect3DStateBlock9
**ppSB
)
2000 struct NineStateBlock9
*nsb
;
2001 struct nine_state
*dst
;
2003 enum nine_stateblock_type type
;
2006 DBG("This=%p Type=%u ppSB=%p\n", This
, Type
, ppSB
);
2008 user_assert(Type
== D3DSBT_ALL
||
2009 Type
== D3DSBT_VERTEXSTATE
||
2010 Type
== D3DSBT_PIXELSTATE
, D3DERR_INVALIDCALL
);
2013 case D3DSBT_VERTEXSTATE
: type
= NINESBT_VERTEXSTATE
; break;
2014 case D3DSBT_PIXELSTATE
: type
= NINESBT_PIXELSTATE
; break;
2020 hr
= NineStateBlock9_new(This
, &nsb
, type
);
2023 *ppSB
= (IDirect3DStateBlock9
*)nsb
;
2026 dst
->changed
.group
=
2027 NINE_STATE_TEXTURE
|
2030 if (Type
== D3DSBT_ALL
|| Type
== D3DSBT_VERTEXSTATE
) {
2031 dst
->changed
.group
|=
2032 NINE_STATE_FF_LIGHTING
|
2033 NINE_STATE_VS
| NINE_STATE_VS_CONST
|
2035 /* TODO: texture/sampler state */
2036 memcpy(dst
->changed
.rs
,
2037 nine_render_states_vertex
, sizeof(dst
->changed
.rs
));
2038 nine_ranges_insert(&dst
->changed
.vs_const_f
, 0, This
->max_vs_const_f
,
2040 dst
->changed
.vs_const_i
= 0xffff;
2041 dst
->changed
.vs_const_b
= 0xffff;
2042 for (s
= 0; s
< NINE_MAX_SAMPLERS
; ++s
)
2043 dst
->changed
.sampler
[s
] |= 1 << D3DSAMP_DMAPOFFSET
;
2044 if (This
->state
.ff
.num_lights
) {
2045 dst
->ff
.num_lights
= This
->state
.ff
.num_lights
;
2046 /* zero'd -> light type won't be NINED3DLIGHT_INVALID, so
2047 * all currently existing lights will be captured
2049 dst
->ff
.light
= CALLOC(This
->state
.ff
.num_lights
,
2051 if (!dst
->ff
.light
) {
2052 nine_bind(ppSB
, NULL
);
2053 return E_OUTOFMEMORY
;
2057 if (Type
== D3DSBT_ALL
|| Type
== D3DSBT_PIXELSTATE
) {
2058 dst
->changed
.group
|=
2059 NINE_STATE_PS
| NINE_STATE_PS_CONST
;
2060 /* TODO: texture/sampler state */
2061 memcpy(dst
->changed
.rs
,
2062 nine_render_states_pixel
, sizeof(dst
->changed
.rs
));
2063 nine_ranges_insert(&dst
->changed
.ps_const_f
, 0, This
->max_ps_const_f
,
2065 dst
->changed
.ps_const_i
= 0xffff;
2066 dst
->changed
.ps_const_b
= 0xffff;
2067 for (s
= 0; s
< NINE_MAX_SAMPLERS
; ++s
)
2068 dst
->changed
.sampler
[s
] |= 0x1ffe;
2070 if (Type
== D3DSBT_ALL
) {
2071 dst
->changed
.group
|=
2072 NINE_STATE_VIEWPORT
|
2073 NINE_STATE_SCISSOR
|
2074 NINE_STATE_RASTERIZER
|
2078 NINE_STATE_MATERIAL
|
2079 NINE_STATE_BLEND_COLOR
|
2080 NINE_STATE_SAMPLE_MASK
;
2081 memset(dst
->changed
.rs
, ~0, (D3DRS_COUNT
/ 32) * sizeof(uint32_t));
2082 dst
->changed
.rs
[D3DRS_LAST
/ 32] |= (1 << (D3DRS_COUNT
% 32)) - 1;
2083 dst
->changed
.vtxbuf
= (1ULL << This
->caps
.MaxStreams
) - 1;
2084 dst
->changed
.stream_freq
= dst
->changed
.vtxbuf
;
2085 dst
->changed
.ucp
= (1 << PIPE_MAX_CLIP_PLANES
) - 1;
2086 dst
->changed
.texture
= (1 << NINE_MAX_SAMPLERS
) - 1;
2088 NineStateBlock9_Capture(NineStateBlock9(*ppSB
));
2090 /* TODO: fixed function state */
2096 NineDevice9_BeginStateBlock( struct NineDevice9
*This
)
2100 DBG("This=%p\n", This
);
2102 user_assert(!This
->record
, D3DERR_INVALIDCALL
);
2104 hr
= NineStateBlock9_new(This
, &This
->record
, NINESBT_CUSTOM
);
2107 NineUnknown_ConvertRefToBind(NineUnknown(This
->record
));
2109 This
->update
= &This
->record
->state
;
2110 This
->is_recording
= TRUE
;
2116 NineDevice9_EndStateBlock( struct NineDevice9
*This
,
2117 IDirect3DStateBlock9
**ppSB
)
2119 DBG("This=%p ppSB=%p\n", This
, ppSB
);
2121 user_assert(This
->record
, D3DERR_INVALIDCALL
);
2123 This
->update
= &This
->state
;
2124 This
->is_recording
= FALSE
;
2126 NineUnknown_AddRef(NineUnknown(This
->record
));
2127 *ppSB
= (IDirect3DStateBlock9
*)This
->record
;
2128 NineUnknown_Unbind(NineUnknown(This
->record
));
2129 This
->record
= NULL
;
2135 NineDevice9_SetClipStatus( struct NineDevice9
*This
,
2136 const D3DCLIPSTATUS9
*pClipStatus
)
2138 STUB(D3DERR_INVALIDCALL
);
2142 NineDevice9_GetClipStatus( struct NineDevice9
*This
,
2143 D3DCLIPSTATUS9
*pClipStatus
)
2145 STUB(D3DERR_INVALIDCALL
);
2149 NineDevice9_GetTexture( struct NineDevice9
*This
,
2151 IDirect3DBaseTexture9
**ppTexture
)
2153 user_assert(Stage
< This
->caps
.MaxSimultaneousTextures
||
2154 Stage
== D3DDMAPSAMPLER
||
2155 (Stage
>= D3DVERTEXTEXTURESAMPLER0
&&
2156 Stage
<= D3DVERTEXTEXTURESAMPLER3
), D3DERR_INVALIDCALL
);
2157 user_assert(ppTexture
, D3DERR_INVALIDCALL
);
2159 if (Stage
>= D3DDMAPSAMPLER
)
2160 Stage
= Stage
- D3DDMAPSAMPLER
+ NINE_MAX_SAMPLERS_PS
;
2162 *ppTexture
= (IDirect3DBaseTexture9
*)This
->state
.texture
[Stage
];
2164 if (This
->state
.texture
[Stage
])
2165 NineUnknown_AddRef(NineUnknown(This
->state
.texture
[Stage
]));
2170 NineDevice9_SetTexture( struct NineDevice9
*This
,
2172 IDirect3DBaseTexture9
*pTexture
)
2174 struct nine_state
*state
= This
->update
;
2176 DBG("This=%p Stage=%u pTexture=%p\n", This
, Stage
, pTexture
);
2178 user_assert(Stage
< This
->caps
.MaxSimultaneousTextures
||
2179 Stage
== D3DDMAPSAMPLER
||
2180 (Stage
>= D3DVERTEXTEXTURESAMPLER0
&&
2181 Stage
<= D3DVERTEXTEXTURESAMPLER3
), D3DERR_INVALIDCALL
);
2183 if (Stage
>= D3DDMAPSAMPLER
)
2184 Stage
= Stage
- D3DDMAPSAMPLER
+ NINE_MAX_SAMPLERS_PS
;
2186 if (!This
->is_recording
) {
2187 struct NineBaseTexture9
*tex
= NineBaseTexture9(pTexture
);
2188 struct NineBaseTexture9
*old
= state
->texture
[Stage
];
2192 state
->samplers_shadow
&= ~(1 << Stage
);
2194 state
->samplers_shadow
|= tex
->shadow
<< Stage
;
2196 if ((tex
->dirty
| tex
->dirty_mip
) && LIST_IS_EMPTY(&tex
->list
))
2197 list_add(&tex
->list
, &This
->update_textures
);
2204 nine_bind(&state
->texture
[Stage
], pTexture
);
2206 state
->changed
.texture
|= 1 << Stage
;
2207 state
->changed
.group
|= NINE_STATE_TEXTURE
;
2213 NineDevice9_GetTextureStageState( struct NineDevice9
*This
,
2215 D3DTEXTURESTAGESTATETYPE Type
,
2218 const struct nine_state
*state
= &This
->state
;
2220 user_assert(Stage
< Elements(state
->ff
.tex_stage
), D3DERR_INVALIDCALL
);
2221 user_assert(Type
< Elements(state
->ff
.tex_stage
[0]), D3DERR_INVALIDCALL
);
2223 *pValue
= state
->ff
.tex_stage
[Stage
][Type
];
2229 NineDevice9_SetTextureStageState( struct NineDevice9
*This
,
2231 D3DTEXTURESTAGESTATETYPE Type
,
2234 struct nine_state
*state
= This
->update
;
2236 DBG("Stage=%u Type=%u Value=%08x\n", Stage
, Type
, Value
);
2237 nine_dump_D3DTSS_value(DBG_FF
, Type
, Value
);
2239 user_assert(Stage
< Elements(state
->ff
.tex_stage
), D3DERR_INVALIDCALL
);
2240 user_assert(Type
< Elements(state
->ff
.tex_stage
[0]), D3DERR_INVALIDCALL
);
2242 state
->ff
.tex_stage
[Stage
][Type
] = Value
;
2244 state
->changed
.group
|= NINE_STATE_FF_PSSTAGES
;
2245 state
->ff
.changed
.tex_stage
[Stage
][Type
/ 32] |= 1 << (Type
% 32);
2251 NineDevice9_GetSamplerState( struct NineDevice9
*This
,
2253 D3DSAMPLERSTATETYPE Type
,
2256 user_assert(Sampler
< This
->caps
.MaxSimultaneousTextures
||
2257 Sampler
== D3DDMAPSAMPLER
||
2258 (Sampler
>= D3DVERTEXTEXTURESAMPLER0
&&
2259 Sampler
<= D3DVERTEXTEXTURESAMPLER3
), D3DERR_INVALIDCALL
);
2261 if (Sampler
>= D3DDMAPSAMPLER
)
2262 Sampler
= Sampler
- D3DDMAPSAMPLER
+ NINE_MAX_SAMPLERS_PS
;
2264 *pValue
= This
->state
.samp
[Sampler
][Type
];
2269 NineDevice9_SetSamplerState( struct NineDevice9
*This
,
2271 D3DSAMPLERSTATETYPE Type
,
2274 struct nine_state
*state
= This
->update
;
2276 DBG("This=%p Sampler=%u Type=%s Value=%08x\n", This
,
2277 Sampler
, nine_D3DSAMP_to_str(Type
), Value
);
2279 user_assert(Sampler
< This
->caps
.MaxSimultaneousTextures
||
2280 Sampler
== D3DDMAPSAMPLER
||
2281 (Sampler
>= D3DVERTEXTEXTURESAMPLER0
&&
2282 Sampler
<= D3DVERTEXTEXTURESAMPLER3
), D3DERR_INVALIDCALL
);
2284 if (Sampler
>= D3DDMAPSAMPLER
)
2285 Sampler
= Sampler
- D3DDMAPSAMPLER
+ NINE_MAX_SAMPLERS_PS
;
2287 state
->samp
[Sampler
][Type
] = Value
;
2288 state
->changed
.group
|= NINE_STATE_SAMPLER
;
2289 state
->changed
.sampler
[Sampler
] |= 1 << Type
;
2295 NineDevice9_ValidateDevice( struct NineDevice9
*This
,
2298 const struct nine_state
*state
= &This
->state
;
2300 unsigned w
= 0, h
= 0;
2302 DBG("This=%p pNumPasses=%p\n", This
, pNumPasses
);
2304 for (i
= 0; i
< Elements(state
->samp
); ++i
) {
2305 if (state
->samp
[i
][D3DSAMP_MINFILTER
] == D3DTEXF_NONE
||
2306 state
->samp
[i
][D3DSAMP_MAGFILTER
] == D3DTEXF_NONE
)
2307 return D3DERR_UNSUPPORTEDTEXTUREFILTER
;
2310 for (i
= 0; i
< This
->caps
.NumSimultaneousRTs
; ++i
) {
2314 w
= state
->rt
[i
]->desc
.Width
;
2315 h
= state
->rt
[i
]->desc
.Height
;
2317 if (state
->rt
[i
]->desc
.Width
!= w
|| state
->rt
[i
]->desc
.Height
!= h
) {
2318 return D3DERR_CONFLICTINGRENDERSTATE
;
2322 (state
->rs
[D3DRS_ZENABLE
] || state
->rs
[D3DRS_STENCILENABLE
])) {
2324 (state
->ds
->desc
.Width
!= w
|| state
->ds
->desc
.Height
!= h
))
2325 return D3DERR_CONFLICTINGRENDERSTATE
;
2335 NineDevice9_SetPaletteEntries( struct NineDevice9
*This
,
2337 const PALETTEENTRY
*pEntries
)
2339 STUB(D3D_OK
); /* like wine */
2343 NineDevice9_GetPaletteEntries( struct NineDevice9
*This
,
2345 PALETTEENTRY
*pEntries
)
2347 STUB(D3DERR_INVALIDCALL
);
2351 NineDevice9_SetCurrentTexturePalette( struct NineDevice9
*This
,
2352 UINT PaletteNumber
)
2354 STUB(D3D_OK
); /* like wine */
2358 NineDevice9_GetCurrentTexturePalette( struct NineDevice9
*This
,
2359 UINT
*PaletteNumber
)
2361 STUB(D3DERR_INVALIDCALL
);
2365 NineDevice9_SetScissorRect( struct NineDevice9
*This
,
2368 struct nine_state
*state
= This
->update
;
2370 DBG("x=(%u..%u) y=(%u..%u)\n",
2371 pRect
->left
, pRect
->top
, pRect
->right
, pRect
->bottom
);
2373 state
->scissor
.minx
= pRect
->left
;
2374 state
->scissor
.miny
= pRect
->top
;
2375 state
->scissor
.maxx
= pRect
->right
;
2376 state
->scissor
.maxy
= pRect
->bottom
;
2378 state
->changed
.group
|= NINE_STATE_SCISSOR
;
2384 NineDevice9_GetScissorRect( struct NineDevice9
*This
,
2387 pRect
->left
= This
->state
.scissor
.minx
;
2388 pRect
->top
= This
->state
.scissor
.miny
;
2389 pRect
->right
= This
->state
.scissor
.maxx
;
2390 pRect
->bottom
= This
->state
.scissor
.maxy
;
2396 NineDevice9_SetSoftwareVertexProcessing( struct NineDevice9
*This
,
2399 STUB(D3DERR_INVALIDCALL
);
2403 NineDevice9_GetSoftwareVertexProcessing( struct NineDevice9
*This
)
2405 return !!(This
->params
.BehaviorFlags
& D3DCREATE_SOFTWARE_VERTEXPROCESSING
);
2409 NineDevice9_SetNPatchMode( struct NineDevice9
*This
,
2412 STUB(D3DERR_INVALIDCALL
);
2416 NineDevice9_GetNPatchMode( struct NineDevice9
*This
)
2422 init_draw_info(struct pipe_draw_info
*info
,
2423 struct NineDevice9
*dev
, D3DPRIMITIVETYPE type
, UINT count
)
2425 info
->mode
= d3dprimitivetype_to_pipe_prim(type
);
2426 info
->count
= prim_count_to_vertex_count(type
, count
);
2427 info
->start_instance
= 0;
2428 info
->instance_count
= 1;
2429 if (dev
->state
.stream_instancedata_mask
& dev
->state
.stream_usage_mask
)
2430 info
->instance_count
= MAX2(dev
->state
.stream_freq
[0] & 0x7FFFFF, 1);
2431 info
->primitive_restart
= FALSE
;
2432 info
->restart_index
= 0;
2433 info
->count_from_stream_output
= NULL
;
2434 info
->indirect
= NULL
;
2438 NineDevice9_DrawPrimitive( struct NineDevice9
*This
,
2439 D3DPRIMITIVETYPE PrimitiveType
,
2441 UINT PrimitiveCount
)
2443 struct pipe_draw_info info
;
2445 DBG("iface %p, PrimitiveType %u, StartVertex %u, PrimitiveCount %u\n",
2446 This
, PrimitiveType
, StartVertex
, PrimitiveCount
);
2448 nine_update_state(This
, ~0);
2450 init_draw_info(&info
, This
, PrimitiveType
, PrimitiveCount
);
2451 info
.indexed
= FALSE
;
2452 info
.start
= StartVertex
;
2453 info
.index_bias
= 0;
2454 info
.min_index
= info
.start
;
2455 info
.max_index
= info
.count
- 1;
2457 This
->pipe
->draw_vbo(This
->pipe
, &info
);
2463 NineDevice9_DrawIndexedPrimitive( struct NineDevice9
*This
,
2464 D3DPRIMITIVETYPE PrimitiveType
,
2465 INT BaseVertexIndex
,
2466 UINT MinVertexIndex
,
2469 UINT PrimitiveCount
)
2471 struct pipe_draw_info info
;
2473 DBG("iface %p, PrimitiveType %u, BaseVertexIndex %u, MinVertexIndex %u "
2474 "NumVertices %u, StartIndex %u, PrimitiveCount %u\n",
2475 This
, PrimitiveType
, BaseVertexIndex
, MinVertexIndex
, NumVertices
,
2476 StartIndex
, PrimitiveCount
);
2478 user_assert(This
->state
.idxbuf
, D3DERR_INVALIDCALL
);
2479 user_assert(This
->state
.vdecl
, D3DERR_INVALIDCALL
);
2481 nine_update_state(This
, ~0);
2483 init_draw_info(&info
, This
, PrimitiveType
, PrimitiveCount
);
2484 info
.indexed
= TRUE
;
2485 info
.start
= StartIndex
;
2486 info
.index_bias
= BaseVertexIndex
;
2487 /* These don't include index bias: */
2488 info
.min_index
= MinVertexIndex
;
2489 info
.max_index
= MinVertexIndex
+ NumVertices
- 1;
2491 This
->pipe
->draw_vbo(This
->pipe
, &info
);
2497 NineDevice9_DrawPrimitiveUP( struct NineDevice9
*This
,
2498 D3DPRIMITIVETYPE PrimitiveType
,
2499 UINT PrimitiveCount
,
2500 const void *pVertexStreamZeroData
,
2501 UINT VertexStreamZeroStride
)
2503 struct pipe_vertex_buffer vtxbuf
;
2504 struct pipe_draw_info info
;
2506 DBG("iface %p, PrimitiveType %u, PrimitiveCount %u, data %p, stride %u\n",
2507 This
, PrimitiveType
, PrimitiveCount
,
2508 pVertexStreamZeroData
, VertexStreamZeroStride
);
2510 user_assert(pVertexStreamZeroData
&& VertexStreamZeroStride
,
2511 D3DERR_INVALIDCALL
);
2513 nine_update_state(This
, ~0);
2515 init_draw_info(&info
, This
, PrimitiveType
, PrimitiveCount
);
2516 info
.indexed
= FALSE
;
2518 info
.index_bias
= 0;
2520 info
.max_index
= info
.count
- 1;
2522 vtxbuf
.stride
= VertexStreamZeroStride
;
2523 vtxbuf
.buffer_offset
= 0;
2524 vtxbuf
.buffer
= NULL
;
2525 vtxbuf
.user_buffer
= pVertexStreamZeroData
;
2527 if (!This
->driver_caps
.user_vbufs
)
2528 u_upload_data(This
->upload
,
2530 (info
.max_index
+ 1) * VertexStreamZeroStride
, /* XXX */
2532 &vtxbuf
.buffer_offset
,
2535 This
->pipe
->set_vertex_buffers(This
->pipe
, 0, 1, &vtxbuf
);
2537 This
->pipe
->draw_vbo(This
->pipe
, &info
);
2539 NineDevice9_PauseRecording(This
);
2540 NineDevice9_SetStreamSource(This
, 0, NULL
, 0, 0);
2541 NineDevice9_ResumeRecording(This
);
2543 pipe_resource_reference(&vtxbuf
.buffer
, NULL
);
2549 NineDevice9_DrawIndexedPrimitiveUP( struct NineDevice9
*This
,
2550 D3DPRIMITIVETYPE PrimitiveType
,
2551 UINT MinVertexIndex
,
2553 UINT PrimitiveCount
,
2554 const void *pIndexData
,
2555 D3DFORMAT IndexDataFormat
,
2556 const void *pVertexStreamZeroData
,
2557 UINT VertexStreamZeroStride
)
2559 struct pipe_draw_info info
;
2560 struct pipe_vertex_buffer vbuf
;
2561 struct pipe_index_buffer ibuf
;
2563 DBG("iface %p, PrimitiveType %u, MinVertexIndex %u, NumVertices %u "
2564 "PrimitiveCount %u, pIndexData %p, IndexDataFormat %u "
2565 "pVertexStreamZeroData %p, VertexStreamZeroStride %u\n",
2566 This
, PrimitiveType
, MinVertexIndex
, NumVertices
, PrimitiveCount
,
2567 pIndexData
, IndexDataFormat
,
2568 pVertexStreamZeroData
, VertexStreamZeroStride
);
2570 user_assert(pIndexData
&& pVertexStreamZeroData
, D3DERR_INVALIDCALL
);
2571 user_assert(VertexStreamZeroStride
, D3DERR_INVALIDCALL
);
2572 user_assert(IndexDataFormat
== D3DFMT_INDEX16
||
2573 IndexDataFormat
== D3DFMT_INDEX32
, D3DERR_INVALIDCALL
);
2575 nine_update_state(This
, ~0);
2577 init_draw_info(&info
, This
, PrimitiveType
, PrimitiveCount
);
2578 info
.indexed
= TRUE
;
2580 info
.index_bias
= 0;
2581 info
.min_index
= MinVertexIndex
;
2582 info
.max_index
= MinVertexIndex
+ NumVertices
- 1;
2584 vbuf
.stride
= VertexStreamZeroStride
;
2585 vbuf
.buffer_offset
= 0;
2587 vbuf
.user_buffer
= pVertexStreamZeroData
;
2589 ibuf
.index_size
= (IndexDataFormat
== D3DFMT_INDEX16
) ? 2 : 4;
2592 ibuf
.user_buffer
= pIndexData
;
2594 if (!This
->driver_caps
.user_vbufs
) {
2595 const unsigned base
= info
.min_index
* VertexStreamZeroStride
;
2596 u_upload_data(This
->upload
,
2599 info
.min_index
+ 1) * VertexStreamZeroStride
, /* XXX */
2600 (const uint8_t *)vbuf
.user_buffer
+ base
,
2601 &vbuf
.buffer_offset
,
2603 /* Won't be used: */
2604 vbuf
.buffer_offset
-= base
;
2606 if (!This
->driver_caps
.user_ibufs
)
2607 u_upload_data(This
->upload
,
2609 info
.count
* ibuf
.index_size
,
2614 This
->pipe
->set_vertex_buffers(This
->pipe
, 0, 1, &vbuf
);
2615 This
->pipe
->set_index_buffer(This
->pipe
, &ibuf
);
2617 This
->pipe
->draw_vbo(This
->pipe
, &info
);
2619 pipe_resource_reference(&vbuf
.buffer
, NULL
);
2620 pipe_resource_reference(&ibuf
.buffer
, NULL
);
2622 NineDevice9_PauseRecording(This
);
2623 NineDevice9_SetIndices(This
, NULL
);
2624 NineDevice9_SetStreamSource(This
, 0, NULL
, 0, 0);
2625 NineDevice9_ResumeRecording(This
);
2630 /* TODO: Write to pDestBuffer directly if vertex declaration contains
2634 NineDevice9_ProcessVertices( struct NineDevice9
*This
,
2638 IDirect3DVertexBuffer9
*pDestBuffer
,
2639 IDirect3DVertexDeclaration9
*pVertexDecl
,
2642 struct pipe_screen
*screen
= This
->screen
;
2643 struct NineVertexDeclaration9
*vdecl
= NineVertexDeclaration9(pVertexDecl
);
2644 struct NineVertexShader9
*vs
;
2645 struct pipe_resource
*resource
;
2646 struct pipe_stream_output_target
*target
;
2647 struct pipe_draw_info draw
;
2649 unsigned buffer_offset
, buffer_size
;
2651 if (!screen
->get_param(screen
, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS
))
2652 STUB(D3DERR_INVALIDCALL
);
2654 nine_update_state(This
, ~0);
2656 /* TODO: Create shader with stream output. */
2657 STUB(D3DERR_INVALIDCALL
);
2658 struct NineVertexBuffer9
*dst
= NineVertexBuffer9(pDestBuffer
);
2660 vs
= This
->state
.vs
? This
->state
.vs
: This
->ff
.vs
;
2662 buffer_size
= VertexCount
* vs
->so
->stride
[0];
2664 struct pipe_resource templ
;
2666 templ
.target
= PIPE_BUFFER
;
2667 templ
.format
= PIPE_FORMAT_R8_UNORM
;
2668 templ
.width0
= buffer_size
;
2670 templ
.bind
= PIPE_BIND_STREAM_OUTPUT
;
2671 templ
.usage
= PIPE_USAGE_STREAM
;
2672 templ
.height0
= templ
.depth0
= templ
.array_size
= 1;
2673 templ
.last_level
= templ
.nr_samples
= 0;
2675 resource
= This
->screen
->resource_create(This
->screen
, &templ
);
2677 return E_OUTOFMEMORY
;
2680 /* SO matches vertex declaration */
2681 resource
= dst
->base
.resource
;
2682 buffer_offset
= DestIndex
* vs
->so
->stride
[0];
2684 target
= This
->pipe
->create_stream_output_target(This
->pipe
, resource
,
2688 pipe_resource_reference(&resource
, NULL
);
2689 return D3DERR_DRIVERINTERNALERROR
;
2693 hr
= NineVertexDeclaration9_new_from_fvf(This
, dst
->desc
.FVF
, &vdecl
);
2698 init_draw_info(&draw
, This
, D3DPT_POINTLIST
, VertexCount
);
2699 draw
.instance_count
= 1;
2700 draw
.indexed
= FALSE
;
2701 draw
.start
= SrcStartIndex
;
2702 draw
.index_bias
= 0;
2703 draw
.min_index
= SrcStartIndex
;
2704 draw
.max_index
= SrcStartIndex
+ VertexCount
- 1;
2706 This
->pipe
->set_stream_output_targets(This
->pipe
, 1, &target
, 0);
2707 This
->pipe
->draw_vbo(This
->pipe
, &draw
);
2708 This
->pipe
->set_stream_output_targets(This
->pipe
, 0, NULL
, 0);
2709 This
->pipe
->stream_output_target_destroy(This
->pipe
, target
);
2711 hr
= NineVertexDeclaration9_ConvertStreamOutput(vdecl
,
2712 dst
, DestIndex
, VertexCount
,
2715 pipe_resource_reference(&resource
, NULL
);
2717 NineUnknown_Release(NineUnknown(vdecl
));
2722 NineDevice9_CreateVertexDeclaration( struct NineDevice9
*This
,
2723 const D3DVERTEXELEMENT9
*pVertexElements
,
2724 IDirect3DVertexDeclaration9
**ppDecl
)
2726 struct NineVertexDeclaration9
*vdecl
;
2728 HRESULT hr
= NineVertexDeclaration9_new(This
, pVertexElements
, &vdecl
);
2730 *ppDecl
= (IDirect3DVertexDeclaration9
*)vdecl
;
2736 NineDevice9_SetVertexDeclaration( struct NineDevice9
*This
,
2737 IDirect3DVertexDeclaration9
*pDecl
)
2739 struct nine_state
*state
= This
->update
;
2741 DBG("This=%p pDecl=%p\n", This
, pDecl
);
2743 if (likely(!This
->is_recording
) && state
->vdecl
== NineVertexDeclaration9(pDecl
))
2745 nine_bind(&state
->vdecl
, pDecl
);
2747 state
->changed
.group
|= NINE_STATE_VDECL
;
2753 NineDevice9_GetVertexDeclaration( struct NineDevice9
*This
,
2754 IDirect3DVertexDeclaration9
**ppDecl
)
2756 user_assert(ppDecl
, D3DERR_INVALIDCALL
);
2758 *ppDecl
= (IDirect3DVertexDeclaration9
*)This
->state
.vdecl
;
2760 NineUnknown_AddRef(NineUnknown(*ppDecl
));
2765 NineDevice9_SetFVF( struct NineDevice9
*This
,
2768 struct NineVertexDeclaration9
*vdecl
;
2771 DBG("FVF = %08x\n", FVF
);
2773 return D3D_OK
; /* like wine */
2775 vdecl
= util_hash_table_get(This
->ff
.ht_fvf
, &FVF
);
2777 hr
= NineVertexDeclaration9_new_from_fvf(This
, FVF
, &vdecl
);
2781 util_hash_table_set(This
->ff
.ht_fvf
, &vdecl
->fvf
, vdecl
);
2782 NineUnknown_ConvertRefToBind(NineUnknown(vdecl
));
2784 return NineDevice9_SetVertexDeclaration(
2785 This
, (IDirect3DVertexDeclaration9
*)vdecl
);
2789 NineDevice9_GetFVF( struct NineDevice9
*This
,
2792 *pFVF
= This
->state
.vdecl
? This
->state
.vdecl
->fvf
: 0;
2797 NineDevice9_CreateVertexShader( struct NineDevice9
*This
,
2798 const DWORD
*pFunction
,
2799 IDirect3DVertexShader9
**ppShader
)
2801 struct NineVertexShader9
*vs
;
2804 hr
= NineVertexShader9_new(This
, &vs
, pFunction
, NULL
);
2807 *ppShader
= (IDirect3DVertexShader9
*)vs
;
2812 NineDevice9_SetVertexShader( struct NineDevice9
*This
,
2813 IDirect3DVertexShader9
*pShader
)
2815 struct nine_state
*state
= This
->update
;
2817 DBG("This=%p pShader=%p\n", This
, pShader
);
2819 nine_bind(&state
->vs
, pShader
);
2821 state
->changed
.group
|= NINE_STATE_VS
;
2827 NineDevice9_GetVertexShader( struct NineDevice9
*This
,
2828 IDirect3DVertexShader9
**ppShader
)
2830 user_assert(ppShader
, D3DERR_INVALIDCALL
);
2831 nine_reference_set(ppShader
, This
->state
.vs
);
2836 NineDevice9_SetVertexShaderConstantF( struct NineDevice9
*This
,
2838 const float *pConstantData
,
2839 UINT Vector4fCount
)
2841 struct nine_state
*state
= This
->update
;
2843 DBG("This=%p StartRegister=%u pConstantData=%p Vector4fCount=%u\n",
2844 This
, StartRegister
, pConstantData
, Vector4fCount
);
2846 user_assert(StartRegister
< This
->caps
.MaxVertexShaderConst
, D3DERR_INVALIDCALL
);
2847 user_assert(StartRegister
+ Vector4fCount
<= This
->caps
.MaxVertexShaderConst
, D3DERR_INVALIDCALL
);
2851 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
2853 memcpy(&state
->vs_const_f
[StartRegister
* 4],
2855 Vector4fCount
* 4 * sizeof(state
->vs_const_f
[0]));
2857 nine_ranges_insert(&state
->changed
.vs_const_f
,
2858 StartRegister
, StartRegister
+ Vector4fCount
,
2861 state
->changed
.group
|= NINE_STATE_VS_CONST
;
2867 NineDevice9_GetVertexShaderConstantF( struct NineDevice9
*This
,
2869 float *pConstantData
,
2870 UINT Vector4fCount
)
2872 const struct nine_state
*state
= &This
->state
;
2874 user_assert(StartRegister
< This
->caps
.MaxVertexShaderConst
, D3DERR_INVALIDCALL
);
2875 user_assert(StartRegister
+ Vector4fCount
<= This
->caps
.MaxVertexShaderConst
, D3DERR_INVALIDCALL
);
2876 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
2878 memcpy(pConstantData
,
2879 &state
->vs_const_f
[StartRegister
* 4],
2880 Vector4fCount
* 4 * sizeof(state
->vs_const_f
[0]));
2886 NineDevice9_SetVertexShaderConstantI( struct NineDevice9
*This
,
2888 const int *pConstantData
,
2889 UINT Vector4iCount
)
2891 struct nine_state
*state
= This
->update
;
2893 DBG("This=%p StartRegister=%u pConstantData=%p Vector4iCount=%u\n",
2894 This
, StartRegister
, pConstantData
, Vector4iCount
);
2896 user_assert(StartRegister
< NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
2897 user_assert(StartRegister
+ Vector4iCount
<= NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
2898 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
2900 memcpy(&state
->vs_const_i
[StartRegister
][0],
2902 Vector4iCount
* sizeof(state
->vs_const_i
[0]));
2904 state
->changed
.vs_const_i
|= ((1 << Vector4iCount
) - 1) << StartRegister
;
2905 state
->changed
.group
|= NINE_STATE_VS_CONST
;
2911 NineDevice9_GetVertexShaderConstantI( struct NineDevice9
*This
,
2914 UINT Vector4iCount
)
2916 const struct nine_state
*state
= &This
->state
;
2918 user_assert(StartRegister
< NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
2919 user_assert(StartRegister
+ Vector4iCount
<= NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
2920 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
2922 memcpy(pConstantData
,
2923 &state
->vs_const_i
[StartRegister
][0],
2924 Vector4iCount
* sizeof(state
->vs_const_i
[0]));
2930 NineDevice9_SetVertexShaderConstantB( struct NineDevice9
*This
,
2932 const BOOL
*pConstantData
,
2935 struct nine_state
*state
= This
->update
;
2937 DBG("This=%p StartRegister=%u pConstantData=%p BoolCount=%u\n",
2938 This
, StartRegister
, pConstantData
, BoolCount
);
2940 user_assert(StartRegister
< NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
2941 user_assert(StartRegister
+ BoolCount
<= NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
2942 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
2944 memcpy(&state
->vs_const_b
[StartRegister
],
2946 BoolCount
* sizeof(state
->vs_const_b
[0]));
2948 state
->changed
.vs_const_b
|= ((1 << BoolCount
) - 1) << StartRegister
;
2949 state
->changed
.group
|= NINE_STATE_VS_CONST
;
2955 NineDevice9_GetVertexShaderConstantB( struct NineDevice9
*This
,
2957 BOOL
*pConstantData
,
2960 const struct nine_state
*state
= &This
->state
;
2962 user_assert(StartRegister
< NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
2963 user_assert(StartRegister
+ BoolCount
<= NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
2964 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
2966 memcpy(pConstantData
,
2967 &state
->vs_const_b
[StartRegister
],
2968 BoolCount
* sizeof(state
->vs_const_b
[0]));
2974 NineDevice9_SetStreamSource( struct NineDevice9
*This
,
2976 IDirect3DVertexBuffer9
*pStreamData
,
2980 struct nine_state
*state
= This
->update
;
2981 struct NineVertexBuffer9
*pVBuf9
= NineVertexBuffer9(pStreamData
);
2982 const unsigned i
= StreamNumber
;
2984 user_assert(StreamNumber
< This
->caps
.MaxStreams
, D3DERR_INVALIDCALL
);
2985 user_assert(Stride
<= This
->caps
.MaxStreamStride
, D3DERR_INVALIDCALL
);
2987 if (likely(!This
->is_recording
)) {
2988 if (state
->stream
[i
] == NineVertexBuffer9(pStreamData
) &&
2989 state
->vtxbuf
[i
].stride
== Stride
&&
2990 state
->vtxbuf
[i
].buffer_offset
== OffsetInBytes
)
2993 nine_bind(&state
->stream
[i
], pStreamData
);
2995 state
->changed
.vtxbuf
|= 1 << StreamNumber
;
2998 state
->vtxbuf
[i
].stride
= Stride
;
2999 state
->vtxbuf
[i
].buffer_offset
= OffsetInBytes
;
3001 state
->vtxbuf
[i
].buffer
= pStreamData
? pVBuf9
->base
.resource
: NULL
;
3007 NineDevice9_GetStreamSource( struct NineDevice9
*This
,
3009 IDirect3DVertexBuffer9
**ppStreamData
,
3010 UINT
*pOffsetInBytes
,
3013 const struct nine_state
*state
= &This
->state
;
3014 const unsigned i
= StreamNumber
;
3016 user_assert(StreamNumber
< This
->caps
.MaxStreams
, D3DERR_INVALIDCALL
);
3017 user_assert(ppStreamData
, D3DERR_INVALIDCALL
);
3019 nine_reference_set(ppStreamData
, state
->stream
[i
]);
3020 *pStride
= state
->vtxbuf
[i
].stride
;
3021 *pOffsetInBytes
= state
->vtxbuf
[i
].buffer_offset
;
3027 NineDevice9_SetStreamSourceFreq( struct NineDevice9
*This
,
3031 struct nine_state
*state
= This
->update
;
3032 /* const UINT freq = Setting & 0x7FFFFF; */
3034 DBG("This=%p StreamNumber=%u FrequencyParameter=0x%x\n", This
,
3035 StreamNumber
, Setting
);
3037 user_assert(StreamNumber
< This
->caps
.MaxStreams
, D3DERR_INVALIDCALL
);
3038 user_assert(StreamNumber
!= 0 || !(Setting
& D3DSTREAMSOURCE_INSTANCEDATA
),
3039 D3DERR_INVALIDCALL
);
3040 user_assert(!((Setting
& D3DSTREAMSOURCE_INSTANCEDATA
) &&
3041 (Setting
& D3DSTREAMSOURCE_INDEXEDDATA
)), D3DERR_INVALIDCALL
);
3042 user_assert(Setting
, D3DERR_INVALIDCALL
);
3044 state
->stream_freq
[StreamNumber
] = Setting
;
3046 if (Setting
& D3DSTREAMSOURCE_INSTANCEDATA
)
3047 state
->stream_instancedata_mask
|= 1 << StreamNumber
;
3049 state
->stream_instancedata_mask
&= ~(1 << StreamNumber
);
3051 state
->changed
.stream_freq
|= 1 << StreamNumber
;
3056 NineDevice9_GetStreamSourceFreq( struct NineDevice9
*This
,
3060 user_assert(StreamNumber
< This
->caps
.MaxStreams
, D3DERR_INVALIDCALL
);
3061 *pSetting
= This
->state
.stream_freq
[StreamNumber
];
3066 NineDevice9_SetIndices( struct NineDevice9
*This
,
3067 IDirect3DIndexBuffer9
*pIndexData
)
3069 struct nine_state
*state
= This
->update
;
3071 if (likely(!This
->is_recording
))
3072 if (state
->idxbuf
== NineIndexBuffer9(pIndexData
))
3074 nine_bind(&state
->idxbuf
, pIndexData
);
3076 state
->changed
.group
|= NINE_STATE_IDXBUF
;
3081 /* XXX: wine/d3d9 doesn't have pBaseVertexIndex, and it doesn't make sense
3082 * here because it's an argument passed to the Draw calls.
3085 NineDevice9_GetIndices( struct NineDevice9
*This
,
3086 IDirect3DIndexBuffer9
**ppIndexData
/*,
3087 UINT *pBaseVertexIndex */ )
3089 user_assert(ppIndexData
, D3DERR_INVALIDCALL
);
3090 nine_reference_set(ppIndexData
, This
->state
.idxbuf
);
3095 NineDevice9_CreatePixelShader( struct NineDevice9
*This
,
3096 const DWORD
*pFunction
,
3097 IDirect3DPixelShader9
**ppShader
)
3099 struct NinePixelShader9
*ps
;
3102 hr
= NinePixelShader9_new(This
, &ps
, pFunction
, NULL
);
3105 *ppShader
= (IDirect3DPixelShader9
*)ps
;
3110 NineDevice9_SetPixelShader( struct NineDevice9
*This
,
3111 IDirect3DPixelShader9
*pShader
)
3113 struct nine_state
*state
= This
->update
;
3115 DBG("This=%p pShader=%p\n", This
, pShader
);
3117 nine_bind(&state
->ps
, pShader
);
3119 state
->changed
.group
|= NINE_STATE_PS
;
3125 NineDevice9_GetPixelShader( struct NineDevice9
*This
,
3126 IDirect3DPixelShader9
**ppShader
)
3128 user_assert(ppShader
, D3DERR_INVALIDCALL
);
3129 nine_reference_set(ppShader
, This
->state
.ps
);
3134 NineDevice9_SetPixelShaderConstantF( struct NineDevice9
*This
,
3136 const float *pConstantData
,
3137 UINT Vector4fCount
)
3139 struct nine_state
*state
= This
->update
;
3141 DBG("This=%p StartRegister=%u pConstantData=%p Vector4fCount=%u\n",
3142 This
, StartRegister
, pConstantData
, Vector4fCount
);
3144 user_assert(StartRegister
< NINE_MAX_CONST_F
, D3DERR_INVALIDCALL
);
3145 user_assert(StartRegister
+ Vector4fCount
<= NINE_MAX_CONST_F
, D3DERR_INVALIDCALL
);
3149 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3151 memcpy(&state
->ps_const_f
[StartRegister
* 4],
3153 Vector4fCount
* 4 * sizeof(state
->ps_const_f
[0]));
3155 nine_ranges_insert(&state
->changed
.ps_const_f
,
3156 StartRegister
, StartRegister
+ Vector4fCount
,
3159 state
->changed
.group
|= NINE_STATE_PS_CONST
;
3165 NineDevice9_GetPixelShaderConstantF( struct NineDevice9
*This
,
3167 float *pConstantData
,
3168 UINT Vector4fCount
)
3170 const struct nine_state
*state
= &This
->state
;
3172 user_assert(StartRegister
< NINE_MAX_CONST_F
, D3DERR_INVALIDCALL
);
3173 user_assert(StartRegister
+ Vector4fCount
<= NINE_MAX_CONST_F
, D3DERR_INVALIDCALL
);
3174 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3176 memcpy(pConstantData
,
3177 &state
->ps_const_f
[StartRegister
* 4],
3178 Vector4fCount
* 4 * sizeof(state
->ps_const_f
[0]));
3184 NineDevice9_SetPixelShaderConstantI( struct NineDevice9
*This
,
3186 const int *pConstantData
,
3187 UINT Vector4iCount
)
3189 struct nine_state
*state
= This
->update
;
3191 DBG("This=%p StartRegister=%u pConstantData=%p Vector4iCount=%u\n",
3192 This
, StartRegister
, pConstantData
, Vector4iCount
);
3194 user_assert(StartRegister
< NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3195 user_assert(StartRegister
+ Vector4iCount
<= NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3196 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3198 memcpy(&state
->ps_const_i
[StartRegister
][0],
3200 Vector4iCount
* sizeof(state
->ps_const_i
[0]));
3202 state
->changed
.ps_const_i
|= ((1 << Vector4iCount
) - 1) << StartRegister
;
3203 state
->changed
.group
|= NINE_STATE_PS_CONST
;
3209 NineDevice9_GetPixelShaderConstantI( struct NineDevice9
*This
,
3212 UINT Vector4iCount
)
3214 const struct nine_state
*state
= &This
->state
;
3216 user_assert(StartRegister
< NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3217 user_assert(StartRegister
+ Vector4iCount
<= NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3218 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3220 memcpy(pConstantData
,
3221 &state
->ps_const_i
[StartRegister
][0],
3222 Vector4iCount
* sizeof(state
->ps_const_i
[0]));
3228 NineDevice9_SetPixelShaderConstantB( struct NineDevice9
*This
,
3230 const BOOL
*pConstantData
,
3233 struct nine_state
*state
= This
->update
;
3235 DBG("This=%p StartRegister=%u pConstantData=%p BoolCount=%u\n",
3236 This
, StartRegister
, pConstantData
, BoolCount
);
3238 user_assert(StartRegister
< NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3239 user_assert(StartRegister
+ BoolCount
<= NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3240 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3242 memcpy(&state
->ps_const_b
[StartRegister
],
3244 BoolCount
* sizeof(state
->ps_const_b
[0]));
3246 state
->changed
.ps_const_b
|= ((1 << BoolCount
) - 1) << StartRegister
;
3247 state
->changed
.group
|= NINE_STATE_PS_CONST
;
3253 NineDevice9_GetPixelShaderConstantB( struct NineDevice9
*This
,
3255 BOOL
*pConstantData
,
3258 const struct nine_state
*state
= &This
->state
;
3260 user_assert(StartRegister
< NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3261 user_assert(StartRegister
+ BoolCount
<= NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3262 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3264 memcpy(pConstantData
,
3265 &state
->ps_const_b
[StartRegister
],
3266 BoolCount
* sizeof(state
->ps_const_b
[0]));
3272 NineDevice9_DrawRectPatch( struct NineDevice9
*This
,
3274 const float *pNumSegs
,
3275 const D3DRECTPATCH_INFO
*pRectPatchInfo
)
3277 STUB(D3DERR_INVALIDCALL
);
3281 NineDevice9_DrawTriPatch( struct NineDevice9
*This
,
3283 const float *pNumSegs
,
3284 const D3DTRIPATCH_INFO
*pTriPatchInfo
)
3286 STUB(D3DERR_INVALIDCALL
);
3290 NineDevice9_DeletePatch( struct NineDevice9
*This
,
3293 STUB(D3DERR_INVALIDCALL
);
3297 NineDevice9_CreateQuery( struct NineDevice9
*This
,
3299 IDirect3DQuery9
**ppQuery
)
3301 struct NineQuery9
*query
;
3305 return nine_is_query_supported(Type
);
3307 hr
= NineQuery9_new(This
, &query
, Type
);
3310 *ppQuery
= (IDirect3DQuery9
*)query
;
3314 IDirect3DDevice9Vtbl NineDevice9_vtable
= {
3315 (void *)NineUnknown_QueryInterface
,
3316 (void *)NineUnknown_AddRef
,
3317 (void *)NineUnknown_Release
,
3318 (void *)NineDevice9_TestCooperativeLevel
,
3319 (void *)NineDevice9_GetAvailableTextureMem
,
3320 (void *)NineDevice9_EvictManagedResources
,
3321 (void *)NineDevice9_GetDirect3D
,
3322 (void *)NineDevice9_GetDeviceCaps
,
3323 (void *)NineDevice9_GetDisplayMode
,
3324 (void *)NineDevice9_GetCreationParameters
,
3325 (void *)NineDevice9_SetCursorProperties
,
3326 (void *)NineDevice9_SetCursorPosition
,
3327 (void *)NineDevice9_ShowCursor
,
3328 (void *)NineDevice9_CreateAdditionalSwapChain
,
3329 (void *)NineDevice9_GetSwapChain
,
3330 (void *)NineDevice9_GetNumberOfSwapChains
,
3331 (void *)NineDevice9_Reset
,
3332 (void *)NineDevice9_Present
,
3333 (void *)NineDevice9_GetBackBuffer
,
3334 (void *)NineDevice9_GetRasterStatus
,
3335 (void *)NineDevice9_SetDialogBoxMode
,
3336 (void *)NineDevice9_SetGammaRamp
,
3337 (void *)NineDevice9_GetGammaRamp
,
3338 (void *)NineDevice9_CreateTexture
,
3339 (void *)NineDevice9_CreateVolumeTexture
,
3340 (void *)NineDevice9_CreateCubeTexture
,
3341 (void *)NineDevice9_CreateVertexBuffer
,
3342 (void *)NineDevice9_CreateIndexBuffer
,
3343 (void *)NineDevice9_CreateRenderTarget
,
3344 (void *)NineDevice9_CreateDepthStencilSurface
,
3345 (void *)NineDevice9_UpdateSurface
,
3346 (void *)NineDevice9_UpdateTexture
,
3347 (void *)NineDevice9_GetRenderTargetData
,
3348 (void *)NineDevice9_GetFrontBufferData
,
3349 (void *)NineDevice9_StretchRect
,
3350 (void *)NineDevice9_ColorFill
,
3351 (void *)NineDevice9_CreateOffscreenPlainSurface
,
3352 (void *)NineDevice9_SetRenderTarget
,
3353 (void *)NineDevice9_GetRenderTarget
,
3354 (void *)NineDevice9_SetDepthStencilSurface
,
3355 (void *)NineDevice9_GetDepthStencilSurface
,
3356 (void *)NineDevice9_BeginScene
,
3357 (void *)NineDevice9_EndScene
,
3358 (void *)NineDevice9_Clear
,
3359 (void *)NineDevice9_SetTransform
,
3360 (void *)NineDevice9_GetTransform
,
3361 (void *)NineDevice9_MultiplyTransform
,
3362 (void *)NineDevice9_SetViewport
,
3363 (void *)NineDevice9_GetViewport
,
3364 (void *)NineDevice9_SetMaterial
,
3365 (void *)NineDevice9_GetMaterial
,
3366 (void *)NineDevice9_SetLight
,
3367 (void *)NineDevice9_GetLight
,
3368 (void *)NineDevice9_LightEnable
,
3369 (void *)NineDevice9_GetLightEnable
,
3370 (void *)NineDevice9_SetClipPlane
,
3371 (void *)NineDevice9_GetClipPlane
,
3372 (void *)NineDevice9_SetRenderState
,
3373 (void *)NineDevice9_GetRenderState
,
3374 (void *)NineDevice9_CreateStateBlock
,
3375 (void *)NineDevice9_BeginStateBlock
,
3376 (void *)NineDevice9_EndStateBlock
,
3377 (void *)NineDevice9_SetClipStatus
,
3378 (void *)NineDevice9_GetClipStatus
,
3379 (void *)NineDevice9_GetTexture
,
3380 (void *)NineDevice9_SetTexture
,
3381 (void *)NineDevice9_GetTextureStageState
,
3382 (void *)NineDevice9_SetTextureStageState
,
3383 (void *)NineDevice9_GetSamplerState
,
3384 (void *)NineDevice9_SetSamplerState
,
3385 (void *)NineDevice9_ValidateDevice
,
3386 (void *)NineDevice9_SetPaletteEntries
,
3387 (void *)NineDevice9_GetPaletteEntries
,
3388 (void *)NineDevice9_SetCurrentTexturePalette
,
3389 (void *)NineDevice9_GetCurrentTexturePalette
,
3390 (void *)NineDevice9_SetScissorRect
,
3391 (void *)NineDevice9_GetScissorRect
,
3392 (void *)NineDevice9_SetSoftwareVertexProcessing
,
3393 (void *)NineDevice9_GetSoftwareVertexProcessing
,
3394 (void *)NineDevice9_SetNPatchMode
,
3395 (void *)NineDevice9_GetNPatchMode
,
3396 (void *)NineDevice9_DrawPrimitive
,
3397 (void *)NineDevice9_DrawIndexedPrimitive
,
3398 (void *)NineDevice9_DrawPrimitiveUP
,
3399 (void *)NineDevice9_DrawIndexedPrimitiveUP
,
3400 (void *)NineDevice9_ProcessVertices
,
3401 (void *)NineDevice9_CreateVertexDeclaration
,
3402 (void *)NineDevice9_SetVertexDeclaration
,
3403 (void *)NineDevice9_GetVertexDeclaration
,
3404 (void *)NineDevice9_SetFVF
,
3405 (void *)NineDevice9_GetFVF
,
3406 (void *)NineDevice9_CreateVertexShader
,
3407 (void *)NineDevice9_SetVertexShader
,
3408 (void *)NineDevice9_GetVertexShader
,
3409 (void *)NineDevice9_SetVertexShaderConstantF
,
3410 (void *)NineDevice9_GetVertexShaderConstantF
,
3411 (void *)NineDevice9_SetVertexShaderConstantI
,
3412 (void *)NineDevice9_GetVertexShaderConstantI
,
3413 (void *)NineDevice9_SetVertexShaderConstantB
,
3414 (void *)NineDevice9_GetVertexShaderConstantB
,
3415 (void *)NineDevice9_SetStreamSource
,
3416 (void *)NineDevice9_GetStreamSource
,
3417 (void *)NineDevice9_SetStreamSourceFreq
,
3418 (void *)NineDevice9_GetStreamSourceFreq
,
3419 (void *)NineDevice9_SetIndices
,
3420 (void *)NineDevice9_GetIndices
,
3421 (void *)NineDevice9_CreatePixelShader
,
3422 (void *)NineDevice9_SetPixelShader
,
3423 (void *)NineDevice9_GetPixelShader
,
3424 (void *)NineDevice9_SetPixelShaderConstantF
,
3425 (void *)NineDevice9_GetPixelShaderConstantF
,
3426 (void *)NineDevice9_SetPixelShaderConstantI
,
3427 (void *)NineDevice9_GetPixelShaderConstantI
,
3428 (void *)NineDevice9_SetPixelShaderConstantB
,
3429 (void *)NineDevice9_GetPixelShaderConstantB
,
3430 (void *)NineDevice9_DrawRectPatch
,
3431 (void *)NineDevice9_DrawTriPatch
,
3432 (void *)NineDevice9_DeletePatch
,
3433 (void *)NineDevice9_CreateQuery
3436 static const GUID
*NineDevice9_IIDs
[] = {
3437 &IID_IDirect3DDevice9
,
3443 NineDevice9_new( struct pipe_screen
*pScreen
,
3444 D3DDEVICE_CREATION_PARAMETERS
*pCreationParameters
,
3446 D3DPRESENT_PARAMETERS
*pPresentationParameters
,
3448 ID3DPresentGroup
*pPresentationGroup
,
3449 struct d3dadapter9_context
*pCTX
,
3451 D3DDISPLAYMODEEX
*pFullscreenDisplayMode
,
3452 struct NineDevice9
**ppOut
)
3455 lock
= !!(pCreationParameters
->BehaviorFlags
& D3DCREATE_MULTITHREADED
);
3457 NINE_NEW(Device9
, ppOut
, lock
, /* args */
3458 pScreen
, pCreationParameters
, pCaps
,
3459 pPresentationParameters
, pD3D9
, pPresentationGroup
, pCTX
,
3460 ex
, pFullscreenDisplayMode
);