user32: Get rid of the unused parameter in the EmptyClipboard driver entry point.
[wine.git] / dlls / wined3d / cs.c
blob874129a0fee77f2b288dc430f8f8f92880bd4702
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_RENDER_STATE,
48 WINED3D_CS_OP_SET_TEXTURE_STATE,
49 WINED3D_CS_OP_SET_SAMPLER_STATE,
50 WINED3D_CS_OP_SET_TRANSFORM,
51 WINED3D_CS_OP_SET_CLIP_PLANE,
52 WINED3D_CS_OP_SET_COLOR_KEY,
53 WINED3D_CS_OP_SET_MATERIAL,
54 WINED3D_CS_OP_RESET_STATE,
57 struct wined3d_cs_present
59 enum wined3d_cs_op opcode;
60 HWND dst_window_override;
61 struct wined3d_swapchain *swapchain;
62 const RECT *src_rect;
63 const RECT *dst_rect;
64 const RGNDATA *dirty_region;
65 DWORD flags;
68 struct wined3d_cs_clear
70 enum wined3d_cs_op opcode;
71 DWORD rect_count;
72 const RECT *rects;
73 DWORD flags;
74 const struct wined3d_color *color;
75 float depth;
76 DWORD stencil;
79 struct wined3d_cs_draw
81 enum wined3d_cs_op opcode;
82 UINT start_idx;
83 UINT index_count;
84 UINT start_instance;
85 UINT instance_count;
86 BOOL indexed;
89 struct wined3d_cs_set_predication
91 enum wined3d_cs_op opcode;
92 struct wined3d_query *predicate;
93 BOOL value;
96 struct wined3d_cs_set_viewport
98 enum wined3d_cs_op opcode;
99 const struct wined3d_viewport *viewport;
102 struct wined3d_cs_set_scissor_rect
104 enum wined3d_cs_op opcode;
105 const RECT *rect;
108 struct wined3d_cs_set_rendertarget_view
110 enum wined3d_cs_op opcode;
111 unsigned int view_idx;
112 struct wined3d_rendertarget_view *view;
115 struct wined3d_cs_set_depth_stencil_view
117 enum wined3d_cs_op opcode;
118 struct wined3d_rendertarget_view *view;
121 struct wined3d_cs_set_vertex_declaration
123 enum wined3d_cs_op opcode;
124 struct wined3d_vertex_declaration *declaration;
127 struct wined3d_cs_set_stream_source
129 enum wined3d_cs_op opcode;
130 UINT stream_idx;
131 struct wined3d_buffer *buffer;
132 UINT offset;
133 UINT stride;
136 struct wined3d_cs_set_stream_source_freq
138 enum wined3d_cs_op opcode;
139 UINT stream_idx;
140 UINT frequency;
141 UINT flags;
144 struct wined3d_cs_set_stream_output
146 enum wined3d_cs_op opcode;
147 UINT stream_idx;
148 struct wined3d_buffer *buffer;
149 UINT offset;
152 struct wined3d_cs_set_index_buffer
154 enum wined3d_cs_op opcode;
155 struct wined3d_buffer *buffer;
156 enum wined3d_format_id format_id;
159 struct wined3d_cs_set_constant_buffer
161 enum wined3d_cs_op opcode;
162 enum wined3d_shader_type type;
163 UINT cb_idx;
164 struct wined3d_buffer *buffer;
167 struct wined3d_cs_set_texture
169 enum wined3d_cs_op opcode;
170 UINT stage;
171 struct wined3d_texture *texture;
174 struct wined3d_cs_set_color_key
176 enum wined3d_cs_op opcode;
177 struct wined3d_texture *texture;
178 WORD flags;
179 WORD set;
180 struct wined3d_color_key color_key;
183 struct wined3d_cs_set_shader_resource_view
185 enum wined3d_cs_op opcode;
186 enum wined3d_shader_type type;
187 UINT view_idx;
188 struct wined3d_shader_resource_view *view;
191 struct wined3d_cs_set_sampler
193 enum wined3d_cs_op opcode;
194 enum wined3d_shader_type type;
195 UINT sampler_idx;
196 struct wined3d_sampler *sampler;
199 struct wined3d_cs_set_shader
201 enum wined3d_cs_op opcode;
202 enum wined3d_shader_type type;
203 struct wined3d_shader *shader;
206 struct wined3d_cs_set_render_state
208 enum wined3d_cs_op opcode;
209 enum wined3d_render_state state;
210 DWORD value;
213 struct wined3d_cs_set_texture_state
215 enum wined3d_cs_op opcode;
216 UINT stage;
217 enum wined3d_texture_stage_state state;
218 DWORD value;
221 struct wined3d_cs_set_sampler_state
223 enum wined3d_cs_op opcode;
224 UINT sampler_idx;
225 enum wined3d_sampler_state state;
226 DWORD value;
229 struct wined3d_cs_set_transform
231 enum wined3d_cs_op opcode;
232 enum wined3d_transform_state state;
233 const struct wined3d_matrix *matrix;
236 struct wined3d_cs_set_clip_plane
238 enum wined3d_cs_op opcode;
239 UINT plane_idx;
240 const struct wined3d_vec4 *plane;
243 struct wined3d_cs_set_material
245 enum wined3d_cs_op opcode;
246 const struct wined3d_material *material;
249 struct wined3d_cs_reset_state
251 enum wined3d_cs_op opcode;
254 static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data)
256 const struct wined3d_cs_present *op = data;
257 struct wined3d_swapchain *swapchain;
259 swapchain = op->swapchain;
260 wined3d_swapchain_set_window(swapchain, op->dst_window_override);
262 swapchain->swapchain_ops->swapchain_present(swapchain,
263 op->src_rect, op->dst_rect, op->dirty_region, op->flags);
266 void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain,
267 const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
268 const RGNDATA *dirty_region, DWORD flags)
270 struct wined3d_cs_present *op;
272 op = cs->ops->require_space(cs, sizeof(*op));
273 op->opcode = WINED3D_CS_OP_PRESENT;
274 op->dst_window_override = dst_window_override;
275 op->swapchain = swapchain;
276 op->src_rect = src_rect;
277 op->dst_rect = dst_rect;
278 op->dirty_region = dirty_region;
279 op->flags = flags;
281 cs->ops->submit(cs);
284 static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data)
286 const struct wined3d_cs_clear *op = data;
287 struct wined3d_device *device;
288 RECT draw_rect;
290 device = cs->device;
291 wined3d_get_draw_rect(&device->state, &draw_rect);
292 device_clear_render_targets(device, device->adapter->gl_info.limits.buffers,
293 &device->fb, op->rect_count, op->rects, &draw_rect, op->flags,
294 op->color, op->depth, op->stencil);
297 void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects,
298 DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil)
300 struct wined3d_cs_clear *op;
302 op = cs->ops->require_space(cs, sizeof(*op));
303 op->opcode = WINED3D_CS_OP_CLEAR;
304 op->rect_count = rect_count;
305 op->rects = rects;
306 op->flags = flags;
307 op->color = color;
308 op->depth = depth;
309 op->stencil = stencil;
311 cs->ops->submit(cs);
314 static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data)
316 const struct wined3d_cs_draw *op = data;
318 draw_primitive(cs->device, op->start_idx, op->index_count,
319 op->start_instance, op->instance_count, op->indexed);
322 void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_count,
323 UINT start_instance, UINT instance_count, BOOL indexed)
325 struct wined3d_cs_draw *op;
327 op = cs->ops->require_space(cs, sizeof(*op));
328 op->opcode = WINED3D_CS_OP_DRAW;
329 op->start_idx = start_idx;
330 op->index_count = index_count;
331 op->start_instance = start_instance;
332 op->instance_count = instance_count;
333 op->indexed = indexed;
335 cs->ops->submit(cs);
338 static void wined3d_cs_exec_set_predication(struct wined3d_cs *cs, const void *data)
340 const struct wined3d_cs_set_predication *op = data;
342 cs->state.predicate = op->predicate;
343 cs->state.predicate_value = op->value;
346 void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query *predicate, BOOL value)
348 struct wined3d_cs_set_predication *op;
350 op = cs->ops->require_space(cs, sizeof(*op));
351 op->opcode = WINED3D_CS_OP_SET_PREDICATION;
352 op->predicate = predicate;
353 op->value = value;
355 cs->ops->submit(cs);
358 static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data)
360 const struct wined3d_cs_set_viewport *op = data;
362 cs->state.viewport = *op->viewport;
363 device_invalidate_state(cs->device, STATE_VIEWPORT);
366 void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport)
368 struct wined3d_cs_set_viewport *op;
370 op = cs->ops->require_space(cs, sizeof(*op));
371 op->opcode = WINED3D_CS_OP_SET_VIEWPORT;
372 op->viewport = viewport;
374 cs->ops->submit(cs);
377 static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data)
379 const struct wined3d_cs_set_scissor_rect *op = data;
381 cs->state.scissor_rect = *op->rect;
382 device_invalidate_state(cs->device, STATE_SCISSORRECT);
385 void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect)
387 struct wined3d_cs_set_scissor_rect *op;
389 op = cs->ops->require_space(cs, sizeof(*op));
390 op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT;
391 op->rect = rect;
393 cs->ops->submit(cs);
396 static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data)
398 const struct wined3d_cs_set_rendertarget_view *op = data;
400 cs->state.fb->render_targets[op->view_idx] = op->view;
401 device_invalidate_state(cs->device, STATE_FRAMEBUFFER);
404 void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int view_idx,
405 struct wined3d_rendertarget_view *view)
407 struct wined3d_cs_set_rendertarget_view *op;
409 op = cs->ops->require_space(cs, sizeof(*op));
410 op->opcode = WINED3D_CS_OP_SET_RENDERTARGET_VIEW;
411 op->view_idx = view_idx;
412 op->view = view;
414 cs->ops->submit(cs);
417 static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const void *data)
419 const struct wined3d_cs_set_depth_stencil_view *op = data;
420 struct wined3d_device *device = cs->device;
421 struct wined3d_rendertarget_view *prev;
423 if ((prev = cs->state.fb->depth_stencil))
425 struct wined3d_surface *prev_surface = wined3d_rendertarget_view_get_surface(prev);
427 if (prev_surface && (device->swapchains[0]->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
428 || prev_surface->flags & SFLAG_DISCARD))
430 surface_modify_ds_location(prev_surface, WINED3D_LOCATION_DISCARDED, prev->width, prev->height);
431 if (prev_surface == device->onscreen_depth_stencil)
433 wined3d_surface_decref(device->onscreen_depth_stencil);
434 device->onscreen_depth_stencil = NULL;
439 cs->fb.depth_stencil = op->view;
441 if (!prev != !op->view)
443 /* Swapping NULL / non NULL depth stencil affects the depth and tests */
444 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_ZENABLE));
445 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILENABLE));
446 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK));
447 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
449 else if (prev && prev->format->depth_size != op->view->format->depth_size)
451 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
454 device_invalidate_state(device, STATE_FRAMEBUFFER);
457 void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view)
459 struct wined3d_cs_set_depth_stencil_view *op;
461 op = cs->ops->require_space(cs, sizeof(*op));
462 op->opcode = WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW;
463 op->view = view;
465 cs->ops->submit(cs);
468 static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data)
470 const struct wined3d_cs_set_vertex_declaration *op = data;
472 cs->state.vertex_declaration = op->declaration;
473 device_invalidate_state(cs->device, STATE_VDECL);
476 void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3d_vertex_declaration *declaration)
478 struct wined3d_cs_set_vertex_declaration *op;
480 op = cs->ops->require_space(cs, sizeof(*op));
481 op->opcode = WINED3D_CS_OP_SET_VERTEX_DECLARATION;
482 op->declaration = declaration;
484 cs->ops->submit(cs);
487 static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data)
489 const struct wined3d_cs_set_stream_source *op = data;
490 struct wined3d_stream_state *stream;
491 struct wined3d_buffer *prev;
493 stream = &cs->state.streams[op->stream_idx];
494 prev = stream->buffer;
495 stream->buffer = op->buffer;
496 stream->offset = op->offset;
497 stream->stride = op->stride;
499 if (op->buffer)
500 InterlockedIncrement(&op->buffer->resource.bind_count);
501 if (prev)
502 InterlockedDecrement(&prev->resource.bind_count);
504 device_invalidate_state(cs->device, STATE_STREAMSRC);
507 void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx,
508 struct wined3d_buffer *buffer, UINT offset, UINT stride)
510 struct wined3d_cs_set_stream_source *op;
512 op = cs->ops->require_space(cs, sizeof(*op));
513 op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE;
514 op->stream_idx = stream_idx;
515 op->buffer = buffer;
516 op->offset = offset;
517 op->stride = stride;
519 cs->ops->submit(cs);
522 static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data)
524 const struct wined3d_cs_set_stream_source_freq *op = data;
525 struct wined3d_stream_state *stream;
527 stream = &cs->state.streams[op->stream_idx];
528 stream->frequency = op->frequency;
529 stream->flags = op->flags;
531 device_invalidate_state(cs->device, STATE_STREAMSRC);
534 void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx, UINT frequency, UINT flags)
536 struct wined3d_cs_set_stream_source_freq *op;
538 op = cs->ops->require_space(cs, sizeof(*op));
539 op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ;
540 op->stream_idx = stream_idx;
541 op->frequency = frequency;
542 op->flags = flags;
544 cs->ops->submit(cs);
547 static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data)
549 const struct wined3d_cs_set_stream_output *op = data;
550 struct wined3d_stream_output *stream;
551 struct wined3d_buffer *prev;
553 stream = &cs->state.stream_output[op->stream_idx];
554 prev = stream->buffer;
555 stream->buffer = op->buffer;
556 stream->offset = op->offset;
558 if (op->buffer)
559 InterlockedIncrement(&op->buffer->resource.bind_count);
560 if (prev)
561 InterlockedDecrement(&prev->resource.bind_count);
564 void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx,
565 struct wined3d_buffer *buffer, UINT offset)
567 struct wined3d_cs_set_stream_output *op;
569 op = cs->ops->require_space(cs, sizeof(*op));
570 op->opcode = WINED3D_CS_OP_SET_STREAM_OUTPUT;
571 op->stream_idx = stream_idx;
572 op->buffer = buffer;
573 op->offset = offset;
575 cs->ops->submit(cs);
578 static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data)
580 const struct wined3d_cs_set_index_buffer *op = data;
581 struct wined3d_buffer *prev;
583 prev = cs->state.index_buffer;
584 cs->state.index_buffer = op->buffer;
585 cs->state.index_format = op->format_id;
587 if (op->buffer)
588 InterlockedIncrement(&op->buffer->resource.bind_count);
589 if (prev)
590 InterlockedDecrement(&prev->resource.bind_count);
592 device_invalidate_state(cs->device, STATE_INDEXBUFFER);
595 void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer,
596 enum wined3d_format_id format_id)
598 struct wined3d_cs_set_index_buffer *op;
600 op = cs->ops->require_space(cs, sizeof(*op));
601 op->opcode = WINED3D_CS_OP_SET_INDEX_BUFFER;
602 op->buffer = buffer;
603 op->format_id = format_id;
605 cs->ops->submit(cs);
608 static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data)
610 const struct wined3d_cs_set_constant_buffer *op = data;
611 struct wined3d_buffer *prev;
613 prev = cs->state.cb[op->type][op->cb_idx];
614 cs->state.cb[op->type][op->cb_idx] = op->buffer;
616 if (op->buffer)
617 InterlockedIncrement(&op->buffer->resource.bind_count);
618 if (prev)
619 InterlockedDecrement(&prev->resource.bind_count);
621 device_invalidate_state(cs->device, STATE_CONSTANT_BUFFER(op->type));
624 void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type,
625 UINT cb_idx, struct wined3d_buffer *buffer)
627 struct wined3d_cs_set_constant_buffer *op;
629 op = cs->ops->require_space(cs, sizeof(*op));
630 op->opcode = WINED3D_CS_OP_SET_CONSTANT_BUFFER;
631 op->type = type;
632 op->cb_idx = cb_idx;
633 op->buffer = buffer;
635 cs->ops->submit(cs);
638 static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data)
640 const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info;
641 const struct wined3d_cs_set_texture *op = data;
642 struct wined3d_texture *prev;
643 BOOL old_use_color_key = FALSE, new_use_color_key = FALSE;
645 prev = cs->state.textures[op->stage];
646 cs->state.textures[op->stage] = op->texture;
648 if (op->texture)
650 const struct wined3d_format *new_format = op->texture->resource.format;
651 const struct wined3d_format *old_format = prev ? prev->resource.format : NULL;
652 unsigned int old_fmt_flags = prev ? prev->resource.format_flags : 0;
653 unsigned int new_fmt_flags = op->texture->resource.format_flags;
655 if (InterlockedIncrement(&op->texture->resource.bind_count) == 1)
656 op->texture->sampler = op->stage;
658 if (!prev || op->texture->target != prev->target
659 || !is_same_fixup(new_format->color_fixup, old_format->color_fixup)
660 || (new_fmt_flags & WINED3DFMT_FLAG_SHADOW) != (old_fmt_flags & WINED3DFMT_FLAG_SHADOW))
661 device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL));
663 if (!prev && op->stage < d3d_info->limits.ffp_blend_stages)
665 /* The source arguments for color and alpha ops have different
666 * meanings when a NULL texture is bound, so the COLOR_OP and
667 * ALPHA_OP have to be dirtified. */
668 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP));
669 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP));
672 if (!op->stage && op->texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
673 new_use_color_key = TRUE;
676 if (prev)
678 if (InterlockedDecrement(&prev->resource.bind_count) && prev->sampler == op->stage)
680 unsigned int i;
682 /* Search for other stages the texture is bound to. Shouldn't
683 * happen if applications bind textures to a single stage only. */
684 TRACE("Searching for other stages the texture is bound to.\n");
685 for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
687 if (cs->state.textures[i] == prev)
689 TRACE("Texture is also bound to stage %u.\n", i);
690 prev->sampler = i;
691 break;
696 if (!op->texture && op->stage < d3d_info->limits.ffp_blend_stages)
698 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP));
699 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP));
702 if (!op->stage && prev->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
703 old_use_color_key = TRUE;
706 device_invalidate_state(cs->device, STATE_SAMPLER(op->stage));
708 if (new_use_color_key != old_use_color_key)
709 device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE));
711 if (new_use_color_key)
712 device_invalidate_state(cs->device, STATE_COLOR_KEY);
715 void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined3d_texture *texture)
717 struct wined3d_cs_set_texture *op;
719 op = cs->ops->require_space(cs, sizeof(*op));
720 op->opcode = WINED3D_CS_OP_SET_TEXTURE;
721 op->stage = stage;
722 op->texture = texture;
724 cs->ops->submit(cs);
727 static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data)
729 const struct wined3d_cs_set_shader_resource_view *op = data;
731 cs->state.shader_resource_view[op->type][op->view_idx] = op->view;
732 device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
735 void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3d_shader_type type,
736 UINT view_idx, struct wined3d_shader_resource_view *view)
738 struct wined3d_cs_set_shader_resource_view *op;
740 op = cs->ops->require_space(cs, sizeof(*op));
741 op->opcode = WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW;
742 op->type = type;
743 op->view_idx = view_idx;
744 op->view = view;
746 cs->ops->submit(cs);
749 static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data)
751 const struct wined3d_cs_set_sampler *op = data;
753 cs->state.sampler[op->type][op->sampler_idx] = op->sampler;
754 device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
757 void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type type,
758 UINT sampler_idx, struct wined3d_sampler *sampler)
760 struct wined3d_cs_set_sampler *op;
762 op = cs->ops->require_space(cs, sizeof(*op));
763 op->opcode = WINED3D_CS_OP_SET_SAMPLER;
764 op->type = type;
765 op->sampler_idx = sampler_idx;
766 op->sampler = sampler;
768 cs->ops->submit(cs);
771 static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data)
773 const struct wined3d_cs_set_shader *op = data;
775 cs->state.shader[op->type] = op->shader;
776 device_invalidate_state(cs->device, STATE_SHADER(op->type));
777 device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
780 void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader)
782 struct wined3d_cs_set_shader *op;
784 op = cs->ops->require_space(cs, sizeof(*op));
785 op->opcode = WINED3D_CS_OP_SET_SHADER;
786 op->type = type;
787 op->shader = shader;
789 cs->ops->submit(cs);
792 static void wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data)
794 const struct wined3d_cs_set_render_state *op = data;
796 cs->state.render_states[op->state] = op->value;
797 device_invalidate_state(cs->device, STATE_RENDER(op->state));
800 void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render_state state, DWORD value)
802 struct wined3d_cs_set_render_state *op;
804 op = cs->ops->require_space(cs, sizeof(*op));
805 op->opcode = WINED3D_CS_OP_SET_RENDER_STATE;
806 op->state = state;
807 op->value = value;
809 cs->ops->submit(cs);
812 static void wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data)
814 const struct wined3d_cs_set_texture_state *op = data;
816 cs->state.texture_states[op->stage][op->state] = op->value;
817 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, op->state));
820 void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage,
821 enum wined3d_texture_stage_state state, DWORD value)
823 struct wined3d_cs_set_texture_state *op;
825 op = cs->ops->require_space(cs, sizeof(*op));
826 op->opcode = WINED3D_CS_OP_SET_TEXTURE_STATE;
827 op->stage = stage;
828 op->state = state;
829 op->value = value;
831 cs->ops->submit(cs);
834 static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data)
836 const struct wined3d_cs_set_sampler_state *op = data;
838 cs->state.sampler_states[op->sampler_idx][op->state] = op->value;
839 device_invalidate_state(cs->device, STATE_SAMPLER(op->sampler_idx));
842 void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx,
843 enum wined3d_sampler_state state, DWORD value)
845 struct wined3d_cs_set_sampler_state *op;
847 op = cs->ops->require_space(cs, sizeof(*op));
848 op->opcode = WINED3D_CS_OP_SET_SAMPLER_STATE;
849 op->sampler_idx = sampler_idx;
850 op->state = state;
851 op->value = value;
853 cs->ops->submit(cs);
856 static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data)
858 const struct wined3d_cs_set_transform *op = data;
860 cs->state.transforms[op->state] = *op->matrix;
861 if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->gl_info.limits.blends))
862 device_invalidate_state(cs->device, STATE_TRANSFORM(op->state));
865 void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform_state state,
866 const struct wined3d_matrix *matrix)
868 struct wined3d_cs_set_transform *op;
870 op = cs->ops->require_space(cs, sizeof(*op));
871 op->opcode = WINED3D_CS_OP_SET_TRANSFORM;
872 op->state = state;
873 op->matrix = matrix;
875 cs->ops->submit(cs);
878 static void wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *data)
880 const struct wined3d_cs_set_clip_plane *op = data;
882 cs->state.clip_planes[op->plane_idx] = *op->plane;
883 device_invalidate_state(cs->device, STATE_CLIPPLANE(op->plane_idx));
886 void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const struct wined3d_vec4 *plane)
888 struct wined3d_cs_set_clip_plane *op;
890 op = cs->ops->require_space(cs, sizeof(*op));
891 op->opcode = WINED3D_CS_OP_SET_CLIP_PLANE;
892 op->plane_idx = plane_idx;
893 op->plane = plane;
895 cs->ops->submit(cs);
898 static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *data)
900 const struct wined3d_cs_set_color_key *op = data;
901 struct wined3d_texture *texture = op->texture;
903 if (op->set)
905 switch (op->flags & ~WINED3D_CKEY_COLORSPACE)
907 case WINED3D_CKEY_DST_BLT:
908 texture->async.dst_blt_color_key = op->color_key;
909 texture->async.color_key_flags |= WINED3D_CKEY_DST_BLT;
910 break;
912 case WINED3D_CKEY_DST_OVERLAY:
913 texture->async.dst_overlay_color_key = op->color_key;
914 texture->async.color_key_flags |= WINED3D_CKEY_DST_OVERLAY;
915 break;
917 case WINED3D_CKEY_SRC_BLT:
918 if (texture == cs->state.textures[0])
920 device_invalidate_state(cs->device, STATE_COLOR_KEY);
921 if (!(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT))
922 device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE));
925 texture->async.src_blt_color_key = op->color_key;
926 texture->async.color_key_flags |= WINED3D_CKEY_SRC_BLT;
927 break;
929 case WINED3D_CKEY_SRC_OVERLAY:
930 texture->async.src_overlay_color_key = op->color_key;
931 texture->async.color_key_flags |= WINED3D_CKEY_SRC_OVERLAY;
932 break;
935 else
937 switch (op->flags & ~WINED3D_CKEY_COLORSPACE)
939 case WINED3D_CKEY_DST_BLT:
940 texture->async.color_key_flags &= ~WINED3D_CKEY_DST_BLT;
941 break;
943 case WINED3D_CKEY_DST_OVERLAY:
944 texture->async.color_key_flags &= ~WINED3D_CKEY_DST_OVERLAY;
945 break;
947 case WINED3D_CKEY_SRC_BLT:
948 if (texture == cs->state.textures[0] && texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
949 device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE));
951 texture->async.color_key_flags &= ~WINED3D_CKEY_SRC_BLT;
952 break;
954 case WINED3D_CKEY_SRC_OVERLAY:
955 texture->async.color_key_flags &= ~WINED3D_CKEY_SRC_OVERLAY;
956 break;
961 void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture,
962 WORD flags, const struct wined3d_color_key *color_key)
964 struct wined3d_cs_set_color_key *op;
966 op = cs->ops->require_space(cs, sizeof(*op));
967 op->opcode = WINED3D_CS_OP_SET_COLOR_KEY;
968 op->texture = texture;
969 op->flags = flags;
970 if (color_key)
972 op->color_key = *color_key;
973 op->set = 1;
975 else
976 op->set = 0;
978 cs->ops->submit(cs);
981 static void wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data)
983 const struct wined3d_cs_set_material *op = data;
985 cs->state.material = *op->material;
986 device_invalidate_state(cs->device, STATE_MATERIAL);
989 void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_material *material)
991 struct wined3d_cs_set_material *op;
993 op = cs->ops->require_space(cs, sizeof(*op));
994 op->opcode = WINED3D_CS_OP_SET_MATERIAL;
995 op->material = material;
997 cs->ops->submit(cs);
1000 static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data)
1002 struct wined3d_adapter *adapter = cs->device->adapter;
1003 HRESULT hr;
1005 state_cleanup(&cs->state);
1006 memset(&cs->state, 0, sizeof(cs->state));
1007 if (FAILED(hr = state_init(&cs->state, &cs->fb, &adapter->gl_info, &adapter->d3d_info,
1008 WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT)))
1009 ERR("Failed to initialize CS state, hr %#x.\n", hr);
1012 void wined3d_cs_emit_reset_state(struct wined3d_cs *cs)
1014 struct wined3d_cs_reset_state *op;
1016 op = cs->ops->require_space(cs, sizeof(*op));
1017 op->opcode = WINED3D_CS_OP_RESET_STATE;
1019 cs->ops->submit(cs);
1022 static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) =
1024 /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present,
1025 /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear,
1026 /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw,
1027 /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication,
1028 /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport,
1029 /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect,
1030 /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view,
1031 /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view,
1032 /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration,
1033 /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source,
1034 /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq,
1035 /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output,
1036 /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer,
1037 /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer,
1038 /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture,
1039 /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view,
1040 /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler,
1041 /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader,
1042 /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state,
1043 /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state,
1044 /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state,
1045 /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform,
1046 /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane,
1047 /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key,
1048 /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material,
1049 /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state,
1052 static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size)
1054 if (size > cs->data_size)
1056 void *new_data;
1058 size = max( size, cs->data_size * 2 );
1059 if (!(new_data = HeapReAlloc(GetProcessHeap(), 0, cs->data, size)))
1060 return NULL;
1062 cs->data_size = size;
1063 cs->data = new_data;
1066 return cs->data;
1069 static void wined3d_cs_st_submit(struct wined3d_cs *cs)
1071 enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)cs->data;
1073 wined3d_cs_op_handlers[opcode](cs, cs->data);
1076 static const struct wined3d_cs_ops wined3d_cs_st_ops =
1078 wined3d_cs_st_require_space,
1079 wined3d_cs_st_submit,
1082 struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
1084 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
1085 struct wined3d_cs *cs;
1087 if (!(cs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cs))))
1088 return NULL;
1090 if (!(cs->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1091 sizeof(*cs->fb.render_targets) * gl_info->limits.buffers)))
1093 HeapFree(GetProcessHeap(), 0, cs);
1094 return NULL;
1097 if (FAILED(state_init(&cs->state, &cs->fb, gl_info, &device->adapter->d3d_info,
1098 WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT)))
1100 HeapFree(GetProcessHeap(), 0, cs->fb.render_targets);
1101 HeapFree(GetProcessHeap(), 0, cs);
1102 return NULL;
1105 cs->ops = &wined3d_cs_st_ops;
1106 cs->device = device;
1108 cs->data_size = WINED3D_INITIAL_CS_SIZE;
1109 if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size)))
1111 HeapFree(GetProcessHeap(), 0, cs);
1112 return NULL;
1115 return cs;
1118 void wined3d_cs_destroy(struct wined3d_cs *cs)
1120 state_cleanup(&cs->state);
1121 HeapFree(GetProcessHeap(), 0, cs->fb.render_targets);
1122 HeapFree(GetProcessHeap(), 0, cs->data);
1123 HeapFree(GetProcessHeap(), 0, cs);