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
,
31 WINED3D_CS_OP_DISPATCH
,
33 WINED3D_CS_OP_SET_PREDICATION
,
34 WINED3D_CS_OP_SET_VIEWPORT
,
35 WINED3D_CS_OP_SET_SCISSOR_RECT
,
36 WINED3D_CS_OP_SET_RENDERTARGET_VIEW
,
37 WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW
,
38 WINED3D_CS_OP_SET_VERTEX_DECLARATION
,
39 WINED3D_CS_OP_SET_STREAM_SOURCE
,
40 WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ
,
41 WINED3D_CS_OP_SET_STREAM_OUTPUT
,
42 WINED3D_CS_OP_SET_INDEX_BUFFER
,
43 WINED3D_CS_OP_SET_CONSTANT_BUFFER
,
44 WINED3D_CS_OP_SET_TEXTURE
,
45 WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW
,
46 WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW
,
47 WINED3D_CS_OP_SET_SAMPLER
,
48 WINED3D_CS_OP_SET_SHADER
,
49 WINED3D_CS_OP_SET_RASTERIZER_STATE
,
50 WINED3D_CS_OP_SET_RENDER_STATE
,
51 WINED3D_CS_OP_SET_TEXTURE_STATE
,
52 WINED3D_CS_OP_SET_SAMPLER_STATE
,
53 WINED3D_CS_OP_SET_TRANSFORM
,
54 WINED3D_CS_OP_SET_CLIP_PLANE
,
55 WINED3D_CS_OP_SET_COLOR_KEY
,
56 WINED3D_CS_OP_SET_MATERIAL
,
57 WINED3D_CS_OP_RESET_STATE
,
58 WINED3D_CS_OP_DESTROY_OBJECT
,
59 WINED3D_CS_OP_QUERY_ISSUE
,
60 WINED3D_CS_OP_PRELOAD_RESOURCE
,
61 WINED3D_CS_OP_UNLOAD_RESOURCE
,
66 struct wined3d_cs_present
68 enum wined3d_cs_op opcode
;
69 HWND dst_window_override
;
70 struct wined3d_swapchain
*swapchain
;
76 struct wined3d_cs_clear
78 enum wined3d_cs_op opcode
;
80 struct wined3d_color color
;
83 unsigned int rect_count
;
87 struct wined3d_cs_dispatch
89 enum wined3d_cs_op opcode
;
90 unsigned int group_count_x
;
91 unsigned int group_count_y
;
92 unsigned int group_count_z
;
95 struct wined3d_cs_draw
97 enum wined3d_cs_op opcode
;
99 unsigned int start_idx
;
100 unsigned int index_count
;
101 unsigned int start_instance
;
102 unsigned int instance_count
;
106 struct wined3d_cs_set_predication
108 enum wined3d_cs_op opcode
;
109 struct wined3d_query
*predicate
;
113 struct wined3d_cs_set_viewport
115 enum wined3d_cs_op opcode
;
116 struct wined3d_viewport viewport
;
119 struct wined3d_cs_set_scissor_rect
121 enum wined3d_cs_op opcode
;
125 struct wined3d_cs_set_rendertarget_view
127 enum wined3d_cs_op opcode
;
128 unsigned int view_idx
;
129 struct wined3d_rendertarget_view
*view
;
132 struct wined3d_cs_set_depth_stencil_view
134 enum wined3d_cs_op opcode
;
135 struct wined3d_rendertarget_view
*view
;
138 struct wined3d_cs_set_vertex_declaration
140 enum wined3d_cs_op opcode
;
141 struct wined3d_vertex_declaration
*declaration
;
144 struct wined3d_cs_set_stream_source
146 enum wined3d_cs_op opcode
;
148 struct wined3d_buffer
*buffer
;
153 struct wined3d_cs_set_stream_source_freq
155 enum wined3d_cs_op opcode
;
161 struct wined3d_cs_set_stream_output
163 enum wined3d_cs_op opcode
;
165 struct wined3d_buffer
*buffer
;
169 struct wined3d_cs_set_index_buffer
171 enum wined3d_cs_op opcode
;
172 struct wined3d_buffer
*buffer
;
173 enum wined3d_format_id format_id
;
177 struct wined3d_cs_set_constant_buffer
179 enum wined3d_cs_op opcode
;
180 enum wined3d_shader_type type
;
182 struct wined3d_buffer
*buffer
;
185 struct wined3d_cs_set_texture
187 enum wined3d_cs_op opcode
;
189 struct wined3d_texture
*texture
;
192 struct wined3d_cs_set_color_key
194 enum wined3d_cs_op opcode
;
195 struct wined3d_texture
*texture
;
198 struct wined3d_color_key color_key
;
201 struct wined3d_cs_set_shader_resource_view
203 enum wined3d_cs_op opcode
;
204 enum wined3d_shader_type type
;
206 struct wined3d_shader_resource_view
*view
;
209 struct wined3d_cs_set_unordered_access_view
211 enum wined3d_cs_op opcode
;
212 enum wined3d_pipeline pipeline
;
213 unsigned int view_idx
;
214 struct wined3d_unordered_access_view
*view
;
217 struct wined3d_cs_set_sampler
219 enum wined3d_cs_op opcode
;
220 enum wined3d_shader_type type
;
222 struct wined3d_sampler
*sampler
;
225 struct wined3d_cs_set_shader
227 enum wined3d_cs_op opcode
;
228 enum wined3d_shader_type type
;
229 struct wined3d_shader
*shader
;
232 struct wined3d_cs_set_rasterizer_state
234 enum wined3d_cs_op opcode
;
235 struct wined3d_rasterizer_state
*state
;
238 struct wined3d_cs_set_render_state
240 enum wined3d_cs_op opcode
;
241 enum wined3d_render_state state
;
245 struct wined3d_cs_set_texture_state
247 enum wined3d_cs_op opcode
;
249 enum wined3d_texture_stage_state state
;
253 struct wined3d_cs_set_sampler_state
255 enum wined3d_cs_op opcode
;
257 enum wined3d_sampler_state state
;
261 struct wined3d_cs_set_transform
263 enum wined3d_cs_op opcode
;
264 enum wined3d_transform_state state
;
265 struct wined3d_matrix matrix
;
268 struct wined3d_cs_set_clip_plane
270 enum wined3d_cs_op opcode
;
272 struct wined3d_vec4 plane
;
275 struct wined3d_cs_set_material
277 enum wined3d_cs_op opcode
;
278 struct wined3d_material material
;
281 struct wined3d_cs_reset_state
283 enum wined3d_cs_op opcode
;
286 struct wined3d_cs_destroy_object
288 enum wined3d_cs_op opcode
;
289 void (*callback
)(void *object
);
293 struct wined3d_cs_query_issue
295 enum wined3d_cs_op opcode
;
296 struct wined3d_query
*query
;
300 struct wined3d_cs_preload_resource
302 enum wined3d_cs_op opcode
;
303 struct wined3d_resource
*resource
;
306 struct wined3d_cs_unload_resource
308 enum wined3d_cs_op opcode
;
309 struct wined3d_resource
*resource
;
312 struct wined3d_cs_map
314 enum wined3d_cs_op opcode
;
315 struct wined3d_resource
*resource
;
316 unsigned int sub_resource_idx
;
317 struct wined3d_map_desc
*map_desc
;
318 const struct wined3d_box
*box
;
323 struct wined3d_cs_unmap
325 enum wined3d_cs_op opcode
;
326 struct wined3d_resource
*resource
;
327 unsigned int sub_resource_idx
;
331 static void wined3d_cs_exec_present(struct wined3d_cs
*cs
, const void *data
)
333 const struct wined3d_cs_present
*op
= data
;
334 struct wined3d_swapchain
*swapchain
;
337 swapchain
= op
->swapchain
;
338 wined3d_swapchain_set_window(swapchain
, op
->dst_window_override
);
340 swapchain
->swapchain_ops
->swapchain_present(swapchain
, &op
->src_rect
, &op
->dst_rect
, op
->flags
);
342 wined3d_resource_release(&swapchain
->front_buffer
->resource
);
343 for (i
= 0; i
< swapchain
->desc
.backbuffer_count
; ++i
)
345 wined3d_resource_release(&swapchain
->back_buffers
[i
]->resource
);
349 void wined3d_cs_emit_present(struct wined3d_cs
*cs
, struct wined3d_swapchain
*swapchain
,
350 const RECT
*src_rect
, const RECT
*dst_rect
, HWND dst_window_override
, DWORD flags
)
352 struct wined3d_cs_present
*op
;
355 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
356 op
->opcode
= WINED3D_CS_OP_PRESENT
;
357 op
->dst_window_override
= dst_window_override
;
358 op
->swapchain
= swapchain
;
359 op
->src_rect
= *src_rect
;
360 op
->dst_rect
= *dst_rect
;
363 wined3d_resource_acquire(&swapchain
->front_buffer
->resource
);
364 for (i
= 0; i
< swapchain
->desc
.backbuffer_count
; ++i
)
366 wined3d_resource_acquire(&swapchain
->back_buffers
[i
]->resource
);
372 static void wined3d_cs_exec_clear(struct wined3d_cs
*cs
, const void *data
)
374 const struct wined3d_cs_clear
*op
= data
;
375 const struct wined3d_state
*state
;
376 struct wined3d_device
*device
;
381 state
= &device
->state
;
382 wined3d_get_draw_rect(state
, &draw_rect
);
383 device_clear_render_targets(device
, device
->adapter
->gl_info
.limits
.buffers
,
384 &device
->fb
, op
->rect_count
, op
->rects
, &draw_rect
, op
->flags
,
385 &op
->color
, op
->depth
, op
->stencil
);
387 if (op
->flags
& WINED3DCLEAR_TARGET
)
389 for (i
= 0; i
< device
->adapter
->gl_info
.limits
.buffers
; ++i
)
391 if (state
->fb
->render_targets
[i
])
392 wined3d_resource_release(state
->fb
->render_targets
[i
]->resource
);
395 if (op
->flags
& (WINED3DCLEAR_ZBUFFER
| WINED3DCLEAR_STENCIL
))
396 wined3d_resource_release(state
->fb
->depth_stencil
->resource
);
399 void wined3d_cs_emit_clear(struct wined3d_cs
*cs
, DWORD rect_count
, const RECT
*rects
,
400 DWORD flags
, const struct wined3d_color
*color
, float depth
, DWORD stencil
)
402 const struct wined3d_state
*state
= &cs
->device
->state
;
403 struct wined3d_cs_clear
*op
;
406 op
= cs
->ops
->require_space(cs
, FIELD_OFFSET(struct wined3d_cs_clear
, rects
[rect_count
]));
407 op
->opcode
= WINED3D_CS_OP_CLEAR
;
411 op
->stencil
= stencil
;
412 op
->rect_count
= rect_count
;
413 memcpy(op
->rects
, rects
, sizeof(*rects
) * rect_count
);
415 if (flags
& WINED3DCLEAR_TARGET
)
417 for (i
= 0; i
< cs
->device
->adapter
->gl_info
.limits
.buffers
; ++i
)
419 if (state
->fb
->render_targets
[i
])
420 wined3d_resource_acquire(state
->fb
->render_targets
[i
]->resource
);
423 if (flags
& (WINED3DCLEAR_ZBUFFER
| WINED3DCLEAR_STENCIL
))
424 wined3d_resource_acquire(state
->fb
->depth_stencil
->resource
);
429 static void acquire_shader_resources(const struct wined3d_state
*state
, unsigned int shader_mask
)
431 struct wined3d_shader_sampler_map_entry
*entry
;
432 struct wined3d_shader_resource_view
*view
;
433 struct wined3d_shader
*shader
;
436 for (i
= 0; i
< WINED3D_SHADER_TYPE_COUNT
; ++i
)
438 if (!(shader_mask
& (1u << i
)))
441 if (!(shader
= state
->shader
[i
]))
444 for (j
= 0; j
< WINED3D_MAX_CBS
; ++j
)
447 wined3d_resource_acquire(&state
->cb
[i
][j
]->resource
);
450 for (j
= 0; j
< shader
->reg_maps
.sampler_map
.count
; ++j
)
452 entry
= &shader
->reg_maps
.sampler_map
.entries
[j
];
454 if (!(view
= state
->shader_resource_view
[i
][entry
->resource_idx
]))
457 wined3d_resource_acquire(view
->resource
);
462 static void release_shader_resources(const struct wined3d_state
*state
, unsigned int shader_mask
)
464 struct wined3d_shader_sampler_map_entry
*entry
;
465 struct wined3d_shader_resource_view
*view
;
466 struct wined3d_shader
*shader
;
469 for (i
= 0; i
< WINED3D_SHADER_TYPE_COUNT
; ++i
)
471 if (!(shader_mask
& (1u << i
)))
474 if (!(shader
= state
->shader
[i
]))
477 for (j
= 0; j
< WINED3D_MAX_CBS
; ++j
)
480 wined3d_resource_release(&state
->cb
[i
][j
]->resource
);
483 for (j
= 0; j
< shader
->reg_maps
.sampler_map
.count
; ++j
)
485 entry
= &shader
->reg_maps
.sampler_map
.entries
[j
];
487 if (!(view
= state
->shader_resource_view
[i
][entry
->resource_idx
]))
490 wined3d_resource_release(view
->resource
);
495 static void acquire_unordered_access_resources(const struct wined3d_shader
*shader
,
496 struct wined3d_unordered_access_view
* const *views
)
503 for (i
= 0; i
< MAX_UNORDERED_ACCESS_VIEWS
; ++i
)
505 if (!shader
->reg_maps
.uav_resource_info
[i
].type
)
511 wined3d_resource_acquire(views
[i
]->resource
);
515 static void release_unordered_access_resources(const struct wined3d_shader
*shader
,
516 struct wined3d_unordered_access_view
* const *views
)
523 for (i
= 0; i
< MAX_UNORDERED_ACCESS_VIEWS
; ++i
)
525 if (!shader
->reg_maps
.uav_resource_info
[i
].type
)
531 wined3d_resource_release(views
[i
]->resource
);
535 static void wined3d_cs_exec_dispatch(struct wined3d_cs
*cs
, const void *data
)
537 struct wined3d_state
*state
= &cs
->device
->state
;
538 const struct wined3d_cs_dispatch
*op
= data
;
540 dispatch_compute(cs
->device
, state
,
541 op
->group_count_x
, op
->group_count_y
, op
->group_count_z
);
543 release_shader_resources(state
, 1u << WINED3D_SHADER_TYPE_COMPUTE
);
544 release_unordered_access_resources(state
->shader
[WINED3D_SHADER_TYPE_COMPUTE
],
545 state
->unordered_access_view
[WINED3D_PIPELINE_COMPUTE
]);
548 void wined3d_cs_emit_dispatch(struct wined3d_cs
*cs
,
549 unsigned int group_count_x
, unsigned int group_count_y
, unsigned int group_count_z
)
551 const struct wined3d_state
*state
= &cs
->device
->state
;
552 struct wined3d_cs_dispatch
*op
;
554 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
555 op
->opcode
= WINED3D_CS_OP_DISPATCH
;
556 op
->group_count_x
= group_count_x
;
557 op
->group_count_y
= group_count_y
;
558 op
->group_count_z
= group_count_z
;
560 acquire_shader_resources(state
, 1u << WINED3D_SHADER_TYPE_COMPUTE
);
561 acquire_unordered_access_resources(state
->shader
[WINED3D_SHADER_TYPE_COMPUTE
],
562 state
->unordered_access_view
[WINED3D_PIPELINE_COMPUTE
]);
567 static void wined3d_cs_exec_draw(struct wined3d_cs
*cs
, const void *data
)
569 struct wined3d_state
*state
= &cs
->device
->state
;
570 const struct wined3d_cs_draw
*op
= data
;
573 if (!cs
->device
->adapter
->gl_info
.supported
[ARB_DRAW_ELEMENTS_BASE_VERTEX
]
574 && state
->load_base_vertex_index
!= op
->base_vertex_idx
)
576 state
->load_base_vertex_index
= op
->base_vertex_idx
;
577 device_invalidate_state(cs
->device
, STATE_BASEVERTEXINDEX
);
580 draw_primitive(cs
->device
, state
, op
->base_vertex_idx
, op
->start_idx
,
581 op
->index_count
, op
->start_instance
, op
->instance_count
, op
->indexed
);
584 wined3d_resource_release(&state
->index_buffer
->resource
);
585 for (i
= 0; i
< ARRAY_SIZE(state
->streams
); ++i
)
587 if (state
->streams
[i
].buffer
)
588 wined3d_resource_release(&state
->streams
[i
].buffer
->resource
);
590 for (i
= 0; i
< ARRAY_SIZE(state
->textures
); ++i
)
592 if (state
->textures
[i
])
593 wined3d_resource_release(&state
->textures
[i
]->resource
);
595 for (i
= 0; i
< cs
->device
->adapter
->gl_info
.limits
.buffers
; ++i
)
597 if (state
->fb
->render_targets
[i
])
598 wined3d_resource_release(state
->fb
->render_targets
[i
]->resource
);
600 if (state
->fb
->depth_stencil
)
601 wined3d_resource_release(state
->fb
->depth_stencil
->resource
);
602 release_shader_resources(state
, ~(1u << WINED3D_SHADER_TYPE_COMPUTE
));
603 release_unordered_access_resources(state
->shader
[WINED3D_SHADER_TYPE_PIXEL
],
604 state
->unordered_access_view
[WINED3D_PIPELINE_GRAPHICS
]);
607 void wined3d_cs_emit_draw(struct wined3d_cs
*cs
, int base_vertex_idx
, unsigned int start_idx
,
608 unsigned int index_count
, unsigned int start_instance
, unsigned int instance_count
, BOOL indexed
)
610 const struct wined3d_state
*state
= &cs
->device
->state
;
611 struct wined3d_cs_draw
*op
;
614 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
615 op
->opcode
= WINED3D_CS_OP_DRAW
;
616 op
->base_vertex_idx
= base_vertex_idx
;
617 op
->start_idx
= start_idx
;
618 op
->index_count
= index_count
;
619 op
->start_instance
= start_instance
;
620 op
->instance_count
= instance_count
;
621 op
->indexed
= indexed
;
624 wined3d_resource_acquire(&state
->index_buffer
->resource
);
625 for (i
= 0; i
< ARRAY_SIZE(state
->streams
); ++i
)
627 if (state
->streams
[i
].buffer
)
628 wined3d_resource_acquire(&state
->streams
[i
].buffer
->resource
);
630 for (i
= 0; i
< ARRAY_SIZE(state
->textures
); ++i
)
632 if (state
->textures
[i
])
633 wined3d_resource_acquire(&state
->textures
[i
]->resource
);
635 for (i
= 0; i
< cs
->device
->adapter
->gl_info
.limits
.buffers
; ++i
)
637 if (state
->fb
->render_targets
[i
])
638 wined3d_resource_acquire(state
->fb
->render_targets
[i
]->resource
);
640 if (state
->fb
->depth_stencil
)
641 wined3d_resource_acquire(state
->fb
->depth_stencil
->resource
);
642 acquire_shader_resources(state
, ~(1u << WINED3D_SHADER_TYPE_COMPUTE
));
643 acquire_unordered_access_resources(state
->shader
[WINED3D_SHADER_TYPE_PIXEL
],
644 state
->unordered_access_view
[WINED3D_PIPELINE_GRAPHICS
]);
649 static void wined3d_cs_exec_set_predication(struct wined3d_cs
*cs
, const void *data
)
651 const struct wined3d_cs_set_predication
*op
= data
;
653 cs
->state
.predicate
= op
->predicate
;
654 cs
->state
.predicate_value
= op
->value
;
657 void wined3d_cs_emit_set_predication(struct wined3d_cs
*cs
, struct wined3d_query
*predicate
, BOOL value
)
659 struct wined3d_cs_set_predication
*op
;
661 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
662 op
->opcode
= WINED3D_CS_OP_SET_PREDICATION
;
663 op
->predicate
= predicate
;
669 static void wined3d_cs_exec_set_viewport(struct wined3d_cs
*cs
, const void *data
)
671 const struct wined3d_cs_set_viewport
*op
= data
;
673 cs
->state
.viewport
= op
->viewport
;
674 device_invalidate_state(cs
->device
, STATE_VIEWPORT
);
677 void wined3d_cs_emit_set_viewport(struct wined3d_cs
*cs
, const struct wined3d_viewport
*viewport
)
679 struct wined3d_cs_set_viewport
*op
;
681 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
682 op
->opcode
= WINED3D_CS_OP_SET_VIEWPORT
;
683 op
->viewport
= *viewport
;
688 static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs
*cs
, const void *data
)
690 const struct wined3d_cs_set_scissor_rect
*op
= data
;
692 cs
->state
.scissor_rect
= op
->rect
;
693 device_invalidate_state(cs
->device
, STATE_SCISSORRECT
);
696 void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs
*cs
, const RECT
*rect
)
698 struct wined3d_cs_set_scissor_rect
*op
;
700 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
701 op
->opcode
= WINED3D_CS_OP_SET_SCISSOR_RECT
;
707 static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs
*cs
, const void *data
)
709 const struct wined3d_cs_set_rendertarget_view
*op
= data
;
711 cs
->state
.fb
->render_targets
[op
->view_idx
] = op
->view
;
712 device_invalidate_state(cs
->device
, STATE_FRAMEBUFFER
);
715 void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs
*cs
, unsigned int view_idx
,
716 struct wined3d_rendertarget_view
*view
)
718 struct wined3d_cs_set_rendertarget_view
*op
;
720 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
721 op
->opcode
= WINED3D_CS_OP_SET_RENDERTARGET_VIEW
;
722 op
->view_idx
= view_idx
;
728 static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs
*cs
, const void *data
)
730 const struct wined3d_cs_set_depth_stencil_view
*op
= data
;
731 struct wined3d_device
*device
= cs
->device
;
732 struct wined3d_rendertarget_view
*prev
;
734 if ((prev
= cs
->state
.fb
->depth_stencil
))
736 struct wined3d_surface
*prev_surface
= wined3d_rendertarget_view_get_surface(prev
);
738 if (prev_surface
&& (device
->swapchains
[0]->desc
.flags
& WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL
739 || prev_surface
->container
->flags
& WINED3D_TEXTURE_DISCARD
))
741 wined3d_texture_validate_location(prev_surface
->container
,
742 prev
->sub_resource_idx
, WINED3D_LOCATION_DISCARDED
);
746 cs
->fb
.depth_stencil
= op
->view
;
748 if (!prev
!= !op
->view
)
750 /* Swapping NULL / non NULL depth stencil affects the depth and tests */
751 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_ZENABLE
));
752 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_STENCILENABLE
));
753 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK
));
754 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_DEPTHBIAS
));
756 else if (prev
&& (prev
->format_flags
& WINED3DFMT_FLAG_FLOAT
)
757 != (op
->view
->format_flags
& WINED3DFMT_FLAG_FLOAT
))
759 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_DEPTHBIAS
));
762 device_invalidate_state(device
, STATE_FRAMEBUFFER
);
765 void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs
*cs
, struct wined3d_rendertarget_view
*view
)
767 struct wined3d_cs_set_depth_stencil_view
*op
;
769 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
770 op
->opcode
= WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW
;
776 static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs
*cs
, const void *data
)
778 const struct wined3d_cs_set_vertex_declaration
*op
= data
;
780 cs
->state
.vertex_declaration
= op
->declaration
;
781 device_invalidate_state(cs
->device
, STATE_VDECL
);
784 void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs
*cs
, struct wined3d_vertex_declaration
*declaration
)
786 struct wined3d_cs_set_vertex_declaration
*op
;
788 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
789 op
->opcode
= WINED3D_CS_OP_SET_VERTEX_DECLARATION
;
790 op
->declaration
= declaration
;
795 static void wined3d_cs_exec_set_stream_source(struct wined3d_cs
*cs
, const void *data
)
797 const struct wined3d_cs_set_stream_source
*op
= data
;
798 struct wined3d_stream_state
*stream
;
799 struct wined3d_buffer
*prev
;
801 stream
= &cs
->state
.streams
[op
->stream_idx
];
802 prev
= stream
->buffer
;
803 stream
->buffer
= op
->buffer
;
804 stream
->offset
= op
->offset
;
805 stream
->stride
= op
->stride
;
808 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
810 InterlockedDecrement(&prev
->resource
.bind_count
);
812 device_invalidate_state(cs
->device
, STATE_STREAMSRC
);
815 void wined3d_cs_emit_set_stream_source(struct wined3d_cs
*cs
, UINT stream_idx
,
816 struct wined3d_buffer
*buffer
, UINT offset
, UINT stride
)
818 struct wined3d_cs_set_stream_source
*op
;
820 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
821 op
->opcode
= WINED3D_CS_OP_SET_STREAM_SOURCE
;
822 op
->stream_idx
= stream_idx
;
830 static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs
*cs
, const void *data
)
832 const struct wined3d_cs_set_stream_source_freq
*op
= data
;
833 struct wined3d_stream_state
*stream
;
835 stream
= &cs
->state
.streams
[op
->stream_idx
];
836 stream
->frequency
= op
->frequency
;
837 stream
->flags
= op
->flags
;
839 device_invalidate_state(cs
->device
, STATE_STREAMSRC
);
842 void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs
*cs
, UINT stream_idx
, UINT frequency
, UINT flags
)
844 struct wined3d_cs_set_stream_source_freq
*op
;
846 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
847 op
->opcode
= WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ
;
848 op
->stream_idx
= stream_idx
;
849 op
->frequency
= frequency
;
855 static void wined3d_cs_exec_set_stream_output(struct wined3d_cs
*cs
, const void *data
)
857 const struct wined3d_cs_set_stream_output
*op
= data
;
858 struct wined3d_stream_output
*stream
;
859 struct wined3d_buffer
*prev
;
861 stream
= &cs
->state
.stream_output
[op
->stream_idx
];
862 prev
= stream
->buffer
;
863 stream
->buffer
= op
->buffer
;
864 stream
->offset
= op
->offset
;
867 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
869 InterlockedDecrement(&prev
->resource
.bind_count
);
872 void wined3d_cs_emit_set_stream_output(struct wined3d_cs
*cs
, UINT stream_idx
,
873 struct wined3d_buffer
*buffer
, UINT offset
)
875 struct wined3d_cs_set_stream_output
*op
;
877 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
878 op
->opcode
= WINED3D_CS_OP_SET_STREAM_OUTPUT
;
879 op
->stream_idx
= stream_idx
;
886 static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs
*cs
, const void *data
)
888 const struct wined3d_cs_set_index_buffer
*op
= data
;
889 struct wined3d_buffer
*prev
;
891 prev
= cs
->state
.index_buffer
;
892 cs
->state
.index_buffer
= op
->buffer
;
893 cs
->state
.index_format
= op
->format_id
;
894 cs
->state
.index_offset
= op
->offset
;
897 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
899 InterlockedDecrement(&prev
->resource
.bind_count
);
901 device_invalidate_state(cs
->device
, STATE_INDEXBUFFER
);
904 void wined3d_cs_emit_set_index_buffer(struct wined3d_cs
*cs
, struct wined3d_buffer
*buffer
,
905 enum wined3d_format_id format_id
, unsigned int offset
)
907 struct wined3d_cs_set_index_buffer
*op
;
909 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
910 op
->opcode
= WINED3D_CS_OP_SET_INDEX_BUFFER
;
912 op
->format_id
= format_id
;
918 static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs
*cs
, const void *data
)
920 const struct wined3d_cs_set_constant_buffer
*op
= data
;
921 struct wined3d_buffer
*prev
;
923 prev
= cs
->state
.cb
[op
->type
][op
->cb_idx
];
924 cs
->state
.cb
[op
->type
][op
->cb_idx
] = op
->buffer
;
927 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
929 InterlockedDecrement(&prev
->resource
.bind_count
);
931 device_invalidate_state(cs
->device
, STATE_CONSTANT_BUFFER(op
->type
));
934 void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs
*cs
, enum wined3d_shader_type type
,
935 UINT cb_idx
, struct wined3d_buffer
*buffer
)
937 struct wined3d_cs_set_constant_buffer
*op
;
939 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
940 op
->opcode
= WINED3D_CS_OP_SET_CONSTANT_BUFFER
;
948 static void wined3d_cs_exec_set_texture(struct wined3d_cs
*cs
, const void *data
)
950 const struct wined3d_gl_info
*gl_info
= &cs
->device
->adapter
->gl_info
;
951 const struct wined3d_d3d_info
*d3d_info
= &cs
->device
->adapter
->d3d_info
;
952 const struct wined3d_cs_set_texture
*op
= data
;
953 struct wined3d_texture
*prev
;
954 BOOL old_use_color_key
= FALSE
, new_use_color_key
= FALSE
;
956 prev
= cs
->state
.textures
[op
->stage
];
957 cs
->state
.textures
[op
->stage
] = op
->texture
;
961 const struct wined3d_format
*new_format
= op
->texture
->resource
.format
;
962 const struct wined3d_format
*old_format
= prev
? prev
->resource
.format
: NULL
;
963 unsigned int old_fmt_flags
= prev
? prev
->resource
.format_flags
: 0;
964 unsigned int new_fmt_flags
= op
->texture
->resource
.format_flags
;
966 if (InterlockedIncrement(&op
->texture
->resource
.bind_count
) == 1)
967 op
->texture
->sampler
= op
->stage
;
969 if (!prev
|| op
->texture
->target
!= prev
->target
970 || (!is_same_fixup(new_format
->color_fixup
, old_format
->color_fixup
)
971 && !(can_use_texture_swizzle(gl_info
, new_format
) && can_use_texture_swizzle(gl_info
, old_format
)))
972 || (new_fmt_flags
& WINED3DFMT_FLAG_SHADOW
) != (old_fmt_flags
& WINED3DFMT_FLAG_SHADOW
))
973 device_invalidate_state(cs
->device
, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL
));
975 if (!prev
&& op
->stage
< d3d_info
->limits
.ffp_blend_stages
)
977 /* The source arguments for color and alpha ops have different
978 * meanings when a NULL texture is bound, so the COLOR_OP and
979 * ALPHA_OP have to be dirtified. */
980 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_COLOR_OP
));
981 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_ALPHA_OP
));
984 if (!op
->stage
&& op
->texture
->async
.color_key_flags
& WINED3D_CKEY_SRC_BLT
)
985 new_use_color_key
= TRUE
;
990 if (InterlockedDecrement(&prev
->resource
.bind_count
) && prev
->sampler
== op
->stage
)
994 /* Search for other stages the texture is bound to. Shouldn't
995 * happen if applications bind textures to a single stage only. */
996 TRACE("Searching for other stages the texture is bound to.\n");
997 for (i
= 0; i
< MAX_COMBINED_SAMPLERS
; ++i
)
999 if (cs
->state
.textures
[i
] == prev
)
1001 TRACE("Texture is also bound to stage %u.\n", i
);
1008 if (!op
->texture
&& op
->stage
< d3d_info
->limits
.ffp_blend_stages
)
1010 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_COLOR_OP
));
1011 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_ALPHA_OP
));
1014 if (!op
->stage
&& prev
->async
.color_key_flags
& WINED3D_CKEY_SRC_BLT
)
1015 old_use_color_key
= TRUE
;
1018 device_invalidate_state(cs
->device
, STATE_SAMPLER(op
->stage
));
1020 if (new_use_color_key
!= old_use_color_key
)
1021 device_invalidate_state(cs
->device
, STATE_RENDER(WINED3D_RS_COLORKEYENABLE
));
1023 if (new_use_color_key
)
1024 device_invalidate_state(cs
->device
, STATE_COLOR_KEY
);
1027 void wined3d_cs_emit_set_texture(struct wined3d_cs
*cs
, UINT stage
, struct wined3d_texture
*texture
)
1029 struct wined3d_cs_set_texture
*op
;
1031 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1032 op
->opcode
= WINED3D_CS_OP_SET_TEXTURE
;
1034 op
->texture
= texture
;
1036 cs
->ops
->submit(cs
);
1039 static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs
*cs
, const void *data
)
1041 const struct wined3d_cs_set_shader_resource_view
*op
= data
;
1042 struct wined3d_shader_resource_view
*prev
;
1044 prev
= cs
->state
.shader_resource_view
[op
->type
][op
->view_idx
];
1045 cs
->state
.shader_resource_view
[op
->type
][op
->view_idx
] = op
->view
;
1048 InterlockedIncrement(&op
->view
->resource
->bind_count
);
1050 InterlockedDecrement(&prev
->resource
->bind_count
);
1052 if (op
->type
!= WINED3D_SHADER_TYPE_COMPUTE
)
1053 device_invalidate_state(cs
->device
, STATE_SHADER_RESOURCE_BINDING
);
1056 void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs
*cs
, enum wined3d_shader_type type
,
1057 UINT view_idx
, struct wined3d_shader_resource_view
*view
)
1059 struct wined3d_cs_set_shader_resource_view
*op
;
1061 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1062 op
->opcode
= WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW
;
1064 op
->view_idx
= view_idx
;
1067 cs
->ops
->submit(cs
);
1070 static void wined3d_cs_exec_set_unordered_access_view(struct wined3d_cs
*cs
, const void *data
)
1072 const struct wined3d_cs_set_unordered_access_view
*op
= data
;
1073 struct wined3d_unordered_access_view
*prev
;
1075 prev
= cs
->state
.unordered_access_view
[op
->pipeline
][op
->view_idx
];
1076 cs
->state
.unordered_access_view
[op
->pipeline
][op
->view_idx
] = op
->view
;
1079 InterlockedIncrement(&op
->view
->resource
->bind_count
);
1081 InterlockedDecrement(&prev
->resource
->bind_count
);
1083 device_invalidate_state(cs
->device
, STATE_UNORDERED_ACCESS_VIEW_BINDING(op
->pipeline
));
1086 void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs
*cs
, enum wined3d_pipeline pipeline
,
1087 unsigned int view_idx
, struct wined3d_unordered_access_view
*view
)
1089 struct wined3d_cs_set_unordered_access_view
*op
;
1091 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1092 op
->opcode
= WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW
;
1093 op
->pipeline
= pipeline
;
1094 op
->view_idx
= view_idx
;
1097 cs
->ops
->submit(cs
);
1100 static void wined3d_cs_exec_set_sampler(struct wined3d_cs
*cs
, const void *data
)
1102 const struct wined3d_cs_set_sampler
*op
= data
;
1104 cs
->state
.sampler
[op
->type
][op
->sampler_idx
] = op
->sampler
;
1105 device_invalidate_state(cs
->device
, STATE_SHADER_RESOURCE_BINDING
);
1108 void wined3d_cs_emit_set_sampler(struct wined3d_cs
*cs
, enum wined3d_shader_type type
,
1109 UINT sampler_idx
, struct wined3d_sampler
*sampler
)
1111 struct wined3d_cs_set_sampler
*op
;
1113 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1114 op
->opcode
= WINED3D_CS_OP_SET_SAMPLER
;
1116 op
->sampler_idx
= sampler_idx
;
1117 op
->sampler
= sampler
;
1119 cs
->ops
->submit(cs
);
1122 static void wined3d_cs_exec_set_shader(struct wined3d_cs
*cs
, const void *data
)
1124 const struct wined3d_cs_set_shader
*op
= data
;
1126 cs
->state
.shader
[op
->type
] = op
->shader
;
1127 device_invalidate_state(cs
->device
, STATE_SHADER(op
->type
));
1128 if (op
->type
!= WINED3D_SHADER_TYPE_COMPUTE
)
1129 device_invalidate_state(cs
->device
, STATE_SHADER_RESOURCE_BINDING
);
1132 void wined3d_cs_emit_set_shader(struct wined3d_cs
*cs
, enum wined3d_shader_type type
, struct wined3d_shader
*shader
)
1134 struct wined3d_cs_set_shader
*op
;
1136 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1137 op
->opcode
= WINED3D_CS_OP_SET_SHADER
;
1139 op
->shader
= shader
;
1141 cs
->ops
->submit(cs
);
1144 static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs
*cs
, const void *data
)
1146 const struct wined3d_cs_set_rasterizer_state
*op
= data
;
1148 cs
->state
.rasterizer_state
= op
->state
;
1149 device_invalidate_state(cs
->device
, STATE_FRONTFACE
);
1152 void wined3d_cs_emit_set_rasterizer_state(struct wined3d_cs
*cs
,
1153 struct wined3d_rasterizer_state
*rasterizer_state
)
1155 struct wined3d_cs_set_rasterizer_state
*op
;
1157 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1158 op
->opcode
= WINED3D_CS_OP_SET_RASTERIZER_STATE
;
1159 op
->state
= rasterizer_state
;
1161 cs
->ops
->submit(cs
);
1164 static void wined3d_cs_exec_set_render_state(struct wined3d_cs
*cs
, const void *data
)
1166 const struct wined3d_cs_set_render_state
*op
= data
;
1168 cs
->state
.render_states
[op
->state
] = op
->value
;
1169 device_invalidate_state(cs
->device
, STATE_RENDER(op
->state
));
1172 void wined3d_cs_emit_set_render_state(struct wined3d_cs
*cs
, enum wined3d_render_state state
, DWORD value
)
1174 struct wined3d_cs_set_render_state
*op
;
1176 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1177 op
->opcode
= WINED3D_CS_OP_SET_RENDER_STATE
;
1181 cs
->ops
->submit(cs
);
1184 static void wined3d_cs_exec_set_texture_state(struct wined3d_cs
*cs
, const void *data
)
1186 const struct wined3d_cs_set_texture_state
*op
= data
;
1188 cs
->state
.texture_states
[op
->stage
][op
->state
] = op
->value
;
1189 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, op
->state
));
1192 void wined3d_cs_emit_set_texture_state(struct wined3d_cs
*cs
, UINT stage
,
1193 enum wined3d_texture_stage_state state
, DWORD value
)
1195 struct wined3d_cs_set_texture_state
*op
;
1197 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1198 op
->opcode
= WINED3D_CS_OP_SET_TEXTURE_STATE
;
1203 cs
->ops
->submit(cs
);
1206 static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs
*cs
, const void *data
)
1208 const struct wined3d_cs_set_sampler_state
*op
= data
;
1210 cs
->state
.sampler_states
[op
->sampler_idx
][op
->state
] = op
->value
;
1211 device_invalidate_state(cs
->device
, STATE_SAMPLER(op
->sampler_idx
));
1214 void wined3d_cs_emit_set_sampler_state(struct wined3d_cs
*cs
, UINT sampler_idx
,
1215 enum wined3d_sampler_state state
, DWORD value
)
1217 struct wined3d_cs_set_sampler_state
*op
;
1219 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1220 op
->opcode
= WINED3D_CS_OP_SET_SAMPLER_STATE
;
1221 op
->sampler_idx
= sampler_idx
;
1225 cs
->ops
->submit(cs
);
1228 static void wined3d_cs_exec_set_transform(struct wined3d_cs
*cs
, const void *data
)
1230 const struct wined3d_cs_set_transform
*op
= data
;
1232 cs
->state
.transforms
[op
->state
] = op
->matrix
;
1233 if (op
->state
< WINED3D_TS_WORLD_MATRIX(cs
->device
->adapter
->d3d_info
.limits
.ffp_vertex_blend_matrices
))
1234 device_invalidate_state(cs
->device
, STATE_TRANSFORM(op
->state
));
1237 void wined3d_cs_emit_set_transform(struct wined3d_cs
*cs
, enum wined3d_transform_state state
,
1238 const struct wined3d_matrix
*matrix
)
1240 struct wined3d_cs_set_transform
*op
;
1242 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1243 op
->opcode
= WINED3D_CS_OP_SET_TRANSFORM
;
1245 op
->matrix
= *matrix
;
1247 cs
->ops
->submit(cs
);
1250 static void wined3d_cs_exec_set_clip_plane(struct wined3d_cs
*cs
, const void *data
)
1252 const struct wined3d_cs_set_clip_plane
*op
= data
;
1254 cs
->state
.clip_planes
[op
->plane_idx
] = op
->plane
;
1255 device_invalidate_state(cs
->device
, STATE_CLIPPLANE(op
->plane_idx
));
1258 void wined3d_cs_emit_set_clip_plane(struct wined3d_cs
*cs
, UINT plane_idx
, const struct wined3d_vec4
*plane
)
1260 struct wined3d_cs_set_clip_plane
*op
;
1262 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1263 op
->opcode
= WINED3D_CS_OP_SET_CLIP_PLANE
;
1264 op
->plane_idx
= plane_idx
;
1267 cs
->ops
->submit(cs
);
1270 static void wined3d_cs_exec_set_color_key(struct wined3d_cs
*cs
, const void *data
)
1272 const struct wined3d_cs_set_color_key
*op
= data
;
1273 struct wined3d_texture
*texture
= op
->texture
;
1279 case WINED3D_CKEY_DST_BLT
:
1280 texture
->async
.dst_blt_color_key
= op
->color_key
;
1281 texture
->async
.color_key_flags
|= WINED3D_CKEY_DST_BLT
;
1284 case WINED3D_CKEY_DST_OVERLAY
:
1285 texture
->async
.dst_overlay_color_key
= op
->color_key
;
1286 texture
->async
.color_key_flags
|= WINED3D_CKEY_DST_OVERLAY
;
1289 case WINED3D_CKEY_SRC_BLT
:
1290 if (texture
== cs
->state
.textures
[0])
1292 device_invalidate_state(cs
->device
, STATE_COLOR_KEY
);
1293 if (!(texture
->async
.color_key_flags
& WINED3D_CKEY_SRC_BLT
))
1294 device_invalidate_state(cs
->device
, STATE_RENDER(WINED3D_RS_COLORKEYENABLE
));
1297 texture
->async
.src_blt_color_key
= op
->color_key
;
1298 texture
->async
.color_key_flags
|= WINED3D_CKEY_SRC_BLT
;
1301 case WINED3D_CKEY_SRC_OVERLAY
:
1302 texture
->async
.src_overlay_color_key
= op
->color_key
;
1303 texture
->async
.color_key_flags
|= WINED3D_CKEY_SRC_OVERLAY
;
1311 case WINED3D_CKEY_DST_BLT
:
1312 texture
->async
.color_key_flags
&= ~WINED3D_CKEY_DST_BLT
;
1315 case WINED3D_CKEY_DST_OVERLAY
:
1316 texture
->async
.color_key_flags
&= ~WINED3D_CKEY_DST_OVERLAY
;
1319 case WINED3D_CKEY_SRC_BLT
:
1320 if (texture
== cs
->state
.textures
[0] && texture
->async
.color_key_flags
& WINED3D_CKEY_SRC_BLT
)
1321 device_invalidate_state(cs
->device
, STATE_RENDER(WINED3D_RS_COLORKEYENABLE
));
1323 texture
->async
.color_key_flags
&= ~WINED3D_CKEY_SRC_BLT
;
1326 case WINED3D_CKEY_SRC_OVERLAY
:
1327 texture
->async
.color_key_flags
&= ~WINED3D_CKEY_SRC_OVERLAY
;
1333 void wined3d_cs_emit_set_color_key(struct wined3d_cs
*cs
, struct wined3d_texture
*texture
,
1334 WORD flags
, const struct wined3d_color_key
*color_key
)
1336 struct wined3d_cs_set_color_key
*op
;
1338 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1339 op
->opcode
= WINED3D_CS_OP_SET_COLOR_KEY
;
1340 op
->texture
= texture
;
1344 op
->color_key
= *color_key
;
1350 cs
->ops
->submit(cs
);
1353 static void wined3d_cs_exec_set_material(struct wined3d_cs
*cs
, const void *data
)
1355 const struct wined3d_cs_set_material
*op
= data
;
1357 cs
->state
.material
= op
->material
;
1358 device_invalidate_state(cs
->device
, STATE_MATERIAL
);
1361 void wined3d_cs_emit_set_material(struct wined3d_cs
*cs
, const struct wined3d_material
*material
)
1363 struct wined3d_cs_set_material
*op
;
1365 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1366 op
->opcode
= WINED3D_CS_OP_SET_MATERIAL
;
1367 op
->material
= *material
;
1369 cs
->ops
->submit(cs
);
1372 static void wined3d_cs_exec_reset_state(struct wined3d_cs
*cs
, const void *data
)
1374 struct wined3d_adapter
*adapter
= cs
->device
->adapter
;
1376 state_cleanup(&cs
->state
);
1377 memset(&cs
->state
, 0, sizeof(cs
->state
));
1378 state_init(&cs
->state
, &cs
->fb
, &adapter
->gl_info
, &adapter
->d3d_info
,
1379 WINED3D_STATE_NO_REF
| WINED3D_STATE_INIT_DEFAULT
);
1382 void wined3d_cs_emit_reset_state(struct wined3d_cs
*cs
)
1384 struct wined3d_cs_reset_state
*op
;
1386 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1387 op
->opcode
= WINED3D_CS_OP_RESET_STATE
;
1389 cs
->ops
->submit(cs
);
1392 static void wined3d_cs_exec_destroy_object(struct wined3d_cs
*cs
, const void *data
)
1394 const struct wined3d_cs_destroy_object
*op
= data
;
1396 op
->callback(op
->object
);
1399 void wined3d_cs_emit_destroy_object(struct wined3d_cs
*cs
, void (*callback
)(void *object
), void *object
)
1401 struct wined3d_cs_destroy_object
*op
;
1403 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1404 op
->opcode
= WINED3D_CS_OP_DESTROY_OBJECT
;
1405 op
->callback
= callback
;
1406 op
->object
= object
;
1408 cs
->ops
->submit(cs
);
1411 static void wined3d_cs_exec_query_issue(struct wined3d_cs
*cs
, const void *data
)
1413 const struct wined3d_cs_query_issue
*op
= data
;
1414 struct wined3d_query
*query
= op
->query
;
1416 query
->query_ops
->query_issue(query
, op
->flags
);
1419 void wined3d_cs_emit_query_issue(struct wined3d_cs
*cs
, struct wined3d_query
*query
, DWORD flags
)
1421 struct wined3d_cs_query_issue
*op
;
1423 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1424 op
->opcode
= WINED3D_CS_OP_QUERY_ISSUE
;
1428 cs
->ops
->submit(cs
);
1431 static void wined3d_cs_exec_preload_resource(struct wined3d_cs
*cs
, const void *data
)
1433 const struct wined3d_cs_preload_resource
*op
= data
;
1434 struct wined3d_resource
*resource
= op
->resource
;
1436 resource
->resource_ops
->resource_preload(resource
);
1437 wined3d_resource_release(resource
);
1440 void wined3d_cs_emit_preload_resource(struct wined3d_cs
*cs
, struct wined3d_resource
*resource
)
1442 struct wined3d_cs_preload_resource
*op
;
1444 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1445 op
->opcode
= WINED3D_CS_OP_PRELOAD_RESOURCE
;
1446 op
->resource
= resource
;
1448 wined3d_resource_acquire(resource
);
1450 cs
->ops
->submit(cs
);
1453 static void wined3d_cs_exec_unload_resource(struct wined3d_cs
*cs
, const void *data
)
1455 const struct wined3d_cs_unload_resource
*op
= data
;
1456 struct wined3d_resource
*resource
= op
->resource
;
1458 resource
->resource_ops
->resource_unload(resource
);
1459 wined3d_resource_release(resource
);
1462 void wined3d_cs_emit_unload_resource(struct wined3d_cs
*cs
, struct wined3d_resource
*resource
)
1464 struct wined3d_cs_unload_resource
*op
;
1466 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1467 op
->opcode
= WINED3D_CS_OP_UNLOAD_RESOURCE
;
1468 op
->resource
= resource
;
1470 wined3d_resource_acquire(resource
);
1472 cs
->ops
->submit(cs
);
1475 static void wined3d_cs_exec_map(struct wined3d_cs
*cs
, const void *data
)
1477 const struct wined3d_cs_map
*op
= data
;
1478 struct wined3d_resource
*resource
= op
->resource
;
1480 *op
->hr
= resource
->resource_ops
->resource_sub_resource_map(resource
,
1481 op
->sub_resource_idx
, op
->map_desc
, op
->box
, op
->flags
);
1484 HRESULT
wined3d_cs_map(struct wined3d_cs
*cs
, struct wined3d_resource
*resource
, unsigned int sub_resource_idx
,
1485 struct wined3d_map_desc
*map_desc
, const struct wined3d_box
*box
, unsigned int flags
)
1487 struct wined3d_cs_map
*op
;
1490 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1491 op
->opcode
= WINED3D_CS_OP_MAP
;
1492 op
->resource
= resource
;
1493 op
->sub_resource_idx
= sub_resource_idx
;
1494 op
->map_desc
= map_desc
;
1499 cs
->ops
->submit(cs
);
1504 static void wined3d_cs_exec_unmap(struct wined3d_cs
*cs
, const void *data
)
1506 const struct wined3d_cs_unmap
*op
= data
;
1507 struct wined3d_resource
*resource
= op
->resource
;
1509 *op
->hr
= resource
->resource_ops
->resource_sub_resource_unmap(resource
, op
->sub_resource_idx
);
1512 HRESULT
wined3d_cs_unmap(struct wined3d_cs
*cs
, struct wined3d_resource
*resource
, unsigned int sub_resource_idx
)
1514 struct wined3d_cs_unmap
*op
;
1517 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1518 op
->opcode
= WINED3D_CS_OP_UNMAP
;
1519 op
->resource
= resource
;
1520 op
->sub_resource_idx
= sub_resource_idx
;
1523 cs
->ops
->submit(cs
);
1528 static void (* const wined3d_cs_op_handlers
[])(struct wined3d_cs
*cs
, const void *data
) =
1530 /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present
,
1531 /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear
,
1532 /* WINED3D_CS_OP_DISPATCH */ wined3d_cs_exec_dispatch
,
1533 /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw
,
1534 /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication
,
1535 /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport
,
1536 /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect
,
1537 /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view
,
1538 /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view
,
1539 /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration
,
1540 /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source
,
1541 /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq
,
1542 /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output
,
1543 /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer
,
1544 /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer
,
1545 /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture
,
1546 /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view
,
1547 /* WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_set_unordered_access_view
,
1548 /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler
,
1549 /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader
,
1550 /* WINED3D_CS_OP_SET_RASTERIZER_STATE */ wined3d_cs_exec_set_rasterizer_state
,
1551 /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state
,
1552 /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state
,
1553 /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state
,
1554 /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform
,
1555 /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane
,
1556 /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key
,
1557 /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material
,
1558 /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state
,
1559 /* WINED3D_CS_OP_DESTROY_OBJECT */ wined3d_cs_exec_destroy_object
,
1560 /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue
,
1561 /* WINED3D_CS_OP_PRELOAD_RESOURCE */ wined3d_cs_exec_preload_resource
,
1562 /* WINED3D_CS_OP_UNLOAD_RESOURCE */ wined3d_cs_exec_unload_resource
,
1563 /* WINED3D_CS_OP_MAP */ wined3d_cs_exec_map
,
1564 /* WINED3D_CS_OP_UNMAP */ wined3d_cs_exec_unmap
,
1567 static void *wined3d_cs_st_require_space(struct wined3d_cs
*cs
, size_t size
)
1569 if (size
> cs
->data_size
)
1573 size
= max( size
, cs
->data_size
* 2 );
1574 if (!(new_data
= HeapReAlloc(GetProcessHeap(), 0, cs
->data
, size
)))
1577 cs
->data_size
= size
;
1578 cs
->data
= new_data
;
1584 static void wined3d_cs_st_submit(struct wined3d_cs
*cs
)
1586 enum wined3d_cs_op opcode
= *(const enum wined3d_cs_op
*)cs
->data
;
1588 wined3d_cs_op_handlers
[opcode
](cs
, cs
->data
);
1591 static void wined3d_cs_st_push_constants(struct wined3d_cs
*cs
, enum wined3d_push_constants p
,
1592 unsigned int start_idx
, unsigned int count
, const void *constants
)
1594 struct wined3d_device
*device
= cs
->device
;
1595 unsigned int context_count
;
1605 push_constant_info
[] =
1607 /* WINED3D_PUSH_CONSTANTS_VS_F */
1608 {FIELD_OFFSET(struct wined3d_state
, vs_consts_f
), sizeof(struct wined3d_vec4
), WINED3D_SHADER_CONST_VS_F
},
1609 /* WINED3D_PUSH_CONSTANTS_PS_F */
1610 {FIELD_OFFSET(struct wined3d_state
, ps_consts_f
), sizeof(struct wined3d_vec4
), WINED3D_SHADER_CONST_PS_F
},
1611 /* WINED3D_PUSH_CONSTANTS_VS_I */
1612 {FIELD_OFFSET(struct wined3d_state
, vs_consts_i
), sizeof(struct wined3d_ivec4
), WINED3D_SHADER_CONST_VS_I
},
1613 /* WINED3D_PUSH_CONSTANTS_PS_I */
1614 {FIELD_OFFSET(struct wined3d_state
, ps_consts_i
), sizeof(struct wined3d_ivec4
), WINED3D_SHADER_CONST_PS_I
},
1615 /* WINED3D_PUSH_CONSTANTS_VS_B */
1616 {FIELD_OFFSET(struct wined3d_state
, vs_consts_b
), sizeof(BOOL
), WINED3D_SHADER_CONST_VS_B
},
1617 /* WINED3D_PUSH_CONSTANTS_PS_B */
1618 {FIELD_OFFSET(struct wined3d_state
, ps_consts_b
), sizeof(BOOL
), WINED3D_SHADER_CONST_PS_B
},
1621 if (p
== WINED3D_PUSH_CONSTANTS_VS_F
)
1622 device
->shader_backend
->shader_update_float_vertex_constants(device
, start_idx
, count
);
1623 else if (p
== WINED3D_PUSH_CONSTANTS_PS_F
)
1624 device
->shader_backend
->shader_update_float_pixel_constants(device
, start_idx
, count
);
1626 offset
= push_constant_info
[p
].offset
+ start_idx
* push_constant_info
[p
].size
;
1627 memcpy((BYTE
*)&cs
->state
+ offset
, constants
, count
* push_constant_info
[p
].size
);
1628 for (i
= 0, context_count
= device
->context_count
; i
< context_count
; ++i
)
1630 device
->contexts
[i
]->constant_update_mask
|= push_constant_info
[p
].mask
;
1634 static const struct wined3d_cs_ops wined3d_cs_st_ops
=
1636 wined3d_cs_st_require_space
,
1637 wined3d_cs_st_submit
,
1638 wined3d_cs_st_push_constants
,
1641 struct wined3d_cs
*wined3d_cs_create(struct wined3d_device
*device
)
1643 const struct wined3d_gl_info
*gl_info
= &device
->adapter
->gl_info
;
1644 struct wined3d_cs
*cs
;
1646 if (!(cs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*cs
))))
1649 if (!(cs
->fb
.render_targets
= wined3d_calloc(gl_info
->limits
.buffers
, sizeof(*cs
->fb
.render_targets
))))
1651 HeapFree(GetProcessHeap(), 0, cs
);
1655 state_init(&cs
->state
, &cs
->fb
, gl_info
, &device
->adapter
->d3d_info
,
1656 WINED3D_STATE_NO_REF
| WINED3D_STATE_INIT_DEFAULT
);
1658 cs
->ops
= &wined3d_cs_st_ops
;
1659 cs
->device
= device
;
1661 cs
->data_size
= WINED3D_INITIAL_CS_SIZE
;
1662 if (!(cs
->data
= HeapAlloc(GetProcessHeap(), 0, cs
->data_size
)))
1664 state_cleanup(&cs
->state
);
1665 HeapFree(GetProcessHeap(), 0, cs
->fb
.render_targets
);
1666 HeapFree(GetProcessHeap(), 0, cs
);
1673 void wined3d_cs_destroy(struct wined3d_cs
*cs
)
1675 state_cleanup(&cs
->state
);
1676 HeapFree(GetProcessHeap(), 0, cs
->fb
.render_targets
);
1677 HeapFree(GetProcessHeap(), 0, cs
->data
);
1678 HeapFree(GetProcessHeap(), 0, cs
);