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"
41 #include "nine_limits.h"
43 #include "pipe/p_screen.h"
44 #include "pipe/p_context.h"
45 #include "pipe/p_config.h"
46 #include "util/u_math.h"
47 #include "util/u_inlines.h"
48 #include "util/u_hash_table.h"
49 #include "util/u_format.h"
50 #include "util/u_surface.h"
51 #include "util/u_upload_mgr.h"
52 #include "hud/hud_context.h"
54 #include "cso_cache/cso_context.h"
56 #define DBG_CHANNEL DBG_DEVICE
58 #if defined(PIPE_CC_GCC) && (defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64))
60 static void nine_setup_fpu()
64 __asm__
__volatile__ ("fnstcw %0" : "=m" (*&c
));
66 /* clear the control word */
68 /* d3d9 doc/wine tests: mask all exceptions, use single-precision
69 * and round to nearest */
72 __asm__
__volatile__ ("fldcw %0" : : "m" (*&c
));
77 static void nine_setup_fpu(void)
79 WARN_ONCE("FPU setup not supported on non-x86 platforms\n");
85 NineDevice9_SetDefaultState( struct NineDevice9
*This
, boolean is_reset
)
87 struct NineSurface9
*refSurf
= NULL
;
89 DBG("This=%p is_reset=%d\n", This
, (int) is_reset
);
91 assert(!This
->is_recording
);
93 nine_state_set_defaults(This
, &This
->caps
, is_reset
);
95 refSurf
= This
->swapchains
[0]->buffers
[0];
98 This
->state
.viewport
.X
= 0;
99 This
->state
.viewport
.Y
= 0;
100 This
->state
.viewport
.Width
= refSurf
->desc
.Width
;
101 This
->state
.viewport
.Height
= refSurf
->desc
.Height
;
103 This
->state
.scissor
.minx
= 0;
104 This
->state
.scissor
.miny
= 0;
105 This
->state
.scissor
.maxx
= refSurf
->desc
.Width
;
106 This
->state
.scissor
.maxy
= refSurf
->desc
.Height
;
108 if (This
->nswapchains
&& This
->swapchains
[0]->params
.EnableAutoDepthStencil
) {
109 nine_context_set_render_state(This
, D3DRS_ZENABLE
, TRUE
);
110 This
->state
.rs_advertised
[D3DRS_ZENABLE
] = TRUE
;
112 if (This
->state
.rs_advertised
[D3DRS_ZENABLE
])
113 NineDevice9_SetDepthStencilSurface(
114 This
, (IDirect3DSurface9
*)This
->swapchains
[0]->zsbuf
);
117 #define GET_PCAP(n) pScreen->get_param(pScreen, PIPE_CAP_##n)
119 NineDevice9_ctor( struct NineDevice9
*This
,
120 struct NineUnknownParams
*pParams
,
121 struct pipe_screen
*pScreen
,
122 D3DDEVICE_CREATION_PARAMETERS
*pCreationParameters
,
124 D3DPRESENT_PARAMETERS
*pPresentationParameters
,
126 ID3DPresentGroup
*pPresentationGroup
,
127 struct d3dadapter9_context
*pCTX
,
129 D3DDISPLAYMODEEX
*pFullscreenDisplayMode
,
130 int minorVersionNum
)
133 HRESULT hr
= NineUnknown_ctor(&This
->base
, pParams
);
135 DBG("This=%p pParams=%p pScreen=%p pCreationParameters=%p pCaps=%p pPresentationParameters=%p "
136 "pD3D9=%p pPresentationGroup=%p pCTX=%p ex=%d pFullscreenDisplayMode=%p\n",
137 This
, pParams
, pScreen
, pCreationParameters
, pCaps
, pPresentationParameters
, pD3D9
,
138 pPresentationGroup
, pCTX
, (int) ex
, pFullscreenDisplayMode
);
140 if (FAILED(hr
)) { return hr
; }
142 list_inithead(&This
->update_buffers
);
143 list_inithead(&This
->update_textures
);
144 list_inithead(&This
->managed_buffers
);
145 list_inithead(&This
->managed_textures
);
147 This
->screen
= pScreen
;
148 This
->screen_sw
= pCTX
->ref
;
151 This
->params
= *pCreationParameters
;
153 This
->present
= pPresentationGroup
;
154 This
->minor_version_num
= minorVersionNum
;
156 IDirect3D9_AddRef(This
->d3d9
);
157 ID3DPresentGroup_AddRef(This
->present
);
159 if (!(This
->params
.BehaviorFlags
& D3DCREATE_FPU_PRESERVE
))
162 if (This
->params
.BehaviorFlags
& D3DCREATE_SOFTWARE_VERTEXPROCESSING
) {
163 DBG("Application asked full Software Vertex Processing.\n");
165 This
->may_swvp
= true;
168 if (This
->params
.BehaviorFlags
& D3DCREATE_MIXED_VERTEXPROCESSING
) {
169 DBG("Application asked mixed Software Vertex Processing.\n");
170 This
->may_swvp
= true;
172 /* TODO: check if swvp is resetted by device Resets */
174 if (This
->may_swvp
&&
175 (This
->screen
->get_shader_param(This
->screen
, PIPE_SHADER_VERTEX
,
176 PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE
)
177 < (NINE_MAX_CONST_F_SWVP
/2) * sizeof(float[4]) ||
178 This
->screen
->get_shader_param(This
->screen
, PIPE_SHADER_VERTEX
,
179 PIPE_SHADER_CAP_MAX_CONST_BUFFERS
) < 5)) {
180 /* Note: We just go on, some apps never use the abilities of
181 * swvp, and just set more constants than allowed at init.
182 * Only cards we support that are affected are the r500 */
183 WARN("Card unable to handle Software Vertex Processing. Game may fail\n");
186 /* When may_swvp, SetConstant* limits are different */
188 This
->caps
.MaxVertexShaderConst
= NINE_MAX_CONST_F_SWVP
;
190 This
->pipe
= This
->screen
->context_create(This
->screen
, NULL
, 0);
191 if (!This
->pipe
) { return E_OUTOFMEMORY
; } /* guess */
192 This
->pipe_sw
= This
->screen_sw
->context_create(This
->screen_sw
, NULL
, 0);
193 if (!This
->pipe_sw
) { return E_OUTOFMEMORY
; }
195 This
->cso
= cso_create_context(This
->pipe
);
196 if (!This
->cso
) { return E_OUTOFMEMORY
; } /* also a guess */
197 This
->cso_sw
= cso_create_context(This
->pipe_sw
);
198 if (!This
->cso_sw
) { return E_OUTOFMEMORY
; }
200 /* Create first, it messes up our state. */
201 This
->hud
= hud_create(This
->pipe
, This
->cso
); /* NULL result is fine */
203 /* Available memory counter. Updated only for allocations with this device
204 * instance. This is the Win 7 behavior.
205 * Win XP shares this counter across multiple devices. */
206 This
->available_texture_mem
= This
->screen
->get_param(This
->screen
, PIPE_CAP_VIDEO_MEMORY
);
207 if (This
->available_texture_mem
< 4096)
208 This
->available_texture_mem
<<= 20;
210 This
->available_texture_mem
= UINT_MAX
;
211 /* We cap texture memory usage to 80% of what is reported free initially
212 * This helps get closer Win behaviour. For example VertexBuffer allocation
213 * still succeeds when texture allocation fails. */
214 This
->available_texture_limit
= This
->available_texture_mem
* 20LL / 100LL;
216 /* create implicit swapchains */
217 This
->nswapchains
= ID3DPresentGroup_GetMultiheadCount(This
->present
);
218 This
->swapchains
= CALLOC(This
->nswapchains
,
219 sizeof(struct NineSwapChain9
*));
220 if (!This
->swapchains
) { return E_OUTOFMEMORY
; }
222 for (i
= 0; i
< This
->nswapchains
; ++i
) {
223 ID3DPresent
*present
;
225 hr
= ID3DPresentGroup_GetPresent(This
->present
, i
, &present
);
230 D3DDISPLAYMODEEX
*mode
= NULL
;
231 struct NineSwapChain9Ex
**ret
=
232 (struct NineSwapChain9Ex
**)&This
->swapchains
[i
];
234 if (pFullscreenDisplayMode
) mode
= &(pFullscreenDisplayMode
[i
]);
235 /* when this is a Device9Ex, it should create SwapChain9Exs */
236 hr
= NineSwapChain9Ex_new(This
, TRUE
, present
,
237 &pPresentationParameters
[i
], pCTX
,
238 This
->params
.hFocusWindow
, mode
, ret
);
240 hr
= NineSwapChain9_new(This
, TRUE
, present
,
241 &pPresentationParameters
[i
], pCTX
,
242 This
->params
.hFocusWindow
,
243 &This
->swapchains
[i
]);
246 ID3DPresent_Release(present
);
249 NineUnknown_ConvertRefToBind(NineUnknown(This
->swapchains
[i
]));
251 hr
= NineSwapChain9_GetBackBuffer(This
->swapchains
[i
], 0,
252 D3DBACKBUFFER_TYPE_MONO
,
253 (IDirect3DSurface9
**)
257 NineUnknown_ConvertRefToBind(NineUnknown(This
->state
.rt
[i
]));
260 /* Initialize a dummy VBO to be used when a vertex declaration does not
261 * specify all the inputs needed by vertex shader, on win default behavior
262 * is to pass 0,0,0,0 to the shader */
264 struct pipe_transfer
*transfer
;
265 struct pipe_resource tmpl
;
269 memset(&tmpl
, 0, sizeof(tmpl
));
270 tmpl
.target
= PIPE_BUFFER
;
271 tmpl
.format
= PIPE_FORMAT_R8_UNORM
;
272 tmpl
.width0
= 16; /* 4 floats */
278 tmpl
.usage
= PIPE_USAGE_DEFAULT
;
279 tmpl
.bind
= PIPE_BIND_VERTEX_BUFFER
;
281 This
->dummy_vbo
= pScreen
->resource_create(pScreen
, &tmpl
);
283 if (!This
->dummy_vbo
)
284 return D3DERR_OUTOFVIDEOMEMORY
;
286 u_box_1d(0, 16, &box
);
287 data
= This
->pipe
->transfer_map(This
->pipe
, This
->dummy_vbo
, 0,
288 PIPE_TRANSFER_WRITE
|
289 PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
,
294 This
->pipe
->transfer_unmap(This
->pipe
, transfer
);
297 This
->cursor
.software
= FALSE
;
298 This
->cursor
.hotspot
.x
= -1;
299 This
->cursor
.hotspot
.y
= -1;
301 struct pipe_resource tmpl
;
302 memset(&tmpl
, 0, sizeof(tmpl
));
303 tmpl
.target
= PIPE_TEXTURE_2D
;
304 tmpl
.format
= PIPE_FORMAT_R8G8B8A8_UNORM
;
311 tmpl
.usage
= PIPE_USAGE_DEFAULT
;
312 tmpl
.bind
= PIPE_BIND_CURSOR
| PIPE_BIND_SAMPLER_VIEW
;
315 This
->cursor
.image
= pScreen
->resource_create(pScreen
, &tmpl
);
316 if (!This
->cursor
.image
)
317 return D3DERR_OUTOFVIDEOMEMORY
;
319 /* For uploading 32x32 (argb) cursor */
320 This
->cursor
.hw_upload_temp
= MALLOC(32 * 4 * 32);
321 if (!This
->cursor
.hw_upload_temp
)
322 return D3DERR_OUTOFVIDEOMEMORY
;
325 /* Create constant buffers. */
327 unsigned max_const_vs
, max_const_ps
;
329 /* vs 3.0: >= 256 float constants, but for cards with exactly 256 slots,
330 * we have to take in some more slots for int and bool*/
331 max_const_vs
= _min(pScreen
->get_shader_param(pScreen
, PIPE_SHADER_VERTEX
,
332 PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE
) /
335 /* ps 3.0: 224 float constants. All cards supported support at least
336 * 256 constants for ps */
337 max_const_ps
= NINE_MAX_CONST_F_PS3
+ (NINE_MAX_CONST_I
+ NINE_MAX_CONST_B
/ 4);
339 This
->max_vs_const_f
= max_const_vs
-
340 (NINE_MAX_CONST_I
+ NINE_MAX_CONST_B
/ 4);
341 This
->max_ps_const_f
= max_const_ps
-
342 (NINE_MAX_CONST_I
+ NINE_MAX_CONST_B
/ 4);
344 This
->vs_const_size
= max_const_vs
* sizeof(float[4]);
345 This
->ps_const_size
= max_const_ps
* sizeof(float[4]);
346 /* Include space for I,B constants for user constbuf. */
347 if (This
->may_swvp
) {
348 This
->state
.vs_const_f_swvp
= CALLOC(NINE_MAX_CONST_F_SWVP
* sizeof(float[4]),1);
349 if (!This
->state
.vs_const_f_swvp
)
350 return E_OUTOFMEMORY
;
351 This
->state
.vs_lconstf_temp
= CALLOC(NINE_MAX_CONST_F_SWVP
* sizeof(float[4]),1);
352 This
->state
.vs_const_i
= CALLOC(NINE_MAX_CONST_I_SWVP
* sizeof(int[4]), 1);
353 This
->state
.vs_const_b
= CALLOC(NINE_MAX_CONST_B_SWVP
* sizeof(BOOL
), 1);
355 This
->state
.vs_const_f_swvp
= NULL
;
356 This
->state
.vs_lconstf_temp
= CALLOC(This
->vs_const_size
,1);
357 This
->state
.vs_const_i
= CALLOC(NINE_MAX_CONST_I
* sizeof(int[4]), 1);
358 This
->state
.vs_const_b
= CALLOC(NINE_MAX_CONST_B
* sizeof(BOOL
), 1);
360 This
->state
.vs_const_f
= CALLOC(This
->vs_const_size
, 1);
361 This
->state
.ps_const_f
= CALLOC(This
->ps_const_size
, 1);
362 This
->state
.ps_lconstf_temp
= CALLOC(This
->ps_const_size
,1);
363 if (!This
->state
.vs_const_f
|| !This
->state
.ps_const_f
||
364 !This
->state
.vs_lconstf_temp
|| !This
->state
.ps_lconstf_temp
||
365 !This
->state
.vs_const_i
|| !This
->state
.vs_const_b
)
366 return E_OUTOFMEMORY
;
368 if (strstr(pScreen
->get_name(pScreen
), "AMD") ||
369 strstr(pScreen
->get_name(pScreen
), "ATI")) {
370 This
->driver_bugs
.buggy_barycentrics
= TRUE
;
374 /* allocate dummy texture/sampler for when there are missing ones bound */
376 struct pipe_resource tmplt
;
377 struct pipe_sampler_view templ
;
378 struct pipe_sampler_state samp
;
379 memset(&tmplt
, 0, sizeof(tmplt
));
380 memset(&samp
, 0, sizeof(samp
));
382 tmplt
.target
= PIPE_TEXTURE_2D
;
386 tmplt
.last_level
= 0;
387 tmplt
.array_size
= 1;
388 tmplt
.usage
= PIPE_USAGE_DEFAULT
;
390 tmplt
.format
= PIPE_FORMAT_B8G8R8A8_UNORM
;
391 tmplt
.bind
= PIPE_BIND_SAMPLER_VIEW
;
392 tmplt
.nr_samples
= 0;
394 This
->dummy_texture
= This
->screen
->resource_create(This
->screen
, &tmplt
);
395 if (!This
->dummy_texture
)
396 return D3DERR_DRIVERINTERNALERROR
;
398 templ
.format
= PIPE_FORMAT_B8G8R8A8_UNORM
;
399 templ
.u
.tex
.first_layer
= 0;
400 templ
.u
.tex
.last_layer
= 0;
401 templ
.u
.tex
.first_level
= 0;
402 templ
.u
.tex
.last_level
= 0;
403 templ
.swizzle_r
= PIPE_SWIZZLE_0
;
404 templ
.swizzle_g
= PIPE_SWIZZLE_0
;
405 templ
.swizzle_b
= PIPE_SWIZZLE_0
;
406 templ
.swizzle_a
= PIPE_SWIZZLE_1
;
407 templ
.target
= This
->dummy_texture
->target
;
409 This
->dummy_sampler_view
= This
->pipe
->create_sampler_view(This
->pipe
, This
->dummy_texture
, &templ
);
410 if (!This
->dummy_sampler_view
)
411 return D3DERR_DRIVERINTERNALERROR
;
413 samp
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
414 samp
.max_lod
= 15.0f
;
415 samp
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
416 samp
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
417 samp
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
418 samp
.min_img_filter
= PIPE_TEX_FILTER_NEAREST
;
419 samp
.mag_img_filter
= PIPE_TEX_FILTER_NEAREST
;
420 samp
.compare_mode
= PIPE_TEX_COMPARE_NONE
;
421 samp
.compare_func
= PIPE_FUNC_LEQUAL
;
422 samp
.normalized_coords
= 1;
423 samp
.seamless_cube_map
= 0;
424 This
->dummy_sampler_state
= samp
;
427 /* Allocate upload helper for drivers that suck (from st pov ;). */
429 This
->driver_caps
.user_vbufs
= GET_PCAP(USER_VERTEX_BUFFERS
);
430 This
->driver_caps
.user_ibufs
= GET_PCAP(USER_INDEX_BUFFERS
);
431 This
->driver_caps
.user_cbufs
= GET_PCAP(USER_CONSTANT_BUFFERS
);
432 This
->driver_caps
.user_sw_vbufs
= This
->screen_sw
->get_param(This
->screen_sw
, PIPE_CAP_USER_VERTEX_BUFFERS
);
433 This
->driver_caps
.user_sw_cbufs
= This
->screen_sw
->get_param(This
->screen_sw
, PIPE_CAP_USER_CONSTANT_BUFFERS
);
435 if (!This
->driver_caps
.user_vbufs
)
436 This
->vertex_uploader
= u_upload_create(This
->pipe
, 65536,
437 PIPE_BIND_VERTEX_BUFFER
, PIPE_USAGE_STREAM
);
438 This
->vertex_sw_uploader
= u_upload_create(This
->pipe_sw
, 65536,
439 PIPE_BIND_VERTEX_BUFFER
, PIPE_USAGE_STREAM
);
440 if (!This
->driver_caps
.user_ibufs
)
441 This
->index_uploader
= u_upload_create(This
->pipe
, 128 * 1024,
442 PIPE_BIND_INDEX_BUFFER
, PIPE_USAGE_STREAM
);
443 if (!This
->driver_caps
.user_cbufs
) {
444 This
->constbuf_alignment
= GET_PCAP(CONSTANT_BUFFER_OFFSET_ALIGNMENT
);
445 This
->constbuf_uploader
= u_upload_create(This
->pipe
, This
->vs_const_size
,
446 PIPE_BIND_CONSTANT_BUFFER
, PIPE_USAGE_STREAM
);
449 This
->constbuf_sw_uploader
= u_upload_create(This
->pipe_sw
, 128 * 1024,
450 PIPE_BIND_CONSTANT_BUFFER
, PIPE_USAGE_STREAM
);
452 This
->driver_caps
.window_space_position_support
= GET_PCAP(TGSI_VS_WINDOW_SPACE_POSITION
);
453 This
->driver_caps
.vs_integer
= pScreen
->get_shader_param(pScreen
, PIPE_SHADER_VERTEX
, PIPE_SHADER_CAP_INTEGERS
);
454 This
->driver_caps
.ps_integer
= pScreen
->get_shader_param(pScreen
, PIPE_SHADER_FRAGMENT
, PIPE_SHADER_CAP_INTEGERS
);
455 This
->driver_caps
.offset_units_unscaled
= GET_PCAP(POLYGON_OFFSET_UNITS_UNSCALED
);
457 nine_ff_init(This
); /* initialize fixed function code */
459 NineDevice9_SetDefaultState(This
, FALSE
);
462 struct pipe_poly_stipple stipple
;
463 memset(&stipple
, ~0, sizeof(stipple
));
464 This
->pipe
->set_polygon_stipple(This
->pipe
, &stipple
);
467 This
->update
= &This
->state
;
469 nine_state_init_sw(This
);
471 ID3DPresentGroup_Release(This
->present
);
478 NineDevice9_dtor( struct NineDevice9
*This
)
482 DBG("This=%p\n", This
);
484 if (This
->pipe
&& This
->cso
)
485 nine_pipe_context_clear(This
);
487 nine_state_destroy_sw(This
);
488 nine_state_clear(&This
->state
, TRUE
);
489 nine_context_clear(&This
->context
);
491 if (This
->vertex_uploader
)
492 u_upload_destroy(This
->vertex_uploader
);
493 if (This
->index_uploader
)
494 u_upload_destroy(This
->index_uploader
);
495 if (This
->constbuf_uploader
)
496 u_upload_destroy(This
->constbuf_uploader
);
497 if (This
->vertex_sw_uploader
)
498 u_upload_destroy(This
->vertex_sw_uploader
);
499 if (This
->constbuf_sw_uploader
)
500 u_upload_destroy(This
->constbuf_sw_uploader
);
502 nine_bind(&This
->record
, NULL
);
504 pipe_sampler_view_reference(&This
->dummy_sampler_view
, NULL
);
505 pipe_resource_reference(&This
->dummy_texture
, NULL
);
506 pipe_resource_reference(&This
->dummy_vbo
, NULL
);
507 FREE(This
->state
.vs_const_f
);
508 FREE(This
->state
.ps_const_f
);
509 FREE(This
->state
.vs_lconstf_temp
);
510 FREE(This
->state
.ps_lconstf_temp
);
511 FREE(This
->state
.vs_const_i
);
512 FREE(This
->state
.vs_const_b
);
513 FREE(This
->state
.vs_const_f_swvp
);
515 pipe_resource_reference(&This
->cursor
.image
, NULL
);
516 FREE(This
->cursor
.hw_upload_temp
);
518 if (This
->swapchains
) {
519 for (i
= 0; i
< This
->nswapchains
; ++i
)
520 if (This
->swapchains
[i
])
521 NineUnknown_Unbind(NineUnknown(This
->swapchains
[i
]));
522 FREE(This
->swapchains
);
525 /* Destroy cso first */
526 if (This
->cso
) { cso_destroy_context(This
->cso
); }
527 if (This
->cso_sw
) { cso_destroy_context(This
->cso_sw
); }
528 if (This
->pipe
&& This
->pipe
->destroy
) { This
->pipe
->destroy(This
->pipe
); }
529 if (This
->pipe_sw
&& This
->pipe_sw
->destroy
) { This
->pipe_sw
->destroy(This
->pipe_sw
); }
531 if (This
->present
) { ID3DPresentGroup_Release(This
->present
); }
532 if (This
->d3d9
) { IDirect3D9_Release(This
->d3d9
); }
534 NineUnknown_dtor(&This
->base
);
538 NineDevice9_GetScreen( struct NineDevice9
*This
)
543 struct pipe_context
*
544 NineDevice9_GetPipe( struct NineDevice9
*This
)
550 NineDevice9_GetCSO( struct NineDevice9
*This
)
556 NineDevice9_GetCaps( struct NineDevice9
*This
)
562 NineDevice9_PauseRecording( struct NineDevice9
*This
)
565 This
->update
= &This
->state
;
566 This
->is_recording
= FALSE
;
571 NineDevice9_ResumeRecording( struct NineDevice9
*This
)
574 This
->update
= &This
->record
->state
;
575 This
->is_recording
= TRUE
;
580 NineDevice9_TestCooperativeLevel( struct NineDevice9
*This
)
582 if (NineSwapChain9_GetOccluded(This
->swapchains
[0])) {
583 This
->device_needs_reset
= TRUE
;
584 return D3DERR_DEVICELOST
;
585 } else if (NineSwapChain9_ResolutionMismatch(This
->swapchains
[0])) {
586 This
->device_needs_reset
= TRUE
;
587 return D3DERR_DEVICENOTRESET
;
588 } else if (This
->device_needs_reset
) {
589 return D3DERR_DEVICENOTRESET
;
596 NineDevice9_GetAvailableTextureMem( struct NineDevice9
*This
)
598 return This
->available_texture_mem
;
602 NineDevice9_EvictManagedResources( struct NineDevice9
*This
)
604 struct NineBaseTexture9
*tex
;
605 struct NineBuffer9
*buf
;
607 DBG("This=%p\n", This
);
608 LIST_FOR_EACH_ENTRY(tex
, &This
->managed_textures
, list2
) {
609 NineBaseTexture9_UnLoad(tex
);
611 /* Vertex/index buffers don't take a lot of space and aren't accounted
612 * for d3d memory usage. Instead of actually freeing from memory,
613 * just mark the buffer dirty to trigger a re-upload later. We
614 * could just ignore, but some bad behaving apps could rely on it (if
615 * they write outside the locked regions typically). */
616 LIST_FOR_EACH_ENTRY(buf
, &This
->managed_buffers
, managed
.list2
) {
617 NineBuffer9_SetDirty(buf
);
624 NineDevice9_GetDirect3D( struct NineDevice9
*This
,
625 IDirect3D9
**ppD3D9
)
627 user_assert(ppD3D9
!= NULL
, E_POINTER
);
628 IDirect3D9_AddRef(This
->d3d9
);
629 *ppD3D9
= This
->d3d9
;
634 NineDevice9_GetDeviceCaps( struct NineDevice9
*This
,
637 user_assert(pCaps
!= NULL
, D3DERR_INVALIDCALL
);
643 NineDevice9_GetDisplayMode( struct NineDevice9
*This
,
645 D3DDISPLAYMODE
*pMode
)
647 DBG("This=%p iSwapChain=%u pMode=%p\n", This
, iSwapChain
, pMode
);
649 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
651 return NineSwapChain9_GetDisplayMode(This
->swapchains
[iSwapChain
], pMode
);
655 NineDevice9_GetCreationParameters( struct NineDevice9
*This
,
656 D3DDEVICE_CREATION_PARAMETERS
*pParameters
)
658 user_assert(pParameters
!= NULL
, D3DERR_INVALIDCALL
);
659 *pParameters
= This
->params
;
664 NineDevice9_SetCursorProperties( struct NineDevice9
*This
,
667 IDirect3DSurface9
*pCursorBitmap
)
669 struct NineSurface9
*surf
= NineSurface9(pCursorBitmap
);
670 struct pipe_context
*pipe
= This
->pipe
;
672 struct pipe_transfer
*transfer
;
676 DBG_FLAG(DBG_SWAPCHAIN
, "This=%p XHotSpot=%u YHotSpot=%u "
677 "pCursorBitmap=%p\n", This
, XHotSpot
, YHotSpot
, pCursorBitmap
);
679 user_assert(pCursorBitmap
, D3DERR_INVALIDCALL
);
680 user_assert(surf
->desc
.Format
== D3DFMT_A8R8G8B8
, D3DERR_INVALIDCALL
);
682 if (This
->swapchains
[0]->params
.Windowed
) {
683 This
->cursor
.w
= MIN2(surf
->desc
.Width
, 32);
684 This
->cursor
.h
= MIN2(surf
->desc
.Height
, 32);
685 hw_cursor
= 1; /* always use hw cursor for windowed mode */
687 This
->cursor
.w
= MIN2(surf
->desc
.Width
, This
->cursor
.image
->width0
);
688 This
->cursor
.h
= MIN2(surf
->desc
.Height
, This
->cursor
.image
->height0
);
689 hw_cursor
= This
->cursor
.w
== 32 && This
->cursor
.h
== 32;
692 u_box_origin_2d(This
->cursor
.w
, This
->cursor
.h
, &box
);
694 ptr
= pipe
->transfer_map(pipe
, This
->cursor
.image
, 0,
695 PIPE_TRANSFER_WRITE
|
696 PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
,
699 ret_err("Failed to update cursor image.\n", D3DERR_DRIVERINTERNALERROR
);
701 This
->cursor
.hotspot
.x
= XHotSpot
;
702 This
->cursor
.hotspot
.y
= YHotSpot
;
704 /* Copy cursor image to internal storage. */
708 const struct util_format_description
*sfmt
=
709 util_format_description(surf
->base
.info
.format
);
712 hr
= NineSurface9_LockRect(surf
, &lock
, NULL
, D3DLOCK_READONLY
);
714 ret_err("Failed to map cursor source image.\n",
715 D3DERR_DRIVERINTERNALERROR
);
717 sfmt
->unpack_rgba_8unorm(ptr
, transfer
->stride
,
718 lock
.pBits
, lock
.Pitch
,
719 This
->cursor
.w
, This
->cursor
.h
);
722 void *data
= lock
.pBits
;
723 /* SetCursor assumes 32x32 argb with pitch 128 */
724 if (lock
.Pitch
!= 128) {
725 sfmt
->unpack_rgba_8unorm(This
->cursor
.hw_upload_temp
, 128,
726 lock
.pBits
, lock
.Pitch
,
728 data
= This
->cursor
.hw_upload_temp
;
730 hw_cursor
= ID3DPresent_SetCursor(This
->swapchains
[0]->present
,
732 &This
->cursor
.hotspot
,
733 This
->cursor
.visible
) == D3D_OK
;
736 NineSurface9_UnlockRect(surf
);
738 pipe
->transfer_unmap(pipe
, transfer
);
740 /* hide cursor if we emulate it */
742 ID3DPresent_SetCursor(This
->swapchains
[0]->present
, NULL
, NULL
, FALSE
);
743 This
->cursor
.software
= !hw_cursor
;
749 NineDevice9_SetCursorPosition( struct NineDevice9
*This
,
754 struct NineSwapChain9
*swap
= This
->swapchains
[0];
756 DBG("This=%p X=%d Y=%d Flags=%d\n", This
, X
, Y
, Flags
);
758 This
->cursor
.pos
.x
= X
;
759 This
->cursor
.pos
.y
= Y
;
761 if (!This
->cursor
.software
)
762 This
->cursor
.software
= ID3DPresent_SetCursorPos(swap
->present
, &This
->cursor
.pos
) != D3D_OK
;
766 NineDevice9_ShowCursor( struct NineDevice9
*This
,
769 BOOL old
= This
->cursor
.visible
;
771 DBG("This=%p bShow=%d\n", This
, (int) bShow
);
773 This
->cursor
.visible
= bShow
&& (This
->cursor
.hotspot
.x
!= -1);
774 if (!This
->cursor
.software
)
775 This
->cursor
.software
= ID3DPresent_SetCursor(This
->swapchains
[0]->present
, NULL
, NULL
, bShow
) != D3D_OK
;
781 NineDevice9_CreateAdditionalSwapChain( struct NineDevice9
*This
,
782 D3DPRESENT_PARAMETERS
*pPresentationParameters
,
783 IDirect3DSwapChain9
**pSwapChain
)
785 struct NineSwapChain9
*swapchain
, *tmplt
= This
->swapchains
[0];
786 ID3DPresent
*present
;
789 DBG("This=%p pPresentationParameters=%p pSwapChain=%p\n",
790 This
, pPresentationParameters
, pSwapChain
);
792 user_assert(pPresentationParameters
, D3DERR_INVALIDCALL
);
793 user_assert(tmplt
->params
.Windowed
&& pPresentationParameters
->Windowed
, D3DERR_INVALIDCALL
);
795 /* TODO: this deserves more tests */
796 if (!pPresentationParameters
->hDeviceWindow
)
797 pPresentationParameters
->hDeviceWindow
= This
->params
.hFocusWindow
;
799 hr
= ID3DPresentGroup_CreateAdditionalPresent(This
->present
, pPresentationParameters
, &present
);
804 hr
= NineSwapChain9_new(This
, FALSE
, present
, pPresentationParameters
,
806 tmplt
->params
.hDeviceWindow
,
811 *pSwapChain
= (IDirect3DSwapChain9
*)swapchain
;
816 NineDevice9_GetSwapChain( struct NineDevice9
*This
,
818 IDirect3DSwapChain9
**pSwapChain
)
820 user_assert(pSwapChain
!= NULL
, D3DERR_INVALIDCALL
);
823 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
825 NineUnknown_AddRef(NineUnknown(This
->swapchains
[iSwapChain
]));
826 *pSwapChain
= (IDirect3DSwapChain9
*)This
->swapchains
[iSwapChain
];
832 NineDevice9_GetNumberOfSwapChains( struct NineDevice9
*This
)
834 return This
->nswapchains
;
838 NineDevice9_Reset( struct NineDevice9
*This
,
839 D3DPRESENT_PARAMETERS
*pPresentationParameters
)
844 DBG("This=%p pPresentationParameters=%p\n", This
, pPresentationParameters
);
846 if (NineSwapChain9_GetOccluded(This
->swapchains
[0])) {
847 This
->device_needs_reset
= TRUE
;
848 return D3DERR_DEVICELOST
;
851 for (i
= 0; i
< This
->nswapchains
; ++i
) {
852 D3DPRESENT_PARAMETERS
*params
= &pPresentationParameters
[i
];
853 hr
= NineSwapChain9_Resize(This
->swapchains
[i
], params
, NULL
);
858 nine_pipe_context_clear(This
);
859 nine_state_clear(&This
->state
, TRUE
);
860 nine_context_clear(&This
->context
);
862 NineDevice9_SetDefaultState(This
, TRUE
);
863 NineDevice9_SetRenderTarget(
864 This
, 0, (IDirect3DSurface9
*)This
->swapchains
[0]->buffers
[0]);
865 /* XXX: better use GetBackBuffer here ? */
867 This
->device_needs_reset
= (hr
!= D3D_OK
);
872 NineDevice9_Present( struct NineDevice9
*This
,
873 const RECT
*pSourceRect
,
874 const RECT
*pDestRect
,
875 HWND hDestWindowOverride
,
876 const RGNDATA
*pDirtyRegion
)
881 DBG("This=%p pSourceRect=%p pDestRect=%p hDestWindowOverride=%p pDirtyRegion=%p\n",
882 This
, pSourceRect
, pDestRect
, hDestWindowOverride
, pDirtyRegion
);
884 /* XXX is this right? */
885 for (i
= 0; i
< This
->nswapchains
; ++i
) {
886 hr
= NineSwapChain9_Present(This
->swapchains
[i
], pSourceRect
, pDestRect
,
887 hDestWindowOverride
, pDirtyRegion
, 0);
888 if (FAILED(hr
)) { return hr
; }
895 NineDevice9_GetBackBuffer( struct NineDevice9
*This
,
898 D3DBACKBUFFER_TYPE Type
,
899 IDirect3DSurface9
**ppBackBuffer
)
901 user_assert(ppBackBuffer
!= NULL
, D3DERR_INVALIDCALL
);
902 /* return NULL on error */
903 *ppBackBuffer
= NULL
;
904 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
906 return NineSwapChain9_GetBackBuffer(This
->swapchains
[iSwapChain
],
907 iBackBuffer
, Type
, ppBackBuffer
);
911 NineDevice9_GetRasterStatus( struct NineDevice9
*This
,
913 D3DRASTER_STATUS
*pRasterStatus
)
915 user_assert(pRasterStatus
!= NULL
, D3DERR_INVALIDCALL
);
916 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
918 return NineSwapChain9_GetRasterStatus(This
->swapchains
[iSwapChain
],
923 NineDevice9_SetDialogBoxMode( struct NineDevice9
*This
,
924 BOOL bEnableDialogs
)
926 STUB(D3DERR_INVALIDCALL
);
930 NineDevice9_SetGammaRamp( struct NineDevice9
*This
,
933 const D3DGAMMARAMP
*pRamp
)
935 DBG("This=%p iSwapChain=%u Flags=%x pRamp=%p\n", This
,
936 iSwapChain
, Flags
, pRamp
);
938 user_warn(iSwapChain
>= This
->nswapchains
);
941 if (pRamp
&& (iSwapChain
< This
->nswapchains
)) {
942 struct NineSwapChain9
*swap
= This
->swapchains
[iSwapChain
];
943 swap
->gamma
= *pRamp
;
944 ID3DPresent_SetGammaRamp(swap
->present
, pRamp
, swap
->params
.hDeviceWindow
);
949 NineDevice9_GetGammaRamp( struct NineDevice9
*This
,
951 D3DGAMMARAMP
*pRamp
)
953 DBG("This=%p iSwapChain=%u pRamp=%p\n", This
, iSwapChain
, pRamp
);
955 user_warn(iSwapChain
>= This
->nswapchains
);
958 if (pRamp
&& (iSwapChain
< This
->nswapchains
))
959 *pRamp
= This
->swapchains
[iSwapChain
]->gamma
;
963 NineDevice9_CreateTexture( struct NineDevice9
*This
,
970 IDirect3DTexture9
**ppTexture
,
971 HANDLE
*pSharedHandle
)
973 struct NineTexture9
*tex
;
976 DBG("This=%p Width=%u Height=%u Levels=%u Usage=%s Format=%s Pool=%s "
977 "ppOut=%p pSharedHandle=%p\n", This
, Width
, Height
, Levels
,
978 nine_D3DUSAGE_to_str(Usage
), d3dformat_to_string(Format
),
979 nine_D3DPOOL_to_str(Pool
), ppTexture
, pSharedHandle
);
981 Usage
&= D3DUSAGE_AUTOGENMIPMAP
| D3DUSAGE_DEPTHSTENCIL
| D3DUSAGE_DMAP
|
982 D3DUSAGE_DYNAMIC
| D3DUSAGE_NONSECURE
| D3DUSAGE_RENDERTARGET
|
983 D3DUSAGE_SOFTWAREPROCESSING
| D3DUSAGE_TEXTAPI
;
987 hr
= NineTexture9_new(This
, Width
, Height
, Levels
, Usage
, Format
, Pool
,
988 &tex
, pSharedHandle
);
990 *ppTexture
= (IDirect3DTexture9
*)tex
;
996 NineDevice9_CreateVolumeTexture( struct NineDevice9
*This
,
1004 IDirect3DVolumeTexture9
**ppVolumeTexture
,
1005 HANDLE
*pSharedHandle
)
1007 struct NineVolumeTexture9
*tex
;
1010 DBG("This=%p Width=%u Height=%u Depth=%u Levels=%u Usage=%s Format=%s Pool=%s "
1011 "ppOut=%p pSharedHandle=%p\n", This
, Width
, Height
, Depth
, Levels
,
1012 nine_D3DUSAGE_to_str(Usage
), d3dformat_to_string(Format
),
1013 nine_D3DPOOL_to_str(Pool
), ppVolumeTexture
, pSharedHandle
);
1015 Usage
&= D3DUSAGE_DYNAMIC
| D3DUSAGE_NONSECURE
|
1016 D3DUSAGE_SOFTWAREPROCESSING
;
1018 *ppVolumeTexture
= NULL
;
1020 hr
= NineVolumeTexture9_new(This
, Width
, Height
, Depth
, Levels
,
1021 Usage
, Format
, Pool
, &tex
, pSharedHandle
);
1023 *ppVolumeTexture
= (IDirect3DVolumeTexture9
*)tex
;
1029 NineDevice9_CreateCubeTexture( struct NineDevice9
*This
,
1035 IDirect3DCubeTexture9
**ppCubeTexture
,
1036 HANDLE
*pSharedHandle
)
1038 struct NineCubeTexture9
*tex
;
1041 DBG("This=%p EdgeLength=%u Levels=%u Usage=%s Format=%s Pool=%s ppOut=%p "
1042 "pSharedHandle=%p\n", This
, EdgeLength
, Levels
,
1043 nine_D3DUSAGE_to_str(Usage
), d3dformat_to_string(Format
),
1044 nine_D3DPOOL_to_str(Pool
), ppCubeTexture
, pSharedHandle
);
1046 Usage
&= D3DUSAGE_AUTOGENMIPMAP
| D3DUSAGE_DEPTHSTENCIL
| D3DUSAGE_DYNAMIC
|
1047 D3DUSAGE_NONSECURE
| D3DUSAGE_RENDERTARGET
|
1048 D3DUSAGE_SOFTWAREPROCESSING
;
1050 *ppCubeTexture
= NULL
;
1052 hr
= NineCubeTexture9_new(This
, EdgeLength
, Levels
, Usage
, Format
, Pool
,
1053 &tex
, pSharedHandle
);
1055 *ppCubeTexture
= (IDirect3DCubeTexture9
*)tex
;
1061 NineDevice9_CreateVertexBuffer( struct NineDevice9
*This
,
1066 IDirect3DVertexBuffer9
**ppVertexBuffer
,
1067 HANDLE
*pSharedHandle
)
1069 struct NineVertexBuffer9
*buf
;
1071 D3DVERTEXBUFFER_DESC desc
;
1073 DBG("This=%p Length=%u Usage=%x FVF=%x Pool=%u ppOut=%p pSharedHandle=%p\n",
1074 This
, Length
, Usage
, FVF
, Pool
, ppVertexBuffer
, pSharedHandle
);
1076 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_NOTAVAILABLE
);
1078 desc
.Format
= D3DFMT_VERTEXDATA
;
1079 desc
.Type
= D3DRTYPE_VERTEXBUFFER
;
1080 desc
.Usage
= Usage
&
1081 (D3DUSAGE_DONOTCLIP
| D3DUSAGE_DYNAMIC
| D3DUSAGE_NONSECURE
|
1082 D3DUSAGE_NPATCHES
| D3DUSAGE_POINTS
| D3DUSAGE_RTPATCHES
|
1083 D3DUSAGE_SOFTWAREPROCESSING
| D3DUSAGE_TEXTAPI
|
1084 D3DUSAGE_WRITEONLY
);
1089 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1090 user_assert(desc
.Usage
== Usage
, D3DERR_INVALIDCALL
);
1092 hr
= NineVertexBuffer9_new(This
, &desc
, &buf
);
1094 *ppVertexBuffer
= (IDirect3DVertexBuffer9
*)buf
;
1099 NineDevice9_CreateIndexBuffer( struct NineDevice9
*This
,
1104 IDirect3DIndexBuffer9
**ppIndexBuffer
,
1105 HANDLE
*pSharedHandle
)
1107 struct NineIndexBuffer9
*buf
;
1109 D3DINDEXBUFFER_DESC desc
;
1111 DBG("This=%p Length=%u Usage=%x Format=%s Pool=%u ppOut=%p "
1112 "pSharedHandle=%p\n", This
, Length
, Usage
,
1113 d3dformat_to_string(Format
), Pool
, ppIndexBuffer
, pSharedHandle
);
1115 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_NOTAVAILABLE
);
1117 desc
.Format
= Format
;
1118 desc
.Type
= D3DRTYPE_INDEXBUFFER
;
1119 desc
.Usage
= Usage
&
1120 (D3DUSAGE_DONOTCLIP
| D3DUSAGE_DYNAMIC
| D3DUSAGE_NONSECURE
|
1121 D3DUSAGE_NPATCHES
| D3DUSAGE_POINTS
| D3DUSAGE_RTPATCHES
|
1122 D3DUSAGE_SOFTWAREPROCESSING
| D3DUSAGE_WRITEONLY
);
1126 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1127 user_assert(desc
.Usage
== Usage
, D3DERR_INVALIDCALL
);
1129 hr
= NineIndexBuffer9_new(This
, &desc
, &buf
);
1131 *ppIndexBuffer
= (IDirect3DIndexBuffer9
*)buf
;
1136 create_zs_or_rt_surface(struct NineDevice9
*This
,
1137 unsigned type
, /* 0 = RT, 1 = ZS, 2 = plain */
1139 UINT Width
, UINT Height
,
1141 D3DMULTISAMPLE_TYPE MultiSample
,
1142 DWORD MultisampleQuality
,
1143 BOOL Discard_or_Lockable
,
1144 IDirect3DSurface9
**ppSurface
,
1145 HANDLE
*pSharedHandle
)
1147 struct NineSurface9
*surface
;
1149 D3DSURFACE_DESC desc
;
1151 DBG("This=%p type=%u Pool=%s Width=%u Height=%u Format=%s MS=%u Quality=%u "
1152 "Discard_or_Lockable=%i ppSurface=%p pSharedHandle=%p\n",
1153 This
, type
, nine_D3DPOOL_to_str(Pool
), Width
, Height
,
1154 d3dformat_to_string(Format
), MultiSample
, MultisampleQuality
,
1155 Discard_or_Lockable
, ppSurface
, pSharedHandle
);
1158 DBG("FIXME Used shared handle! This option isn't probably handled correctly!\n");
1160 user_assert(Width
&& Height
, D3DERR_INVALIDCALL
);
1161 user_assert(Pool
!= D3DPOOL_MANAGED
, D3DERR_INVALIDCALL
);
1163 desc
.Format
= Format
;
1164 desc
.Type
= D3DRTYPE_SURFACE
;
1167 desc
.MultiSampleType
= MultiSample
;
1168 desc
.MultiSampleQuality
= MultisampleQuality
;
1170 desc
.Height
= Height
;
1172 case 0: desc
.Usage
= D3DUSAGE_RENDERTARGET
; break;
1173 case 1: desc
.Usage
= D3DUSAGE_DEPTHSTENCIL
; break;
1174 default: assert(type
== 2); break;
1177 hr
= NineSurface9_new(This
, NULL
, NULL
, NULL
, 0, 0, 0, &desc
, &surface
);
1178 if (SUCCEEDED(hr
)) {
1179 *ppSurface
= (IDirect3DSurface9
*)surface
;
1181 if (surface
->base
.resource
&& Discard_or_Lockable
&& (type
!= 1))
1182 surface
->base
.resource
->flags
|= NINE_RESOURCE_FLAG_LOCKABLE
;
1189 NineDevice9_CreateRenderTarget( struct NineDevice9
*This
,
1193 D3DMULTISAMPLE_TYPE MultiSample
,
1194 DWORD MultisampleQuality
,
1196 IDirect3DSurface9
**ppSurface
,
1197 HANDLE
*pSharedHandle
)
1200 return create_zs_or_rt_surface(This
, 0, D3DPOOL_DEFAULT
,
1201 Width
, Height
, Format
,
1202 MultiSample
, MultisampleQuality
,
1203 Lockable
, ppSurface
, pSharedHandle
);
1207 NineDevice9_CreateDepthStencilSurface( struct NineDevice9
*This
,
1211 D3DMULTISAMPLE_TYPE MultiSample
,
1212 DWORD MultisampleQuality
,
1214 IDirect3DSurface9
**ppSurface
,
1215 HANDLE
*pSharedHandle
)
1218 if (!depth_stencil_format(Format
))
1219 return D3DERR_NOTAVAILABLE
;
1220 return create_zs_or_rt_surface(This
, 1, D3DPOOL_DEFAULT
,
1221 Width
, Height
, Format
,
1222 MultiSample
, MultisampleQuality
,
1223 Discard
, ppSurface
, pSharedHandle
);
1227 NineDevice9_UpdateSurface( struct NineDevice9
*This
,
1228 IDirect3DSurface9
*pSourceSurface
,
1229 const RECT
*pSourceRect
,
1230 IDirect3DSurface9
*pDestinationSurface
,
1231 const POINT
*pDestPoint
)
1233 struct NineSurface9
*dst
= NineSurface9(pDestinationSurface
);
1234 struct NineSurface9
*src
= NineSurface9(pSourceSurface
);
1235 int copy_width
, copy_height
;
1238 DBG("This=%p pSourceSurface=%p pDestinationSurface=%p "
1239 "pSourceRect=%p pDestPoint=%p\n", This
,
1240 pSourceSurface
, pDestinationSurface
, pSourceRect
, pDestPoint
);
1242 DBG("pSourceRect = (%u,%u)-(%u,%u)\n",
1243 pSourceRect
->left
, pSourceRect
->top
,
1244 pSourceRect
->right
, pSourceRect
->bottom
);
1246 DBG("pDestPoint = (%u,%u)\n", pDestPoint
->x
, pDestPoint
->y
);
1248 user_assert(dst
&& src
, D3DERR_INVALIDCALL
);
1250 user_assert(dst
->base
.pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1251 user_assert(src
->base
.pool
== D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
1253 user_assert(dst
->desc
.MultiSampleType
== D3DMULTISAMPLE_NONE
, D3DERR_INVALIDCALL
);
1254 user_assert(src
->desc
.MultiSampleType
== D3DMULTISAMPLE_NONE
, D3DERR_INVALIDCALL
);
1256 user_assert(!src
->lock_count
, D3DERR_INVALIDCALL
);
1257 user_assert(!dst
->lock_count
, D3DERR_INVALIDCALL
);
1259 user_assert(dst
->desc
.Format
== src
->desc
.Format
, D3DERR_INVALIDCALL
);
1260 user_assert(!depth_stencil_format(dst
->desc
.Format
), D3DERR_INVALIDCALL
);
1263 copy_width
= pSourceRect
->right
- pSourceRect
->left
;
1264 copy_height
= pSourceRect
->bottom
- pSourceRect
->top
;
1266 user_assert(pSourceRect
->left
>= 0 &&
1268 pSourceRect
->right
<= src
->desc
.Width
&&
1269 pSourceRect
->top
>= 0 &&
1271 pSourceRect
->bottom
<= src
->desc
.Height
,
1272 D3DERR_INVALIDCALL
);
1274 copy_width
= src
->desc
.Width
;
1275 copy_height
= src
->desc
.Height
;
1278 destRect
.right
= copy_width
;
1279 destRect
.bottom
= copy_height
;
1282 user_assert(pDestPoint
->x
>= 0 && pDestPoint
->y
>= 0,
1283 D3DERR_INVALIDCALL
);
1284 destRect
.right
+= pDestPoint
->x
;
1285 destRect
.bottom
+= pDestPoint
->y
;
1288 user_assert(destRect
.right
<= dst
->desc
.Width
&&
1289 destRect
.bottom
<= dst
->desc
.Height
,
1290 D3DERR_INVALIDCALL
);
1292 if (compressed_format(dst
->desc
.Format
)) {
1293 const unsigned w
= util_format_get_blockwidth(dst
->base
.info
.format
);
1294 const unsigned h
= util_format_get_blockheight(dst
->base
.info
.format
);
1297 user_assert(!(pDestPoint
->x
% w
) && !(pDestPoint
->y
% h
),
1298 D3DERR_INVALIDCALL
);
1302 user_assert(!(pSourceRect
->left
% w
) && !(pSourceRect
->top
% h
),
1303 D3DERR_INVALIDCALL
);
1305 if (!(copy_width
== src
->desc
.Width
&&
1306 copy_width
== dst
->desc
.Width
&&
1307 copy_height
== src
->desc
.Height
&&
1308 copy_height
== dst
->desc
.Height
)) {
1309 user_assert(!(copy_width
% w
) && !(copy_height
% h
),
1310 D3DERR_INVALIDCALL
);
1314 NineSurface9_CopyMemToDefault(dst
, src
, pDestPoint
, pSourceRect
);
1320 NineDevice9_UpdateTexture( struct NineDevice9
*This
,
1321 IDirect3DBaseTexture9
*pSourceTexture
,
1322 IDirect3DBaseTexture9
*pDestinationTexture
)
1324 struct NineBaseTexture9
*dstb
= NineBaseTexture9(pDestinationTexture
);
1325 struct NineBaseTexture9
*srcb
= NineBaseTexture9(pSourceTexture
);
1327 unsigned last_src_level
, last_dst_level
;
1330 DBG("This=%p pSourceTexture=%p pDestinationTexture=%p\n", This
,
1331 pSourceTexture
, pDestinationTexture
);
1333 user_assert(pSourceTexture
&& pDestinationTexture
, D3DERR_INVALIDCALL
);
1334 user_assert(pSourceTexture
!= pDestinationTexture
, D3DERR_INVALIDCALL
);
1336 user_assert(dstb
->base
.pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1337 user_assert(srcb
->base
.pool
== D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
1338 user_assert(dstb
->base
.type
== srcb
->base
.type
, D3DERR_INVALIDCALL
);
1339 user_assert(!(srcb
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
) ||
1340 dstb
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
, D3DERR_INVALIDCALL
);
1343 * . Different formats
1344 * . Fewer src levels than dst levels (if the opposite, only matching levels
1345 * are supposed to be copied)
1346 * . Levels do not match
1347 * DDI: Actually the above should pass because of legacy applications
1348 * Do what you want about these, but you shouldn't crash.
1349 * However driver can expect that the top dimension is greater for src than dst.
1350 * Wine tests: Every combination that passes the initial checks should pass.
1351 * . Different formats => conversion driver and format dependent.
1352 * . 1 level, but size not matching => copy is done (and even crash if src bigger
1353 * than dst. For the case where dst bigger, wine doesn't test if a stretch is applied
1354 * or if a subrect is copied).
1355 * . 8x8 4 sublevels -> 7x7 2 sublevels => driver dependent, On NV seems to be 4x4 subrect
1358 * From these, the proposal is:
1359 * . Different formats -> use util_format_translate to translate if possible for surfaces.
1360 * Accept ARGB/XRGB for Volumes. Do nothing for the other combinations
1361 * . First level copied -> the first level such that src is smaller or equal to dst first level
1362 * . number of levels copied -> as long as it fits and textures have levels
1363 * That should satisfy the constraints (and instead of crashing for some cases we return D3D_OK)
1366 last_src_level
= (srcb
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
) ? 0 : srcb
->base
.info
.last_level
;
1367 last_dst_level
= (dstb
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
) ? 0 : dstb
->base
.info
.last_level
;
1369 for (m
= 0; m
<= last_src_level
; ++m
) {
1370 unsigned w
= u_minify(srcb
->base
.info
.width0
, m
);
1371 unsigned h
= u_minify(srcb
->base
.info
.height0
, m
);
1372 unsigned d
= u_minify(srcb
->base
.info
.depth0
, m
);
1374 if (w
<= dstb
->base
.info
.width0
&&
1375 h
<= dstb
->base
.info
.height0
&&
1376 d
<= dstb
->base
.info
.depth0
)
1379 user_assert(m
<= last_src_level
, D3D_OK
);
1381 last_dst_level
= MIN2(srcb
->base
.info
.last_level
- m
, last_dst_level
);
1383 if (dstb
->base
.type
== D3DRTYPE_TEXTURE
) {
1384 struct NineTexture9
*dst
= NineTexture9(dstb
);
1385 struct NineTexture9
*src
= NineTexture9(srcb
);
1387 if (src
->dirty_rect
.width
== 0)
1390 pipe_box_to_rect(&rect
, &src
->dirty_rect
);
1391 for (l
= 0; l
< m
; ++l
)
1392 rect_minify_inclusive(&rect
);
1394 for (l
= 0; l
<= last_dst_level
; ++l
, ++m
) {
1395 fit_rect_format_inclusive(dst
->base
.base
.info
.format
,
1397 dst
->surfaces
[l
]->desc
.Width
,
1398 dst
->surfaces
[l
]->desc
.Height
);
1399 NineSurface9_CopyMemToDefault(dst
->surfaces
[l
],
1403 rect_minify_inclusive(&rect
);
1405 u_box_origin_2d(0, 0, &src
->dirty_rect
);
1407 if (dstb
->base
.type
== D3DRTYPE_CUBETEXTURE
) {
1408 struct NineCubeTexture9
*dst
= NineCubeTexture9(dstb
);
1409 struct NineCubeTexture9
*src
= NineCubeTexture9(srcb
);
1412 /* GPUs usually have them stored as arrays of mip-mapped 2D textures. */
1413 for (z
= 0; z
< 6; ++z
) {
1414 if (src
->dirty_rect
[z
].width
== 0)
1417 pipe_box_to_rect(&rect
, &src
->dirty_rect
[z
]);
1418 for (l
= 0; l
< m
; ++l
)
1419 rect_minify_inclusive(&rect
);
1421 for (l
= 0; l
<= last_dst_level
; ++l
, ++m
) {
1422 fit_rect_format_inclusive(dst
->base
.base
.info
.format
,
1424 dst
->surfaces
[l
* 6 + z
]->desc
.Width
,
1425 dst
->surfaces
[l
* 6 + z
]->desc
.Height
);
1426 NineSurface9_CopyMemToDefault(dst
->surfaces
[l
* 6 + z
],
1427 src
->surfaces
[m
* 6 + z
],
1430 rect_minify_inclusive(&rect
);
1432 u_box_origin_2d(0, 0, &src
->dirty_rect
[z
]);
1436 if (dstb
->base
.type
== D3DRTYPE_VOLUMETEXTURE
) {
1437 struct NineVolumeTexture9
*dst
= NineVolumeTexture9(dstb
);
1438 struct NineVolumeTexture9
*src
= NineVolumeTexture9(srcb
);
1440 if (src
->dirty_box
.width
== 0)
1442 for (l
= 0; l
<= last_dst_level
; ++l
, ++m
)
1443 NineVolume9_CopyMemToDefault(dst
->volumes
[l
],
1444 src
->volumes
[m
], 0, 0, 0, NULL
);
1445 u_box_3d(0, 0, 0, 0, 0, 0, &src
->dirty_box
);
1447 assert(!"invalid texture type");
1450 if (dstb
->base
.usage
& D3DUSAGE_AUTOGENMIPMAP
) {
1451 dstb
->dirty_mip
= TRUE
;
1452 NineBaseTexture9_GenerateMipSubLevels(dstb
);
1459 NineDevice9_GetRenderTargetData( struct NineDevice9
*This
,
1460 IDirect3DSurface9
*pRenderTarget
,
1461 IDirect3DSurface9
*pDestSurface
)
1463 struct NineSurface9
*dst
= NineSurface9(pDestSurface
);
1464 struct NineSurface9
*src
= NineSurface9(pRenderTarget
);
1466 DBG("This=%p pRenderTarget=%p pDestSurface=%p\n",
1467 This
, pRenderTarget
, pDestSurface
);
1469 user_assert(pRenderTarget
&& pDestSurface
, D3DERR_INVALIDCALL
);
1471 user_assert(dst
->desc
.Pool
== D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
1472 user_assert(src
->desc
.Pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1474 user_assert(dst
->desc
.MultiSampleType
< 2, D3DERR_INVALIDCALL
);
1475 user_assert(src
->desc
.MultiSampleType
< 2, D3DERR_INVALIDCALL
);
1477 user_assert(src
->desc
.Width
== dst
->desc
.Width
, D3DERR_INVALIDCALL
);
1478 user_assert(src
->desc
.Height
== dst
->desc
.Height
, D3DERR_INVALIDCALL
);
1480 user_assert(src
->desc
.Format
!= D3DFMT_NULL
, D3DERR_INVALIDCALL
);
1482 NineSurface9_CopyDefaultToMem(dst
, src
);
1488 NineDevice9_GetFrontBufferData( struct NineDevice9
*This
,
1490 IDirect3DSurface9
*pDestSurface
)
1492 DBG("This=%p iSwapChain=%u pDestSurface=%p\n", This
,
1493 iSwapChain
, pDestSurface
);
1495 user_assert(pDestSurface
!= NULL
, D3DERR_INVALIDCALL
);
1496 user_assert(iSwapChain
< This
->nswapchains
, D3DERR_INVALIDCALL
);
1498 return NineSwapChain9_GetFrontBufferData(This
->swapchains
[iSwapChain
],
1503 NineDevice9_StretchRect( struct NineDevice9
*This
,
1504 IDirect3DSurface9
*pSourceSurface
,
1505 const RECT
*pSourceRect
,
1506 IDirect3DSurface9
*pDestSurface
,
1507 const RECT
*pDestRect
,
1508 D3DTEXTUREFILTERTYPE Filter
)
1510 struct pipe_screen
*screen
= This
->screen
;
1511 struct pipe_context
*pipe
= This
->pipe
;
1512 struct NineSurface9
*dst
= NineSurface9(pDestSurface
);
1513 struct NineSurface9
*src
= NineSurface9(pSourceSurface
);
1514 struct pipe_resource
*dst_res
= NineSurface9_GetResource(dst
);
1515 struct pipe_resource
*src_res
= NineSurface9_GetResource(src
);
1517 struct pipe_blit_info blit
;
1518 boolean scaled
, clamped
, ms
, flip_x
= FALSE
, flip_y
= FALSE
;
1520 DBG("This=%p pSourceSurface=%p pSourceRect=%p pDestSurface=%p "
1521 "pDestRect=%p Filter=%u\n",
1522 This
, pSourceSurface
, pSourceRect
, pDestSurface
, pDestRect
, Filter
);
1524 DBG("pSourceRect=(%u,%u)-(%u,%u)\n",
1525 pSourceRect
->left
, pSourceRect
->top
,
1526 pSourceRect
->right
, pSourceRect
->bottom
);
1528 DBG("pDestRect=(%u,%u)-(%u,%u)\n", pDestRect
->left
, pDestRect
->top
,
1529 pDestRect
->right
, pDestRect
->bottom
);
1531 user_assert(dst
->base
.pool
== D3DPOOL_DEFAULT
&&
1532 src
->base
.pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1533 zs
= util_format_is_depth_or_stencil(dst_res
->format
);
1534 user_assert(!zs
|| !This
->in_scene
, D3DERR_INVALIDCALL
);
1535 user_assert(!zs
|| !pSourceRect
||
1536 (pSourceRect
->left
== 0 &&
1537 pSourceRect
->top
== 0 &&
1538 pSourceRect
->right
== src
->desc
.Width
&&
1539 pSourceRect
->bottom
== src
->desc
.Height
), D3DERR_INVALIDCALL
);
1540 user_assert(!zs
|| !pDestRect
||
1541 (pDestRect
->left
== 0 &&
1542 pDestRect
->top
== 0 &&
1543 pDestRect
->right
== dst
->desc
.Width
&&
1544 pDestRect
->bottom
== dst
->desc
.Height
), D3DERR_INVALIDCALL
);
1546 (dst
->desc
.Width
== src
->desc
.Width
&&
1547 dst
->desc
.Height
== src
->desc
.Height
), D3DERR_INVALIDCALL
);
1548 user_assert(zs
|| !util_format_is_depth_or_stencil(src_res
->format
),
1549 D3DERR_INVALIDCALL
);
1550 user_assert(!zs
|| dst
->desc
.Format
== src
->desc
.Format
,
1551 D3DERR_INVALIDCALL
);
1552 user_assert(screen
->is_format_supported(screen
, src_res
->format
,
1554 src_res
->nr_samples
,
1555 PIPE_BIND_SAMPLER_VIEW
),
1556 D3DERR_INVALIDCALL
);
1558 /* We might want to permit these, but wine thinks we shouldn't. */
1559 user_assert(!pDestRect
||
1560 (pDestRect
->left
<= pDestRect
->right
&&
1561 pDestRect
->top
<= pDestRect
->bottom
), D3DERR_INVALIDCALL
);
1562 user_assert(!pSourceRect
||
1563 (pSourceRect
->left
<= pSourceRect
->right
&&
1564 pSourceRect
->top
<= pSourceRect
->bottom
), D3DERR_INVALIDCALL
);
1566 memset(&blit
, 0, sizeof(blit
));
1567 blit
.dst
.resource
= dst_res
;
1568 blit
.dst
.level
= dst
->level
;
1569 blit
.dst
.box
.z
= dst
->layer
;
1570 blit
.dst
.box
.depth
= 1;
1571 blit
.dst
.format
= dst_res
->format
;
1573 flip_x
= pDestRect
->left
> pDestRect
->right
;
1575 blit
.dst
.box
.x
= pDestRect
->right
;
1576 blit
.dst
.box
.width
= pDestRect
->left
- pDestRect
->right
;
1578 blit
.dst
.box
.x
= pDestRect
->left
;
1579 blit
.dst
.box
.width
= pDestRect
->right
- pDestRect
->left
;
1581 flip_y
= pDestRect
->top
> pDestRect
->bottom
;
1583 blit
.dst
.box
.y
= pDestRect
->bottom
;
1584 blit
.dst
.box
.height
= pDestRect
->top
- pDestRect
->bottom
;
1586 blit
.dst
.box
.y
= pDestRect
->top
;
1587 blit
.dst
.box
.height
= pDestRect
->bottom
- pDestRect
->top
;
1592 blit
.dst
.box
.width
= dst
->desc
.Width
;
1593 blit
.dst
.box
.height
= dst
->desc
.Height
;
1595 blit
.src
.resource
= src_res
;
1596 blit
.src
.level
= src
->level
;
1597 blit
.src
.box
.z
= src
->layer
;
1598 blit
.src
.box
.depth
= 1;
1599 blit
.src
.format
= src_res
->format
;
1601 if (flip_x
^ (pSourceRect
->left
> pSourceRect
->right
)) {
1602 blit
.src
.box
.x
= pSourceRect
->right
;
1603 blit
.src
.box
.width
= pSourceRect
->left
- pSourceRect
->right
;
1605 blit
.src
.box
.x
= pSourceRect
->left
;
1606 blit
.src
.box
.width
= pSourceRect
->right
- pSourceRect
->left
;
1608 if (flip_y
^ (pSourceRect
->top
> pSourceRect
->bottom
)) {
1609 blit
.src
.box
.y
= pSourceRect
->bottom
;
1610 blit
.src
.box
.height
= pSourceRect
->top
- pSourceRect
->bottom
;
1612 blit
.src
.box
.y
= pSourceRect
->top
;
1613 blit
.src
.box
.height
= pSourceRect
->bottom
- pSourceRect
->top
;
1616 blit
.src
.box
.x
= flip_x
? src
->desc
.Width
: 0;
1617 blit
.src
.box
.y
= flip_y
? src
->desc
.Height
: 0;
1618 blit
.src
.box
.width
= flip_x
? -src
->desc
.Width
: src
->desc
.Width
;
1619 blit
.src
.box
.height
= flip_y
? -src
->desc
.Height
: src
->desc
.Height
;
1621 blit
.mask
= zs
? PIPE_MASK_ZS
: PIPE_MASK_RGBA
;
1622 blit
.filter
= Filter
== D3DTEXF_LINEAR
?
1623 PIPE_TEX_FILTER_LINEAR
: PIPE_TEX_FILTER_NEAREST
;
1624 blit
.scissor_enable
= FALSE
;
1625 blit
.alpha_blend
= FALSE
;
1627 /* If both of a src and dst dimension are negative, flip them. */
1628 if (blit
.dst
.box
.width
< 0 && blit
.src
.box
.width
< 0) {
1629 blit
.dst
.box
.width
= -blit
.dst
.box
.width
;
1630 blit
.src
.box
.width
= -blit
.src
.box
.width
;
1632 if (blit
.dst
.box
.height
< 0 && blit
.src
.box
.height
< 0) {
1633 blit
.dst
.box
.height
= -blit
.dst
.box
.height
;
1634 blit
.src
.box
.height
= -blit
.src
.box
.height
;
1637 blit
.dst
.box
.width
!= blit
.src
.box
.width
||
1638 blit
.dst
.box
.height
!= blit
.src
.box
.height
;
1640 user_assert(!scaled
|| dst
!= src
, D3DERR_INVALIDCALL
);
1641 user_assert(!scaled
||
1642 !NineSurface9_IsOffscreenPlain(dst
), D3DERR_INVALIDCALL
);
1643 user_assert(!NineSurface9_IsOffscreenPlain(dst
) ||
1644 NineSurface9_IsOffscreenPlain(src
), D3DERR_INVALIDCALL
);
1645 user_assert(NineSurface9_IsOffscreenPlain(dst
) ||
1646 dst
->desc
.Usage
& (D3DUSAGE_RENDERTARGET
| D3DUSAGE_DEPTHSTENCIL
),
1647 D3DERR_INVALIDCALL
);
1648 user_assert(!scaled
||
1649 (!util_format_is_compressed(dst
->base
.info
.format
) &&
1650 !util_format_is_compressed(src
->base
.info
.format
)),
1651 D3DERR_INVALIDCALL
);
1653 user_warn(src
== dst
&&
1654 u_box_test_intersection_2d(&blit
.src
.box
, &blit
.dst
.box
));
1656 /* Check for clipping/clamping: */
1658 struct pipe_box box
;
1661 xy
= u_box_clip_2d(&box
, &blit
.dst
.box
,
1662 dst
->desc
.Width
, dst
->desc
.Height
);
1666 xy
= u_box_clip_2d(&box
, &blit
.src
.box
,
1667 src
->desc
.Width
, src
->desc
.Height
);
1671 ms
= (dst
->desc
.MultiSampleType
!= src
->desc
.MultiSampleType
) ||
1672 (dst
->desc
.MultiSampleQuality
!= src
->desc
.MultiSampleQuality
);
1674 if (clamped
|| scaled
|| (blit
.dst
.format
!= blit
.src
.format
) || ms
) {
1675 DBG("using pipe->blit()\n");
1676 /* TODO: software scaling */
1677 user_assert(screen
->is_format_supported(screen
, dst_res
->format
,
1679 dst_res
->nr_samples
,
1680 zs
? PIPE_BIND_DEPTH_STENCIL
:
1681 PIPE_BIND_RENDER_TARGET
),
1682 D3DERR_INVALIDCALL
);
1684 pipe
->blit(pipe
, &blit
);
1686 assert(blit
.dst
.box
.x
>= 0 && blit
.dst
.box
.y
>= 0 &&
1687 blit
.src
.box
.x
>= 0 && blit
.src
.box
.y
>= 0 &&
1688 blit
.dst
.box
.x
+ blit
.dst
.box
.width
<= dst
->desc
.Width
&&
1689 blit
.src
.box
.x
+ blit
.src
.box
.width
<= src
->desc
.Width
&&
1690 blit
.dst
.box
.y
+ blit
.dst
.box
.height
<= dst
->desc
.Height
&&
1691 blit
.src
.box
.y
+ blit
.src
.box
.height
<= src
->desc
.Height
);
1692 /* Or drivers might crash ... */
1693 DBG("Using resource_copy_region.\n");
1694 pipe
->resource_copy_region(pipe
,
1695 blit
.dst
.resource
, blit
.dst
.level
,
1696 blit
.dst
.box
.x
, blit
.dst
.box
.y
, blit
.dst
.box
.z
,
1697 blit
.src
.resource
, blit
.src
.level
,
1701 /* Communicate the container it needs to update sublevels - if apply */
1702 NineSurface9_MarkContainerDirty(dst
);
1708 NineDevice9_ColorFill( struct NineDevice9
*This
,
1709 IDirect3DSurface9
*pSurface
,
1713 struct pipe_context
*pipe
= This
->pipe
;
1714 struct NineSurface9
*surf
= NineSurface9(pSurface
);
1715 struct pipe_surface
*psurf
;
1716 unsigned x
, y
, w
, h
;
1717 union pipe_color_union rgba
;
1720 DBG("This=%p pSurface=%p pRect=%p color=%08x\n", This
,
1721 pSurface
, pRect
, color
);
1723 DBG("pRect=(%u,%u)-(%u,%u)\n", pRect
->left
, pRect
->top
,
1724 pRect
->right
, pRect
->bottom
);
1726 user_assert(surf
->base
.pool
== D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
);
1728 user_assert((surf
->base
.usage
& D3DUSAGE_RENDERTARGET
) ||
1729 NineSurface9_IsOffscreenPlain(surf
), D3DERR_INVALIDCALL
);
1731 user_assert(surf
->desc
.Format
!= D3DFMT_NULL
, D3D_OK
);
1736 w
= pRect
->right
- pRect
->left
;
1737 h
= pRect
->bottom
- pRect
->top
;
1739 if (compressed_format(surf
->desc
.Format
)) {
1740 const unsigned bw
= util_format_get_blockwidth(surf
->base
.info
.format
);
1741 const unsigned bh
= util_format_get_blockheight(surf
->base
.info
.format
);
1743 user_assert(!(x
% bw
) && !(y
% bh
) && !(w
% bw
) && !(h
% bh
),
1744 D3DERR_INVALIDCALL
);
1749 w
= surf
->desc
.Width
;
1750 h
= surf
->desc
.Height
;
1752 d3dcolor_to_pipe_color_union(&rgba
, color
);
1754 fallback
= !(surf
->base
.info
.bind
& PIPE_BIND_RENDER_TARGET
);
1757 psurf
= NineSurface9_GetSurface(surf
, 0);
1763 pipe
->clear_render_target(pipe
, psurf
, &rgba
, x
, y
, w
, h
, false);
1765 D3DLOCKED_RECT lock
;
1766 union util_color uc
;
1768 /* XXX: lock pRect and fix util_fill_rect */
1769 hr
= NineSurface9_LockRect(surf
, &lock
, NULL
, 0);
1772 util_pack_color_ub(color
>> 16, color
>> 8, color
>> 0, color
>> 24,
1773 surf
->base
.info
.format
, &uc
);
1774 util_fill_rect(lock
.pBits
, surf
->base
.info
.format
,lock
.Pitch
,
1776 NineSurface9_UnlockRect(surf
);
1783 NineDevice9_CreateOffscreenPlainSurface( struct NineDevice9
*This
,
1788 IDirect3DSurface9
**ppSurface
,
1789 HANDLE
*pSharedHandle
)
1793 DBG("This=%p Width=%u Height=%u Format=%s(0x%x) Pool=%u "
1794 "ppSurface=%p pSharedHandle=%p\n", This
,
1795 Width
, Height
, d3dformat_to_string(Format
), Format
, Pool
,
1796 ppSurface
, pSharedHandle
);
1799 user_assert(!pSharedHandle
|| Pool
== D3DPOOL_DEFAULT
1800 || Pool
== D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
);
1801 user_assert(Pool
!= D3DPOOL_MANAGED
, D3DERR_INVALIDCALL
);
1803 /* Can be used with StretchRect and ColorFill. It's also always lockable.
1805 hr
= create_zs_or_rt_surface(This
, 2, Pool
, Width
, Height
,
1807 D3DMULTISAMPLE_NONE
, 0,
1809 ppSurface
, pSharedHandle
);
1811 DBG("Failed to create surface.\n");
1816 NineDevice9_SetRenderTarget( struct NineDevice9
*This
,
1817 DWORD RenderTargetIndex
,
1818 IDirect3DSurface9
*pRenderTarget
)
1820 struct NineSurface9
*rt
= NineSurface9(pRenderTarget
);
1821 const unsigned i
= RenderTargetIndex
;
1823 DBG("This=%p RenderTargetIndex=%u pRenderTarget=%p\n", This
,
1824 RenderTargetIndex
, pRenderTarget
);
1826 user_assert(i
< This
->caps
.NumSimultaneousRTs
, D3DERR_INVALIDCALL
);
1827 user_assert(i
!= 0 || pRenderTarget
, D3DERR_INVALIDCALL
);
1828 user_assert(!pRenderTarget
||
1829 rt
->desc
.Usage
& D3DUSAGE_RENDERTARGET
, D3DERR_INVALIDCALL
);
1832 This
->state
.viewport
.X
= 0;
1833 This
->state
.viewport
.Y
= 0;
1834 This
->state
.viewport
.Width
= rt
->desc
.Width
;
1835 This
->state
.viewport
.Height
= rt
->desc
.Height
;
1836 This
->state
.viewport
.MinZ
= 0.0f
;
1837 This
->state
.viewport
.MaxZ
= 1.0f
;
1839 This
->state
.scissor
.minx
= 0;
1840 This
->state
.scissor
.miny
= 0;
1841 This
->state
.scissor
.maxx
= rt
->desc
.Width
;
1842 This
->state
.scissor
.maxy
= rt
->desc
.Height
;
1844 This
->state
.changed
.group
|= NINE_STATE_VIEWPORT
| NINE_STATE_SCISSOR
| NINE_STATE_MULTISAMPLE
;
1846 if (This
->state
.rt
[0] &&
1847 (This
->state
.rt
[0]->desc
.MultiSampleType
<= D3DMULTISAMPLE_NONMASKABLE
) !=
1848 (rt
->desc
.MultiSampleType
<= D3DMULTISAMPLE_NONMASKABLE
))
1849 This
->state
.changed
.group
|= NINE_STATE_SAMPLE_MASK
;
1852 if (This
->state
.rt
[i
] != NineSurface9(pRenderTarget
)) {
1853 nine_bind(&This
->state
.rt
[i
], pRenderTarget
);
1854 This
->state
.changed
.group
|= NINE_STATE_FB
;
1860 NineDevice9_GetRenderTarget( struct NineDevice9
*This
,
1861 DWORD RenderTargetIndex
,
1862 IDirect3DSurface9
**ppRenderTarget
)
1864 const unsigned i
= RenderTargetIndex
;
1866 user_assert(i
< This
->caps
.NumSimultaneousRTs
, D3DERR_INVALIDCALL
);
1867 user_assert(ppRenderTarget
, D3DERR_INVALIDCALL
);
1869 *ppRenderTarget
= (IDirect3DSurface9
*)This
->state
.rt
[i
];
1870 if (!This
->state
.rt
[i
])
1871 return D3DERR_NOTFOUND
;
1873 NineUnknown_AddRef(NineUnknown(This
->state
.rt
[i
]));
1878 NineDevice9_SetDepthStencilSurface( struct NineDevice9
*This
,
1879 IDirect3DSurface9
*pNewZStencil
)
1881 DBG("This=%p pNewZStencil=%p\n", This
, pNewZStencil
);
1883 if (This
->state
.ds
!= NineSurface9(pNewZStencil
)) {
1884 nine_bind(&This
->state
.ds
, pNewZStencil
);
1885 This
->state
.changed
.group
|= NINE_STATE_FB
;
1891 NineDevice9_GetDepthStencilSurface( struct NineDevice9
*This
,
1892 IDirect3DSurface9
**ppZStencilSurface
)
1894 user_assert(ppZStencilSurface
, D3DERR_INVALIDCALL
);
1896 *ppZStencilSurface
= (IDirect3DSurface9
*)This
->state
.ds
;
1897 if (!This
->state
.ds
)
1898 return D3DERR_NOTFOUND
;
1900 NineUnknown_AddRef(NineUnknown(This
->state
.ds
));
1905 NineDevice9_BeginScene( struct NineDevice9
*This
)
1907 DBG("This=%p\n", This
);
1908 user_assert(!This
->in_scene
, D3DERR_INVALIDCALL
);
1909 This
->in_scene
= TRUE
;
1910 /* Do we want to do anything else here ? */
1915 NineDevice9_EndScene( struct NineDevice9
*This
)
1917 DBG("This=%p\n", This
);
1918 user_assert(This
->in_scene
, D3DERR_INVALIDCALL
);
1919 This
->in_scene
= FALSE
;
1924 NineDevice9_Clear( struct NineDevice9
*This
,
1926 const D3DRECT
*pRects
,
1932 struct NineSurface9
*zsbuf_surf
= This
->state
.ds
;
1934 DBG("This=%p Count=%u pRects=%p Flags=%x Color=%08x Z=%f Stencil=%x\n",
1935 This
, Count
, pRects
, Flags
, Color
, Z
, Stencil
);
1937 user_assert(This
->state
.ds
|| !(Flags
& NINED3DCLEAR_DEPTHSTENCIL
),
1938 D3DERR_INVALIDCALL
);
1939 user_assert(!(Flags
& D3DCLEAR_STENCIL
) ||
1941 util_format_is_depth_and_stencil(zsbuf_surf
->base
.info
.format
)),
1942 D3DERR_INVALIDCALL
);
1944 user_assert((Count
&& pRects
) || (!Count
&& !pRects
), D3DERR_INVALIDCALL
);
1946 user_warn((pRects
&& !Count
) || (!pRects
&& Count
));
1947 if (pRects
&& !Count
)
1953 nine_context_clear_fb(This
, Count
, pRects
, Flags
, Color
, Z
, Stencil
);
1958 NineDevice9_SetTransform( struct NineDevice9
*This
,
1959 D3DTRANSFORMSTATETYPE State
,
1960 const D3DMATRIX
*pMatrix
)
1962 struct nine_state
*state
= This
->update
;
1963 D3DMATRIX
*M
= nine_state_access_transform(state
, State
, TRUE
);
1965 DBG("This=%p State=%d pMatrix=%p\n", This
, State
, pMatrix
);
1967 user_assert(M
, D3DERR_INVALIDCALL
);
1970 state
->ff
.changed
.transform
[State
/ 32] |= 1 << (State
% 32);
1971 state
->changed
.group
|= NINE_STATE_FF
;
1977 NineDevice9_GetTransform( struct NineDevice9
*This
,
1978 D3DTRANSFORMSTATETYPE State
,
1979 D3DMATRIX
*pMatrix
)
1981 D3DMATRIX
*M
= nine_state_access_transform(&This
->state
, State
, FALSE
);
1982 user_assert(M
, D3DERR_INVALIDCALL
);
1988 NineDevice9_MultiplyTransform( struct NineDevice9
*This
,
1989 D3DTRANSFORMSTATETYPE State
,
1990 const D3DMATRIX
*pMatrix
)
1992 struct nine_state
*state
= This
->update
;
1994 D3DMATRIX
*M
= nine_state_access_transform(state
, State
, TRUE
);
1996 DBG("This=%p State=%d pMatrix=%p\n", This
, State
, pMatrix
);
1998 user_assert(M
, D3DERR_INVALIDCALL
);
2000 nine_d3d_matrix_matrix_mul(&T
, pMatrix
, M
);
2001 return NineDevice9_SetTransform(This
, State
, &T
);
2005 NineDevice9_SetViewport( struct NineDevice9
*This
,
2006 const D3DVIEWPORT9
*pViewport
)
2008 struct nine_state
*state
= This
->update
;
2010 DBG("X=%u Y=%u W=%u H=%u MinZ=%f MaxZ=%f\n",
2011 pViewport
->X
, pViewport
->Y
, pViewport
->Width
, pViewport
->Height
,
2012 pViewport
->MinZ
, pViewport
->MaxZ
);
2014 state
->viewport
= *pViewport
;
2015 state
->changed
.group
|= NINE_STATE_VIEWPORT
;
2021 NineDevice9_GetViewport( struct NineDevice9
*This
,
2022 D3DVIEWPORT9
*pViewport
)
2024 *pViewport
= This
->state
.viewport
;
2029 NineDevice9_SetMaterial( struct NineDevice9
*This
,
2030 const D3DMATERIAL9
*pMaterial
)
2032 struct nine_state
*state
= This
->update
;
2034 DBG("This=%p pMaterial=%p\n", This
, pMaterial
);
2036 nine_dump_D3DMATERIAL9(DBG_FF
, pMaterial
);
2038 user_assert(pMaterial
, E_POINTER
);
2040 state
->ff
.material
= *pMaterial
;
2041 state
->changed
.group
|= NINE_STATE_FF_MATERIAL
;
2047 NineDevice9_GetMaterial( struct NineDevice9
*This
,
2048 D3DMATERIAL9
*pMaterial
)
2050 user_assert(pMaterial
, E_POINTER
);
2051 *pMaterial
= This
->state
.ff
.material
;
2056 NineDevice9_SetLight( struct NineDevice9
*This
,
2058 const D3DLIGHT9
*pLight
)
2060 struct nine_state
*state
= This
->update
;
2062 DBG("This=%p Index=%u pLight=%p\n", This
, Index
, pLight
);
2064 nine_dump_D3DLIGHT9(DBG_FF
, pLight
);
2066 user_assert(pLight
, D3DERR_INVALIDCALL
);
2067 user_assert(pLight
->Type
< NINED3DLIGHT_INVALID
, D3DERR_INVALIDCALL
);
2069 user_assert(Index
< NINE_MAX_LIGHTS
, D3DERR_INVALIDCALL
); /* sanity */
2071 if (Index
>= state
->ff
.num_lights
) {
2072 unsigned n
= state
->ff
.num_lights
;
2073 unsigned N
= Index
+ 1;
2075 state
->ff
.light
= REALLOC(state
->ff
.light
, n
* sizeof(D3DLIGHT9
),
2076 N
* sizeof(D3DLIGHT9
));
2077 if (!state
->ff
.light
)
2078 return E_OUTOFMEMORY
;
2079 state
->ff
.num_lights
= N
;
2081 for (; n
< Index
; ++n
) {
2082 memset(&state
->ff
.light
[n
], 0, sizeof(D3DLIGHT9
));
2083 state
->ff
.light
[n
].Type
= (D3DLIGHTTYPE
)NINED3DLIGHT_INVALID
;
2086 state
->ff
.light
[Index
] = *pLight
;
2088 if (pLight
->Type
== D3DLIGHT_SPOT
&& pLight
->Theta
>= pLight
->Phi
) {
2089 DBG("Warning: clamping D3DLIGHT9.Theta\n");
2090 state
->ff
.light
[Index
].Theta
= state
->ff
.light
[Index
].Phi
;
2092 if (pLight
->Type
!= D3DLIGHT_DIRECTIONAL
&&
2093 pLight
->Attenuation0
== 0.0f
&&
2094 pLight
->Attenuation1
== 0.0f
&&
2095 pLight
->Attenuation2
== 0.0f
) {
2096 DBG("Warning: all D3DLIGHT9.Attenuation[i] are 0\n");
2099 state
->changed
.group
|= NINE_STATE_FF_LIGHTING
;
2105 NineDevice9_GetLight( struct NineDevice9
*This
,
2109 const struct nine_state
*state
= &This
->state
;
2111 user_assert(pLight
, D3DERR_INVALIDCALL
);
2112 user_assert(Index
< state
->ff
.num_lights
, D3DERR_INVALIDCALL
);
2113 user_assert(state
->ff
.light
[Index
].Type
< NINED3DLIGHT_INVALID
,
2114 D3DERR_INVALIDCALL
);
2116 *pLight
= state
->ff
.light
[Index
];
2122 NineDevice9_LightEnable( struct NineDevice9
*This
,
2126 struct nine_state
*state
= This
->update
;
2129 DBG("This=%p Index=%u Enable=%i\n", This
, Index
, Enable
);
2131 if (Index
>= state
->ff
.num_lights
||
2132 state
->ff
.light
[Index
].Type
== NINED3DLIGHT_INVALID
) {
2133 /* This should create a default light. */
2135 memset(&light
, 0, sizeof(light
));
2136 light
.Type
= D3DLIGHT_DIRECTIONAL
;
2137 light
.Diffuse
.r
= 1.0f
;
2138 light
.Diffuse
.g
= 1.0f
;
2139 light
.Diffuse
.b
= 1.0f
;
2140 light
.Direction
.z
= 1.0f
;
2141 NineDevice9_SetLight(This
, Index
, &light
);
2143 user_assert(Index
< state
->ff
.num_lights
, D3DERR_INVALIDCALL
);
2145 for (i
= 0; i
< state
->ff
.num_lights_active
; ++i
) {
2146 if (state
->ff
.active_light
[i
] == Index
)
2151 if (i
< state
->ff
.num_lights_active
)
2153 /* XXX wine thinks this should still succeed:
2155 user_assert(i
< NINE_MAX_LIGHTS_ACTIVE
, D3DERR_INVALIDCALL
);
2157 state
->ff
.active_light
[i
] = Index
;
2158 state
->ff
.num_lights_active
++;
2160 if (i
== state
->ff
.num_lights_active
)
2162 --state
->ff
.num_lights_active
;
2163 for (; i
< state
->ff
.num_lights_active
; ++i
)
2164 state
->ff
.active_light
[i
] = state
->ff
.active_light
[i
+ 1];
2166 state
->changed
.group
|= NINE_STATE_FF_LIGHTING
;
2172 NineDevice9_GetLightEnable( struct NineDevice9
*This
,
2176 const struct nine_state
*state
= &This
->state
;
2179 user_assert(Index
< state
->ff
.num_lights
, D3DERR_INVALIDCALL
);
2180 user_assert(state
->ff
.light
[Index
].Type
< NINED3DLIGHT_INVALID
,
2181 D3DERR_INVALIDCALL
);
2183 for (i
= 0; i
< state
->ff
.num_lights_active
; ++i
)
2184 if (state
->ff
.active_light
[i
] == Index
)
2187 *pEnable
= i
!= state
->ff
.num_lights_active
? 128 : 0; // Taken from wine
2193 NineDevice9_SetClipPlane( struct NineDevice9
*This
,
2195 const float *pPlane
)
2197 struct nine_state
*state
= This
->update
;
2199 user_assert(pPlane
, D3DERR_INVALIDCALL
);
2201 DBG("This=%p Index=%u pPlane=%f %f %f %f\n", This
, Index
,
2202 pPlane
[0], pPlane
[1],
2203 pPlane
[2], pPlane
[3]);
2205 user_assert(Index
< PIPE_MAX_CLIP_PLANES
, D3DERR_INVALIDCALL
);
2207 memcpy(&state
->clip
.ucp
[Index
][0], pPlane
, sizeof(state
->clip
.ucp
[0]));
2208 state
->changed
.ucp
|= 1 << Index
;
2214 NineDevice9_GetClipPlane( struct NineDevice9
*This
,
2218 const struct nine_state
*state
= &This
->state
;
2220 user_assert(Index
< PIPE_MAX_CLIP_PLANES
, D3DERR_INVALIDCALL
);
2222 memcpy(pPlane
, &state
->clip
.ucp
[Index
][0], sizeof(state
->clip
.ucp
[0]));
2227 NineDevice9_SetRenderState( struct NineDevice9
*This
,
2228 D3DRENDERSTATETYPE State
,
2231 struct nine_state
*state
= This
->update
;
2233 DBG("This=%p State=%u(%s) Value=%08x\n", This
,
2234 State
, nine_d3drs_to_string(State
), Value
);
2236 user_assert(State
< D3DRS_COUNT
, D3DERR_INVALIDCALL
);
2238 if (unlikely(This
->is_recording
)) {
2239 state
->rs_advertised
[State
] = Value
;
2240 /* only need to record changed render states for stateblocks */
2241 state
->changed
.rs
[State
/ 32] |= 1 << (State
% 32);
2242 state
->changed
.group
|= nine_render_state_group
[State
];
2246 if (state
->rs_advertised
[State
] == Value
)
2249 state
->rs_advertised
[State
] = Value
;
2250 nine_context_set_render_state(This
, State
, Value
);
2256 NineDevice9_GetRenderState( struct NineDevice9
*This
,
2257 D3DRENDERSTATETYPE State
,
2260 user_assert(State
< D3DRS_COUNT
, D3DERR_INVALIDCALL
);
2262 *pValue
= This
->state
.rs_advertised
[State
];
2267 NineDevice9_CreateStateBlock( struct NineDevice9
*This
,
2268 D3DSTATEBLOCKTYPE Type
,
2269 IDirect3DStateBlock9
**ppSB
)
2271 struct NineStateBlock9
*nsb
;
2272 struct nine_state
*dst
;
2274 enum nine_stateblock_type type
;
2277 DBG("This=%p Type=%u ppSB=%p\n", This
, Type
, ppSB
);
2279 user_assert(Type
== D3DSBT_ALL
||
2280 Type
== D3DSBT_VERTEXSTATE
||
2281 Type
== D3DSBT_PIXELSTATE
, D3DERR_INVALIDCALL
);
2284 case D3DSBT_VERTEXSTATE
: type
= NINESBT_VERTEXSTATE
; break;
2285 case D3DSBT_PIXELSTATE
: type
= NINESBT_PIXELSTATE
; break;
2291 hr
= NineStateBlock9_new(This
, &nsb
, type
);
2294 *ppSB
= (IDirect3DStateBlock9
*)nsb
;
2297 dst
->changed
.group
=
2298 NINE_STATE_TEXTURE
|
2301 if (Type
== D3DSBT_ALL
|| Type
== D3DSBT_VERTEXSTATE
) {
2302 dst
->changed
.group
|=
2303 NINE_STATE_FF_LIGHTING
|
2304 NINE_STATE_VS
| NINE_STATE_VS_CONST
|
2306 /* TODO: texture/sampler state */
2307 memcpy(dst
->changed
.rs
,
2308 nine_render_states_vertex
, sizeof(dst
->changed
.rs
));
2309 nine_ranges_insert(&dst
->changed
.vs_const_f
, 0, This
->may_swvp
? NINE_MAX_CONST_F_SWVP
: This
->max_vs_const_f
,
2311 nine_ranges_insert(&dst
->changed
.vs_const_i
, 0, This
->may_swvp
? NINE_MAX_CONST_I_SWVP
: NINE_MAX_CONST_I
,
2313 nine_ranges_insert(&dst
->changed
.vs_const_b
, 0, This
->may_swvp
? NINE_MAX_CONST_B_SWVP
: NINE_MAX_CONST_B
,
2315 for (s
= 0; s
< NINE_MAX_SAMPLERS
; ++s
)
2316 dst
->changed
.sampler
[s
] |= 1 << D3DSAMP_DMAPOFFSET
;
2317 if (This
->state
.ff
.num_lights
) {
2318 dst
->ff
.num_lights
= This
->state
.ff
.num_lights
;
2319 /* zero'd -> light type won't be NINED3DLIGHT_INVALID, so
2320 * all currently existing lights will be captured
2322 dst
->ff
.light
= CALLOC(This
->state
.ff
.num_lights
,
2324 if (!dst
->ff
.light
) {
2325 nine_bind(ppSB
, NULL
);
2326 return E_OUTOFMEMORY
;
2330 if (Type
== D3DSBT_ALL
|| Type
== D3DSBT_PIXELSTATE
) {
2331 dst
->changed
.group
|=
2332 NINE_STATE_PS
| NINE_STATE_PS_CONST
| NINE_STATE_BLEND
|
2333 NINE_STATE_FF_OTHER
| NINE_STATE_FF_PSSTAGES
| NINE_STATE_PS_CONST
|
2334 NINE_STATE_FB
| NINE_STATE_DSA
| NINE_STATE_MULTISAMPLE
|
2335 NINE_STATE_RASTERIZER
| NINE_STATE_STENCIL_REF
;
2336 memcpy(dst
->changed
.rs
,
2337 nine_render_states_pixel
, sizeof(dst
->changed
.rs
));
2338 nine_ranges_insert(&dst
->changed
.ps_const_f
, 0, This
->max_ps_const_f
,
2340 dst
->changed
.ps_const_i
= 0xffff;
2341 dst
->changed
.ps_const_b
= 0xffff;
2342 for (s
= 0; s
< NINE_MAX_SAMPLERS
; ++s
)
2343 dst
->changed
.sampler
[s
] |= 0x1ffe;
2344 for (s
= 0; s
< NINE_MAX_TEXTURE_STAGES
; ++s
) {
2345 dst
->ff
.changed
.tex_stage
[s
][0] |= 0xffffffff;
2346 dst
->ff
.changed
.tex_stage
[s
][1] |= 0xffffffff;
2349 if (Type
== D3DSBT_ALL
) {
2350 dst
->changed
.group
|=
2351 NINE_STATE_VIEWPORT
|
2352 NINE_STATE_SCISSOR
|
2353 NINE_STATE_RASTERIZER
|
2357 NINE_STATE_MATERIAL
|
2358 NINE_STATE_BLEND_COLOR
|
2359 NINE_STATE_SAMPLE_MASK
;
2360 memset(dst
->changed
.rs
, ~0, (D3DRS_COUNT
/ 32) * sizeof(uint32_t));
2361 dst
->changed
.rs
[D3DRS_LAST
/ 32] |= (1 << (D3DRS_COUNT
% 32)) - 1;
2362 dst
->changed
.vtxbuf
= (1ULL << This
->caps
.MaxStreams
) - 1;
2363 dst
->changed
.stream_freq
= dst
->changed
.vtxbuf
;
2364 dst
->changed
.ucp
= (1 << PIPE_MAX_CLIP_PLANES
) - 1;
2365 dst
->changed
.texture
= (1 << NINE_MAX_SAMPLERS
) - 1;
2367 NineStateBlock9_Capture(NineStateBlock9(*ppSB
));
2369 /* TODO: fixed function state */
2375 NineDevice9_BeginStateBlock( struct NineDevice9
*This
)
2379 DBG("This=%p\n", This
);
2381 user_assert(!This
->record
, D3DERR_INVALIDCALL
);
2383 hr
= NineStateBlock9_new(This
, &This
->record
, NINESBT_CUSTOM
);
2386 NineUnknown_ConvertRefToBind(NineUnknown(This
->record
));
2388 This
->update
= &This
->record
->state
;
2389 This
->is_recording
= TRUE
;
2395 NineDevice9_EndStateBlock( struct NineDevice9
*This
,
2396 IDirect3DStateBlock9
**ppSB
)
2398 DBG("This=%p ppSB=%p\n", This
, ppSB
);
2400 user_assert(This
->record
, D3DERR_INVALIDCALL
);
2402 This
->update
= &This
->state
;
2403 This
->is_recording
= FALSE
;
2405 NineUnknown_AddRef(NineUnknown(This
->record
));
2406 *ppSB
= (IDirect3DStateBlock9
*)This
->record
;
2407 NineUnknown_Unbind(NineUnknown(This
->record
));
2408 This
->record
= NULL
;
2414 NineDevice9_SetClipStatus( struct NineDevice9
*This
,
2415 const D3DCLIPSTATUS9
*pClipStatus
)
2417 STUB(D3DERR_INVALIDCALL
);
2421 NineDevice9_GetClipStatus( struct NineDevice9
*This
,
2422 D3DCLIPSTATUS9
*pClipStatus
)
2424 STUB(D3DERR_INVALIDCALL
);
2428 NineDevice9_GetTexture( struct NineDevice9
*This
,
2430 IDirect3DBaseTexture9
**ppTexture
)
2432 user_assert(Stage
< This
->caps
.MaxSimultaneousTextures
||
2433 Stage
== D3DDMAPSAMPLER
||
2434 (Stage
>= D3DVERTEXTEXTURESAMPLER0
&&
2435 Stage
<= D3DVERTEXTEXTURESAMPLER3
), D3DERR_INVALIDCALL
);
2436 user_assert(ppTexture
, D3DERR_INVALIDCALL
);
2438 if (Stage
>= D3DDMAPSAMPLER
)
2439 Stage
= Stage
- D3DDMAPSAMPLER
+ NINE_MAX_SAMPLERS_PS
;
2441 *ppTexture
= (IDirect3DBaseTexture9
*)This
->state
.texture
[Stage
];
2443 if (This
->state
.texture
[Stage
])
2444 NineUnknown_AddRef(NineUnknown(This
->state
.texture
[Stage
]));
2449 NineDevice9_SetTexture( struct NineDevice9
*This
,
2451 IDirect3DBaseTexture9
*pTexture
)
2453 struct nine_state
*state
= This
->update
;
2454 struct NineBaseTexture9
*tex
= NineBaseTexture9(pTexture
);
2455 struct NineBaseTexture9
*old
;
2457 DBG("This=%p Stage=%u pTexture=%p\n", This
, Stage
, pTexture
);
2459 user_assert(Stage
< This
->caps
.MaxSimultaneousTextures
||
2460 Stage
== D3DDMAPSAMPLER
||
2461 (Stage
>= D3DVERTEXTEXTURESAMPLER0
&&
2462 Stage
<= D3DVERTEXTEXTURESAMPLER3
), D3DERR_INVALIDCALL
);
2463 user_assert(!tex
|| (tex
->base
.pool
!= D3DPOOL_SCRATCH
&&
2464 tex
->base
.pool
!= D3DPOOL_SYSTEMMEM
), D3DERR_INVALIDCALL
);
2466 if (Stage
>= D3DDMAPSAMPLER
)
2467 Stage
= Stage
- D3DDMAPSAMPLER
+ NINE_MAX_SAMPLERS_PS
;
2469 if (This
->is_recording
) {
2470 state
->changed
.texture
|= 1 << Stage
;
2471 state
->changed
.group
|= NINE_STATE_TEXTURE
;
2472 nine_bind(&state
->texture
[Stage
], pTexture
);
2476 old
= state
->texture
[Stage
];
2481 if ((tex
->managed
.dirty
| tex
->dirty_mip
) && LIST_IS_EMPTY(&tex
->list
))
2482 list_add(&tex
->list
, &This
->update_textures
);
2489 nine_context_set_texture(This
, Stage
, tex
);
2491 nine_bind(&state
->texture
[Stage
], pTexture
);
2497 NineDevice9_GetTextureStageState( struct NineDevice9
*This
,
2499 D3DTEXTURESTAGESTATETYPE Type
,
2502 const struct nine_state
*state
= &This
->state
;
2504 user_assert(Stage
< ARRAY_SIZE(state
->ff
.tex_stage
), D3DERR_INVALIDCALL
);
2505 user_assert(Type
< ARRAY_SIZE(state
->ff
.tex_stage
[0]), D3DERR_INVALIDCALL
);
2507 *pValue
= state
->ff
.tex_stage
[Stage
][Type
];
2513 NineDevice9_SetTextureStageState( struct NineDevice9
*This
,
2515 D3DTEXTURESTAGESTATETYPE Type
,
2518 struct nine_state
*state
= This
->update
;
2519 struct nine_context
*context
= &This
->context
;
2520 int bumpmap_index
= -1;
2522 DBG("Stage=%u Type=%u Value=%08x\n", Stage
, Type
, Value
);
2523 nine_dump_D3DTSS_value(DBG_FF
, Type
, Value
);
2525 user_assert(Stage
< ARRAY_SIZE(state
->ff
.tex_stage
), D3DERR_INVALIDCALL
);
2526 user_assert(Type
< ARRAY_SIZE(state
->ff
.tex_stage
[0]), D3DERR_INVALIDCALL
);
2528 state
->ff
.tex_stage
[Stage
][Type
] = Value
;
2530 case D3DTSS_BUMPENVMAT00
:
2531 bumpmap_index
= 4 * Stage
;
2533 case D3DTSS_BUMPENVMAT01
:
2534 bumpmap_index
= 4 * Stage
+ 1;
2536 case D3DTSS_BUMPENVMAT10
:
2537 bumpmap_index
= 4 * Stage
+ 2;
2539 case D3DTSS_BUMPENVMAT11
:
2540 bumpmap_index
= 4 * Stage
+ 3;
2542 case D3DTSS_BUMPENVLSCALE
:
2543 bumpmap_index
= 4 * 8 + 2 * Stage
;
2545 case D3DTSS_BUMPENVLOFFSET
:
2546 bumpmap_index
= 4 * 8 + 2 * Stage
+ 1;
2548 case D3DTSS_TEXTURETRANSFORMFLAGS
:
2549 state
->changed
.group
|= NINE_STATE_PS1X_SHADER
;
2555 if (bumpmap_index
>= 0 && !This
->is_recording
) {
2556 context
->bumpmap_vars
[bumpmap_index
] = Value
;
2557 state
->changed
.group
|= NINE_STATE_PS_CONST
;
2560 state
->changed
.group
|= NINE_STATE_FF_PSSTAGES
;
2561 state
->ff
.changed
.tex_stage
[Stage
][Type
/ 32] |= 1 << (Type
% 32);
2567 NineDevice9_GetSamplerState( struct NineDevice9
*This
,
2569 D3DSAMPLERSTATETYPE Type
,
2572 user_assert(Sampler
< This
->caps
.MaxSimultaneousTextures
||
2573 Sampler
== D3DDMAPSAMPLER
||
2574 (Sampler
>= D3DVERTEXTEXTURESAMPLER0
&&
2575 Sampler
<= D3DVERTEXTEXTURESAMPLER3
), D3DERR_INVALIDCALL
);
2577 if (Sampler
>= D3DDMAPSAMPLER
)
2578 Sampler
= Sampler
- D3DDMAPSAMPLER
+ NINE_MAX_SAMPLERS_PS
;
2580 *pValue
= This
->state
.samp_advertised
[Sampler
][Type
];
2585 NineDevice9_SetSamplerState( struct NineDevice9
*This
,
2587 D3DSAMPLERSTATETYPE Type
,
2590 struct nine_state
*state
= This
->update
;
2592 DBG("This=%p Sampler=%u Type=%s Value=%08x\n", This
,
2593 Sampler
, nine_D3DSAMP_to_str(Type
), Value
);
2595 user_assert(Sampler
< This
->caps
.MaxSimultaneousTextures
||
2596 Sampler
== D3DDMAPSAMPLER
||
2597 (Sampler
>= D3DVERTEXTEXTURESAMPLER0
&&
2598 Sampler
<= D3DVERTEXTEXTURESAMPLER3
), D3DERR_INVALIDCALL
);
2600 if (Sampler
>= D3DDMAPSAMPLER
)
2601 Sampler
= Sampler
- D3DDMAPSAMPLER
+ NINE_MAX_SAMPLERS_PS
;
2603 if (unlikely(This
->is_recording
)) {
2604 state
->samp_advertised
[Sampler
][Type
] = Value
;
2605 state
->changed
.group
|= NINE_STATE_SAMPLER
;
2606 state
->changed
.sampler
[Sampler
] |= 1 << Type
;
2610 if (state
->samp_advertised
[Sampler
][Type
] == Value
)
2613 state
->samp_advertised
[Sampler
][Type
] = Value
;
2614 nine_context_set_sampler_state(This
, Sampler
, Type
, Value
);
2620 NineDevice9_ValidateDevice( struct NineDevice9
*This
,
2623 const struct nine_state
*state
= &This
->state
;
2625 unsigned w
= 0, h
= 0;
2627 DBG("This=%p pNumPasses=%p\n", This
, pNumPasses
);
2629 for (i
= 0; i
< ARRAY_SIZE(state
->samp_advertised
); ++i
) {
2630 if (state
->samp_advertised
[i
][D3DSAMP_MINFILTER
] == D3DTEXF_NONE
||
2631 state
->samp_advertised
[i
][D3DSAMP_MAGFILTER
] == D3DTEXF_NONE
)
2632 return D3DERR_UNSUPPORTEDTEXTUREFILTER
;
2635 for (i
= 0; i
< This
->caps
.NumSimultaneousRTs
; ++i
) {
2639 w
= state
->rt
[i
]->desc
.Width
;
2640 h
= state
->rt
[i
]->desc
.Height
;
2642 if (state
->rt
[i
]->desc
.Width
!= w
|| state
->rt
[i
]->desc
.Height
!= h
) {
2643 return D3DERR_CONFLICTINGRENDERSTATE
;
2647 (state
->rs_advertised
[D3DRS_ZENABLE
] || state
->rs_advertised
[D3DRS_STENCILENABLE
])) {
2649 (state
->ds
->desc
.Width
!= w
|| state
->ds
->desc
.Height
!= h
))
2650 return D3DERR_CONFLICTINGRENDERSTATE
;
2660 NineDevice9_SetPaletteEntries( struct NineDevice9
*This
,
2662 const PALETTEENTRY
*pEntries
)
2664 STUB(D3D_OK
); /* like wine */
2668 NineDevice9_GetPaletteEntries( struct NineDevice9
*This
,
2670 PALETTEENTRY
*pEntries
)
2672 STUB(D3DERR_INVALIDCALL
);
2676 NineDevice9_SetCurrentTexturePalette( struct NineDevice9
*This
,
2677 UINT PaletteNumber
)
2679 STUB(D3D_OK
); /* like wine */
2683 NineDevice9_GetCurrentTexturePalette( struct NineDevice9
*This
,
2684 UINT
*PaletteNumber
)
2686 STUB(D3DERR_INVALIDCALL
);
2690 NineDevice9_SetScissorRect( struct NineDevice9
*This
,
2693 struct nine_state
*state
= This
->update
;
2695 DBG("x=(%u..%u) y=(%u..%u)\n",
2696 pRect
->left
, pRect
->top
, pRect
->right
, pRect
->bottom
);
2698 state
->scissor
.minx
= pRect
->left
;
2699 state
->scissor
.miny
= pRect
->top
;
2700 state
->scissor
.maxx
= pRect
->right
;
2701 state
->scissor
.maxy
= pRect
->bottom
;
2703 state
->changed
.group
|= NINE_STATE_SCISSOR
;
2709 NineDevice9_GetScissorRect( struct NineDevice9
*This
,
2712 pRect
->left
= This
->state
.scissor
.minx
;
2713 pRect
->top
= This
->state
.scissor
.miny
;
2714 pRect
->right
= This
->state
.scissor
.maxx
;
2715 pRect
->bottom
= This
->state
.scissor
.maxy
;
2721 NineDevice9_SetSoftwareVertexProcessing( struct NineDevice9
*This
,
2724 if (This
->params
.BehaviorFlags
& D3DCREATE_MIXED_VERTEXPROCESSING
) {
2725 This
->swvp
= bSoftware
;
2726 This
->state
.changed
.group
|= NINE_STATE_SWVP
;
2729 return D3DERR_INVALIDCALL
; /* msdn. TODO: check in practice */
2733 NineDevice9_GetSoftwareVertexProcessing( struct NineDevice9
*This
)
2739 NineDevice9_SetNPatchMode( struct NineDevice9
*This
,
2742 return D3D_OK
; /* Nothing to do because we don't advertise NPatch support */
2746 NineDevice9_GetNPatchMode( struct NineDevice9
*This
)
2752 NineDevice9_DrawPrimitive( struct NineDevice9
*This
,
2753 D3DPRIMITIVETYPE PrimitiveType
,
2755 UINT PrimitiveCount
)
2757 DBG("iface %p, PrimitiveType %u, StartVertex %u, PrimitiveCount %u\n",
2758 This
, PrimitiveType
, StartVertex
, PrimitiveCount
);
2760 nine_context_draw_primitive(This
, PrimitiveType
, StartVertex
, PrimitiveCount
);
2766 NineDevice9_DrawIndexedPrimitive( struct NineDevice9
*This
,
2767 D3DPRIMITIVETYPE PrimitiveType
,
2768 INT BaseVertexIndex
,
2769 UINT MinVertexIndex
,
2772 UINT PrimitiveCount
)
2774 DBG("iface %p, PrimitiveType %u, BaseVertexIndex %u, MinVertexIndex %u "
2775 "NumVertices %u, StartIndex %u, PrimitiveCount %u\n",
2776 This
, PrimitiveType
, BaseVertexIndex
, MinVertexIndex
, NumVertices
,
2777 StartIndex
, PrimitiveCount
);
2779 user_assert(This
->state
.idxbuf
, D3DERR_INVALIDCALL
);
2780 user_assert(This
->state
.vdecl
, D3DERR_INVALIDCALL
);
2782 nine_context_draw_indexed_primitive(This
, PrimitiveType
, BaseVertexIndex
,
2783 MinVertexIndex
, NumVertices
, StartIndex
,
2790 NineDevice9_DrawPrimitiveUP( struct NineDevice9
*This
,
2791 D3DPRIMITIVETYPE PrimitiveType
,
2792 UINT PrimitiveCount
,
2793 const void *pVertexStreamZeroData
,
2794 UINT VertexStreamZeroStride
)
2796 struct pipe_vertex_buffer vtxbuf
;
2798 DBG("iface %p, PrimitiveType %u, PrimitiveCount %u, data %p, stride %u\n",
2799 This
, PrimitiveType
, PrimitiveCount
,
2800 pVertexStreamZeroData
, VertexStreamZeroStride
);
2802 user_assert(pVertexStreamZeroData
&& VertexStreamZeroStride
,
2803 D3DERR_INVALIDCALL
);
2804 user_assert(PrimitiveCount
, D3D_OK
);
2806 vtxbuf
.stride
= VertexStreamZeroStride
;
2807 vtxbuf
.buffer_offset
= 0;
2808 vtxbuf
.buffer
= NULL
;
2809 vtxbuf
.user_buffer
= pVertexStreamZeroData
;
2811 if (!This
->driver_caps
.user_vbufs
) {
2812 u_upload_data(This
->vertex_uploader
,
2814 (prim_count_to_vertex_count(PrimitiveType
, PrimitiveCount
)) * VertexStreamZeroStride
, /* XXX */
2817 &vtxbuf
.buffer_offset
,
2819 u_upload_unmap(This
->vertex_uploader
);
2820 vtxbuf
.user_buffer
= NULL
;
2823 nine_context_draw_primitive_from_vtxbuf(This
, PrimitiveType
, PrimitiveCount
, &vtxbuf
);
2825 pipe_resource_reference(&vtxbuf
.buffer
, NULL
);
2827 NineDevice9_PauseRecording(This
);
2828 NineDevice9_SetStreamSource(This
, 0, NULL
, 0, 0);
2829 NineDevice9_ResumeRecording(This
);
2835 NineDevice9_DrawIndexedPrimitiveUP( struct NineDevice9
*This
,
2836 D3DPRIMITIVETYPE PrimitiveType
,
2837 UINT MinVertexIndex
,
2839 UINT PrimitiveCount
,
2840 const void *pIndexData
,
2841 D3DFORMAT IndexDataFormat
,
2842 const void *pVertexStreamZeroData
,
2843 UINT VertexStreamZeroStride
)
2845 struct pipe_vertex_buffer vbuf
;
2846 struct pipe_index_buffer ibuf
;
2848 DBG("iface %p, PrimitiveType %u, MinVertexIndex %u, NumVertices %u "
2849 "PrimitiveCount %u, pIndexData %p, IndexDataFormat %u "
2850 "pVertexStreamZeroData %p, VertexStreamZeroStride %u\n",
2851 This
, PrimitiveType
, MinVertexIndex
, NumVertices
, PrimitiveCount
,
2852 pIndexData
, IndexDataFormat
,
2853 pVertexStreamZeroData
, VertexStreamZeroStride
);
2855 user_assert(pIndexData
&& pVertexStreamZeroData
, D3DERR_INVALIDCALL
);
2856 user_assert(VertexStreamZeroStride
, D3DERR_INVALIDCALL
);
2857 user_assert(IndexDataFormat
== D3DFMT_INDEX16
||
2858 IndexDataFormat
== D3DFMT_INDEX32
, D3DERR_INVALIDCALL
);
2859 user_assert(PrimitiveCount
, D3D_OK
);
2861 vbuf
.stride
= VertexStreamZeroStride
;
2862 vbuf
.buffer_offset
= 0;
2864 vbuf
.user_buffer
= pVertexStreamZeroData
;
2866 ibuf
.index_size
= (IndexDataFormat
== D3DFMT_INDEX16
) ? 2 : 4;
2869 ibuf
.user_buffer
= pIndexData
;
2871 if (!This
->driver_caps
.user_vbufs
) {
2872 const unsigned base
= MinVertexIndex
* VertexStreamZeroStride
;
2873 u_upload_data(This
->vertex_uploader
,
2875 NumVertices
* VertexStreamZeroStride
, /* XXX */
2877 (const uint8_t *)vbuf
.user_buffer
+ base
,
2878 &vbuf
.buffer_offset
,
2880 u_upload_unmap(This
->vertex_uploader
);
2881 /* Won't be used: */
2882 vbuf
.buffer_offset
-= base
;
2883 vbuf
.user_buffer
= NULL
;
2885 if (!This
->driver_caps
.user_ibufs
) {
2886 u_upload_data(This
->index_uploader
,
2888 (prim_count_to_vertex_count(PrimitiveType
, PrimitiveCount
)) * ibuf
.index_size
,
2893 u_upload_unmap(This
->index_uploader
);
2894 ibuf
.user_buffer
= NULL
;
2897 nine_context_draw_indexed_primitive_from_vtxbuf_idxbuf(This
, PrimitiveType
,
2904 pipe_resource_reference(&vbuf
.buffer
, NULL
);
2905 pipe_resource_reference(&ibuf
.buffer
, NULL
);
2907 NineDevice9_PauseRecording(This
);
2908 NineDevice9_SetIndices(This
, NULL
);
2909 NineDevice9_SetStreamSource(This
, 0, NULL
, 0, 0);
2910 NineDevice9_ResumeRecording(This
);
2916 NineDevice9_ProcessVertices( struct NineDevice9
*This
,
2920 IDirect3DVertexBuffer9
*pDestBuffer
,
2921 IDirect3DVertexDeclaration9
*pVertexDecl
,
2924 struct pipe_screen
*screen_sw
= This
->screen_sw
;
2925 struct pipe_context
*pipe_sw
= This
->pipe_sw
;
2926 struct NineVertexDeclaration9
*vdecl
= NineVertexDeclaration9(pVertexDecl
);
2927 struct NineVertexBuffer9
*dst
= NineVertexBuffer9(pDestBuffer
);
2928 struct NineVertexShader9
*vs
;
2929 struct pipe_resource
*resource
;
2930 struct pipe_transfer
*transfer
= NULL
;
2931 struct pipe_stream_output_info so
;
2932 struct pipe_stream_output_target
*target
;
2933 struct pipe_draw_info draw
;
2934 struct pipe_box box
;
2935 bool programmable_vs
= This
->state
.vs
&& !(This
->state
.vdecl
&& This
->state
.vdecl
->position_t
);
2936 unsigned offsets
[1] = {0};
2938 unsigned buffer_size
;
2941 DBG("This=%p SrcStartIndex=%u DestIndex=%u VertexCount=%u "
2942 "pDestBuffer=%p pVertexDecl=%p Flags=%d\n",
2943 This
, SrcStartIndex
, DestIndex
, VertexCount
, pDestBuffer
,
2944 pVertexDecl
, Flags
);
2946 if (!screen_sw
->get_param(screen_sw
, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS
)) {
2947 DBG("ProcessVertices not supported\n");
2948 return D3DERR_INVALIDCALL
;
2952 vs
= programmable_vs
? This
->state
.vs
: This
->ff
.vs
;
2953 /* Note: version is 0 for ff */
2954 user_assert(vdecl
|| (vs
->byte_code
.version
< 0x30 && dst
->desc
.FVF
),
2955 D3DERR_INVALIDCALL
);
2957 DWORD FVF
= dst
->desc
.FVF
;
2958 vdecl
= util_hash_table_get(This
->ff
.ht_fvf
, &FVF
);
2960 hr
= NineVertexDeclaration9_new_from_fvf(This
, FVF
, &vdecl
);
2964 util_hash_table_set(This
->ff
.ht_fvf
, &vdecl
->fvf
, vdecl
);
2965 NineUnknown_ConvertRefToBind(NineUnknown(vdecl
));
2969 /* Flags: Can be 0 or D3DPV_DONOTCOPYDATA, and/or lock flags
2970 * D3DPV_DONOTCOPYDATA -> Has effect only for ff. In particular
2971 * if not set, everything from src will be used, and dst
2972 * must match exactly the ff vs outputs.
2973 * TODO: Handle all the checks, etc for ff */
2974 user_assert(vdecl
->position_t
|| programmable_vs
,
2975 D3DERR_INVALIDCALL
);
2977 /* TODO: Support vs < 3 and ff */
2978 user_assert(vs
->byte_code
.version
== 0x30,
2979 D3DERR_INVALIDCALL
);
2980 /* TODO: Not hardcode the constant buffers for swvp */
2981 user_assert(This
->may_swvp
,
2982 D3DERR_INVALIDCALL
);
2984 nine_state_prepare_draw_sw(This
, vdecl
, SrcStartIndex
, VertexCount
, &so
);
2986 buffer_size
= VertexCount
* so
.stride
[0] * 4;
2988 struct pipe_resource templ
;
2990 memset(&templ
, 0, sizeof(templ
));
2991 templ
.target
= PIPE_BUFFER
;
2992 templ
.format
= PIPE_FORMAT_R8_UNORM
;
2993 templ
.width0
= buffer_size
;
2995 templ
.bind
= PIPE_BIND_STREAM_OUTPUT
;
2996 templ
.usage
= PIPE_USAGE_STREAM
;
2997 templ
.height0
= templ
.depth0
= templ
.array_size
= 1;
2998 templ
.last_level
= templ
.nr_samples
= 0;
3000 resource
= screen_sw
->resource_create(screen_sw
, &templ
);
3002 return E_OUTOFMEMORY
;
3004 target
= pipe_sw
->create_stream_output_target(pipe_sw
, resource
,
3007 pipe_resource_reference(&resource
, NULL
);
3008 return D3DERR_DRIVERINTERNALERROR
;
3011 draw
.mode
= PIPE_PRIM_POINTS
;
3012 draw
.count
= VertexCount
;
3013 draw
.start_instance
= 0;
3014 draw
.primitive_restart
= FALSE
;
3015 draw
.restart_index
= 0;
3016 draw
.count_from_stream_output
= NULL
;
3017 draw
.indirect
= NULL
;
3018 draw
.indirect_params
= NULL
;
3019 draw
.instance_count
= 1;
3020 draw
.indexed
= FALSE
;
3022 draw
.index_bias
= 0;
3024 draw
.max_index
= VertexCount
- 1;
3027 pipe_sw
->set_stream_output_targets(pipe_sw
, 1, &target
, offsets
);
3029 pipe_sw
->draw_vbo(pipe_sw
, &draw
);
3031 pipe_sw
->set_stream_output_targets(pipe_sw
, 0, NULL
, 0);
3032 pipe_sw
->stream_output_target_destroy(pipe_sw
, target
);
3034 u_box_1d(0, VertexCount
* so
.stride
[0] * 4, &box
);
3035 map
= pipe_sw
->transfer_map(pipe_sw
, resource
, 0, PIPE_TRANSFER_READ
, &box
,
3038 hr
= D3DERR_DRIVERINTERNALERROR
;
3042 hr
= NineVertexDeclaration9_ConvertStreamOutput(vdecl
,
3043 dst
, DestIndex
, VertexCount
,
3046 pipe_sw
->transfer_unmap(pipe_sw
, transfer
);
3049 nine_state_after_draw_sw(This
);
3050 pipe_resource_reference(&resource
, NULL
);
3055 NineDevice9_CreateVertexDeclaration( struct NineDevice9
*This
,
3056 const D3DVERTEXELEMENT9
*pVertexElements
,
3057 IDirect3DVertexDeclaration9
**ppDecl
)
3059 struct NineVertexDeclaration9
*vdecl
;
3061 DBG("This=%p pVertexElements=%p ppDecl=%p\n",
3062 This
, pVertexElements
, ppDecl
);
3064 HRESULT hr
= NineVertexDeclaration9_new(This
, pVertexElements
, &vdecl
);
3066 *ppDecl
= (IDirect3DVertexDeclaration9
*)vdecl
;
3072 NineDevice9_SetVertexDeclaration( struct NineDevice9
*This
,
3073 IDirect3DVertexDeclaration9
*pDecl
)
3075 struct nine_state
*state
= This
->update
;
3076 struct NineVertexDeclaration9
*vdecl
= NineVertexDeclaration9(pDecl
);
3078 DBG("This=%p pDecl=%p\n", This
, pDecl
);
3080 if (unlikely(This
->is_recording
)) {
3081 nine_bind(&state
->vdecl
, vdecl
);
3082 state
->changed
.group
|= NINE_STATE_VDECL
;
3086 if (state
->vdecl
== vdecl
)
3089 nine_bind(&state
->vdecl
, vdecl
);
3091 nine_context_set_vertex_declaration(This
, vdecl
);
3097 NineDevice9_GetVertexDeclaration( struct NineDevice9
*This
,
3098 IDirect3DVertexDeclaration9
**ppDecl
)
3100 user_assert(ppDecl
, D3DERR_INVALIDCALL
);
3102 *ppDecl
= (IDirect3DVertexDeclaration9
*)This
->state
.vdecl
;
3104 NineUnknown_AddRef(NineUnknown(*ppDecl
));
3109 NineDevice9_SetFVF( struct NineDevice9
*This
,
3112 struct NineVertexDeclaration9
*vdecl
;
3115 DBG("FVF = %08x\n", FVF
);
3117 return D3D_OK
; /* like wine */
3119 vdecl
= util_hash_table_get(This
->ff
.ht_fvf
, &FVF
);
3121 hr
= NineVertexDeclaration9_new_from_fvf(This
, FVF
, &vdecl
);
3125 util_hash_table_set(This
->ff
.ht_fvf
, &vdecl
->fvf
, vdecl
);
3126 NineUnknown_ConvertRefToBind(NineUnknown(vdecl
));
3128 return NineDevice9_SetVertexDeclaration(
3129 This
, (IDirect3DVertexDeclaration9
*)vdecl
);
3133 NineDevice9_GetFVF( struct NineDevice9
*This
,
3136 *pFVF
= This
->state
.vdecl
? This
->state
.vdecl
->fvf
: 0;
3141 NineDevice9_CreateVertexShader( struct NineDevice9
*This
,
3142 const DWORD
*pFunction
,
3143 IDirect3DVertexShader9
**ppShader
)
3145 struct NineVertexShader9
*vs
;
3148 DBG("This=%p pFunction=%p ppShader=%p\n", This
, pFunction
, ppShader
);
3150 hr
= NineVertexShader9_new(This
, &vs
, pFunction
, NULL
);
3153 *ppShader
= (IDirect3DVertexShader9
*)vs
;
3158 NineDevice9_SetVertexShader( struct NineDevice9
*This
,
3159 IDirect3DVertexShader9
*pShader
)
3161 struct nine_state
*state
= This
->update
;
3162 struct NineVertexShader9
*vs_shader
= (struct NineVertexShader9
*)pShader
;
3164 DBG("This=%p pShader=%p\n", This
, pShader
);
3166 if (unlikely(This
->is_recording
)) {
3167 nine_bind(&state
->vs
, vs_shader
);
3168 state
->changed
.group
|= NINE_STATE_VS
;
3172 if (state
->vs
== vs_shader
)
3175 nine_bind(&state
->vs
, vs_shader
);
3177 nine_context_set_vertex_shader(This
, vs_shader
);
3183 NineDevice9_GetVertexShader( struct NineDevice9
*This
,
3184 IDirect3DVertexShader9
**ppShader
)
3186 user_assert(ppShader
, D3DERR_INVALIDCALL
);
3187 nine_reference_set(ppShader
, This
->state
.vs
);
3192 NineDevice9_SetVertexShaderConstantF( struct NineDevice9
*This
,
3194 const float *pConstantData
,
3195 UINT Vector4fCount
)
3197 struct nine_state
*state
= This
->update
;
3198 float *vs_const_f
= This
->may_swvp
? state
->vs_const_f_swvp
: state
->vs_const_f
;
3200 DBG("This=%p StartRegister=%u pConstantData=%p Vector4fCount=%u\n",
3201 This
, StartRegister
, pConstantData
, Vector4fCount
);
3203 user_assert(StartRegister
< This
->caps
.MaxVertexShaderConst
, D3DERR_INVALIDCALL
);
3204 user_assert(StartRegister
+ Vector4fCount
<= This
->caps
.MaxVertexShaderConst
, D3DERR_INVALIDCALL
);
3208 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3210 if (!This
->is_recording
) {
3211 if (!memcmp(&vs_const_f
[StartRegister
* 4], pConstantData
,
3212 Vector4fCount
* 4 * sizeof(state
->vs_const_f
[0])))
3216 memcpy(&vs_const_f
[StartRegister
* 4],
3218 Vector4fCount
* 4 * sizeof(state
->vs_const_f
[0]));
3220 nine_ranges_insert(&state
->changed
.vs_const_f
,
3221 StartRegister
, StartRegister
+ Vector4fCount
,
3224 if (This
->may_swvp
) {
3225 Vector4fCount
= MIN2(StartRegister
+ Vector4fCount
, NINE_MAX_CONST_F
) - StartRegister
;
3226 if (StartRegister
< NINE_MAX_CONST_F
)
3227 memcpy(&state
->vs_const_f
[StartRegister
* 4],
3229 Vector4fCount
* 4 * sizeof(state
->vs_const_f
[0]));
3232 state
->changed
.group
|= NINE_STATE_VS_CONST
;
3238 NineDevice9_GetVertexShaderConstantF( struct NineDevice9
*This
,
3240 float *pConstantData
,
3241 UINT Vector4fCount
)
3243 const struct nine_state
*state
= &This
->state
;
3244 float *vs_const_f
= This
->may_swvp
? state
->vs_const_f_swvp
: state
->vs_const_f
;
3246 user_assert(StartRegister
< This
->caps
.MaxVertexShaderConst
, D3DERR_INVALIDCALL
);
3247 user_assert(StartRegister
+ Vector4fCount
<= This
->caps
.MaxVertexShaderConst
, D3DERR_INVALIDCALL
);
3248 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3250 memcpy(pConstantData
,
3251 &vs_const_f
[StartRegister
* 4],
3252 Vector4fCount
* 4 * sizeof(state
->vs_const_f
[0]));
3258 NineDevice9_SetVertexShaderConstantI( struct NineDevice9
*This
,
3260 const int *pConstantData
,
3261 UINT Vector4iCount
)
3263 struct nine_state
*state
= This
->update
;
3266 DBG("This=%p StartRegister=%u pConstantData=%p Vector4iCount=%u\n",
3267 This
, StartRegister
, pConstantData
, Vector4iCount
);
3269 user_assert(StartRegister
< (This
->may_swvp
? NINE_MAX_CONST_I_SWVP
: NINE_MAX_CONST_I
),
3270 D3DERR_INVALIDCALL
);
3271 user_assert(StartRegister
+ Vector4iCount
<= (This
->may_swvp
? NINE_MAX_CONST_I_SWVP
: NINE_MAX_CONST_I
),
3272 D3DERR_INVALIDCALL
);
3273 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3275 if (This
->driver_caps
.vs_integer
) {
3276 if (!This
->is_recording
) {
3277 if (!memcmp(&state
->vs_const_i
[4 * StartRegister
], pConstantData
,
3278 Vector4iCount
* sizeof(int[4])))
3281 memcpy(&state
->vs_const_i
[4 * StartRegister
],
3283 Vector4iCount
* sizeof(int[4]));
3285 for (i
= 0; i
< Vector4iCount
; i
++) {
3286 state
->vs_const_i
[4 * (StartRegister
+ i
)] = fui((float)(pConstantData
[4 * i
]));
3287 state
->vs_const_i
[4 * (StartRegister
+ i
) + 1] = fui((float)(pConstantData
[4 * i
+ 1]));
3288 state
->vs_const_i
[4 * (StartRegister
+ i
) + 2] = fui((float)(pConstantData
[4 * i
+ 2]));
3289 state
->vs_const_i
[4 * (StartRegister
+ i
) + 3] = fui((float)(pConstantData
[4 * i
+ 3]));
3293 nine_ranges_insert(&state
->changed
.vs_const_i
,
3294 StartRegister
, StartRegister
+ Vector4iCount
,
3296 state
->changed
.group
|= NINE_STATE_VS_CONST
;
3302 NineDevice9_GetVertexShaderConstantI( struct NineDevice9
*This
,
3305 UINT Vector4iCount
)
3307 const struct nine_state
*state
= &This
->state
;
3310 user_assert(StartRegister
< (This
->may_swvp
? NINE_MAX_CONST_I_SWVP
: NINE_MAX_CONST_I
),
3311 D3DERR_INVALIDCALL
);
3312 user_assert(StartRegister
+ Vector4iCount
<= (This
->may_swvp
? NINE_MAX_CONST_I_SWVP
: NINE_MAX_CONST_I
),
3313 D3DERR_INVALIDCALL
);
3314 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3316 if (This
->driver_caps
.vs_integer
) {
3317 memcpy(pConstantData
,
3318 &state
->vs_const_i
[4 * StartRegister
],
3319 Vector4iCount
* sizeof(int[4]));
3321 for (i
= 0; i
< Vector4iCount
; i
++) {
3322 pConstantData
[4 * i
] = (int32_t) uif(state
->vs_const_i
[4 * (StartRegister
+ i
)]);
3323 pConstantData
[4 * i
+ 1] = (int32_t) uif(state
->vs_const_i
[4 * (StartRegister
+ i
) + 1]);
3324 pConstantData
[4 * i
+ 2] = (int32_t) uif(state
->vs_const_i
[4 * (StartRegister
+ i
) + 2]);
3325 pConstantData
[4 * i
+ 3] = (int32_t) uif(state
->vs_const_i
[4 * (StartRegister
+ i
) + 3]);
3333 NineDevice9_SetVertexShaderConstantB( struct NineDevice9
*This
,
3335 const BOOL
*pConstantData
,
3338 struct nine_state
*state
= This
->update
;
3340 uint32_t bool_true
= This
->driver_caps
.vs_integer
? 0xFFFFFFFF : fui(1.0f
);
3342 DBG("This=%p StartRegister=%u pConstantData=%p BoolCount=%u\n",
3343 This
, StartRegister
, pConstantData
, BoolCount
);
3345 user_assert(StartRegister
< (This
->may_swvp
? NINE_MAX_CONST_B_SWVP
: NINE_MAX_CONST_B
),
3346 D3DERR_INVALIDCALL
);
3347 user_assert(StartRegister
+ BoolCount
<= (This
->may_swvp
? NINE_MAX_CONST_B_SWVP
: NINE_MAX_CONST_B
),
3348 D3DERR_INVALIDCALL
);
3349 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3351 if (!This
->is_recording
) {
3352 bool noChange
= true;
3353 for (i
= 0; i
< BoolCount
; i
++) {
3354 if (!!state
->vs_const_b
[StartRegister
+ i
] != !!pConstantData
[i
])
3361 for (i
= 0; i
< BoolCount
; i
++)
3362 state
->vs_const_b
[StartRegister
+ i
] = pConstantData
[i
] ? bool_true
: 0;
3364 nine_ranges_insert(&state
->changed
.vs_const_b
,
3365 StartRegister
, StartRegister
+ BoolCount
,
3367 state
->changed
.group
|= NINE_STATE_VS_CONST
;
3373 NineDevice9_GetVertexShaderConstantB( struct NineDevice9
*This
,
3375 BOOL
*pConstantData
,
3378 const struct nine_state
*state
= &This
->state
;
3381 user_assert(StartRegister
< (This
->may_swvp
? NINE_MAX_CONST_B_SWVP
: NINE_MAX_CONST_B
),
3382 D3DERR_INVALIDCALL
);
3383 user_assert(StartRegister
+ BoolCount
<= (This
->may_swvp
? NINE_MAX_CONST_B_SWVP
: NINE_MAX_CONST_B
),
3384 D3DERR_INVALIDCALL
);
3385 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3387 for (i
= 0; i
< BoolCount
; i
++)
3388 pConstantData
[i
] = state
->vs_const_b
[StartRegister
+ i
] != 0 ? TRUE
: FALSE
;
3394 NineDevice9_SetStreamSource( struct NineDevice9
*This
,
3396 IDirect3DVertexBuffer9
*pStreamData
,
3400 struct nine_state
*state
= This
->update
;
3401 struct NineVertexBuffer9
*pVBuf9
= NineVertexBuffer9(pStreamData
);
3402 const unsigned i
= StreamNumber
;
3404 DBG("This=%p StreamNumber=%u pStreamData=%p OffsetInBytes=%u Stride=%u\n",
3405 This
, StreamNumber
, pStreamData
, OffsetInBytes
, Stride
);
3407 user_assert(StreamNumber
< This
->caps
.MaxStreams
, D3DERR_INVALIDCALL
);
3408 user_assert(Stride
<= This
->caps
.MaxStreamStride
, D3DERR_INVALIDCALL
);
3410 if (unlikely(This
->is_recording
)) {
3411 nine_bind(&state
->stream
[i
], pStreamData
);
3412 state
->changed
.vtxbuf
|= 1 << StreamNumber
;
3413 state
->vtxbuf
[i
].stride
= Stride
;
3414 state
->vtxbuf
[i
].buffer_offset
= OffsetInBytes
;
3418 if (state
->stream
[i
] == NineVertexBuffer9(pStreamData
) &&
3419 state
->vtxbuf
[i
].stride
== Stride
&&
3420 state
->vtxbuf
[i
].buffer_offset
== OffsetInBytes
)
3423 state
->vtxbuf
[i
].stride
= Stride
;
3424 state
->vtxbuf
[i
].buffer_offset
= OffsetInBytes
;
3426 nine_bind(&state
->stream
[i
], pStreamData
);
3428 nine_context_set_stream_source(This
,
3438 NineDevice9_GetStreamSource( struct NineDevice9
*This
,
3440 IDirect3DVertexBuffer9
**ppStreamData
,
3441 UINT
*pOffsetInBytes
,
3444 const struct nine_state
*state
= &This
->state
;
3445 const unsigned i
= StreamNumber
;
3447 user_assert(StreamNumber
< This
->caps
.MaxStreams
, D3DERR_INVALIDCALL
);
3448 user_assert(ppStreamData
, D3DERR_INVALIDCALL
);
3450 nine_reference_set(ppStreamData
, state
->stream
[i
]);
3451 *pStride
= state
->vtxbuf
[i
].stride
;
3452 *pOffsetInBytes
= state
->vtxbuf
[i
].buffer_offset
;
3458 NineDevice9_SetStreamSourceFreq( struct NineDevice9
*This
,
3462 struct nine_state
*state
= This
->update
;
3463 /* const UINT freq = Setting & 0x7FFFFF; */
3465 DBG("This=%p StreamNumber=%u FrequencyParameter=0x%x\n", This
,
3466 StreamNumber
, Setting
);
3468 user_assert(StreamNumber
< This
->caps
.MaxStreams
, D3DERR_INVALIDCALL
);
3469 user_assert(StreamNumber
!= 0 || !(Setting
& D3DSTREAMSOURCE_INSTANCEDATA
),
3470 D3DERR_INVALIDCALL
);
3471 user_assert(!((Setting
& D3DSTREAMSOURCE_INSTANCEDATA
) &&
3472 (Setting
& D3DSTREAMSOURCE_INDEXEDDATA
)), D3DERR_INVALIDCALL
);
3473 user_assert(Setting
, D3DERR_INVALIDCALL
);
3475 if (unlikely(This
->is_recording
)) {
3476 state
->stream_freq
[StreamNumber
] = Setting
;
3477 state
->changed
.stream_freq
|= 1 << StreamNumber
;
3478 if (StreamNumber
!= 0)
3479 state
->changed
.group
|= NINE_STATE_STREAMFREQ
;
3483 if (state
->stream_freq
[StreamNumber
] == Setting
)
3486 state
->stream_freq
[StreamNumber
] = Setting
;
3488 nine_context_set_stream_source_freq(This
, StreamNumber
, Setting
);
3493 NineDevice9_GetStreamSourceFreq( struct NineDevice9
*This
,
3497 user_assert(StreamNumber
< This
->caps
.MaxStreams
, D3DERR_INVALIDCALL
);
3498 *pSetting
= This
->state
.stream_freq
[StreamNumber
];
3503 NineDevice9_SetIndices( struct NineDevice9
*This
,
3504 IDirect3DIndexBuffer9
*pIndexData
)
3506 struct nine_state
*state
= This
->update
;
3508 DBG("This=%p pIndexData=%p\n", This
, pIndexData
);
3510 if (likely(!This
->is_recording
))
3511 if (state
->idxbuf
== NineIndexBuffer9(pIndexData
))
3513 nine_bind(&state
->idxbuf
, pIndexData
);
3515 state
->changed
.group
|= NINE_STATE_IDXBUF
;
3520 /* XXX: wine/d3d9 doesn't have pBaseVertexIndex, and it doesn't make sense
3521 * here because it's an argument passed to the Draw calls.
3524 NineDevice9_GetIndices( struct NineDevice9
*This
,
3525 IDirect3DIndexBuffer9
**ppIndexData
)
3527 user_assert(ppIndexData
, D3DERR_INVALIDCALL
);
3528 nine_reference_set(ppIndexData
, This
->state
.idxbuf
);
3533 NineDevice9_CreatePixelShader( struct NineDevice9
*This
,
3534 const DWORD
*pFunction
,
3535 IDirect3DPixelShader9
**ppShader
)
3537 struct NinePixelShader9
*ps
;
3540 DBG("This=%p pFunction=%p ppShader=%p\n", This
, pFunction
, ppShader
);
3542 hr
= NinePixelShader9_new(This
, &ps
, pFunction
, NULL
);
3545 *ppShader
= (IDirect3DPixelShader9
*)ps
;
3550 NineDevice9_SetPixelShader( struct NineDevice9
*This
,
3551 IDirect3DPixelShader9
*pShader
)
3553 struct nine_state
*state
= This
->update
;
3554 struct nine_context
*context
= &This
->context
;
3555 unsigned old_mask
= state
->ps
? state
->ps
->rt_mask
: 1;
3558 DBG("This=%p pShader=%p\n", This
, pShader
);
3560 if (!This
->is_recording
&& state
->ps
== (struct NinePixelShader9
*)pShader
)
3563 /* ff -> non-ff: commit back non-ff constants */
3564 if (!state
->ps
&& pShader
)
3565 context
->commit
|= NINE_STATE_COMMIT_CONST_PS
;
3567 nine_bind(&state
->ps
, pShader
);
3569 state
->changed
.group
|= NINE_STATE_PS
;
3571 mask
= state
->ps
? state
->ps
->rt_mask
: 1;
3572 /* We need to update cbufs if the pixel shader would
3573 * write to different render targets */
3574 if (mask
!= old_mask
)
3575 state
->changed
.group
|= NINE_STATE_FB
;
3581 NineDevice9_GetPixelShader( struct NineDevice9
*This
,
3582 IDirect3DPixelShader9
**ppShader
)
3584 user_assert(ppShader
, D3DERR_INVALIDCALL
);
3585 nine_reference_set(ppShader
, This
->state
.ps
);
3590 NineDevice9_SetPixelShaderConstantF( struct NineDevice9
*This
,
3592 const float *pConstantData
,
3593 UINT Vector4fCount
)
3595 struct nine_state
*state
= This
->update
;
3597 DBG("This=%p StartRegister=%u pConstantData=%p Vector4fCount=%u\n",
3598 This
, StartRegister
, pConstantData
, Vector4fCount
);
3600 user_assert(StartRegister
< NINE_MAX_CONST_F_PS3
, D3DERR_INVALIDCALL
);
3601 user_assert(StartRegister
+ Vector4fCount
<= NINE_MAX_CONST_F_PS3
, D3DERR_INVALIDCALL
);
3605 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3607 if (!This
->is_recording
) {
3608 if (!memcmp(&state
->ps_const_f
[StartRegister
* 4], pConstantData
,
3609 Vector4fCount
* 4 * sizeof(state
->ps_const_f
[0])))
3613 memcpy(&state
->ps_const_f
[StartRegister
* 4],
3615 Vector4fCount
* 4 * sizeof(state
->ps_const_f
[0]));
3617 nine_ranges_insert(&state
->changed
.ps_const_f
,
3618 StartRegister
, StartRegister
+ Vector4fCount
,
3621 state
->changed
.group
|= NINE_STATE_PS_CONST
;
3627 NineDevice9_GetPixelShaderConstantF( struct NineDevice9
*This
,
3629 float *pConstantData
,
3630 UINT Vector4fCount
)
3632 const struct nine_state
*state
= &This
->state
;
3634 user_assert(StartRegister
< NINE_MAX_CONST_F_PS3
, D3DERR_INVALIDCALL
);
3635 user_assert(StartRegister
+ Vector4fCount
<= NINE_MAX_CONST_F_PS3
, D3DERR_INVALIDCALL
);
3636 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3638 memcpy(pConstantData
,
3639 &state
->ps_const_f
[StartRegister
* 4],
3640 Vector4fCount
* 4 * sizeof(state
->ps_const_f
[0]));
3646 NineDevice9_SetPixelShaderConstantI( struct NineDevice9
*This
,
3648 const int *pConstantData
,
3649 UINT Vector4iCount
)
3651 struct nine_state
*state
= This
->update
;
3654 DBG("This=%p StartRegister=%u pConstantData=%p Vector4iCount=%u\n",
3655 This
, StartRegister
, pConstantData
, Vector4iCount
);
3657 user_assert(StartRegister
< NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3658 user_assert(StartRegister
+ Vector4iCount
<= NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3659 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3661 if (This
->driver_caps
.ps_integer
) {
3662 if (!This
->is_recording
) {
3663 if (!memcmp(&state
->ps_const_i
[StartRegister
][0], pConstantData
,
3664 Vector4iCount
* sizeof(state
->ps_const_i
[0])))
3667 memcpy(&state
->ps_const_i
[StartRegister
][0],
3669 Vector4iCount
* sizeof(state
->ps_const_i
[0]));
3671 for (i
= 0; i
< Vector4iCount
; i
++) {
3672 state
->ps_const_i
[StartRegister
+i
][0] = fui((float)(pConstantData
[4*i
]));
3673 state
->ps_const_i
[StartRegister
+i
][1] = fui((float)(pConstantData
[4*i
+1]));
3674 state
->ps_const_i
[StartRegister
+i
][2] = fui((float)(pConstantData
[4*i
+2]));
3675 state
->ps_const_i
[StartRegister
+i
][3] = fui((float)(pConstantData
[4*i
+3]));
3678 state
->changed
.ps_const_i
|= ((1 << Vector4iCount
) - 1) << StartRegister
;
3679 state
->changed
.group
|= NINE_STATE_PS_CONST
;
3685 NineDevice9_GetPixelShaderConstantI( struct NineDevice9
*This
,
3688 UINT Vector4iCount
)
3690 const struct nine_state
*state
= &This
->state
;
3693 user_assert(StartRegister
< NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3694 user_assert(StartRegister
+ Vector4iCount
<= NINE_MAX_CONST_I
, D3DERR_INVALIDCALL
);
3695 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3697 if (This
->driver_caps
.ps_integer
) {
3698 memcpy(pConstantData
,
3699 &state
->ps_const_i
[StartRegister
][0],
3700 Vector4iCount
* sizeof(state
->ps_const_i
[0]));
3702 for (i
= 0; i
< Vector4iCount
; i
++) {
3703 pConstantData
[4*i
] = (int32_t) uif(state
->ps_const_i
[StartRegister
+i
][0]);
3704 pConstantData
[4*i
+1] = (int32_t) uif(state
->ps_const_i
[StartRegister
+i
][1]);
3705 pConstantData
[4*i
+2] = (int32_t) uif(state
->ps_const_i
[StartRegister
+i
][2]);
3706 pConstantData
[4*i
+3] = (int32_t) uif(state
->ps_const_i
[StartRegister
+i
][3]);
3714 NineDevice9_SetPixelShaderConstantB( struct NineDevice9
*This
,
3716 const BOOL
*pConstantData
,
3719 struct nine_state
*state
= This
->update
;
3721 uint32_t bool_true
= This
->driver_caps
.ps_integer
? 0xFFFFFFFF : fui(1.0f
);
3723 DBG("This=%p StartRegister=%u pConstantData=%p BoolCount=%u\n",
3724 This
, StartRegister
, pConstantData
, BoolCount
);
3726 user_assert(StartRegister
< NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3727 user_assert(StartRegister
+ BoolCount
<= NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3728 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3730 if (!This
->is_recording
) {
3731 bool noChange
= true;
3732 for (i
= 0; i
< BoolCount
; i
++) {
3733 if (!!state
->ps_const_b
[StartRegister
+ i
] != !!pConstantData
[i
])
3740 for (i
= 0; i
< BoolCount
; i
++)
3741 state
->ps_const_b
[StartRegister
+ i
] = pConstantData
[i
] ? bool_true
: 0;
3743 state
->changed
.ps_const_b
|= ((1 << BoolCount
) - 1) << StartRegister
;
3744 state
->changed
.group
|= NINE_STATE_PS_CONST
;
3750 NineDevice9_GetPixelShaderConstantB( struct NineDevice9
*This
,
3752 BOOL
*pConstantData
,
3755 const struct nine_state
*state
= &This
->state
;
3758 user_assert(StartRegister
< NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3759 user_assert(StartRegister
+ BoolCount
<= NINE_MAX_CONST_B
, D3DERR_INVALIDCALL
);
3760 user_assert(pConstantData
, D3DERR_INVALIDCALL
);
3762 for (i
= 0; i
< BoolCount
; i
++)
3763 pConstantData
[i
] = state
->ps_const_b
[StartRegister
+ i
] ? TRUE
: FALSE
;
3769 NineDevice9_DrawRectPatch( struct NineDevice9
*This
,
3771 const float *pNumSegs
,
3772 const D3DRECTPATCH_INFO
*pRectPatchInfo
)
3774 STUB(D3DERR_INVALIDCALL
);
3778 NineDevice9_DrawTriPatch( struct NineDevice9
*This
,
3780 const float *pNumSegs
,
3781 const D3DTRIPATCH_INFO
*pTriPatchInfo
)
3783 STUB(D3DERR_INVALIDCALL
);
3787 NineDevice9_DeletePatch( struct NineDevice9
*This
,
3790 STUB(D3DERR_INVALIDCALL
);
3794 NineDevice9_CreateQuery( struct NineDevice9
*This
,
3796 IDirect3DQuery9
**ppQuery
)
3798 struct NineQuery9
*query
;
3801 DBG("This=%p Type=%d ppQuery=%p\n", This
, Type
, ppQuery
);
3803 hr
= nine_is_query_supported(This
->screen
, Type
);
3804 if (!ppQuery
|| hr
!= D3D_OK
)
3807 hr
= NineQuery9_new(This
, &query
, Type
);
3810 *ppQuery
= (IDirect3DQuery9
*)query
;
3814 IDirect3DDevice9Vtbl NineDevice9_vtable
= {
3815 (void *)NineUnknown_QueryInterface
,
3816 (void *)NineUnknown_AddRef
,
3817 (void *)NineUnknown_Release
,
3818 (void *)NineDevice9_TestCooperativeLevel
,
3819 (void *)NineDevice9_GetAvailableTextureMem
,
3820 (void *)NineDevice9_EvictManagedResources
,
3821 (void *)NineDevice9_GetDirect3D
,
3822 (void *)NineDevice9_GetDeviceCaps
,
3823 (void *)NineDevice9_GetDisplayMode
,
3824 (void *)NineDevice9_GetCreationParameters
,
3825 (void *)NineDevice9_SetCursorProperties
,
3826 (void *)NineDevice9_SetCursorPosition
,
3827 (void *)NineDevice9_ShowCursor
,
3828 (void *)NineDevice9_CreateAdditionalSwapChain
,
3829 (void *)NineDevice9_GetSwapChain
,
3830 (void *)NineDevice9_GetNumberOfSwapChains
,
3831 (void *)NineDevice9_Reset
,
3832 (void *)NineDevice9_Present
,
3833 (void *)NineDevice9_GetBackBuffer
,
3834 (void *)NineDevice9_GetRasterStatus
,
3835 (void *)NineDevice9_SetDialogBoxMode
,
3836 (void *)NineDevice9_SetGammaRamp
,
3837 (void *)NineDevice9_GetGammaRamp
,
3838 (void *)NineDevice9_CreateTexture
,
3839 (void *)NineDevice9_CreateVolumeTexture
,
3840 (void *)NineDevice9_CreateCubeTexture
,
3841 (void *)NineDevice9_CreateVertexBuffer
,
3842 (void *)NineDevice9_CreateIndexBuffer
,
3843 (void *)NineDevice9_CreateRenderTarget
,
3844 (void *)NineDevice9_CreateDepthStencilSurface
,
3845 (void *)NineDevice9_UpdateSurface
,
3846 (void *)NineDevice9_UpdateTexture
,
3847 (void *)NineDevice9_GetRenderTargetData
,
3848 (void *)NineDevice9_GetFrontBufferData
,
3849 (void *)NineDevice9_StretchRect
,
3850 (void *)NineDevice9_ColorFill
,
3851 (void *)NineDevice9_CreateOffscreenPlainSurface
,
3852 (void *)NineDevice9_SetRenderTarget
,
3853 (void *)NineDevice9_GetRenderTarget
,
3854 (void *)NineDevice9_SetDepthStencilSurface
,
3855 (void *)NineDevice9_GetDepthStencilSurface
,
3856 (void *)NineDevice9_BeginScene
,
3857 (void *)NineDevice9_EndScene
,
3858 (void *)NineDevice9_Clear
,
3859 (void *)NineDevice9_SetTransform
,
3860 (void *)NineDevice9_GetTransform
,
3861 (void *)NineDevice9_MultiplyTransform
,
3862 (void *)NineDevice9_SetViewport
,
3863 (void *)NineDevice9_GetViewport
,
3864 (void *)NineDevice9_SetMaterial
,
3865 (void *)NineDevice9_GetMaterial
,
3866 (void *)NineDevice9_SetLight
,
3867 (void *)NineDevice9_GetLight
,
3868 (void *)NineDevice9_LightEnable
,
3869 (void *)NineDevice9_GetLightEnable
,
3870 (void *)NineDevice9_SetClipPlane
,
3871 (void *)NineDevice9_GetClipPlane
,
3872 (void *)NineDevice9_SetRenderState
,
3873 (void *)NineDevice9_GetRenderState
,
3874 (void *)NineDevice9_CreateStateBlock
,
3875 (void *)NineDevice9_BeginStateBlock
,
3876 (void *)NineDevice9_EndStateBlock
,
3877 (void *)NineDevice9_SetClipStatus
,
3878 (void *)NineDevice9_GetClipStatus
,
3879 (void *)NineDevice9_GetTexture
,
3880 (void *)NineDevice9_SetTexture
,
3881 (void *)NineDevice9_GetTextureStageState
,
3882 (void *)NineDevice9_SetTextureStageState
,
3883 (void *)NineDevice9_GetSamplerState
,
3884 (void *)NineDevice9_SetSamplerState
,
3885 (void *)NineDevice9_ValidateDevice
,
3886 (void *)NineDevice9_SetPaletteEntries
,
3887 (void *)NineDevice9_GetPaletteEntries
,
3888 (void *)NineDevice9_SetCurrentTexturePalette
,
3889 (void *)NineDevice9_GetCurrentTexturePalette
,
3890 (void *)NineDevice9_SetScissorRect
,
3891 (void *)NineDevice9_GetScissorRect
,
3892 (void *)NineDevice9_SetSoftwareVertexProcessing
,
3893 (void *)NineDevice9_GetSoftwareVertexProcessing
,
3894 (void *)NineDevice9_SetNPatchMode
,
3895 (void *)NineDevice9_GetNPatchMode
,
3896 (void *)NineDevice9_DrawPrimitive
,
3897 (void *)NineDevice9_DrawIndexedPrimitive
,
3898 (void *)NineDevice9_DrawPrimitiveUP
,
3899 (void *)NineDevice9_DrawIndexedPrimitiveUP
,
3900 (void *)NineDevice9_ProcessVertices
,
3901 (void *)NineDevice9_CreateVertexDeclaration
,
3902 (void *)NineDevice9_SetVertexDeclaration
,
3903 (void *)NineDevice9_GetVertexDeclaration
,
3904 (void *)NineDevice9_SetFVF
,
3905 (void *)NineDevice9_GetFVF
,
3906 (void *)NineDevice9_CreateVertexShader
,
3907 (void *)NineDevice9_SetVertexShader
,
3908 (void *)NineDevice9_GetVertexShader
,
3909 (void *)NineDevice9_SetVertexShaderConstantF
,
3910 (void *)NineDevice9_GetVertexShaderConstantF
,
3911 (void *)NineDevice9_SetVertexShaderConstantI
,
3912 (void *)NineDevice9_GetVertexShaderConstantI
,
3913 (void *)NineDevice9_SetVertexShaderConstantB
,
3914 (void *)NineDevice9_GetVertexShaderConstantB
,
3915 (void *)NineDevice9_SetStreamSource
,
3916 (void *)NineDevice9_GetStreamSource
,
3917 (void *)NineDevice9_SetStreamSourceFreq
,
3918 (void *)NineDevice9_GetStreamSourceFreq
,
3919 (void *)NineDevice9_SetIndices
,
3920 (void *)NineDevice9_GetIndices
,
3921 (void *)NineDevice9_CreatePixelShader
,
3922 (void *)NineDevice9_SetPixelShader
,
3923 (void *)NineDevice9_GetPixelShader
,
3924 (void *)NineDevice9_SetPixelShaderConstantF
,
3925 (void *)NineDevice9_GetPixelShaderConstantF
,
3926 (void *)NineDevice9_SetPixelShaderConstantI
,
3927 (void *)NineDevice9_GetPixelShaderConstantI
,
3928 (void *)NineDevice9_SetPixelShaderConstantB
,
3929 (void *)NineDevice9_GetPixelShaderConstantB
,
3930 (void *)NineDevice9_DrawRectPatch
,
3931 (void *)NineDevice9_DrawTriPatch
,
3932 (void *)NineDevice9_DeletePatch
,
3933 (void *)NineDevice9_CreateQuery
3936 static const GUID
*NineDevice9_IIDs
[] = {
3937 &IID_IDirect3DDevice9
,
3943 NineDevice9_new( struct pipe_screen
*pScreen
,
3944 D3DDEVICE_CREATION_PARAMETERS
*pCreationParameters
,
3946 D3DPRESENT_PARAMETERS
*pPresentationParameters
,
3948 ID3DPresentGroup
*pPresentationGroup
,
3949 struct d3dadapter9_context
*pCTX
,
3951 D3DDISPLAYMODEEX
*pFullscreenDisplayMode
,
3952 struct NineDevice9
**ppOut
,
3953 int minorVersionNum
)
3956 lock
= !!(pCreationParameters
->BehaviorFlags
& D3DCREATE_MULTITHREADED
);
3958 NINE_NEW(Device9
, ppOut
, lock
, /* args */
3959 pScreen
, pCreationParameters
, pCaps
,
3960 pPresentationParameters
, pD3D9
, pPresentationGroup
, pCTX
,
3961 ex
, pFullscreenDisplayMode
, minorVersionNum
);