dbghelp: Fix compiler warnings with flag -Wunused-macros.
[wine.git] / dlls / wined3d / cs.c
blobb8a32e58ded98fbef84969fabc9d1f8ff2fcacf8
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_MATERIAL,
53 WINED3D_CS_OP_RESET_STATE,
56 struct wined3d_cs_present
58 enum wined3d_cs_op opcode;
59 HWND dst_window_override;
60 struct wined3d_swapchain *swapchain;
61 const RECT *src_rect;
62 const RECT *dst_rect;
63 const RGNDATA *dirty_region;
64 DWORD flags;
67 struct wined3d_cs_clear
69 enum wined3d_cs_op opcode;
70 DWORD rect_count;
71 const RECT *rects;
72 DWORD flags;
73 const struct wined3d_color *color;
74 float depth;
75 DWORD stencil;
78 struct wined3d_cs_draw
80 enum wined3d_cs_op opcode;
81 UINT start_idx;
82 UINT index_count;
83 UINT start_instance;
84 UINT instance_count;
85 BOOL indexed;
88 struct wined3d_cs_set_predication
90 enum wined3d_cs_op opcode;
91 struct wined3d_query *predicate;
92 BOOL value;
95 struct wined3d_cs_set_viewport
97 enum wined3d_cs_op opcode;
98 const struct wined3d_viewport *viewport;
101 struct wined3d_cs_set_scissor_rect
103 enum wined3d_cs_op opcode;
104 const RECT *rect;
107 struct wined3d_cs_set_rendertarget_view
109 enum wined3d_cs_op opcode;
110 unsigned int view_idx;
111 struct wined3d_rendertarget_view *view;
114 struct wined3d_cs_set_depth_stencil_view
116 enum wined3d_cs_op opcode;
117 struct wined3d_rendertarget_view *view;
120 struct wined3d_cs_set_vertex_declaration
122 enum wined3d_cs_op opcode;
123 struct wined3d_vertex_declaration *declaration;
126 struct wined3d_cs_set_stream_source
128 enum wined3d_cs_op opcode;
129 UINT stream_idx;
130 struct wined3d_buffer *buffer;
131 UINT offset;
132 UINT stride;
135 struct wined3d_cs_set_stream_source_freq
137 enum wined3d_cs_op opcode;
138 UINT stream_idx;
139 UINT frequency;
140 UINT flags;
143 struct wined3d_cs_set_stream_output
145 enum wined3d_cs_op opcode;
146 UINT stream_idx;
147 struct wined3d_buffer *buffer;
148 UINT offset;
151 struct wined3d_cs_set_index_buffer
153 enum wined3d_cs_op opcode;
154 struct wined3d_buffer *buffer;
155 enum wined3d_format_id format_id;
158 struct wined3d_cs_set_constant_buffer
160 enum wined3d_cs_op opcode;
161 enum wined3d_shader_type type;
162 UINT cb_idx;
163 struct wined3d_buffer *buffer;
166 struct wined3d_cs_set_texture
168 enum wined3d_cs_op opcode;
169 UINT stage;
170 struct wined3d_texture *texture;
173 struct wined3d_cs_set_shader_resource_view
175 enum wined3d_cs_op opcode;
176 enum wined3d_shader_type type;
177 UINT view_idx;
178 struct wined3d_shader_resource_view *view;
181 struct wined3d_cs_set_sampler
183 enum wined3d_cs_op opcode;
184 enum wined3d_shader_type type;
185 UINT sampler_idx;
186 struct wined3d_sampler *sampler;
189 struct wined3d_cs_set_shader
191 enum wined3d_cs_op opcode;
192 enum wined3d_shader_type type;
193 struct wined3d_shader *shader;
196 struct wined3d_cs_set_render_state
198 enum wined3d_cs_op opcode;
199 enum wined3d_render_state state;
200 DWORD value;
203 struct wined3d_cs_set_texture_state
205 enum wined3d_cs_op opcode;
206 UINT stage;
207 enum wined3d_texture_stage_state state;
208 DWORD value;
211 struct wined3d_cs_set_sampler_state
213 enum wined3d_cs_op opcode;
214 UINT sampler_idx;
215 enum wined3d_sampler_state state;
216 DWORD value;
219 struct wined3d_cs_set_transform
221 enum wined3d_cs_op opcode;
222 enum wined3d_transform_state state;
223 const struct wined3d_matrix *matrix;
226 struct wined3d_cs_set_clip_plane
228 enum wined3d_cs_op opcode;
229 UINT plane_idx;
230 const struct wined3d_vec4 *plane;
233 struct wined3d_cs_set_material
235 enum wined3d_cs_op opcode;
236 const struct wined3d_material *material;
239 struct wined3d_cs_reset_state
241 enum wined3d_cs_op opcode;
244 static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data)
246 const struct wined3d_cs_present *op = data;
247 struct wined3d_swapchain *swapchain;
249 swapchain = op->swapchain;
250 wined3d_swapchain_set_window(swapchain, op->dst_window_override);
252 swapchain->swapchain_ops->swapchain_present(swapchain,
253 op->src_rect, op->dst_rect, op->dirty_region, op->flags);
256 void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain,
257 const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
258 const RGNDATA *dirty_region, DWORD flags)
260 struct wined3d_cs_present *op;
262 op = cs->ops->require_space(cs, sizeof(*op));
263 op->opcode = WINED3D_CS_OP_PRESENT;
264 op->dst_window_override = dst_window_override;
265 op->swapchain = swapchain;
266 op->src_rect = src_rect;
267 op->dst_rect = dst_rect;
268 op->dirty_region = dirty_region;
269 op->flags = flags;
271 cs->ops->submit(cs);
274 static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data)
276 const struct wined3d_cs_clear *op = data;
277 struct wined3d_device *device;
278 RECT draw_rect;
280 device = cs->device;
281 wined3d_get_draw_rect(&device->state, &draw_rect);
282 device_clear_render_targets(device, device->adapter->gl_info.limits.buffers,
283 &device->fb, op->rect_count, op->rects, &draw_rect, op->flags,
284 op->color, op->depth, op->stencil);
287 void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects,
288 DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil)
290 struct wined3d_cs_clear *op;
292 op = cs->ops->require_space(cs, sizeof(*op));
293 op->opcode = WINED3D_CS_OP_CLEAR;
294 op->rect_count = rect_count;
295 op->rects = rects;
296 op->flags = flags;
297 op->color = color;
298 op->depth = depth;
299 op->stencil = stencil;
301 cs->ops->submit(cs);
304 static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data)
306 const struct wined3d_cs_draw *op = data;
308 draw_primitive(cs->device, op->start_idx, op->index_count,
309 op->start_instance, op->instance_count, op->indexed);
312 void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_count,
313 UINT start_instance, UINT instance_count, BOOL indexed)
315 struct wined3d_cs_draw *op;
317 op = cs->ops->require_space(cs, sizeof(*op));
318 op->opcode = WINED3D_CS_OP_DRAW;
319 op->start_idx = start_idx;
320 op->index_count = index_count;
321 op->start_instance = start_instance;
322 op->instance_count = instance_count;
323 op->indexed = indexed;
325 cs->ops->submit(cs);
328 static void wined3d_cs_exec_set_predication(struct wined3d_cs *cs, const void *data)
330 const struct wined3d_cs_set_predication *op = data;
332 cs->state.predicate = op->predicate;
333 cs->state.predicate_value = op->value;
336 void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query *predicate, BOOL value)
338 struct wined3d_cs_set_predication *op;
340 op = cs->ops->require_space(cs, sizeof(*op));
341 op->opcode = WINED3D_CS_OP_SET_PREDICATION;
342 op->predicate = predicate;
343 op->value = value;
345 cs->ops->submit(cs);
348 static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data)
350 const struct wined3d_cs_set_viewport *op = data;
352 cs->state.viewport = *op->viewport;
353 device_invalidate_state(cs->device, STATE_VIEWPORT);
356 void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport)
358 struct wined3d_cs_set_viewport *op;
360 op = cs->ops->require_space(cs, sizeof(*op));
361 op->opcode = WINED3D_CS_OP_SET_VIEWPORT;
362 op->viewport = viewport;
364 cs->ops->submit(cs);
367 static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data)
369 const struct wined3d_cs_set_scissor_rect *op = data;
371 cs->state.scissor_rect = *op->rect;
372 device_invalidate_state(cs->device, STATE_SCISSORRECT);
375 void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect)
377 struct wined3d_cs_set_scissor_rect *op;
379 op = cs->ops->require_space(cs, sizeof(*op));
380 op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT;
381 op->rect = rect;
383 cs->ops->submit(cs);
386 static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data)
388 const struct wined3d_cs_set_rendertarget_view *op = data;
390 cs->state.fb->render_targets[op->view_idx] = op->view;
391 device_invalidate_state(cs->device, STATE_FRAMEBUFFER);
394 void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int view_idx,
395 struct wined3d_rendertarget_view *view)
397 struct wined3d_cs_set_rendertarget_view *op;
399 op = cs->ops->require_space(cs, sizeof(*op));
400 op->opcode = WINED3D_CS_OP_SET_RENDERTARGET_VIEW;
401 op->view_idx = view_idx;
402 op->view = view;
404 cs->ops->submit(cs);
407 static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const void *data)
409 const struct wined3d_cs_set_depth_stencil_view *op = data;
410 struct wined3d_device *device = cs->device;
411 struct wined3d_rendertarget_view *prev;
413 if ((prev = cs->state.fb->depth_stencil))
415 struct wined3d_surface *prev_surface = wined3d_rendertarget_view_get_surface(prev);
417 if (prev_surface && (device->swapchains[0]->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
418 || prev_surface->flags & SFLAG_DISCARD))
420 surface_modify_ds_location(prev_surface, WINED3D_LOCATION_DISCARDED, prev->width, prev->height);
421 if (prev_surface == device->onscreen_depth_stencil)
423 wined3d_surface_decref(device->onscreen_depth_stencil);
424 device->onscreen_depth_stencil = NULL;
429 cs->fb.depth_stencil = op->view;
431 if (!prev != !op->view)
433 /* Swapping NULL / non NULL depth stencil affects the depth and tests */
434 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_ZENABLE));
435 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILENABLE));
436 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK));
437 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
439 else if (prev && prev->format->depth_size != op->view->format->depth_size)
441 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
444 device_invalidate_state(device, STATE_FRAMEBUFFER);
447 void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view)
449 struct wined3d_cs_set_depth_stencil_view *op;
451 op = cs->ops->require_space(cs, sizeof(*op));
452 op->opcode = WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW;
453 op->view = view;
455 cs->ops->submit(cs);
458 static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data)
460 const struct wined3d_cs_set_vertex_declaration *op = data;
462 cs->state.vertex_declaration = op->declaration;
463 device_invalidate_state(cs->device, STATE_VDECL);
466 void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3d_vertex_declaration *declaration)
468 struct wined3d_cs_set_vertex_declaration *op;
470 op = cs->ops->require_space(cs, sizeof(*op));
471 op->opcode = WINED3D_CS_OP_SET_VERTEX_DECLARATION;
472 op->declaration = declaration;
474 cs->ops->submit(cs);
477 static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data)
479 const struct wined3d_cs_set_stream_source *op = data;
480 struct wined3d_stream_state *stream;
481 struct wined3d_buffer *prev;
483 stream = &cs->state.streams[op->stream_idx];
484 prev = stream->buffer;
485 stream->buffer = op->buffer;
486 stream->offset = op->offset;
487 stream->stride = op->stride;
489 if (op->buffer)
490 InterlockedIncrement(&op->buffer->resource.bind_count);
491 if (prev)
492 InterlockedDecrement(&prev->resource.bind_count);
494 device_invalidate_state(cs->device, STATE_STREAMSRC);
497 void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx,
498 struct wined3d_buffer *buffer, UINT offset, UINT stride)
500 struct wined3d_cs_set_stream_source *op;
502 op = cs->ops->require_space(cs, sizeof(*op));
503 op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE;
504 op->stream_idx = stream_idx;
505 op->buffer = buffer;
506 op->offset = offset;
507 op->stride = stride;
509 cs->ops->submit(cs);
512 static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data)
514 const struct wined3d_cs_set_stream_source_freq *op = data;
515 struct wined3d_stream_state *stream;
517 stream = &cs->state.streams[op->stream_idx];
518 stream->frequency = op->frequency;
519 stream->flags = op->flags;
521 device_invalidate_state(cs->device, STATE_STREAMSRC);
524 void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx, UINT frequency, UINT flags)
526 struct wined3d_cs_set_stream_source_freq *op;
528 op = cs->ops->require_space(cs, sizeof(*op));
529 op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ;
530 op->stream_idx = stream_idx;
531 op->frequency = frequency;
532 op->flags = flags;
534 cs->ops->submit(cs);
537 static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data)
539 const struct wined3d_cs_set_stream_output *op = data;
540 struct wined3d_stream_output *stream;
541 struct wined3d_buffer *prev;
543 stream = &cs->state.stream_output[op->stream_idx];
544 prev = stream->buffer;
545 stream->buffer = op->buffer;
546 stream->offset = op->offset;
548 if (op->buffer)
549 InterlockedIncrement(&op->buffer->resource.bind_count);
550 if (prev)
551 InterlockedDecrement(&prev->resource.bind_count);
554 void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx,
555 struct wined3d_buffer *buffer, UINT offset)
557 struct wined3d_cs_set_stream_output *op;
559 op = cs->ops->require_space(cs, sizeof(*op));
560 op->opcode = WINED3D_CS_OP_SET_STREAM_OUTPUT;
561 op->stream_idx = stream_idx;
562 op->buffer = buffer;
563 op->offset = offset;
565 cs->ops->submit(cs);
568 static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data)
570 const struct wined3d_cs_set_index_buffer *op = data;
571 struct wined3d_buffer *prev;
573 prev = cs->state.index_buffer;
574 cs->state.index_buffer = op->buffer;
575 cs->state.index_format = op->format_id;
577 if (op->buffer)
578 InterlockedIncrement(&op->buffer->resource.bind_count);
579 if (prev)
580 InterlockedDecrement(&prev->resource.bind_count);
582 device_invalidate_state(cs->device, STATE_INDEXBUFFER);
585 void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer,
586 enum wined3d_format_id format_id)
588 struct wined3d_cs_set_index_buffer *op;
590 op = cs->ops->require_space(cs, sizeof(*op));
591 op->opcode = WINED3D_CS_OP_SET_INDEX_BUFFER;
592 op->buffer = buffer;
593 op->format_id = format_id;
595 cs->ops->submit(cs);
598 static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data)
600 const struct wined3d_cs_set_constant_buffer *op = data;
601 struct wined3d_buffer *prev;
603 prev = cs->state.cb[op->type][op->cb_idx];
604 cs->state.cb[op->type][op->cb_idx] = op->buffer;
606 if (op->buffer)
607 InterlockedIncrement(&op->buffer->resource.bind_count);
608 if (prev)
609 InterlockedDecrement(&prev->resource.bind_count);
611 device_invalidate_state(cs->device, STATE_CONSTANT_BUFFER(op->type));
614 void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type,
615 UINT cb_idx, struct wined3d_buffer *buffer)
617 struct wined3d_cs_set_constant_buffer *op;
619 op = cs->ops->require_space(cs, sizeof(*op));
620 op->opcode = WINED3D_CS_OP_SET_CONSTANT_BUFFER;
621 op->type = type;
622 op->cb_idx = cb_idx;
623 op->buffer = buffer;
625 cs->ops->submit(cs);
628 static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data)
630 const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info;
631 const struct wined3d_cs_set_texture *op = data;
632 struct wined3d_texture *prev;
634 prev = cs->state.textures[op->stage];
635 cs->state.textures[op->stage] = op->texture;
637 if (op->texture)
639 const struct wined3d_format *new_format = op->texture->resource.format;
640 const struct wined3d_format *old_format = prev ? prev->resource.format : NULL;
642 if (InterlockedIncrement(&op->texture->resource.bind_count) == 1)
643 op->texture->sampler = op->stage;
645 if (!prev || op->texture->target != prev->target
646 || !is_same_fixup(new_format->color_fixup, old_format->color_fixup)
647 || (new_format->flags & WINED3DFMT_FLAG_SHADOW) != (old_format->flags & WINED3DFMT_FLAG_SHADOW))
648 device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL));
650 if (!prev && op->stage < d3d_info->limits.ffp_blend_stages)
652 /* The source arguments for color and alpha ops have different
653 * meanings when a NULL texture is bound, so the COLOR_OP and
654 * ALPHA_OP have to be dirtified. */
655 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP));
656 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP));
660 if (prev)
662 if (InterlockedDecrement(&prev->resource.bind_count) && prev->sampler == op->stage)
664 unsigned int i;
666 /* Search for other stages the texture is bound to. Shouldn't
667 * happen if applications bind textures to a single stage only. */
668 TRACE("Searching for other stages the texture is bound to.\n");
669 for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
671 if (cs->state.textures[i] == prev)
673 TRACE("Texture is also bound to stage %u.\n", i);
674 prev->sampler = i;
675 break;
680 if (!op->texture && op->stage < d3d_info->limits.ffp_blend_stages)
682 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP));
683 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP));
687 device_invalidate_state(cs->device, STATE_SAMPLER(op->stage));
690 void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined3d_texture *texture)
692 struct wined3d_cs_set_texture *op;
694 op = cs->ops->require_space(cs, sizeof(*op));
695 op->opcode = WINED3D_CS_OP_SET_TEXTURE;
696 op->stage = stage;
697 op->texture = texture;
699 cs->ops->submit(cs);
702 static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data)
704 const struct wined3d_cs_set_shader_resource_view *op = data;
706 cs->state.shader_resource_view[op->type][op->view_idx] = op->view;
709 void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3d_shader_type type,
710 UINT view_idx, struct wined3d_shader_resource_view *view)
712 struct wined3d_cs_set_shader_resource_view *op;
714 op = cs->ops->require_space(cs, sizeof(*op));
715 op->opcode = WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW;
716 op->type = type;
717 op->view_idx = view_idx;
718 op->view = view;
720 cs->ops->submit(cs);
723 static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data)
725 const struct wined3d_cs_set_sampler *op = data;
727 cs->state.sampler[op->type][op->sampler_idx] = op->sampler;
730 void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type type,
731 UINT sampler_idx, struct wined3d_sampler *sampler)
733 struct wined3d_cs_set_sampler *op;
735 op = cs->ops->require_space(cs, sizeof(*op));
736 op->opcode = WINED3D_CS_OP_SET_SAMPLER;
737 op->type = type;
738 op->sampler_idx = sampler_idx;
739 op->sampler = sampler;
741 cs->ops->submit(cs);
744 static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data)
746 const struct wined3d_cs_set_shader *op = data;
748 cs->state.shader[op->type] = op->shader;
749 device_invalidate_state(cs->device, STATE_SHADER(op->type));
752 void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader)
754 struct wined3d_cs_set_shader *op;
756 op = cs->ops->require_space(cs, sizeof(*op));
757 op->opcode = WINED3D_CS_OP_SET_SHADER;
758 op->type = type;
759 op->shader = shader;
761 cs->ops->submit(cs);
764 static void wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data)
766 const struct wined3d_cs_set_render_state *op = data;
768 cs->state.render_states[op->state] = op->value;
769 device_invalidate_state(cs->device, STATE_RENDER(op->state));
772 void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render_state state, DWORD value)
774 struct wined3d_cs_set_render_state *op;
776 op = cs->ops->require_space(cs, sizeof(*op));
777 op->opcode = WINED3D_CS_OP_SET_RENDER_STATE;
778 op->state = state;
779 op->value = value;
781 cs->ops->submit(cs);
784 static void wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data)
786 const struct wined3d_cs_set_texture_state *op = data;
788 cs->state.texture_states[op->stage][op->state] = op->value;
789 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, op->state));
792 void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage,
793 enum wined3d_texture_stage_state state, DWORD value)
795 struct wined3d_cs_set_texture_state *op;
797 op = cs->ops->require_space(cs, sizeof(*op));
798 op->opcode = WINED3D_CS_OP_SET_TEXTURE_STATE;
799 op->stage = stage;
800 op->state = state;
801 op->value = value;
803 cs->ops->submit(cs);
806 static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data)
808 const struct wined3d_cs_set_sampler_state *op = data;
810 cs->state.sampler_states[op->sampler_idx][op->state] = op->value;
811 device_invalidate_state(cs->device, STATE_SAMPLER(op->sampler_idx));
814 void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx,
815 enum wined3d_sampler_state state, DWORD value)
817 struct wined3d_cs_set_sampler_state *op;
819 op = cs->ops->require_space(cs, sizeof(*op));
820 op->opcode = WINED3D_CS_OP_SET_SAMPLER_STATE;
821 op->sampler_idx = sampler_idx;
822 op->state = state;
823 op->value = value;
825 cs->ops->submit(cs);
828 static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data)
830 const struct wined3d_cs_set_transform *op = data;
832 cs->state.transforms[op->state] = *op->matrix;
833 if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->gl_info.limits.blends))
834 device_invalidate_state(cs->device, STATE_TRANSFORM(op->state));
837 void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform_state state,
838 const struct wined3d_matrix *matrix)
840 struct wined3d_cs_set_transform *op;
842 op = cs->ops->require_space(cs, sizeof(*op));
843 op->opcode = WINED3D_CS_OP_SET_TRANSFORM;
844 op->state = state;
845 op->matrix = matrix;
847 cs->ops->submit(cs);
850 static void wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *data)
852 const struct wined3d_cs_set_clip_plane *op = data;
854 cs->state.clip_planes[op->plane_idx] = *op->plane;
855 device_invalidate_state(cs->device, STATE_CLIPPLANE(op->plane_idx));
858 void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const struct wined3d_vec4 *plane)
860 struct wined3d_cs_set_clip_plane *op;
862 op = cs->ops->require_space(cs, sizeof(*op));
863 op->opcode = WINED3D_CS_OP_SET_CLIP_PLANE;
864 op->plane_idx = plane_idx;
865 op->plane = plane;
867 cs->ops->submit(cs);
870 static void wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data)
872 const struct wined3d_cs_set_material *op = data;
874 cs->state.material = *op->material;
875 device_invalidate_state(cs->device, STATE_MATERIAL);
878 void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_material *material)
880 struct wined3d_cs_set_material *op;
882 op = cs->ops->require_space(cs, sizeof(*op));
883 op->opcode = WINED3D_CS_OP_SET_MATERIAL;
884 op->material = material;
886 cs->ops->submit(cs);
889 static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data)
891 struct wined3d_adapter *adapter = cs->device->adapter;
892 HRESULT hr;
894 state_cleanup(&cs->state);
895 memset(&cs->state, 0, sizeof(cs->state));
896 if (FAILED(hr = state_init(&cs->state, &cs->fb, &adapter->gl_info, &adapter->d3d_info,
897 WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT)))
898 ERR("Failed to initialize CS state, hr %#x.\n", hr);
901 void wined3d_cs_emit_reset_state(struct wined3d_cs *cs)
903 struct wined3d_cs_reset_state *op;
905 op = cs->ops->require_space(cs, sizeof(*op));
906 op->opcode = WINED3D_CS_OP_RESET_STATE;
908 cs->ops->submit(cs);
911 static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) =
913 /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present,
914 /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear,
915 /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw,
916 /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication,
917 /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport,
918 /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect,
919 /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view,
920 /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view,
921 /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration,
922 /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source,
923 /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq,
924 /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output,
925 /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer,
926 /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer,
927 /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture,
928 /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view,
929 /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler,
930 /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader,
931 /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state,
932 /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state,
933 /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state,
934 /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform,
935 /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane,
936 /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material,
937 /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state,
940 static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size)
942 if (size > cs->data_size)
944 void *new_data;
946 size = max( size, cs->data_size * 2 );
947 if (!(new_data = HeapReAlloc(GetProcessHeap(), 0, cs->data, size)))
948 return NULL;
950 cs->data_size = size;
951 cs->data = new_data;
954 return cs->data;
957 static void wined3d_cs_st_submit(struct wined3d_cs *cs)
959 enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)cs->data;
961 wined3d_cs_op_handlers[opcode](cs, cs->data);
964 static const struct wined3d_cs_ops wined3d_cs_st_ops =
966 wined3d_cs_st_require_space,
967 wined3d_cs_st_submit,
970 struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
972 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
973 struct wined3d_cs *cs;
975 if (!(cs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cs))))
976 return NULL;
978 if (!(cs->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
979 sizeof(*cs->fb.render_targets) * gl_info->limits.buffers)))
981 HeapFree(GetProcessHeap(), 0, cs);
982 return NULL;
985 if (FAILED(state_init(&cs->state, &cs->fb, gl_info, &device->adapter->d3d_info,
986 WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT)))
988 HeapFree(GetProcessHeap(), 0, cs->fb.render_targets);
989 HeapFree(GetProcessHeap(), 0, cs);
990 return NULL;
993 cs->ops = &wined3d_cs_st_ops;
994 cs->device = device;
996 cs->data_size = WINED3D_INITIAL_CS_SIZE;
997 if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size)))
999 HeapFree(GetProcessHeap(), 0, cs);
1000 return NULL;
1003 return cs;
1006 void wined3d_cs_destroy(struct wined3d_cs *cs)
1008 state_cleanup(&cs->state);
1009 HeapFree(GetProcessHeap(), 0, cs->fb.render_targets);
1010 HeapFree(GetProcessHeap(), 0, cs->data);
1011 HeapFree(GetProcessHeap(), 0, cs);