secur32/tests: Use importlib for functions available since Windows XP.
[wine.git] / dlls / wined3d / cs.c
blobf41b1a56f3c8a7aeed285e0d581a8bb6e6776b33
1 /*
2 * Copyright 2013 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "config.h"
20 #include "wine/port.h"
21 #include "wined3d_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
25 #define WINED3D_INITIAL_CS_SIZE 4096
27 enum wined3d_cs_op
29 WINED3D_CS_OP_PRESENT,
30 WINED3D_CS_OP_CLEAR,
31 WINED3D_CS_OP_DRAW,
32 WINED3D_CS_OP_SET_PREDICATION,
33 WINED3D_CS_OP_SET_VIEWPORT,
34 WINED3D_CS_OP_SET_SCISSOR_RECT,
35 WINED3D_CS_OP_SET_RENDERTARGET_VIEW,
36 WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW,
37 WINED3D_CS_OP_SET_VERTEX_DECLARATION,
38 WINED3D_CS_OP_SET_STREAM_SOURCE,
39 WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ,
40 WINED3D_CS_OP_SET_STREAM_OUTPUT,
41 WINED3D_CS_OP_SET_INDEX_BUFFER,
42 WINED3D_CS_OP_SET_CONSTANT_BUFFER,
43 WINED3D_CS_OP_SET_TEXTURE,
44 WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW,
45 WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW,
46 WINED3D_CS_OP_SET_SAMPLER,
47 WINED3D_CS_OP_SET_SHADER,
48 WINED3D_CS_OP_SET_RASTERIZER_STATE,
49 WINED3D_CS_OP_SET_RENDER_STATE,
50 WINED3D_CS_OP_SET_TEXTURE_STATE,
51 WINED3D_CS_OP_SET_SAMPLER_STATE,
52 WINED3D_CS_OP_SET_TRANSFORM,
53 WINED3D_CS_OP_SET_CLIP_PLANE,
54 WINED3D_CS_OP_SET_COLOR_KEY,
55 WINED3D_CS_OP_SET_MATERIAL,
56 WINED3D_CS_OP_RESET_STATE,
57 WINED3D_CS_OP_DESTROY_OBJECT,
58 WINED3D_CS_OP_QUERY_ISSUE,
59 WINED3D_CS_OP_PRELOAD_RESOURCE,
60 WINED3D_CS_OP_UNLOAD_RESOURCE,
61 WINED3D_CS_OP_MAP,
62 WINED3D_CS_OP_UNMAP,
65 struct wined3d_cs_present
67 enum wined3d_cs_op opcode;
68 HWND dst_window_override;
69 struct wined3d_swapchain *swapchain;
70 RECT src_rect;
71 RECT dst_rect;
72 DWORD flags;
75 struct wined3d_cs_clear
77 enum wined3d_cs_op opcode;
78 DWORD flags;
79 struct wined3d_color color;
80 float depth;
81 DWORD stencil;
82 unsigned int rect_count;
83 RECT rects[1];
86 struct wined3d_cs_draw
88 enum wined3d_cs_op opcode;
89 int base_vertex_idx;
90 unsigned int start_idx;
91 unsigned int index_count;
92 unsigned int start_instance;
93 unsigned int instance_count;
94 BOOL indexed;
97 struct wined3d_cs_set_predication
99 enum wined3d_cs_op opcode;
100 struct wined3d_query *predicate;
101 BOOL value;
104 struct wined3d_cs_set_viewport
106 enum wined3d_cs_op opcode;
107 struct wined3d_viewport viewport;
110 struct wined3d_cs_set_scissor_rect
112 enum wined3d_cs_op opcode;
113 RECT rect;
116 struct wined3d_cs_set_rendertarget_view
118 enum wined3d_cs_op opcode;
119 unsigned int view_idx;
120 struct wined3d_rendertarget_view *view;
123 struct wined3d_cs_set_depth_stencil_view
125 enum wined3d_cs_op opcode;
126 struct wined3d_rendertarget_view *view;
129 struct wined3d_cs_set_vertex_declaration
131 enum wined3d_cs_op opcode;
132 struct wined3d_vertex_declaration *declaration;
135 struct wined3d_cs_set_stream_source
137 enum wined3d_cs_op opcode;
138 UINT stream_idx;
139 struct wined3d_buffer *buffer;
140 UINT offset;
141 UINT stride;
144 struct wined3d_cs_set_stream_source_freq
146 enum wined3d_cs_op opcode;
147 UINT stream_idx;
148 UINT frequency;
149 UINT flags;
152 struct wined3d_cs_set_stream_output
154 enum wined3d_cs_op opcode;
155 UINT stream_idx;
156 struct wined3d_buffer *buffer;
157 UINT offset;
160 struct wined3d_cs_set_index_buffer
162 enum wined3d_cs_op opcode;
163 struct wined3d_buffer *buffer;
164 enum wined3d_format_id format_id;
165 unsigned int offset;
168 struct wined3d_cs_set_constant_buffer
170 enum wined3d_cs_op opcode;
171 enum wined3d_shader_type type;
172 UINT cb_idx;
173 struct wined3d_buffer *buffer;
176 struct wined3d_cs_set_texture
178 enum wined3d_cs_op opcode;
179 UINT stage;
180 struct wined3d_texture *texture;
183 struct wined3d_cs_set_color_key
185 enum wined3d_cs_op opcode;
186 struct wined3d_texture *texture;
187 WORD flags;
188 WORD set;
189 struct wined3d_color_key color_key;
192 struct wined3d_cs_set_shader_resource_view
194 enum wined3d_cs_op opcode;
195 enum wined3d_shader_type type;
196 UINT view_idx;
197 struct wined3d_shader_resource_view *view;
200 struct wined3d_cs_set_unordered_access_view
202 enum wined3d_cs_op opcode;
203 unsigned int view_idx;
204 struct wined3d_unordered_access_view *view;
207 struct wined3d_cs_set_sampler
209 enum wined3d_cs_op opcode;
210 enum wined3d_shader_type type;
211 UINT sampler_idx;
212 struct wined3d_sampler *sampler;
215 struct wined3d_cs_set_shader
217 enum wined3d_cs_op opcode;
218 enum wined3d_shader_type type;
219 struct wined3d_shader *shader;
222 struct wined3d_cs_set_rasterizer_state
224 enum wined3d_cs_op opcode;
225 struct wined3d_rasterizer_state *state;
228 struct wined3d_cs_set_render_state
230 enum wined3d_cs_op opcode;
231 enum wined3d_render_state state;
232 DWORD value;
235 struct wined3d_cs_set_texture_state
237 enum wined3d_cs_op opcode;
238 UINT stage;
239 enum wined3d_texture_stage_state state;
240 DWORD value;
243 struct wined3d_cs_set_sampler_state
245 enum wined3d_cs_op opcode;
246 UINT sampler_idx;
247 enum wined3d_sampler_state state;
248 DWORD value;
251 struct wined3d_cs_set_transform
253 enum wined3d_cs_op opcode;
254 enum wined3d_transform_state state;
255 struct wined3d_matrix matrix;
258 struct wined3d_cs_set_clip_plane
260 enum wined3d_cs_op opcode;
261 UINT plane_idx;
262 struct wined3d_vec4 plane;
265 struct wined3d_cs_set_material
267 enum wined3d_cs_op opcode;
268 struct wined3d_material material;
271 struct wined3d_cs_reset_state
273 enum wined3d_cs_op opcode;
276 struct wined3d_cs_destroy_object
278 enum wined3d_cs_op opcode;
279 void (*callback)(void *object);
280 void *object;
283 struct wined3d_cs_query_issue
285 enum wined3d_cs_op opcode;
286 struct wined3d_query *query;
287 DWORD flags;
290 struct wined3d_cs_preload_resource
292 enum wined3d_cs_op opcode;
293 struct wined3d_resource *resource;
296 struct wined3d_cs_unload_resource
298 enum wined3d_cs_op opcode;
299 struct wined3d_resource *resource;
302 struct wined3d_cs_map
304 enum wined3d_cs_op opcode;
305 struct wined3d_resource *resource;
306 unsigned int sub_resource_idx;
307 struct wined3d_map_desc *map_desc;
308 const struct wined3d_box *box;
309 DWORD flags;
310 HRESULT *hr;
313 struct wined3d_cs_unmap
315 enum wined3d_cs_op opcode;
316 struct wined3d_resource *resource;
317 unsigned int sub_resource_idx;
318 HRESULT *hr;
321 static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data)
323 const struct wined3d_cs_present *op = data;
324 struct wined3d_swapchain *swapchain;
325 unsigned int i;
327 swapchain = op->swapchain;
328 wined3d_swapchain_set_window(swapchain, op->dst_window_override);
330 swapchain->swapchain_ops->swapchain_present(swapchain, &op->src_rect, &op->dst_rect, op->flags);
332 wined3d_resource_release(&swapchain->front_buffer->resource);
333 for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
335 wined3d_resource_release(&swapchain->back_buffers[i]->resource);
339 void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain,
340 const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD flags)
342 struct wined3d_cs_present *op;
343 unsigned int i;
345 op = cs->ops->require_space(cs, sizeof(*op));
346 op->opcode = WINED3D_CS_OP_PRESENT;
347 op->dst_window_override = dst_window_override;
348 op->swapchain = swapchain;
349 op->src_rect = *src_rect;
350 op->dst_rect = *dst_rect;
351 op->flags = flags;
353 wined3d_resource_acquire(&swapchain->front_buffer->resource);
354 for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
356 wined3d_resource_acquire(&swapchain->back_buffers[i]->resource);
359 cs->ops->submit(cs);
362 static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data)
364 const struct wined3d_cs_clear *op = data;
365 const struct wined3d_state *state;
366 struct wined3d_device *device;
367 unsigned int i;
368 RECT draw_rect;
370 device = cs->device;
371 state = &device->state;
372 wined3d_get_draw_rect(state, &draw_rect);
373 device_clear_render_targets(device, device->adapter->gl_info.limits.buffers,
374 &device->fb, op->rect_count, op->rects, &draw_rect, op->flags,
375 &op->color, op->depth, op->stencil);
377 if (op->flags & WINED3DCLEAR_TARGET)
379 for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
381 if (state->fb->render_targets[i])
382 wined3d_resource_release(state->fb->render_targets[i]->resource);
385 if (op->flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
386 wined3d_resource_release(state->fb->depth_stencil->resource);
389 void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects,
390 DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil)
392 const struct wined3d_state *state = &cs->device->state;
393 struct wined3d_cs_clear *op;
394 unsigned int i;
396 op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_clear, rects[rect_count]));
397 op->opcode = WINED3D_CS_OP_CLEAR;
398 op->flags = flags;
399 op->color = *color;
400 op->depth = depth;
401 op->stencil = stencil;
402 op->rect_count = rect_count;
403 memcpy(op->rects, rects, sizeof(*rects) * rect_count);
405 if (flags & WINED3DCLEAR_TARGET)
407 for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; ++i)
409 if (state->fb->render_targets[i])
410 wined3d_resource_acquire(state->fb->render_targets[i]->resource);
413 if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
414 wined3d_resource_acquire(state->fb->depth_stencil->resource);
416 cs->ops->submit(cs);
419 static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data)
421 struct wined3d_state *state = &cs->device->state;
422 struct wined3d_shader_sampler_map_entry *entry;
423 struct wined3d_shader_resource_view *view;
424 const struct wined3d_cs_draw *op = data;
425 struct wined3d_shader *shader;
426 unsigned int i, j;
428 if (!cs->device->adapter->gl_info.supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]
429 && state->load_base_vertex_index != op->base_vertex_idx)
431 state->load_base_vertex_index = op->base_vertex_idx;
432 device_invalidate_state(cs->device, STATE_BASEVERTEXINDEX);
435 draw_primitive(cs->device, state, op->base_vertex_idx, op->start_idx,
436 op->index_count, op->start_instance, op->instance_count, op->indexed);
438 if (op->indexed)
439 wined3d_resource_release(&state->index_buffer->resource);
440 for (i = 0; i < ARRAY_SIZE(state->streams); ++i)
442 if (state->streams[i].buffer)
443 wined3d_resource_release(&state->streams[i].buffer->resource);
445 for (i = 0; i < ARRAY_SIZE(state->textures); ++i)
447 if (state->textures[i])
448 wined3d_resource_release(&state->textures[i]->resource);
450 for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; ++i)
452 if (state->fb->render_targets[i])
453 wined3d_resource_release(state->fb->render_targets[i]->resource);
455 if (state->fb->depth_stencil)
456 wined3d_resource_release(state->fb->depth_stencil->resource);
457 for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i)
459 if (!(shader = state->shader[i]))
460 continue;
462 for (j = 0; j < WINED3D_MAX_CBS; ++j)
464 if (state->cb[i][j])
465 wined3d_resource_release(&state->cb[i][j]->resource);
468 for (j = 0; j < shader->reg_maps.sampler_map.count; ++j)
470 entry = &shader->reg_maps.sampler_map.entries[j];
472 if (!(view = state->shader_resource_view[i][entry->resource_idx]))
473 continue;
475 wined3d_resource_release(view->resource);
480 void wined3d_cs_emit_draw(struct wined3d_cs *cs, int base_vertex_idx, unsigned int start_idx,
481 unsigned int index_count, unsigned int start_instance, unsigned int instance_count, BOOL indexed)
483 const struct wined3d_state *state = &cs->device->state;
484 struct wined3d_shader_sampler_map_entry *entry;
485 struct wined3d_shader_resource_view *view;
486 struct wined3d_shader *shader;
487 struct wined3d_cs_draw *op;
488 unsigned int i, j;
490 op = cs->ops->require_space(cs, sizeof(*op));
491 op->opcode = WINED3D_CS_OP_DRAW;
492 op->base_vertex_idx = base_vertex_idx;
493 op->start_idx = start_idx;
494 op->index_count = index_count;
495 op->start_instance = start_instance;
496 op->instance_count = instance_count;
497 op->indexed = indexed;
499 if (indexed)
500 wined3d_resource_acquire(&state->index_buffer->resource);
501 for (i = 0; i < ARRAY_SIZE(state->streams); ++i)
503 if (state->streams[i].buffer)
504 wined3d_resource_acquire(&state->streams[i].buffer->resource);
506 for (i = 0; i < ARRAY_SIZE(state->textures); ++i)
508 if (state->textures[i])
509 wined3d_resource_acquire(&state->textures[i]->resource);
511 for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; ++i)
513 if (state->fb->render_targets[i])
514 wined3d_resource_acquire(state->fb->render_targets[i]->resource);
516 if (state->fb->depth_stencil)
517 wined3d_resource_acquire(state->fb->depth_stencil->resource);
518 for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i)
520 if (!(shader = state->shader[i]))
521 continue;
523 for (j = 0; j < WINED3D_MAX_CBS; ++j)
525 if (state->cb[i][j])
526 wined3d_resource_acquire(&state->cb[i][j]->resource);
529 for (j = 0; j < shader->reg_maps.sampler_map.count; ++j)
531 entry = &shader->reg_maps.sampler_map.entries[j];
533 if (!(view = state->shader_resource_view[i][entry->resource_idx]))
534 continue;
536 wined3d_resource_acquire(view->resource);
540 cs->ops->submit(cs);
543 static void wined3d_cs_exec_set_predication(struct wined3d_cs *cs, const void *data)
545 const struct wined3d_cs_set_predication *op = data;
547 cs->state.predicate = op->predicate;
548 cs->state.predicate_value = op->value;
551 void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query *predicate, BOOL value)
553 struct wined3d_cs_set_predication *op;
555 op = cs->ops->require_space(cs, sizeof(*op));
556 op->opcode = WINED3D_CS_OP_SET_PREDICATION;
557 op->predicate = predicate;
558 op->value = value;
560 cs->ops->submit(cs);
563 static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data)
565 const struct wined3d_cs_set_viewport *op = data;
567 cs->state.viewport = op->viewport;
568 device_invalidate_state(cs->device, STATE_VIEWPORT);
571 void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport)
573 struct wined3d_cs_set_viewport *op;
575 op = cs->ops->require_space(cs, sizeof(*op));
576 op->opcode = WINED3D_CS_OP_SET_VIEWPORT;
577 op->viewport = *viewport;
579 cs->ops->submit(cs);
582 static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data)
584 const struct wined3d_cs_set_scissor_rect *op = data;
586 cs->state.scissor_rect = op->rect;
587 device_invalidate_state(cs->device, STATE_SCISSORRECT);
590 void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect)
592 struct wined3d_cs_set_scissor_rect *op;
594 op = cs->ops->require_space(cs, sizeof(*op));
595 op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT;
596 op->rect = *rect;
598 cs->ops->submit(cs);
601 static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data)
603 const struct wined3d_cs_set_rendertarget_view *op = data;
605 cs->state.fb->render_targets[op->view_idx] = op->view;
606 device_invalidate_state(cs->device, STATE_FRAMEBUFFER);
609 void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int view_idx,
610 struct wined3d_rendertarget_view *view)
612 struct wined3d_cs_set_rendertarget_view *op;
614 op = cs->ops->require_space(cs, sizeof(*op));
615 op->opcode = WINED3D_CS_OP_SET_RENDERTARGET_VIEW;
616 op->view_idx = view_idx;
617 op->view = view;
619 cs->ops->submit(cs);
622 static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const void *data)
624 const struct wined3d_cs_set_depth_stencil_view *op = data;
625 struct wined3d_device *device = cs->device;
626 struct wined3d_rendertarget_view *prev;
628 if ((prev = cs->state.fb->depth_stencil))
630 struct wined3d_surface *prev_surface = wined3d_rendertarget_view_get_surface(prev);
632 if (prev_surface && (device->swapchains[0]->desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL
633 || prev_surface->container->flags & WINED3D_TEXTURE_DISCARD))
635 surface_modify_ds_location(prev_surface, WINED3D_LOCATION_DISCARDED, prev->width, prev->height);
636 if (prev_surface == device->onscreen_depth_stencil)
638 wined3d_texture_decref(device->onscreen_depth_stencil->container);
639 device->onscreen_depth_stencil = NULL;
644 cs->fb.depth_stencil = op->view;
646 if (!prev != !op->view)
648 /* Swapping NULL / non NULL depth stencil affects the depth and tests */
649 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_ZENABLE));
650 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILENABLE));
651 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK));
652 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
654 else if (prev && (prev->format_flags & WINED3DFMT_FLAG_FLOAT)
655 != (op->view->format_flags & WINED3DFMT_FLAG_FLOAT))
657 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
660 device_invalidate_state(device, STATE_FRAMEBUFFER);
663 void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view)
665 struct wined3d_cs_set_depth_stencil_view *op;
667 op = cs->ops->require_space(cs, sizeof(*op));
668 op->opcode = WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW;
669 op->view = view;
671 cs->ops->submit(cs);
674 static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data)
676 const struct wined3d_cs_set_vertex_declaration *op = data;
678 cs->state.vertex_declaration = op->declaration;
679 device_invalidate_state(cs->device, STATE_VDECL);
682 void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3d_vertex_declaration *declaration)
684 struct wined3d_cs_set_vertex_declaration *op;
686 op = cs->ops->require_space(cs, sizeof(*op));
687 op->opcode = WINED3D_CS_OP_SET_VERTEX_DECLARATION;
688 op->declaration = declaration;
690 cs->ops->submit(cs);
693 static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data)
695 const struct wined3d_cs_set_stream_source *op = data;
696 struct wined3d_stream_state *stream;
697 struct wined3d_buffer *prev;
699 stream = &cs->state.streams[op->stream_idx];
700 prev = stream->buffer;
701 stream->buffer = op->buffer;
702 stream->offset = op->offset;
703 stream->stride = op->stride;
705 if (op->buffer)
706 InterlockedIncrement(&op->buffer->resource.bind_count);
707 if (prev)
708 InterlockedDecrement(&prev->resource.bind_count);
710 device_invalidate_state(cs->device, STATE_STREAMSRC);
713 void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx,
714 struct wined3d_buffer *buffer, UINT offset, UINT stride)
716 struct wined3d_cs_set_stream_source *op;
718 op = cs->ops->require_space(cs, sizeof(*op));
719 op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE;
720 op->stream_idx = stream_idx;
721 op->buffer = buffer;
722 op->offset = offset;
723 op->stride = stride;
725 cs->ops->submit(cs);
728 static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data)
730 const struct wined3d_cs_set_stream_source_freq *op = data;
731 struct wined3d_stream_state *stream;
733 stream = &cs->state.streams[op->stream_idx];
734 stream->frequency = op->frequency;
735 stream->flags = op->flags;
737 device_invalidate_state(cs->device, STATE_STREAMSRC);
740 void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx, UINT frequency, UINT flags)
742 struct wined3d_cs_set_stream_source_freq *op;
744 op = cs->ops->require_space(cs, sizeof(*op));
745 op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ;
746 op->stream_idx = stream_idx;
747 op->frequency = frequency;
748 op->flags = flags;
750 cs->ops->submit(cs);
753 static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data)
755 const struct wined3d_cs_set_stream_output *op = data;
756 struct wined3d_stream_output *stream;
757 struct wined3d_buffer *prev;
759 stream = &cs->state.stream_output[op->stream_idx];
760 prev = stream->buffer;
761 stream->buffer = op->buffer;
762 stream->offset = op->offset;
764 if (op->buffer)
765 InterlockedIncrement(&op->buffer->resource.bind_count);
766 if (prev)
767 InterlockedDecrement(&prev->resource.bind_count);
770 void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx,
771 struct wined3d_buffer *buffer, UINT offset)
773 struct wined3d_cs_set_stream_output *op;
775 op = cs->ops->require_space(cs, sizeof(*op));
776 op->opcode = WINED3D_CS_OP_SET_STREAM_OUTPUT;
777 op->stream_idx = stream_idx;
778 op->buffer = buffer;
779 op->offset = offset;
781 cs->ops->submit(cs);
784 static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data)
786 const struct wined3d_cs_set_index_buffer *op = data;
787 struct wined3d_buffer *prev;
789 prev = cs->state.index_buffer;
790 cs->state.index_buffer = op->buffer;
791 cs->state.index_format = op->format_id;
792 cs->state.index_offset = op->offset;
794 if (op->buffer)
795 InterlockedIncrement(&op->buffer->resource.bind_count);
796 if (prev)
797 InterlockedDecrement(&prev->resource.bind_count);
799 device_invalidate_state(cs->device, STATE_INDEXBUFFER);
802 void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer,
803 enum wined3d_format_id format_id, unsigned int offset)
805 struct wined3d_cs_set_index_buffer *op;
807 op = cs->ops->require_space(cs, sizeof(*op));
808 op->opcode = WINED3D_CS_OP_SET_INDEX_BUFFER;
809 op->buffer = buffer;
810 op->format_id = format_id;
811 op->offset = offset;
813 cs->ops->submit(cs);
816 static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data)
818 const struct wined3d_cs_set_constant_buffer *op = data;
819 struct wined3d_buffer *prev;
821 prev = cs->state.cb[op->type][op->cb_idx];
822 cs->state.cb[op->type][op->cb_idx] = op->buffer;
824 if (op->buffer)
825 InterlockedIncrement(&op->buffer->resource.bind_count);
826 if (prev)
827 InterlockedDecrement(&prev->resource.bind_count);
829 device_invalidate_state(cs->device, STATE_CONSTANT_BUFFER(op->type));
832 void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type,
833 UINT cb_idx, struct wined3d_buffer *buffer)
835 struct wined3d_cs_set_constant_buffer *op;
837 op = cs->ops->require_space(cs, sizeof(*op));
838 op->opcode = WINED3D_CS_OP_SET_CONSTANT_BUFFER;
839 op->type = type;
840 op->cb_idx = cb_idx;
841 op->buffer = buffer;
843 cs->ops->submit(cs);
846 static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data)
848 const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info;
849 const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info;
850 const struct wined3d_cs_set_texture *op = data;
851 struct wined3d_texture *prev;
852 BOOL old_use_color_key = FALSE, new_use_color_key = FALSE;
854 prev = cs->state.textures[op->stage];
855 cs->state.textures[op->stage] = op->texture;
857 if (op->texture)
859 const struct wined3d_format *new_format = op->texture->resource.format;
860 const struct wined3d_format *old_format = prev ? prev->resource.format : NULL;
861 unsigned int old_fmt_flags = prev ? prev->resource.format_flags : 0;
862 unsigned int new_fmt_flags = op->texture->resource.format_flags;
864 if (InterlockedIncrement(&op->texture->resource.bind_count) == 1)
865 op->texture->sampler = op->stage;
867 if (!prev || op->texture->target != prev->target
868 || (!is_same_fixup(new_format->color_fixup, old_format->color_fixup)
869 && !(can_use_texture_swizzle(gl_info, new_format) && can_use_texture_swizzle(gl_info, old_format)))
870 || (new_fmt_flags & WINED3DFMT_FLAG_SHADOW) != (old_fmt_flags & WINED3DFMT_FLAG_SHADOW))
871 device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL));
873 if (!prev && op->stage < d3d_info->limits.ffp_blend_stages)
875 /* The source arguments for color and alpha ops have different
876 * meanings when a NULL texture is bound, so the COLOR_OP and
877 * ALPHA_OP have to be dirtified. */
878 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP));
879 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP));
882 if (!op->stage && op->texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
883 new_use_color_key = TRUE;
886 if (prev)
888 if (InterlockedDecrement(&prev->resource.bind_count) && prev->sampler == op->stage)
890 unsigned int i;
892 /* Search for other stages the texture is bound to. Shouldn't
893 * happen if applications bind textures to a single stage only. */
894 TRACE("Searching for other stages the texture is bound to.\n");
895 for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
897 if (cs->state.textures[i] == prev)
899 TRACE("Texture is also bound to stage %u.\n", i);
900 prev->sampler = i;
901 break;
906 if (!op->texture && op->stage < d3d_info->limits.ffp_blend_stages)
908 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP));
909 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP));
912 if (!op->stage && prev->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
913 old_use_color_key = TRUE;
916 device_invalidate_state(cs->device, STATE_SAMPLER(op->stage));
918 if (new_use_color_key != old_use_color_key)
919 device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE));
921 if (new_use_color_key)
922 device_invalidate_state(cs->device, STATE_COLOR_KEY);
925 void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined3d_texture *texture)
927 struct wined3d_cs_set_texture *op;
929 op = cs->ops->require_space(cs, sizeof(*op));
930 op->opcode = WINED3D_CS_OP_SET_TEXTURE;
931 op->stage = stage;
932 op->texture = texture;
934 cs->ops->submit(cs);
937 static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data)
939 const struct wined3d_cs_set_shader_resource_view *op = data;
941 cs->state.shader_resource_view[op->type][op->view_idx] = op->view;
942 device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
945 void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs *cs, unsigned int view_idx,
946 struct wined3d_unordered_access_view *view)
948 struct wined3d_cs_set_unordered_access_view *op;
950 op = cs->ops->require_space(cs, sizeof(*op));
951 op->opcode = WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW;
952 op->view_idx = view_idx;
953 op->view = view;
955 cs->ops->submit(cs);
958 static void wined3d_cs_exec_set_unordered_access_view(struct wined3d_cs *cs, const void *data)
960 const struct wined3d_cs_set_unordered_access_view *op = data;
961 struct wined3d_unordered_access_view *prev;
963 prev = cs->state.unordered_access_view[op->view_idx];
964 cs->state.unordered_access_view[op->view_idx] = op->view;
966 if (op->view)
967 InterlockedIncrement(&op->view->resource->bind_count);
968 if (prev)
969 InterlockedDecrement(&prev->resource->bind_count);
971 device_invalidate_state(cs->device, STATE_UNORDERED_ACCESS_VIEW_BINDING);
974 void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3d_shader_type type,
975 UINT view_idx, struct wined3d_shader_resource_view *view)
977 struct wined3d_cs_set_shader_resource_view *op;
979 op = cs->ops->require_space(cs, sizeof(*op));
980 op->opcode = WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW;
981 op->type = type;
982 op->view_idx = view_idx;
983 op->view = view;
985 cs->ops->submit(cs);
988 static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data)
990 const struct wined3d_cs_set_sampler *op = data;
992 cs->state.sampler[op->type][op->sampler_idx] = op->sampler;
993 device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
996 void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type type,
997 UINT sampler_idx, struct wined3d_sampler *sampler)
999 struct wined3d_cs_set_sampler *op;
1001 op = cs->ops->require_space(cs, sizeof(*op));
1002 op->opcode = WINED3D_CS_OP_SET_SAMPLER;
1003 op->type = type;
1004 op->sampler_idx = sampler_idx;
1005 op->sampler = sampler;
1007 cs->ops->submit(cs);
1010 static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data)
1012 const struct wined3d_cs_set_shader *op = data;
1014 cs->state.shader[op->type] = op->shader;
1015 device_invalidate_state(cs->device, STATE_SHADER(op->type));
1016 device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
1019 void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader)
1021 struct wined3d_cs_set_shader *op;
1023 op = cs->ops->require_space(cs, sizeof(*op));
1024 op->opcode = WINED3D_CS_OP_SET_SHADER;
1025 op->type = type;
1026 op->shader = shader;
1028 cs->ops->submit(cs);
1031 static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs *cs, const void *data)
1033 const struct wined3d_cs_set_rasterizer_state *op = data;
1035 cs->state.rasterizer_state = op->state;
1036 device_invalidate_state(cs->device, STATE_FRONTFACE);
1039 void wined3d_cs_emit_set_rasterizer_state(struct wined3d_cs *cs,
1040 struct wined3d_rasterizer_state *rasterizer_state)
1042 struct wined3d_cs_set_rasterizer_state *op;
1044 op = cs->ops->require_space(cs, sizeof(*op));
1045 op->opcode = WINED3D_CS_OP_SET_RASTERIZER_STATE;
1046 op->state = rasterizer_state;
1048 cs->ops->submit(cs);
1051 static void wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data)
1053 const struct wined3d_cs_set_render_state *op = data;
1055 cs->state.render_states[op->state] = op->value;
1056 device_invalidate_state(cs->device, STATE_RENDER(op->state));
1059 void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render_state state, DWORD value)
1061 struct wined3d_cs_set_render_state *op;
1063 op = cs->ops->require_space(cs, sizeof(*op));
1064 op->opcode = WINED3D_CS_OP_SET_RENDER_STATE;
1065 op->state = state;
1066 op->value = value;
1068 cs->ops->submit(cs);
1071 static void wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data)
1073 const struct wined3d_cs_set_texture_state *op = data;
1075 cs->state.texture_states[op->stage][op->state] = op->value;
1076 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, op->state));
1079 void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage,
1080 enum wined3d_texture_stage_state state, DWORD value)
1082 struct wined3d_cs_set_texture_state *op;
1084 op = cs->ops->require_space(cs, sizeof(*op));
1085 op->opcode = WINED3D_CS_OP_SET_TEXTURE_STATE;
1086 op->stage = stage;
1087 op->state = state;
1088 op->value = value;
1090 cs->ops->submit(cs);
1093 static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data)
1095 const struct wined3d_cs_set_sampler_state *op = data;
1097 cs->state.sampler_states[op->sampler_idx][op->state] = op->value;
1098 device_invalidate_state(cs->device, STATE_SAMPLER(op->sampler_idx));
1101 void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx,
1102 enum wined3d_sampler_state state, DWORD value)
1104 struct wined3d_cs_set_sampler_state *op;
1106 op = cs->ops->require_space(cs, sizeof(*op));
1107 op->opcode = WINED3D_CS_OP_SET_SAMPLER_STATE;
1108 op->sampler_idx = sampler_idx;
1109 op->state = state;
1110 op->value = value;
1112 cs->ops->submit(cs);
1115 static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data)
1117 const struct wined3d_cs_set_transform *op = data;
1119 cs->state.transforms[op->state] = op->matrix;
1120 if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices))
1121 device_invalidate_state(cs->device, STATE_TRANSFORM(op->state));
1124 void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform_state state,
1125 const struct wined3d_matrix *matrix)
1127 struct wined3d_cs_set_transform *op;
1129 op = cs->ops->require_space(cs, sizeof(*op));
1130 op->opcode = WINED3D_CS_OP_SET_TRANSFORM;
1131 op->state = state;
1132 op->matrix = *matrix;
1134 cs->ops->submit(cs);
1137 static void wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *data)
1139 const struct wined3d_cs_set_clip_plane *op = data;
1141 cs->state.clip_planes[op->plane_idx] = op->plane;
1142 device_invalidate_state(cs->device, STATE_CLIPPLANE(op->plane_idx));
1145 void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const struct wined3d_vec4 *plane)
1147 struct wined3d_cs_set_clip_plane *op;
1149 op = cs->ops->require_space(cs, sizeof(*op));
1150 op->opcode = WINED3D_CS_OP_SET_CLIP_PLANE;
1151 op->plane_idx = plane_idx;
1152 op->plane = *plane;
1154 cs->ops->submit(cs);
1157 static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *data)
1159 const struct wined3d_cs_set_color_key *op = data;
1160 struct wined3d_texture *texture = op->texture;
1162 if (op->set)
1164 switch (op->flags)
1166 case WINED3D_CKEY_DST_BLT:
1167 texture->async.dst_blt_color_key = op->color_key;
1168 texture->async.color_key_flags |= WINED3D_CKEY_DST_BLT;
1169 break;
1171 case WINED3D_CKEY_DST_OVERLAY:
1172 texture->async.dst_overlay_color_key = op->color_key;
1173 texture->async.color_key_flags |= WINED3D_CKEY_DST_OVERLAY;
1174 break;
1176 case WINED3D_CKEY_SRC_BLT:
1177 if (texture == cs->state.textures[0])
1179 device_invalidate_state(cs->device, STATE_COLOR_KEY);
1180 if (!(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT))
1181 device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE));
1184 texture->async.src_blt_color_key = op->color_key;
1185 texture->async.color_key_flags |= WINED3D_CKEY_SRC_BLT;
1186 break;
1188 case WINED3D_CKEY_SRC_OVERLAY:
1189 texture->async.src_overlay_color_key = op->color_key;
1190 texture->async.color_key_flags |= WINED3D_CKEY_SRC_OVERLAY;
1191 break;
1194 else
1196 switch (op->flags)
1198 case WINED3D_CKEY_DST_BLT:
1199 texture->async.color_key_flags &= ~WINED3D_CKEY_DST_BLT;
1200 break;
1202 case WINED3D_CKEY_DST_OVERLAY:
1203 texture->async.color_key_flags &= ~WINED3D_CKEY_DST_OVERLAY;
1204 break;
1206 case WINED3D_CKEY_SRC_BLT:
1207 if (texture == cs->state.textures[0] && texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
1208 device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE));
1210 texture->async.color_key_flags &= ~WINED3D_CKEY_SRC_BLT;
1211 break;
1213 case WINED3D_CKEY_SRC_OVERLAY:
1214 texture->async.color_key_flags &= ~WINED3D_CKEY_SRC_OVERLAY;
1215 break;
1220 void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture,
1221 WORD flags, const struct wined3d_color_key *color_key)
1223 struct wined3d_cs_set_color_key *op;
1225 op = cs->ops->require_space(cs, sizeof(*op));
1226 op->opcode = WINED3D_CS_OP_SET_COLOR_KEY;
1227 op->texture = texture;
1228 op->flags = flags;
1229 if (color_key)
1231 op->color_key = *color_key;
1232 op->set = 1;
1234 else
1235 op->set = 0;
1237 cs->ops->submit(cs);
1240 static void wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data)
1242 const struct wined3d_cs_set_material *op = data;
1244 cs->state.material = op->material;
1245 device_invalidate_state(cs->device, STATE_MATERIAL);
1248 void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_material *material)
1250 struct wined3d_cs_set_material *op;
1252 op = cs->ops->require_space(cs, sizeof(*op));
1253 op->opcode = WINED3D_CS_OP_SET_MATERIAL;
1254 op->material = *material;
1256 cs->ops->submit(cs);
1259 static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data)
1261 struct wined3d_adapter *adapter = cs->device->adapter;
1263 state_cleanup(&cs->state);
1264 memset(&cs->state, 0, sizeof(cs->state));
1265 state_init(&cs->state, &cs->fb, &adapter->gl_info, &adapter->d3d_info,
1266 WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT);
1269 void wined3d_cs_emit_reset_state(struct wined3d_cs *cs)
1271 struct wined3d_cs_reset_state *op;
1273 op = cs->ops->require_space(cs, sizeof(*op));
1274 op->opcode = WINED3D_CS_OP_RESET_STATE;
1276 cs->ops->submit(cs);
1279 static void wined3d_cs_exec_destroy_object(struct wined3d_cs *cs, const void *data)
1281 const struct wined3d_cs_destroy_object *op = data;
1283 op->callback(op->object);
1286 void wined3d_cs_emit_destroy_object(struct wined3d_cs *cs, void (*callback)(void *object), void *object)
1288 struct wined3d_cs_destroy_object *op;
1290 op = cs->ops->require_space(cs, sizeof(*op));
1291 op->opcode = WINED3D_CS_OP_DESTROY_OBJECT;
1292 op->callback = callback;
1293 op->object = object;
1295 cs->ops->submit(cs);
1298 static void wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data)
1300 const struct wined3d_cs_query_issue *op = data;
1301 struct wined3d_query *query = op->query;
1303 query->query_ops->query_issue(query, op->flags);
1306 void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, DWORD flags)
1308 struct wined3d_cs_query_issue *op;
1310 op = cs->ops->require_space(cs, sizeof(*op));
1311 op->opcode = WINED3D_CS_OP_QUERY_ISSUE;
1312 op->query = query;
1313 op->flags = flags;
1315 cs->ops->submit(cs);
1318 static void wined3d_cs_exec_preload_resource(struct wined3d_cs *cs, const void *data)
1320 const struct wined3d_cs_preload_resource *op = data;
1321 struct wined3d_resource *resource = op->resource;
1323 resource->resource_ops->resource_preload(resource);
1324 wined3d_resource_release(resource);
1327 void wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource)
1329 struct wined3d_cs_preload_resource *op;
1331 op = cs->ops->require_space(cs, sizeof(*op));
1332 op->opcode = WINED3D_CS_OP_PRELOAD_RESOURCE;
1333 op->resource = resource;
1335 wined3d_resource_acquire(resource);
1337 cs->ops->submit(cs);
1340 static void wined3d_cs_exec_unload_resource(struct wined3d_cs *cs, const void *data)
1342 const struct wined3d_cs_unload_resource *op = data;
1343 struct wined3d_resource *resource = op->resource;
1345 resource->resource_ops->resource_unload(resource);
1346 wined3d_resource_release(resource);
1349 void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource)
1351 struct wined3d_cs_unload_resource *op;
1353 op = cs->ops->require_space(cs, sizeof(*op));
1354 op->opcode = WINED3D_CS_OP_UNLOAD_RESOURCE;
1355 op->resource = resource;
1357 wined3d_resource_acquire(resource);
1359 cs->ops->submit(cs);
1362 static void wined3d_cs_exec_map(struct wined3d_cs *cs, const void *data)
1364 const struct wined3d_cs_map *op = data;
1365 struct wined3d_resource *resource = op->resource;
1367 *op->hr = resource->resource_ops->resource_sub_resource_map(resource,
1368 op->sub_resource_idx, op->map_desc, op->box, op->flags);
1371 HRESULT wined3d_cs_map(struct wined3d_cs *cs, struct wined3d_resource *resource, unsigned int sub_resource_idx,
1372 struct wined3d_map_desc *map_desc, const struct wined3d_box *box, unsigned int flags)
1374 struct wined3d_cs_map *op;
1375 HRESULT hr;
1377 op = cs->ops->require_space(cs, sizeof(*op));
1378 op->opcode = WINED3D_CS_OP_MAP;
1379 op->resource = resource;
1380 op->sub_resource_idx = sub_resource_idx;
1381 op->map_desc = map_desc;
1382 op->box = box;
1383 op->flags = flags;
1384 op->hr = &hr;
1386 cs->ops->submit(cs);
1388 return hr;
1391 static void wined3d_cs_exec_unmap(struct wined3d_cs *cs, const void *data)
1393 const struct wined3d_cs_unmap *op = data;
1394 struct wined3d_resource *resource = op->resource;
1396 *op->hr = resource->resource_ops->resource_sub_resource_unmap(resource, op->sub_resource_idx);
1399 HRESULT wined3d_cs_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource, unsigned int sub_resource_idx)
1401 struct wined3d_cs_unmap *op;
1402 HRESULT hr;
1404 op = cs->ops->require_space(cs, sizeof(*op));
1405 op->opcode = WINED3D_CS_OP_UNMAP;
1406 op->resource = resource;
1407 op->sub_resource_idx = sub_resource_idx;
1408 op->hr = &hr;
1410 cs->ops->submit(cs);
1412 return hr;
1415 static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) =
1417 /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present,
1418 /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear,
1419 /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw,
1420 /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication,
1421 /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport,
1422 /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect,
1423 /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view,
1424 /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view,
1425 /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration,
1426 /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source,
1427 /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq,
1428 /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output,
1429 /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer,
1430 /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer,
1431 /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture,
1432 /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view,
1433 /* WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_set_unordered_access_view,
1434 /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler,
1435 /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader,
1436 /* WINED3D_CS_OP_SET_RASTERIZER_STATE */ wined3d_cs_exec_set_rasterizer_state,
1437 /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state,
1438 /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state,
1439 /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state,
1440 /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform,
1441 /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane,
1442 /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key,
1443 /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material,
1444 /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state,
1445 /* WINED3D_CS_OP_DESTROY_OBJECT */ wined3d_cs_exec_destroy_object,
1446 /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue,
1447 /* WINED3D_CS_OP_PRELOAD_RESOURCE */ wined3d_cs_exec_preload_resource,
1448 /* WINED3D_CS_OP_UNLOAD_RESOURCE */ wined3d_cs_exec_unload_resource,
1449 /* WINED3D_CS_OP_MAP */ wined3d_cs_exec_map,
1450 /* WINED3D_CS_OP_UNMAP */ wined3d_cs_exec_unmap,
1453 static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size)
1455 if (size > cs->data_size)
1457 void *new_data;
1459 size = max( size, cs->data_size * 2 );
1460 if (!(new_data = HeapReAlloc(GetProcessHeap(), 0, cs->data, size)))
1461 return NULL;
1463 cs->data_size = size;
1464 cs->data = new_data;
1467 return cs->data;
1470 static void wined3d_cs_st_submit(struct wined3d_cs *cs)
1472 enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)cs->data;
1474 wined3d_cs_op_handlers[opcode](cs, cs->data);
1477 static void wined3d_cs_st_push_constants(struct wined3d_cs *cs, enum wined3d_push_constants p,
1478 unsigned int start_idx, unsigned int count, const void *constants)
1480 struct wined3d_device *device = cs->device;
1481 unsigned int context_count;
1482 unsigned int i;
1483 size_t offset;
1485 static const struct
1487 size_t offset;
1488 size_t size;
1489 DWORD mask;
1491 push_constant_info[] =
1493 /* WINED3D_PUSH_CONSTANTS_VS_F */
1494 {FIELD_OFFSET(struct wined3d_state, vs_consts_f), sizeof(struct wined3d_vec4), WINED3D_SHADER_CONST_VS_F},
1495 /* WINED3D_PUSH_CONSTANTS_PS_F */
1496 {FIELD_OFFSET(struct wined3d_state, ps_consts_f), sizeof(struct wined3d_vec4), WINED3D_SHADER_CONST_PS_F},
1497 /* WINED3D_PUSH_CONSTANTS_VS_I */
1498 {FIELD_OFFSET(struct wined3d_state, vs_consts_i), sizeof(struct wined3d_ivec4), WINED3D_SHADER_CONST_VS_I},
1499 /* WINED3D_PUSH_CONSTANTS_PS_I */
1500 {FIELD_OFFSET(struct wined3d_state, ps_consts_i), sizeof(struct wined3d_ivec4), WINED3D_SHADER_CONST_PS_I},
1501 /* WINED3D_PUSH_CONSTANTS_VS_B */
1502 {FIELD_OFFSET(struct wined3d_state, vs_consts_b), sizeof(BOOL), WINED3D_SHADER_CONST_VS_B},
1503 /* WINED3D_PUSH_CONSTANTS_PS_B */
1504 {FIELD_OFFSET(struct wined3d_state, ps_consts_b), sizeof(BOOL), WINED3D_SHADER_CONST_PS_B},
1507 if (p == WINED3D_PUSH_CONSTANTS_VS_F)
1508 device->shader_backend->shader_update_float_vertex_constants(device, start_idx, count);
1509 else if (p == WINED3D_PUSH_CONSTANTS_PS_F)
1510 device->shader_backend->shader_update_float_pixel_constants(device, start_idx, count);
1512 offset = push_constant_info[p].offset + start_idx * push_constant_info[p].size;
1513 memcpy((BYTE *)&cs->state + offset, constants, count * push_constant_info[p].size);
1514 for (i = 0, context_count = device->context_count; i < context_count; ++i)
1516 device->contexts[i]->constant_update_mask |= push_constant_info[p].mask;
1520 static const struct wined3d_cs_ops wined3d_cs_st_ops =
1522 wined3d_cs_st_require_space,
1523 wined3d_cs_st_submit,
1524 wined3d_cs_st_push_constants,
1527 struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
1529 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
1530 struct wined3d_cs *cs;
1532 if (!(cs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cs))))
1533 return NULL;
1535 if (!(cs->fb.render_targets = wined3d_calloc(gl_info->limits.buffers, sizeof(*cs->fb.render_targets))))
1537 HeapFree(GetProcessHeap(), 0, cs);
1538 return NULL;
1541 state_init(&cs->state, &cs->fb, gl_info, &device->adapter->d3d_info,
1542 WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT);
1544 cs->ops = &wined3d_cs_st_ops;
1545 cs->device = device;
1547 cs->data_size = WINED3D_INITIAL_CS_SIZE;
1548 if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size)))
1550 state_cleanup(&cs->state);
1551 HeapFree(GetProcessHeap(), 0, cs->fb.render_targets);
1552 HeapFree(GetProcessHeap(), 0, cs);
1553 return NULL;
1556 return cs;
1559 void wined3d_cs_destroy(struct wined3d_cs *cs)
1561 state_cleanup(&cs->state);
1562 HeapFree(GetProcessHeap(), 0, cs->fb.render_targets);
1563 HeapFree(GetProcessHeap(), 0, cs->data);
1564 HeapFree(GetProcessHeap(), 0, cs);