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