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
20 #include "wine/port.h"
21 #include "wined3d_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
25 #define WINED3D_INITIAL_CS_SIZE 4096
29 WINED3D_CS_OP_PRESENT
,
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
;
63 const RGNDATA
*dirty_region
;
67 struct wined3d_cs_clear
69 enum wined3d_cs_op opcode
;
73 const struct wined3d_color
*color
;
78 struct wined3d_cs_draw
80 enum wined3d_cs_op opcode
;
88 struct wined3d_cs_set_predication
90 enum wined3d_cs_op opcode
;
91 struct wined3d_query
*predicate
;
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
;
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
;
130 struct wined3d_buffer
*buffer
;
135 struct wined3d_cs_set_stream_source_freq
137 enum wined3d_cs_op opcode
;
143 struct wined3d_cs_set_stream_output
145 enum wined3d_cs_op opcode
;
147 struct wined3d_buffer
*buffer
;
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
;
163 struct wined3d_buffer
*buffer
;
166 struct wined3d_cs_set_texture
168 enum wined3d_cs_op opcode
;
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
;
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
;
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
;
203 struct wined3d_cs_set_texture_state
205 enum wined3d_cs_op opcode
;
207 enum wined3d_texture_stage_state state
;
211 struct wined3d_cs_set_sampler_state
213 enum wined3d_cs_op opcode
;
215 enum wined3d_sampler_state state
;
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
;
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
;
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
;
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
;
299 op
->stencil
= stencil
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
490 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
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
;
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
;
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
;
549 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
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
;
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
;
578 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
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
;
593 op
->format_id
= format_id
;
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
;
607 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
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
;
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
;
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
));
662 if (InterlockedDecrement(&prev
->resource
.bind_count
) && prev
->sampler
== op
->stage
)
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
);
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
;
697 op
->texture
= texture
;
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
;
717 op
->view_idx
= view_idx
;
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
;
738 op
->sampler_idx
= sampler_idx
;
739 op
->sampler
= sampler
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
889 static void wined3d_cs_exec_reset_state(struct wined3d_cs
*cs
, const void *data
)
891 struct wined3d_adapter
*adapter
= cs
->device
->adapter
;
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
;
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
)
946 size
= max( size
, cs
->data_size
* 2 );
947 if (!(new_data
= HeapReAlloc(GetProcessHeap(), 0, cs
->data
, size
)))
950 cs
->data_size
= size
;
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
))))
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
);
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
);
993 cs
->ops
= &wined3d_cs_st_ops
;
996 cs
->data_size
= WINED3D_INITIAL_CS_SIZE
;
997 if (!(cs
->data
= HeapAlloc(GetProcessHeap(), 0, cs
->data_size
)))
999 HeapFree(GetProcessHeap(), 0, 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
);