user32: Cache clipboard data on the client side.
[wine.git] / dlls / wined3d / cs.c
blob7af0b812cdf94b2d4f2ef8eba4bc8451256caf77
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_SAMPLER,
46 WINED3D_CS_OP_SET_SHADER,
47 WINED3D_CS_OP_SET_RASTERIZER_STATE,
48 WINED3D_CS_OP_SET_RENDER_STATE,
49 WINED3D_CS_OP_SET_TEXTURE_STATE,
50 WINED3D_CS_OP_SET_SAMPLER_STATE,
51 WINED3D_CS_OP_SET_TRANSFORM,
52 WINED3D_CS_OP_SET_CLIP_PLANE,
53 WINED3D_CS_OP_SET_COLOR_KEY,
54 WINED3D_CS_OP_SET_MATERIAL,
55 WINED3D_CS_OP_RESET_STATE,
56 WINED3D_CS_OP_DESTROY_OBJECT,
57 WINED3D_CS_OP_QUERY_ISSUE,
58 WINED3D_CS_OP_PRELOAD_RESOURCE,
59 WINED3D_CS_OP_UNLOAD_RESOURCE,
60 WINED3D_CS_OP_MAP,
61 WINED3D_CS_OP_UNMAP,
64 struct wined3d_cs_present
66 enum wined3d_cs_op opcode;
67 HWND dst_window_override;
68 struct wined3d_swapchain *swapchain;
69 RECT src_rect;
70 RECT dst_rect;
71 DWORD flags;
74 struct wined3d_cs_clear
76 enum wined3d_cs_op opcode;
77 DWORD flags;
78 struct wined3d_color color;
79 float depth;
80 DWORD stencil;
81 unsigned int rect_count;
82 RECT rects[1];
85 struct wined3d_cs_draw
87 enum wined3d_cs_op opcode;
88 int base_vertex_idx;
89 unsigned int start_idx;
90 unsigned int index_count;
91 unsigned int start_instance;
92 unsigned int instance_count;
93 BOOL indexed;
96 struct wined3d_cs_set_predication
98 enum wined3d_cs_op opcode;
99 struct wined3d_query *predicate;
100 BOOL value;
103 struct wined3d_cs_set_viewport
105 enum wined3d_cs_op opcode;
106 struct wined3d_viewport viewport;
109 struct wined3d_cs_set_scissor_rect
111 enum wined3d_cs_op opcode;
112 RECT rect;
115 struct wined3d_cs_set_rendertarget_view
117 enum wined3d_cs_op opcode;
118 unsigned int view_idx;
119 struct wined3d_rendertarget_view *view;
122 struct wined3d_cs_set_depth_stencil_view
124 enum wined3d_cs_op opcode;
125 struct wined3d_rendertarget_view *view;
128 struct wined3d_cs_set_vertex_declaration
130 enum wined3d_cs_op opcode;
131 struct wined3d_vertex_declaration *declaration;
134 struct wined3d_cs_set_stream_source
136 enum wined3d_cs_op opcode;
137 UINT stream_idx;
138 struct wined3d_buffer *buffer;
139 UINT offset;
140 UINT stride;
143 struct wined3d_cs_set_stream_source_freq
145 enum wined3d_cs_op opcode;
146 UINT stream_idx;
147 UINT frequency;
148 UINT flags;
151 struct wined3d_cs_set_stream_output
153 enum wined3d_cs_op opcode;
154 UINT stream_idx;
155 struct wined3d_buffer *buffer;
156 UINT offset;
159 struct wined3d_cs_set_index_buffer
161 enum wined3d_cs_op opcode;
162 struct wined3d_buffer *buffer;
163 enum wined3d_format_id format_id;
164 unsigned int offset;
167 struct wined3d_cs_set_constant_buffer
169 enum wined3d_cs_op opcode;
170 enum wined3d_shader_type type;
171 UINT cb_idx;
172 struct wined3d_buffer *buffer;
175 struct wined3d_cs_set_texture
177 enum wined3d_cs_op opcode;
178 UINT stage;
179 struct wined3d_texture *texture;
182 struct wined3d_cs_set_color_key
184 enum wined3d_cs_op opcode;
185 struct wined3d_texture *texture;
186 WORD flags;
187 WORD set;
188 struct wined3d_color_key color_key;
191 struct wined3d_cs_set_shader_resource_view
193 enum wined3d_cs_op opcode;
194 enum wined3d_shader_type type;
195 UINT view_idx;
196 struct wined3d_shader_resource_view *view;
199 struct wined3d_cs_set_sampler
201 enum wined3d_cs_op opcode;
202 enum wined3d_shader_type type;
203 UINT sampler_idx;
204 struct wined3d_sampler *sampler;
207 struct wined3d_cs_set_shader
209 enum wined3d_cs_op opcode;
210 enum wined3d_shader_type type;
211 struct wined3d_shader *shader;
214 struct wined3d_cs_set_rasterizer_state
216 enum wined3d_cs_op opcode;
217 struct wined3d_rasterizer_state *state;
220 struct wined3d_cs_set_render_state
222 enum wined3d_cs_op opcode;
223 enum wined3d_render_state state;
224 DWORD value;
227 struct wined3d_cs_set_texture_state
229 enum wined3d_cs_op opcode;
230 UINT stage;
231 enum wined3d_texture_stage_state state;
232 DWORD value;
235 struct wined3d_cs_set_sampler_state
237 enum wined3d_cs_op opcode;
238 UINT sampler_idx;
239 enum wined3d_sampler_state state;
240 DWORD value;
243 struct wined3d_cs_set_transform
245 enum wined3d_cs_op opcode;
246 enum wined3d_transform_state state;
247 struct wined3d_matrix matrix;
250 struct wined3d_cs_set_clip_plane
252 enum wined3d_cs_op opcode;
253 UINT plane_idx;
254 struct wined3d_vec4 plane;
257 struct wined3d_cs_set_material
259 enum wined3d_cs_op opcode;
260 struct wined3d_material material;
263 struct wined3d_cs_reset_state
265 enum wined3d_cs_op opcode;
268 struct wined3d_cs_destroy_object
270 enum wined3d_cs_op opcode;
271 void (*callback)(void *object);
272 void *object;
275 struct wined3d_cs_query_issue
277 enum wined3d_cs_op opcode;
278 struct wined3d_query *query;
279 DWORD flags;
282 struct wined3d_cs_preload_resource
284 enum wined3d_cs_op opcode;
285 struct wined3d_resource *resource;
288 struct wined3d_cs_unload_resource
290 enum wined3d_cs_op opcode;
291 struct wined3d_resource *resource;
294 struct wined3d_cs_map
296 enum wined3d_cs_op opcode;
297 struct wined3d_resource *resource;
298 unsigned int sub_resource_idx;
299 struct wined3d_map_desc *map_desc;
300 const struct wined3d_box *box;
301 DWORD flags;
302 HRESULT *hr;
305 struct wined3d_cs_unmap
307 enum wined3d_cs_op opcode;
308 struct wined3d_resource *resource;
309 unsigned int sub_resource_idx;
310 HRESULT *hr;
313 static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data)
315 const struct wined3d_cs_present *op = data;
316 struct wined3d_swapchain *swapchain;
317 unsigned int i;
319 swapchain = op->swapchain;
320 wined3d_swapchain_set_window(swapchain, op->dst_window_override);
322 swapchain->swapchain_ops->swapchain_present(swapchain, &op->src_rect, &op->dst_rect, op->flags);
324 wined3d_resource_release(&swapchain->front_buffer->resource);
325 for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
327 wined3d_resource_release(&swapchain->back_buffers[i]->resource);
331 void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain,
332 const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, DWORD flags)
334 struct wined3d_cs_present *op;
335 unsigned int i;
337 op = cs->ops->require_space(cs, sizeof(*op));
338 op->opcode = WINED3D_CS_OP_PRESENT;
339 op->dst_window_override = dst_window_override;
340 op->swapchain = swapchain;
341 op->src_rect = *src_rect;
342 op->dst_rect = *dst_rect;
343 op->flags = flags;
345 wined3d_resource_acquire(&swapchain->front_buffer->resource);
346 for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
348 wined3d_resource_acquire(&swapchain->back_buffers[i]->resource);
351 cs->ops->submit(cs);
354 static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data)
356 const struct wined3d_cs_clear *op = data;
357 const struct wined3d_state *state;
358 struct wined3d_device *device;
359 unsigned int i;
360 RECT draw_rect;
362 device = cs->device;
363 state = &device->state;
364 wined3d_get_draw_rect(state, &draw_rect);
365 device_clear_render_targets(device, device->adapter->gl_info.limits.buffers,
366 &device->fb, op->rect_count, op->rects, &draw_rect, op->flags,
367 &op->color, op->depth, op->stencil);
369 if (op->flags & WINED3DCLEAR_TARGET)
371 for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
373 if (state->fb->render_targets[i])
374 wined3d_resource_release(state->fb->render_targets[i]->resource);
377 if (op->flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
378 wined3d_resource_release(state->fb->depth_stencil->resource);
381 void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects,
382 DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil)
384 const struct wined3d_state *state = &cs->device->state;
385 struct wined3d_cs_clear *op;
386 unsigned int i;
388 op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_clear, rects[rect_count]));
389 op->opcode = WINED3D_CS_OP_CLEAR;
390 op->flags = flags;
391 op->color = *color;
392 op->depth = depth;
393 op->stencil = stencil;
394 op->rect_count = rect_count;
395 memcpy(op->rects, rects, sizeof(*rects) * rect_count);
397 if (flags & WINED3DCLEAR_TARGET)
399 for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; ++i)
401 if (state->fb->render_targets[i])
402 wined3d_resource_acquire(state->fb->render_targets[i]->resource);
405 if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
406 wined3d_resource_acquire(state->fb->depth_stencil->resource);
408 cs->ops->submit(cs);
411 static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data)
413 struct wined3d_state *state = &cs->device->state;
414 struct wined3d_shader_sampler_map_entry *entry;
415 struct wined3d_shader_resource_view *view;
416 const struct wined3d_cs_draw *op = data;
417 struct wined3d_shader *shader;
418 unsigned int i, j;
420 if (!cs->device->adapter->gl_info.supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]
421 && state->load_base_vertex_index != op->base_vertex_idx)
423 state->load_base_vertex_index = op->base_vertex_idx;
424 device_invalidate_state(cs->device, STATE_BASEVERTEXINDEX);
427 draw_primitive(cs->device, state, op->base_vertex_idx, op->start_idx,
428 op->index_count, op->start_instance, op->instance_count, op->indexed);
430 if (op->indexed)
431 wined3d_resource_release(&state->index_buffer->resource);
432 for (i = 0; i < ARRAY_SIZE(state->streams); ++i)
434 if (state->streams[i].buffer)
435 wined3d_resource_release(&state->streams[i].buffer->resource);
437 for (i = 0; i < ARRAY_SIZE(state->textures); ++i)
439 if (state->textures[i])
440 wined3d_resource_release(&state->textures[i]->resource);
442 for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; ++i)
444 if (state->fb->render_targets[i])
445 wined3d_resource_release(state->fb->render_targets[i]->resource);
447 if (state->fb->depth_stencil)
448 wined3d_resource_release(state->fb->depth_stencil->resource);
449 for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i)
451 if (!(shader = state->shader[i]))
452 continue;
454 for (j = 0; j < WINED3D_MAX_CBS; ++j)
456 if (state->cb[i][j])
457 wined3d_resource_release(&state->cb[i][j]->resource);
460 for (j = 0; j < shader->reg_maps.sampler_map.count; ++j)
462 entry = &shader->reg_maps.sampler_map.entries[j];
464 if (!(view = state->shader_resource_view[i][entry->resource_idx]))
465 continue;
467 wined3d_resource_release(view->resource);
472 void wined3d_cs_emit_draw(struct wined3d_cs *cs, int base_vertex_idx, unsigned int start_idx,
473 unsigned int index_count, unsigned int start_instance, unsigned int instance_count, BOOL indexed)
475 const struct wined3d_state *state = &cs->device->state;
476 struct wined3d_shader_sampler_map_entry *entry;
477 struct wined3d_shader_resource_view *view;
478 struct wined3d_shader *shader;
479 struct wined3d_cs_draw *op;
480 unsigned int i, j;
482 op = cs->ops->require_space(cs, sizeof(*op));
483 op->opcode = WINED3D_CS_OP_DRAW;
484 op->base_vertex_idx = base_vertex_idx;
485 op->start_idx = start_idx;
486 op->index_count = index_count;
487 op->start_instance = start_instance;
488 op->instance_count = instance_count;
489 op->indexed = indexed;
491 if (indexed)
492 wined3d_resource_acquire(&state->index_buffer->resource);
493 for (i = 0; i < ARRAY_SIZE(state->streams); ++i)
495 if (state->streams[i].buffer)
496 wined3d_resource_acquire(&state->streams[i].buffer->resource);
498 for (i = 0; i < ARRAY_SIZE(state->textures); ++i)
500 if (state->textures[i])
501 wined3d_resource_acquire(&state->textures[i]->resource);
503 for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; ++i)
505 if (state->fb->render_targets[i])
506 wined3d_resource_acquire(state->fb->render_targets[i]->resource);
508 if (state->fb->depth_stencil)
509 wined3d_resource_acquire(state->fb->depth_stencil->resource);
510 for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i)
512 if (!(shader = state->shader[i]))
513 continue;
515 for (j = 0; j < WINED3D_MAX_CBS; ++j)
517 if (state->cb[i][j])
518 wined3d_resource_acquire(&state->cb[i][j]->resource);
521 for (j = 0; j < shader->reg_maps.sampler_map.count; ++j)
523 entry = &shader->reg_maps.sampler_map.entries[j];
525 if (!(view = state->shader_resource_view[i][entry->resource_idx]))
526 continue;
528 wined3d_resource_acquire(view->resource);
532 cs->ops->submit(cs);
535 static void wined3d_cs_exec_set_predication(struct wined3d_cs *cs, const void *data)
537 const struct wined3d_cs_set_predication *op = data;
539 cs->state.predicate = op->predicate;
540 cs->state.predicate_value = op->value;
543 void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query *predicate, BOOL value)
545 struct wined3d_cs_set_predication *op;
547 op = cs->ops->require_space(cs, sizeof(*op));
548 op->opcode = WINED3D_CS_OP_SET_PREDICATION;
549 op->predicate = predicate;
550 op->value = value;
552 cs->ops->submit(cs);
555 static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data)
557 const struct wined3d_cs_set_viewport *op = data;
559 cs->state.viewport = op->viewport;
560 device_invalidate_state(cs->device, STATE_VIEWPORT);
563 void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport)
565 struct wined3d_cs_set_viewport *op;
567 op = cs->ops->require_space(cs, sizeof(*op));
568 op->opcode = WINED3D_CS_OP_SET_VIEWPORT;
569 op->viewport = *viewport;
571 cs->ops->submit(cs);
574 static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data)
576 const struct wined3d_cs_set_scissor_rect *op = data;
578 cs->state.scissor_rect = op->rect;
579 device_invalidate_state(cs->device, STATE_SCISSORRECT);
582 void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect)
584 struct wined3d_cs_set_scissor_rect *op;
586 op = cs->ops->require_space(cs, sizeof(*op));
587 op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT;
588 op->rect = *rect;
590 cs->ops->submit(cs);
593 static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data)
595 const struct wined3d_cs_set_rendertarget_view *op = data;
597 cs->state.fb->render_targets[op->view_idx] = op->view;
598 device_invalidate_state(cs->device, STATE_FRAMEBUFFER);
601 void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int view_idx,
602 struct wined3d_rendertarget_view *view)
604 struct wined3d_cs_set_rendertarget_view *op;
606 op = cs->ops->require_space(cs, sizeof(*op));
607 op->opcode = WINED3D_CS_OP_SET_RENDERTARGET_VIEW;
608 op->view_idx = view_idx;
609 op->view = view;
611 cs->ops->submit(cs);
614 static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const void *data)
616 const struct wined3d_cs_set_depth_stencil_view *op = data;
617 struct wined3d_device *device = cs->device;
618 struct wined3d_rendertarget_view *prev;
620 if ((prev = cs->state.fb->depth_stencil))
622 struct wined3d_surface *prev_surface = wined3d_rendertarget_view_get_surface(prev);
624 if (prev_surface && (device->swapchains[0]->desc.flags & WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL
625 || prev_surface->container->flags & WINED3D_TEXTURE_DISCARD))
627 surface_modify_ds_location(prev_surface, WINED3D_LOCATION_DISCARDED, prev->width, prev->height);
628 if (prev_surface == device->onscreen_depth_stencil)
630 wined3d_texture_decref(device->onscreen_depth_stencil->container);
631 device->onscreen_depth_stencil = NULL;
636 cs->fb.depth_stencil = op->view;
638 if (!prev != !op->view)
640 /* Swapping NULL / non NULL depth stencil affects the depth and tests */
641 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_ZENABLE));
642 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILENABLE));
643 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK));
644 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
646 else if (prev && (prev->format_flags & WINED3DFMT_FLAG_FLOAT)
647 != (op->view->format_flags & WINED3DFMT_FLAG_FLOAT))
649 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
652 device_invalidate_state(device, STATE_FRAMEBUFFER);
655 void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view)
657 struct wined3d_cs_set_depth_stencil_view *op;
659 op = cs->ops->require_space(cs, sizeof(*op));
660 op->opcode = WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW;
661 op->view = view;
663 cs->ops->submit(cs);
666 static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data)
668 const struct wined3d_cs_set_vertex_declaration *op = data;
670 cs->state.vertex_declaration = op->declaration;
671 device_invalidate_state(cs->device, STATE_VDECL);
674 void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3d_vertex_declaration *declaration)
676 struct wined3d_cs_set_vertex_declaration *op;
678 op = cs->ops->require_space(cs, sizeof(*op));
679 op->opcode = WINED3D_CS_OP_SET_VERTEX_DECLARATION;
680 op->declaration = declaration;
682 cs->ops->submit(cs);
685 static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data)
687 const struct wined3d_cs_set_stream_source *op = data;
688 struct wined3d_stream_state *stream;
689 struct wined3d_buffer *prev;
691 stream = &cs->state.streams[op->stream_idx];
692 prev = stream->buffer;
693 stream->buffer = op->buffer;
694 stream->offset = op->offset;
695 stream->stride = op->stride;
697 if (op->buffer)
698 InterlockedIncrement(&op->buffer->resource.bind_count);
699 if (prev)
700 InterlockedDecrement(&prev->resource.bind_count);
702 device_invalidate_state(cs->device, STATE_STREAMSRC);
705 void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx,
706 struct wined3d_buffer *buffer, UINT offset, UINT stride)
708 struct wined3d_cs_set_stream_source *op;
710 op = cs->ops->require_space(cs, sizeof(*op));
711 op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE;
712 op->stream_idx = stream_idx;
713 op->buffer = buffer;
714 op->offset = offset;
715 op->stride = stride;
717 cs->ops->submit(cs);
720 static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data)
722 const struct wined3d_cs_set_stream_source_freq *op = data;
723 struct wined3d_stream_state *stream;
725 stream = &cs->state.streams[op->stream_idx];
726 stream->frequency = op->frequency;
727 stream->flags = op->flags;
729 device_invalidate_state(cs->device, STATE_STREAMSRC);
732 void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx, UINT frequency, UINT flags)
734 struct wined3d_cs_set_stream_source_freq *op;
736 op = cs->ops->require_space(cs, sizeof(*op));
737 op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ;
738 op->stream_idx = stream_idx;
739 op->frequency = frequency;
740 op->flags = flags;
742 cs->ops->submit(cs);
745 static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data)
747 const struct wined3d_cs_set_stream_output *op = data;
748 struct wined3d_stream_output *stream;
749 struct wined3d_buffer *prev;
751 stream = &cs->state.stream_output[op->stream_idx];
752 prev = stream->buffer;
753 stream->buffer = op->buffer;
754 stream->offset = op->offset;
756 if (op->buffer)
757 InterlockedIncrement(&op->buffer->resource.bind_count);
758 if (prev)
759 InterlockedDecrement(&prev->resource.bind_count);
762 void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx,
763 struct wined3d_buffer *buffer, UINT offset)
765 struct wined3d_cs_set_stream_output *op;
767 op = cs->ops->require_space(cs, sizeof(*op));
768 op->opcode = WINED3D_CS_OP_SET_STREAM_OUTPUT;
769 op->stream_idx = stream_idx;
770 op->buffer = buffer;
771 op->offset = offset;
773 cs->ops->submit(cs);
776 static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data)
778 const struct wined3d_cs_set_index_buffer *op = data;
779 struct wined3d_buffer *prev;
781 prev = cs->state.index_buffer;
782 cs->state.index_buffer = op->buffer;
783 cs->state.index_format = op->format_id;
784 cs->state.index_offset = op->offset;
786 if (op->buffer)
787 InterlockedIncrement(&op->buffer->resource.bind_count);
788 if (prev)
789 InterlockedDecrement(&prev->resource.bind_count);
791 device_invalidate_state(cs->device, STATE_INDEXBUFFER);
794 void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer,
795 enum wined3d_format_id format_id, unsigned int offset)
797 struct wined3d_cs_set_index_buffer *op;
799 op = cs->ops->require_space(cs, sizeof(*op));
800 op->opcode = WINED3D_CS_OP_SET_INDEX_BUFFER;
801 op->buffer = buffer;
802 op->format_id = format_id;
803 op->offset = offset;
805 cs->ops->submit(cs);
808 static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data)
810 const struct wined3d_cs_set_constant_buffer *op = data;
811 struct wined3d_buffer *prev;
813 prev = cs->state.cb[op->type][op->cb_idx];
814 cs->state.cb[op->type][op->cb_idx] = op->buffer;
816 if (op->buffer)
817 InterlockedIncrement(&op->buffer->resource.bind_count);
818 if (prev)
819 InterlockedDecrement(&prev->resource.bind_count);
821 device_invalidate_state(cs->device, STATE_CONSTANT_BUFFER(op->type));
824 void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type,
825 UINT cb_idx, struct wined3d_buffer *buffer)
827 struct wined3d_cs_set_constant_buffer *op;
829 op = cs->ops->require_space(cs, sizeof(*op));
830 op->opcode = WINED3D_CS_OP_SET_CONSTANT_BUFFER;
831 op->type = type;
832 op->cb_idx = cb_idx;
833 op->buffer = buffer;
835 cs->ops->submit(cs);
838 static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data)
840 const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info;
841 const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info;
842 const struct wined3d_cs_set_texture *op = data;
843 struct wined3d_texture *prev;
844 BOOL old_use_color_key = FALSE, new_use_color_key = FALSE;
846 prev = cs->state.textures[op->stage];
847 cs->state.textures[op->stage] = op->texture;
849 if (op->texture)
851 const struct wined3d_format *new_format = op->texture->resource.format;
852 const struct wined3d_format *old_format = prev ? prev->resource.format : NULL;
853 unsigned int old_fmt_flags = prev ? prev->resource.format_flags : 0;
854 unsigned int new_fmt_flags = op->texture->resource.format_flags;
856 if (InterlockedIncrement(&op->texture->resource.bind_count) == 1)
857 op->texture->sampler = op->stage;
859 if (!prev || op->texture->target != prev->target
860 || (!is_same_fixup(new_format->color_fixup, old_format->color_fixup)
861 && !(can_use_texture_swizzle(gl_info, new_format) && can_use_texture_swizzle(gl_info, old_format)))
862 || (new_fmt_flags & WINED3DFMT_FLAG_SHADOW) != (old_fmt_flags & WINED3DFMT_FLAG_SHADOW))
863 device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL));
865 if (!prev && op->stage < d3d_info->limits.ffp_blend_stages)
867 /* The source arguments for color and alpha ops have different
868 * meanings when a NULL texture is bound, so the COLOR_OP and
869 * ALPHA_OP have to be dirtified. */
870 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP));
871 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP));
874 if (!op->stage && op->texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
875 new_use_color_key = TRUE;
878 if (prev)
880 if (InterlockedDecrement(&prev->resource.bind_count) && prev->sampler == op->stage)
882 unsigned int i;
884 /* Search for other stages the texture is bound to. Shouldn't
885 * happen if applications bind textures to a single stage only. */
886 TRACE("Searching for other stages the texture is bound to.\n");
887 for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
889 if (cs->state.textures[i] == prev)
891 TRACE("Texture is also bound to stage %u.\n", i);
892 prev->sampler = i;
893 break;
898 if (!op->texture && op->stage < d3d_info->limits.ffp_blend_stages)
900 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP));
901 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP));
904 if (!op->stage && prev->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
905 old_use_color_key = TRUE;
908 device_invalidate_state(cs->device, STATE_SAMPLER(op->stage));
910 if (new_use_color_key != old_use_color_key)
911 device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE));
913 if (new_use_color_key)
914 device_invalidate_state(cs->device, STATE_COLOR_KEY);
917 void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined3d_texture *texture)
919 struct wined3d_cs_set_texture *op;
921 op = cs->ops->require_space(cs, sizeof(*op));
922 op->opcode = WINED3D_CS_OP_SET_TEXTURE;
923 op->stage = stage;
924 op->texture = texture;
926 cs->ops->submit(cs);
929 static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data)
931 const struct wined3d_cs_set_shader_resource_view *op = data;
933 cs->state.shader_resource_view[op->type][op->view_idx] = op->view;
934 device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
937 void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3d_shader_type type,
938 UINT view_idx, struct wined3d_shader_resource_view *view)
940 struct wined3d_cs_set_shader_resource_view *op;
942 op = cs->ops->require_space(cs, sizeof(*op));
943 op->opcode = WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW;
944 op->type = type;
945 op->view_idx = view_idx;
946 op->view = view;
948 cs->ops->submit(cs);
951 static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data)
953 const struct wined3d_cs_set_sampler *op = data;
955 cs->state.sampler[op->type][op->sampler_idx] = op->sampler;
956 device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
959 void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type type,
960 UINT sampler_idx, struct wined3d_sampler *sampler)
962 struct wined3d_cs_set_sampler *op;
964 op = cs->ops->require_space(cs, sizeof(*op));
965 op->opcode = WINED3D_CS_OP_SET_SAMPLER;
966 op->type = type;
967 op->sampler_idx = sampler_idx;
968 op->sampler = sampler;
970 cs->ops->submit(cs);
973 static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data)
975 const struct wined3d_cs_set_shader *op = data;
977 cs->state.shader[op->type] = op->shader;
978 device_invalidate_state(cs->device, STATE_SHADER(op->type));
979 device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
982 void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader)
984 struct wined3d_cs_set_shader *op;
986 op = cs->ops->require_space(cs, sizeof(*op));
987 op->opcode = WINED3D_CS_OP_SET_SHADER;
988 op->type = type;
989 op->shader = shader;
991 cs->ops->submit(cs);
994 static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs *cs, const void *data)
996 const struct wined3d_cs_set_rasterizer_state *op = data;
998 cs->state.rasterizer_state = op->state;
999 device_invalidate_state(cs->device, STATE_FRONTFACE);
1002 void wined3d_cs_emit_set_rasterizer_state(struct wined3d_cs *cs,
1003 struct wined3d_rasterizer_state *rasterizer_state)
1005 struct wined3d_cs_set_rasterizer_state *op;
1007 op = cs->ops->require_space(cs, sizeof(*op));
1008 op->opcode = WINED3D_CS_OP_SET_RASTERIZER_STATE;
1009 op->state = rasterizer_state;
1011 cs->ops->submit(cs);
1014 static void wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data)
1016 const struct wined3d_cs_set_render_state *op = data;
1018 cs->state.render_states[op->state] = op->value;
1019 device_invalidate_state(cs->device, STATE_RENDER(op->state));
1022 void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render_state state, DWORD value)
1024 struct wined3d_cs_set_render_state *op;
1026 op = cs->ops->require_space(cs, sizeof(*op));
1027 op->opcode = WINED3D_CS_OP_SET_RENDER_STATE;
1028 op->state = state;
1029 op->value = value;
1031 cs->ops->submit(cs);
1034 static void wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data)
1036 const struct wined3d_cs_set_texture_state *op = data;
1038 cs->state.texture_states[op->stage][op->state] = op->value;
1039 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, op->state));
1042 void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage,
1043 enum wined3d_texture_stage_state state, DWORD value)
1045 struct wined3d_cs_set_texture_state *op;
1047 op = cs->ops->require_space(cs, sizeof(*op));
1048 op->opcode = WINED3D_CS_OP_SET_TEXTURE_STATE;
1049 op->stage = stage;
1050 op->state = state;
1051 op->value = value;
1053 cs->ops->submit(cs);
1056 static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data)
1058 const struct wined3d_cs_set_sampler_state *op = data;
1060 cs->state.sampler_states[op->sampler_idx][op->state] = op->value;
1061 device_invalidate_state(cs->device, STATE_SAMPLER(op->sampler_idx));
1064 void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx,
1065 enum wined3d_sampler_state state, DWORD value)
1067 struct wined3d_cs_set_sampler_state *op;
1069 op = cs->ops->require_space(cs, sizeof(*op));
1070 op->opcode = WINED3D_CS_OP_SET_SAMPLER_STATE;
1071 op->sampler_idx = sampler_idx;
1072 op->state = state;
1073 op->value = value;
1075 cs->ops->submit(cs);
1078 static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data)
1080 const struct wined3d_cs_set_transform *op = data;
1082 cs->state.transforms[op->state] = op->matrix;
1083 if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices))
1084 device_invalidate_state(cs->device, STATE_TRANSFORM(op->state));
1087 void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform_state state,
1088 const struct wined3d_matrix *matrix)
1090 struct wined3d_cs_set_transform *op;
1092 op = cs->ops->require_space(cs, sizeof(*op));
1093 op->opcode = WINED3D_CS_OP_SET_TRANSFORM;
1094 op->state = state;
1095 op->matrix = *matrix;
1097 cs->ops->submit(cs);
1100 static void wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *data)
1102 const struct wined3d_cs_set_clip_plane *op = data;
1104 cs->state.clip_planes[op->plane_idx] = op->plane;
1105 device_invalidate_state(cs->device, STATE_CLIPPLANE(op->plane_idx));
1108 void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const struct wined3d_vec4 *plane)
1110 struct wined3d_cs_set_clip_plane *op;
1112 op = cs->ops->require_space(cs, sizeof(*op));
1113 op->opcode = WINED3D_CS_OP_SET_CLIP_PLANE;
1114 op->plane_idx = plane_idx;
1115 op->plane = *plane;
1117 cs->ops->submit(cs);
1120 static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *data)
1122 const struct wined3d_cs_set_color_key *op = data;
1123 struct wined3d_texture *texture = op->texture;
1125 if (op->set)
1127 switch (op->flags)
1129 case WINED3D_CKEY_DST_BLT:
1130 texture->async.dst_blt_color_key = op->color_key;
1131 texture->async.color_key_flags |= WINED3D_CKEY_DST_BLT;
1132 break;
1134 case WINED3D_CKEY_DST_OVERLAY:
1135 texture->async.dst_overlay_color_key = op->color_key;
1136 texture->async.color_key_flags |= WINED3D_CKEY_DST_OVERLAY;
1137 break;
1139 case WINED3D_CKEY_SRC_BLT:
1140 if (texture == cs->state.textures[0])
1142 device_invalidate_state(cs->device, STATE_COLOR_KEY);
1143 if (!(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT))
1144 device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE));
1147 texture->async.src_blt_color_key = op->color_key;
1148 texture->async.color_key_flags |= WINED3D_CKEY_SRC_BLT;
1149 break;
1151 case WINED3D_CKEY_SRC_OVERLAY:
1152 texture->async.src_overlay_color_key = op->color_key;
1153 texture->async.color_key_flags |= WINED3D_CKEY_SRC_OVERLAY;
1154 break;
1157 else
1159 switch (op->flags)
1161 case WINED3D_CKEY_DST_BLT:
1162 texture->async.color_key_flags &= ~WINED3D_CKEY_DST_BLT;
1163 break;
1165 case WINED3D_CKEY_DST_OVERLAY:
1166 texture->async.color_key_flags &= ~WINED3D_CKEY_DST_OVERLAY;
1167 break;
1169 case WINED3D_CKEY_SRC_BLT:
1170 if (texture == cs->state.textures[0] && texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
1171 device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE));
1173 texture->async.color_key_flags &= ~WINED3D_CKEY_SRC_BLT;
1174 break;
1176 case WINED3D_CKEY_SRC_OVERLAY:
1177 texture->async.color_key_flags &= ~WINED3D_CKEY_SRC_OVERLAY;
1178 break;
1183 void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture,
1184 WORD flags, const struct wined3d_color_key *color_key)
1186 struct wined3d_cs_set_color_key *op;
1188 op = cs->ops->require_space(cs, sizeof(*op));
1189 op->opcode = WINED3D_CS_OP_SET_COLOR_KEY;
1190 op->texture = texture;
1191 op->flags = flags;
1192 if (color_key)
1194 op->color_key = *color_key;
1195 op->set = 1;
1197 else
1198 op->set = 0;
1200 cs->ops->submit(cs);
1203 static void wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data)
1205 const struct wined3d_cs_set_material *op = data;
1207 cs->state.material = op->material;
1208 device_invalidate_state(cs->device, STATE_MATERIAL);
1211 void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_material *material)
1213 struct wined3d_cs_set_material *op;
1215 op = cs->ops->require_space(cs, sizeof(*op));
1216 op->opcode = WINED3D_CS_OP_SET_MATERIAL;
1217 op->material = *material;
1219 cs->ops->submit(cs);
1222 static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data)
1224 struct wined3d_adapter *adapter = cs->device->adapter;
1226 state_cleanup(&cs->state);
1227 memset(&cs->state, 0, sizeof(cs->state));
1228 state_init(&cs->state, &cs->fb, &adapter->gl_info, &adapter->d3d_info,
1229 WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT);
1232 void wined3d_cs_emit_reset_state(struct wined3d_cs *cs)
1234 struct wined3d_cs_reset_state *op;
1236 op = cs->ops->require_space(cs, sizeof(*op));
1237 op->opcode = WINED3D_CS_OP_RESET_STATE;
1239 cs->ops->submit(cs);
1242 static void wined3d_cs_exec_destroy_object(struct wined3d_cs *cs, const void *data)
1244 const struct wined3d_cs_destroy_object *op = data;
1246 op->callback(op->object);
1249 void wined3d_cs_emit_destroy_object(struct wined3d_cs *cs, void (*callback)(void *object), void *object)
1251 struct wined3d_cs_destroy_object *op;
1253 op = cs->ops->require_space(cs, sizeof(*op));
1254 op->opcode = WINED3D_CS_OP_DESTROY_OBJECT;
1255 op->callback = callback;
1256 op->object = object;
1258 cs->ops->submit(cs);
1261 static void wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data)
1263 const struct wined3d_cs_query_issue *op = data;
1264 struct wined3d_query *query = op->query;
1266 query->query_ops->query_issue(query, op->flags);
1269 void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, DWORD flags)
1271 struct wined3d_cs_query_issue *op;
1273 op = cs->ops->require_space(cs, sizeof(*op));
1274 op->opcode = WINED3D_CS_OP_QUERY_ISSUE;
1275 op->query = query;
1276 op->flags = flags;
1278 cs->ops->submit(cs);
1281 static void wined3d_cs_exec_preload_resource(struct wined3d_cs *cs, const void *data)
1283 const struct wined3d_cs_preload_resource *op = data;
1284 struct wined3d_resource *resource = op->resource;
1286 resource->resource_ops->resource_preload(resource);
1287 wined3d_resource_release(resource);
1290 void wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource)
1292 struct wined3d_cs_preload_resource *op;
1294 op = cs->ops->require_space(cs, sizeof(*op));
1295 op->opcode = WINED3D_CS_OP_PRELOAD_RESOURCE;
1296 op->resource = resource;
1298 wined3d_resource_acquire(resource);
1300 cs->ops->submit(cs);
1303 static void wined3d_cs_exec_unload_resource(struct wined3d_cs *cs, const void *data)
1305 const struct wined3d_cs_unload_resource *op = data;
1306 struct wined3d_resource *resource = op->resource;
1308 resource->resource_ops->resource_unload(resource);
1309 wined3d_resource_release(resource);
1312 void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource)
1314 struct wined3d_cs_unload_resource *op;
1316 op = cs->ops->require_space(cs, sizeof(*op));
1317 op->opcode = WINED3D_CS_OP_UNLOAD_RESOURCE;
1318 op->resource = resource;
1320 wined3d_resource_acquire(resource);
1322 cs->ops->submit(cs);
1325 static void wined3d_cs_exec_map(struct wined3d_cs *cs, const void *data)
1327 const struct wined3d_cs_map *op = data;
1328 struct wined3d_resource *resource = op->resource;
1330 *op->hr = resource->resource_ops->resource_sub_resource_map(resource,
1331 op->sub_resource_idx, op->map_desc, op->box, op->flags);
1334 HRESULT wined3d_cs_map(struct wined3d_cs *cs, struct wined3d_resource *resource, unsigned int sub_resource_idx,
1335 struct wined3d_map_desc *map_desc, const struct wined3d_box *box, unsigned int flags)
1337 struct wined3d_cs_map *op;
1338 HRESULT hr;
1340 op = cs->ops->require_space(cs, sizeof(*op));
1341 op->opcode = WINED3D_CS_OP_MAP;
1342 op->resource = resource;
1343 op->sub_resource_idx = sub_resource_idx;
1344 op->map_desc = map_desc;
1345 op->box = box;
1346 op->flags = flags;
1347 op->hr = &hr;
1349 cs->ops->submit(cs);
1351 return hr;
1354 static void wined3d_cs_exec_unmap(struct wined3d_cs *cs, const void *data)
1356 const struct wined3d_cs_unmap *op = data;
1357 struct wined3d_resource *resource = op->resource;
1359 *op->hr = resource->resource_ops->resource_sub_resource_unmap(resource, op->sub_resource_idx);
1362 HRESULT wined3d_cs_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource, unsigned int sub_resource_idx)
1364 struct wined3d_cs_unmap *op;
1365 HRESULT hr;
1367 op = cs->ops->require_space(cs, sizeof(*op));
1368 op->opcode = WINED3D_CS_OP_UNMAP;
1369 op->resource = resource;
1370 op->sub_resource_idx = sub_resource_idx;
1371 op->hr = &hr;
1373 cs->ops->submit(cs);
1375 return hr;
1378 static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) =
1380 /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present,
1381 /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear,
1382 /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw,
1383 /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication,
1384 /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport,
1385 /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect,
1386 /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view,
1387 /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view,
1388 /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration,
1389 /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source,
1390 /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq,
1391 /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output,
1392 /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer,
1393 /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer,
1394 /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture,
1395 /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view,
1396 /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler,
1397 /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader,
1398 /* WINED3D_CS_OP_SET_RASTERIZER_STATE */ wined3d_cs_exec_set_rasterizer_state,
1399 /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state,
1400 /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state,
1401 /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state,
1402 /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform,
1403 /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane,
1404 /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key,
1405 /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material,
1406 /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state,
1407 /* WINED3D_CS_OP_DESTROY_OBJECT */ wined3d_cs_exec_destroy_object,
1408 /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue,
1409 /* WINED3D_CS_OP_PRELOAD_RESOURCE */ wined3d_cs_exec_preload_resource,
1410 /* WINED3D_CS_OP_UNLOAD_RESOURCE */ wined3d_cs_exec_unload_resource,
1411 /* WINED3D_CS_OP_MAP */ wined3d_cs_exec_map,
1412 /* WINED3D_CS_OP_UNMAP */ wined3d_cs_exec_unmap,
1415 static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size)
1417 if (size > cs->data_size)
1419 void *new_data;
1421 size = max( size, cs->data_size * 2 );
1422 if (!(new_data = HeapReAlloc(GetProcessHeap(), 0, cs->data, size)))
1423 return NULL;
1425 cs->data_size = size;
1426 cs->data = new_data;
1429 return cs->data;
1432 static void wined3d_cs_st_submit(struct wined3d_cs *cs)
1434 enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)cs->data;
1436 wined3d_cs_op_handlers[opcode](cs, cs->data);
1439 static void wined3d_cs_st_push_constants(struct wined3d_cs *cs, enum wined3d_push_constants p,
1440 unsigned int start_idx, unsigned int count, const void *constants)
1442 struct wined3d_device *device = cs->device;
1443 unsigned int context_count;
1444 unsigned int i;
1445 size_t offset;
1447 static const struct
1449 size_t offset;
1450 size_t size;
1451 DWORD mask;
1453 push_constant_info[] =
1455 /* WINED3D_PUSH_CONSTANTS_VS_F */
1456 {FIELD_OFFSET(struct wined3d_state, vs_consts_f), sizeof(struct wined3d_vec4), WINED3D_SHADER_CONST_VS_F},
1457 /* WINED3D_PUSH_CONSTANTS_PS_F */
1458 {FIELD_OFFSET(struct wined3d_state, ps_consts_f), sizeof(struct wined3d_vec4), WINED3D_SHADER_CONST_PS_F},
1459 /* WINED3D_PUSH_CONSTANTS_VS_I */
1460 {FIELD_OFFSET(struct wined3d_state, vs_consts_i), sizeof(struct wined3d_ivec4), WINED3D_SHADER_CONST_VS_I},
1461 /* WINED3D_PUSH_CONSTANTS_PS_I */
1462 {FIELD_OFFSET(struct wined3d_state, ps_consts_i), sizeof(struct wined3d_ivec4), WINED3D_SHADER_CONST_PS_I},
1463 /* WINED3D_PUSH_CONSTANTS_VS_B */
1464 {FIELD_OFFSET(struct wined3d_state, vs_consts_b), sizeof(BOOL), WINED3D_SHADER_CONST_VS_B},
1465 /* WINED3D_PUSH_CONSTANTS_PS_B */
1466 {FIELD_OFFSET(struct wined3d_state, ps_consts_b), sizeof(BOOL), WINED3D_SHADER_CONST_PS_B},
1469 if (p == WINED3D_PUSH_CONSTANTS_VS_F)
1470 device->shader_backend->shader_update_float_vertex_constants(device, start_idx, count);
1471 else if (p == WINED3D_PUSH_CONSTANTS_PS_F)
1472 device->shader_backend->shader_update_float_pixel_constants(device, start_idx, count);
1474 offset = push_constant_info[p].offset + start_idx * push_constant_info[p].size;
1475 memcpy((BYTE *)&cs->state + offset, constants, count * push_constant_info[p].size);
1476 for (i = 0, context_count = device->context_count; i < context_count; ++i)
1478 device->contexts[i]->constant_update_mask |= push_constant_info[p].mask;
1482 static const struct wined3d_cs_ops wined3d_cs_st_ops =
1484 wined3d_cs_st_require_space,
1485 wined3d_cs_st_submit,
1486 wined3d_cs_st_push_constants,
1489 struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
1491 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
1492 struct wined3d_cs *cs;
1494 if (!(cs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cs))))
1495 return NULL;
1497 if (!(cs->fb.render_targets = wined3d_calloc(gl_info->limits.buffers, sizeof(*cs->fb.render_targets))))
1499 HeapFree(GetProcessHeap(), 0, cs);
1500 return NULL;
1503 state_init(&cs->state, &cs->fb, gl_info, &device->adapter->d3d_info,
1504 WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT);
1506 cs->ops = &wined3d_cs_st_ops;
1507 cs->device = device;
1509 cs->data_size = WINED3D_INITIAL_CS_SIZE;
1510 if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size)))
1512 state_cleanup(&cs->state);
1513 HeapFree(GetProcessHeap(), 0, cs->fb.render_targets);
1514 HeapFree(GetProcessHeap(), 0, cs);
1515 return NULL;
1518 return cs;
1521 void wined3d_cs_destroy(struct wined3d_cs *cs)
1523 state_cleanup(&cs->state);
1524 HeapFree(GetProcessHeap(), 0, cs->fb.render_targets);
1525 HeapFree(GetProcessHeap(), 0, cs->data);
1526 HeapFree(GetProcessHeap(), 0, cs);