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_UNORDERED_ACCESS_VIEW
,
46 WINED3D_CS_OP_SET_SAMPLER
,
47 WINED3D_CS_OP_SET_SHADER
,
48 WINED3D_CS_OP_SET_RASTERIZER_STATE
,
49 WINED3D_CS_OP_SET_RENDER_STATE
,
50 WINED3D_CS_OP_SET_TEXTURE_STATE
,
51 WINED3D_CS_OP_SET_SAMPLER_STATE
,
52 WINED3D_CS_OP_SET_TRANSFORM
,
53 WINED3D_CS_OP_SET_CLIP_PLANE
,
54 WINED3D_CS_OP_SET_COLOR_KEY
,
55 WINED3D_CS_OP_SET_MATERIAL
,
56 WINED3D_CS_OP_RESET_STATE
,
57 WINED3D_CS_OP_DESTROY_OBJECT
,
58 WINED3D_CS_OP_QUERY_ISSUE
,
59 WINED3D_CS_OP_PRELOAD_RESOURCE
,
60 WINED3D_CS_OP_UNLOAD_RESOURCE
,
65 struct wined3d_cs_present
67 enum wined3d_cs_op opcode
;
68 HWND dst_window_override
;
69 struct wined3d_swapchain
*swapchain
;
75 struct wined3d_cs_clear
77 enum wined3d_cs_op opcode
;
79 struct wined3d_color color
;
82 unsigned int rect_count
;
86 struct wined3d_cs_draw
88 enum wined3d_cs_op opcode
;
90 unsigned int start_idx
;
91 unsigned int index_count
;
92 unsigned int start_instance
;
93 unsigned int instance_count
;
97 struct wined3d_cs_set_predication
99 enum wined3d_cs_op opcode
;
100 struct wined3d_query
*predicate
;
104 struct wined3d_cs_set_viewport
106 enum wined3d_cs_op opcode
;
107 struct wined3d_viewport viewport
;
110 struct wined3d_cs_set_scissor_rect
112 enum wined3d_cs_op opcode
;
116 struct wined3d_cs_set_rendertarget_view
118 enum wined3d_cs_op opcode
;
119 unsigned int view_idx
;
120 struct wined3d_rendertarget_view
*view
;
123 struct wined3d_cs_set_depth_stencil_view
125 enum wined3d_cs_op opcode
;
126 struct wined3d_rendertarget_view
*view
;
129 struct wined3d_cs_set_vertex_declaration
131 enum wined3d_cs_op opcode
;
132 struct wined3d_vertex_declaration
*declaration
;
135 struct wined3d_cs_set_stream_source
137 enum wined3d_cs_op opcode
;
139 struct wined3d_buffer
*buffer
;
144 struct wined3d_cs_set_stream_source_freq
146 enum wined3d_cs_op opcode
;
152 struct wined3d_cs_set_stream_output
154 enum wined3d_cs_op opcode
;
156 struct wined3d_buffer
*buffer
;
160 struct wined3d_cs_set_index_buffer
162 enum wined3d_cs_op opcode
;
163 struct wined3d_buffer
*buffer
;
164 enum wined3d_format_id format_id
;
168 struct wined3d_cs_set_constant_buffer
170 enum wined3d_cs_op opcode
;
171 enum wined3d_shader_type type
;
173 struct wined3d_buffer
*buffer
;
176 struct wined3d_cs_set_texture
178 enum wined3d_cs_op opcode
;
180 struct wined3d_texture
*texture
;
183 struct wined3d_cs_set_color_key
185 enum wined3d_cs_op opcode
;
186 struct wined3d_texture
*texture
;
189 struct wined3d_color_key color_key
;
192 struct wined3d_cs_set_shader_resource_view
194 enum wined3d_cs_op opcode
;
195 enum wined3d_shader_type type
;
197 struct wined3d_shader_resource_view
*view
;
200 struct wined3d_cs_set_unordered_access_view
202 enum wined3d_cs_op opcode
;
203 unsigned int view_idx
;
204 struct wined3d_unordered_access_view
*view
;
207 struct wined3d_cs_set_sampler
209 enum wined3d_cs_op opcode
;
210 enum wined3d_shader_type type
;
212 struct wined3d_sampler
*sampler
;
215 struct wined3d_cs_set_shader
217 enum wined3d_cs_op opcode
;
218 enum wined3d_shader_type type
;
219 struct wined3d_shader
*shader
;
222 struct wined3d_cs_set_rasterizer_state
224 enum wined3d_cs_op opcode
;
225 struct wined3d_rasterizer_state
*state
;
228 struct wined3d_cs_set_render_state
230 enum wined3d_cs_op opcode
;
231 enum wined3d_render_state state
;
235 struct wined3d_cs_set_texture_state
237 enum wined3d_cs_op opcode
;
239 enum wined3d_texture_stage_state state
;
243 struct wined3d_cs_set_sampler_state
245 enum wined3d_cs_op opcode
;
247 enum wined3d_sampler_state state
;
251 struct wined3d_cs_set_transform
253 enum wined3d_cs_op opcode
;
254 enum wined3d_transform_state state
;
255 struct wined3d_matrix matrix
;
258 struct wined3d_cs_set_clip_plane
260 enum wined3d_cs_op opcode
;
262 struct wined3d_vec4 plane
;
265 struct wined3d_cs_set_material
267 enum wined3d_cs_op opcode
;
268 struct wined3d_material material
;
271 struct wined3d_cs_reset_state
273 enum wined3d_cs_op opcode
;
276 struct wined3d_cs_destroy_object
278 enum wined3d_cs_op opcode
;
279 void (*callback
)(void *object
);
283 struct wined3d_cs_query_issue
285 enum wined3d_cs_op opcode
;
286 struct wined3d_query
*query
;
290 struct wined3d_cs_preload_resource
292 enum wined3d_cs_op opcode
;
293 struct wined3d_resource
*resource
;
296 struct wined3d_cs_unload_resource
298 enum wined3d_cs_op opcode
;
299 struct wined3d_resource
*resource
;
302 struct wined3d_cs_map
304 enum wined3d_cs_op opcode
;
305 struct wined3d_resource
*resource
;
306 unsigned int sub_resource_idx
;
307 struct wined3d_map_desc
*map_desc
;
308 const struct wined3d_box
*box
;
313 struct wined3d_cs_unmap
315 enum wined3d_cs_op opcode
;
316 struct wined3d_resource
*resource
;
317 unsigned int sub_resource_idx
;
321 static void wined3d_cs_exec_present(struct wined3d_cs
*cs
, const void *data
)
323 const struct wined3d_cs_present
*op
= data
;
324 struct wined3d_swapchain
*swapchain
;
327 swapchain
= op
->swapchain
;
328 wined3d_swapchain_set_window(swapchain
, op
->dst_window_override
);
330 swapchain
->swapchain_ops
->swapchain_present(swapchain
, &op
->src_rect
, &op
->dst_rect
, op
->flags
);
332 wined3d_resource_release(&swapchain
->front_buffer
->resource
);
333 for (i
= 0; i
< swapchain
->desc
.backbuffer_count
; ++i
)
335 wined3d_resource_release(&swapchain
->back_buffers
[i
]->resource
);
339 void wined3d_cs_emit_present(struct wined3d_cs
*cs
, struct wined3d_swapchain
*swapchain
,
340 const RECT
*src_rect
, const RECT
*dst_rect
, HWND dst_window_override
, DWORD flags
)
342 struct wined3d_cs_present
*op
;
345 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
346 op
->opcode
= WINED3D_CS_OP_PRESENT
;
347 op
->dst_window_override
= dst_window_override
;
348 op
->swapchain
= swapchain
;
349 op
->src_rect
= *src_rect
;
350 op
->dst_rect
= *dst_rect
;
353 wined3d_resource_acquire(&swapchain
->front_buffer
->resource
);
354 for (i
= 0; i
< swapchain
->desc
.backbuffer_count
; ++i
)
356 wined3d_resource_acquire(&swapchain
->back_buffers
[i
]->resource
);
362 static void wined3d_cs_exec_clear(struct wined3d_cs
*cs
, const void *data
)
364 const struct wined3d_cs_clear
*op
= data
;
365 const struct wined3d_state
*state
;
366 struct wined3d_device
*device
;
371 state
= &device
->state
;
372 wined3d_get_draw_rect(state
, &draw_rect
);
373 device_clear_render_targets(device
, device
->adapter
->gl_info
.limits
.buffers
,
374 &device
->fb
, op
->rect_count
, op
->rects
, &draw_rect
, op
->flags
,
375 &op
->color
, op
->depth
, op
->stencil
);
377 if (op
->flags
& WINED3DCLEAR_TARGET
)
379 for (i
= 0; i
< device
->adapter
->gl_info
.limits
.buffers
; ++i
)
381 if (state
->fb
->render_targets
[i
])
382 wined3d_resource_release(state
->fb
->render_targets
[i
]->resource
);
385 if (op
->flags
& (WINED3DCLEAR_ZBUFFER
| WINED3DCLEAR_STENCIL
))
386 wined3d_resource_release(state
->fb
->depth_stencil
->resource
);
389 void wined3d_cs_emit_clear(struct wined3d_cs
*cs
, DWORD rect_count
, const RECT
*rects
,
390 DWORD flags
, const struct wined3d_color
*color
, float depth
, DWORD stencil
)
392 const struct wined3d_state
*state
= &cs
->device
->state
;
393 struct wined3d_cs_clear
*op
;
396 op
= cs
->ops
->require_space(cs
, FIELD_OFFSET(struct wined3d_cs_clear
, rects
[rect_count
]));
397 op
->opcode
= WINED3D_CS_OP_CLEAR
;
401 op
->stencil
= stencil
;
402 op
->rect_count
= rect_count
;
403 memcpy(op
->rects
, rects
, sizeof(*rects
) * rect_count
);
405 if (flags
& WINED3DCLEAR_TARGET
)
407 for (i
= 0; i
< cs
->device
->adapter
->gl_info
.limits
.buffers
; ++i
)
409 if (state
->fb
->render_targets
[i
])
410 wined3d_resource_acquire(state
->fb
->render_targets
[i
]->resource
);
413 if (flags
& (WINED3DCLEAR_ZBUFFER
| WINED3DCLEAR_STENCIL
))
414 wined3d_resource_acquire(state
->fb
->depth_stencil
->resource
);
419 static void wined3d_cs_exec_draw(struct wined3d_cs
*cs
, const void *data
)
421 struct wined3d_state
*state
= &cs
->device
->state
;
422 struct wined3d_shader_sampler_map_entry
*entry
;
423 struct wined3d_shader_resource_view
*view
;
424 const struct wined3d_cs_draw
*op
= data
;
425 struct wined3d_shader
*shader
;
428 if (!cs
->device
->adapter
->gl_info
.supported
[ARB_DRAW_ELEMENTS_BASE_VERTEX
]
429 && state
->load_base_vertex_index
!= op
->base_vertex_idx
)
431 state
->load_base_vertex_index
= op
->base_vertex_idx
;
432 device_invalidate_state(cs
->device
, STATE_BASEVERTEXINDEX
);
435 draw_primitive(cs
->device
, state
, op
->base_vertex_idx
, op
->start_idx
,
436 op
->index_count
, op
->start_instance
, op
->instance_count
, op
->indexed
);
439 wined3d_resource_release(&state
->index_buffer
->resource
);
440 for (i
= 0; i
< ARRAY_SIZE(state
->streams
); ++i
)
442 if (state
->streams
[i
].buffer
)
443 wined3d_resource_release(&state
->streams
[i
].buffer
->resource
);
445 for (i
= 0; i
< ARRAY_SIZE(state
->textures
); ++i
)
447 if (state
->textures
[i
])
448 wined3d_resource_release(&state
->textures
[i
]->resource
);
450 for (i
= 0; i
< cs
->device
->adapter
->gl_info
.limits
.buffers
; ++i
)
452 if (state
->fb
->render_targets
[i
])
453 wined3d_resource_release(state
->fb
->render_targets
[i
]->resource
);
455 if (state
->fb
->depth_stencil
)
456 wined3d_resource_release(state
->fb
->depth_stencil
->resource
);
457 for (i
= 0; i
< WINED3D_SHADER_TYPE_COUNT
; ++i
)
459 if (!(shader
= state
->shader
[i
]))
462 for (j
= 0; j
< WINED3D_MAX_CBS
; ++j
)
465 wined3d_resource_release(&state
->cb
[i
][j
]->resource
);
468 for (j
= 0; j
< shader
->reg_maps
.sampler_map
.count
; ++j
)
470 entry
= &shader
->reg_maps
.sampler_map
.entries
[j
];
472 if (!(view
= state
->shader_resource_view
[i
][entry
->resource_idx
]))
475 wined3d_resource_release(view
->resource
);
480 void wined3d_cs_emit_draw(struct wined3d_cs
*cs
, int base_vertex_idx
, unsigned int start_idx
,
481 unsigned int index_count
, unsigned int start_instance
, unsigned int instance_count
, BOOL indexed
)
483 const struct wined3d_state
*state
= &cs
->device
->state
;
484 struct wined3d_shader_sampler_map_entry
*entry
;
485 struct wined3d_shader_resource_view
*view
;
486 struct wined3d_shader
*shader
;
487 struct wined3d_cs_draw
*op
;
490 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
491 op
->opcode
= WINED3D_CS_OP_DRAW
;
492 op
->base_vertex_idx
= base_vertex_idx
;
493 op
->start_idx
= start_idx
;
494 op
->index_count
= index_count
;
495 op
->start_instance
= start_instance
;
496 op
->instance_count
= instance_count
;
497 op
->indexed
= indexed
;
500 wined3d_resource_acquire(&state
->index_buffer
->resource
);
501 for (i
= 0; i
< ARRAY_SIZE(state
->streams
); ++i
)
503 if (state
->streams
[i
].buffer
)
504 wined3d_resource_acquire(&state
->streams
[i
].buffer
->resource
);
506 for (i
= 0; i
< ARRAY_SIZE(state
->textures
); ++i
)
508 if (state
->textures
[i
])
509 wined3d_resource_acquire(&state
->textures
[i
]->resource
);
511 for (i
= 0; i
< cs
->device
->adapter
->gl_info
.limits
.buffers
; ++i
)
513 if (state
->fb
->render_targets
[i
])
514 wined3d_resource_acquire(state
->fb
->render_targets
[i
]->resource
);
516 if (state
->fb
->depth_stencil
)
517 wined3d_resource_acquire(state
->fb
->depth_stencil
->resource
);
518 for (i
= 0; i
< WINED3D_SHADER_TYPE_COUNT
; ++i
)
520 if (!(shader
= state
->shader
[i
]))
523 for (j
= 0; j
< WINED3D_MAX_CBS
; ++j
)
526 wined3d_resource_acquire(&state
->cb
[i
][j
]->resource
);
529 for (j
= 0; j
< shader
->reg_maps
.sampler_map
.count
; ++j
)
531 entry
= &shader
->reg_maps
.sampler_map
.entries
[j
];
533 if (!(view
= state
->shader_resource_view
[i
][entry
->resource_idx
]))
536 wined3d_resource_acquire(view
->resource
);
543 static void wined3d_cs_exec_set_predication(struct wined3d_cs
*cs
, const void *data
)
545 const struct wined3d_cs_set_predication
*op
= data
;
547 cs
->state
.predicate
= op
->predicate
;
548 cs
->state
.predicate_value
= op
->value
;
551 void wined3d_cs_emit_set_predication(struct wined3d_cs
*cs
, struct wined3d_query
*predicate
, BOOL value
)
553 struct wined3d_cs_set_predication
*op
;
555 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
556 op
->opcode
= WINED3D_CS_OP_SET_PREDICATION
;
557 op
->predicate
= predicate
;
563 static void wined3d_cs_exec_set_viewport(struct wined3d_cs
*cs
, const void *data
)
565 const struct wined3d_cs_set_viewport
*op
= data
;
567 cs
->state
.viewport
= op
->viewport
;
568 device_invalidate_state(cs
->device
, STATE_VIEWPORT
);
571 void wined3d_cs_emit_set_viewport(struct wined3d_cs
*cs
, const struct wined3d_viewport
*viewport
)
573 struct wined3d_cs_set_viewport
*op
;
575 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
576 op
->opcode
= WINED3D_CS_OP_SET_VIEWPORT
;
577 op
->viewport
= *viewport
;
582 static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs
*cs
, const void *data
)
584 const struct wined3d_cs_set_scissor_rect
*op
= data
;
586 cs
->state
.scissor_rect
= op
->rect
;
587 device_invalidate_state(cs
->device
, STATE_SCISSORRECT
);
590 void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs
*cs
, const RECT
*rect
)
592 struct wined3d_cs_set_scissor_rect
*op
;
594 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
595 op
->opcode
= WINED3D_CS_OP_SET_SCISSOR_RECT
;
601 static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs
*cs
, const void *data
)
603 const struct wined3d_cs_set_rendertarget_view
*op
= data
;
605 cs
->state
.fb
->render_targets
[op
->view_idx
] = op
->view
;
606 device_invalidate_state(cs
->device
, STATE_FRAMEBUFFER
);
609 void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs
*cs
, unsigned int view_idx
,
610 struct wined3d_rendertarget_view
*view
)
612 struct wined3d_cs_set_rendertarget_view
*op
;
614 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
615 op
->opcode
= WINED3D_CS_OP_SET_RENDERTARGET_VIEW
;
616 op
->view_idx
= view_idx
;
622 static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs
*cs
, const void *data
)
624 const struct wined3d_cs_set_depth_stencil_view
*op
= data
;
625 struct wined3d_device
*device
= cs
->device
;
626 struct wined3d_rendertarget_view
*prev
;
628 if ((prev
= cs
->state
.fb
->depth_stencil
))
630 struct wined3d_surface
*prev_surface
= wined3d_rendertarget_view_get_surface(prev
);
632 if (prev_surface
&& (device
->swapchains
[0]->desc
.flags
& WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL
633 || prev_surface
->container
->flags
& WINED3D_TEXTURE_DISCARD
))
635 surface_modify_ds_location(prev_surface
, WINED3D_LOCATION_DISCARDED
, prev
->width
, prev
->height
);
636 if (prev_surface
== device
->onscreen_depth_stencil
)
638 wined3d_texture_decref(device
->onscreen_depth_stencil
->container
);
639 device
->onscreen_depth_stencil
= NULL
;
644 cs
->fb
.depth_stencil
= op
->view
;
646 if (!prev
!= !op
->view
)
648 /* Swapping NULL / non NULL depth stencil affects the depth and tests */
649 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_ZENABLE
));
650 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_STENCILENABLE
));
651 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK
));
652 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_DEPTHBIAS
));
654 else if (prev
&& (prev
->format_flags
& WINED3DFMT_FLAG_FLOAT
)
655 != (op
->view
->format_flags
& WINED3DFMT_FLAG_FLOAT
))
657 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_DEPTHBIAS
));
660 device_invalidate_state(device
, STATE_FRAMEBUFFER
);
663 void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs
*cs
, struct wined3d_rendertarget_view
*view
)
665 struct wined3d_cs_set_depth_stencil_view
*op
;
667 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
668 op
->opcode
= WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW
;
674 static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs
*cs
, const void *data
)
676 const struct wined3d_cs_set_vertex_declaration
*op
= data
;
678 cs
->state
.vertex_declaration
= op
->declaration
;
679 device_invalidate_state(cs
->device
, STATE_VDECL
);
682 void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs
*cs
, struct wined3d_vertex_declaration
*declaration
)
684 struct wined3d_cs_set_vertex_declaration
*op
;
686 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
687 op
->opcode
= WINED3D_CS_OP_SET_VERTEX_DECLARATION
;
688 op
->declaration
= declaration
;
693 static void wined3d_cs_exec_set_stream_source(struct wined3d_cs
*cs
, const void *data
)
695 const struct wined3d_cs_set_stream_source
*op
= data
;
696 struct wined3d_stream_state
*stream
;
697 struct wined3d_buffer
*prev
;
699 stream
= &cs
->state
.streams
[op
->stream_idx
];
700 prev
= stream
->buffer
;
701 stream
->buffer
= op
->buffer
;
702 stream
->offset
= op
->offset
;
703 stream
->stride
= op
->stride
;
706 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
708 InterlockedDecrement(&prev
->resource
.bind_count
);
710 device_invalidate_state(cs
->device
, STATE_STREAMSRC
);
713 void wined3d_cs_emit_set_stream_source(struct wined3d_cs
*cs
, UINT stream_idx
,
714 struct wined3d_buffer
*buffer
, UINT offset
, UINT stride
)
716 struct wined3d_cs_set_stream_source
*op
;
718 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
719 op
->opcode
= WINED3D_CS_OP_SET_STREAM_SOURCE
;
720 op
->stream_idx
= stream_idx
;
728 static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs
*cs
, const void *data
)
730 const struct wined3d_cs_set_stream_source_freq
*op
= data
;
731 struct wined3d_stream_state
*stream
;
733 stream
= &cs
->state
.streams
[op
->stream_idx
];
734 stream
->frequency
= op
->frequency
;
735 stream
->flags
= op
->flags
;
737 device_invalidate_state(cs
->device
, STATE_STREAMSRC
);
740 void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs
*cs
, UINT stream_idx
, UINT frequency
, UINT flags
)
742 struct wined3d_cs_set_stream_source_freq
*op
;
744 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
745 op
->opcode
= WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ
;
746 op
->stream_idx
= stream_idx
;
747 op
->frequency
= frequency
;
753 static void wined3d_cs_exec_set_stream_output(struct wined3d_cs
*cs
, const void *data
)
755 const struct wined3d_cs_set_stream_output
*op
= data
;
756 struct wined3d_stream_output
*stream
;
757 struct wined3d_buffer
*prev
;
759 stream
= &cs
->state
.stream_output
[op
->stream_idx
];
760 prev
= stream
->buffer
;
761 stream
->buffer
= op
->buffer
;
762 stream
->offset
= op
->offset
;
765 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
767 InterlockedDecrement(&prev
->resource
.bind_count
);
770 void wined3d_cs_emit_set_stream_output(struct wined3d_cs
*cs
, UINT stream_idx
,
771 struct wined3d_buffer
*buffer
, UINT offset
)
773 struct wined3d_cs_set_stream_output
*op
;
775 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
776 op
->opcode
= WINED3D_CS_OP_SET_STREAM_OUTPUT
;
777 op
->stream_idx
= stream_idx
;
784 static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs
*cs
, const void *data
)
786 const struct wined3d_cs_set_index_buffer
*op
= data
;
787 struct wined3d_buffer
*prev
;
789 prev
= cs
->state
.index_buffer
;
790 cs
->state
.index_buffer
= op
->buffer
;
791 cs
->state
.index_format
= op
->format_id
;
792 cs
->state
.index_offset
= op
->offset
;
795 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
797 InterlockedDecrement(&prev
->resource
.bind_count
);
799 device_invalidate_state(cs
->device
, STATE_INDEXBUFFER
);
802 void wined3d_cs_emit_set_index_buffer(struct wined3d_cs
*cs
, struct wined3d_buffer
*buffer
,
803 enum wined3d_format_id format_id
, unsigned int offset
)
805 struct wined3d_cs_set_index_buffer
*op
;
807 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
808 op
->opcode
= WINED3D_CS_OP_SET_INDEX_BUFFER
;
810 op
->format_id
= format_id
;
816 static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs
*cs
, const void *data
)
818 const struct wined3d_cs_set_constant_buffer
*op
= data
;
819 struct wined3d_buffer
*prev
;
821 prev
= cs
->state
.cb
[op
->type
][op
->cb_idx
];
822 cs
->state
.cb
[op
->type
][op
->cb_idx
] = op
->buffer
;
825 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
827 InterlockedDecrement(&prev
->resource
.bind_count
);
829 device_invalidate_state(cs
->device
, STATE_CONSTANT_BUFFER(op
->type
));
832 void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs
*cs
, enum wined3d_shader_type type
,
833 UINT cb_idx
, struct wined3d_buffer
*buffer
)
835 struct wined3d_cs_set_constant_buffer
*op
;
837 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
838 op
->opcode
= WINED3D_CS_OP_SET_CONSTANT_BUFFER
;
846 static void wined3d_cs_exec_set_texture(struct wined3d_cs
*cs
, const void *data
)
848 const struct wined3d_gl_info
*gl_info
= &cs
->device
->adapter
->gl_info
;
849 const struct wined3d_d3d_info
*d3d_info
= &cs
->device
->adapter
->d3d_info
;
850 const struct wined3d_cs_set_texture
*op
= data
;
851 struct wined3d_texture
*prev
;
852 BOOL old_use_color_key
= FALSE
, new_use_color_key
= FALSE
;
854 prev
= cs
->state
.textures
[op
->stage
];
855 cs
->state
.textures
[op
->stage
] = op
->texture
;
859 const struct wined3d_format
*new_format
= op
->texture
->resource
.format
;
860 const struct wined3d_format
*old_format
= prev
? prev
->resource
.format
: NULL
;
861 unsigned int old_fmt_flags
= prev
? prev
->resource
.format_flags
: 0;
862 unsigned int new_fmt_flags
= op
->texture
->resource
.format_flags
;
864 if (InterlockedIncrement(&op
->texture
->resource
.bind_count
) == 1)
865 op
->texture
->sampler
= op
->stage
;
867 if (!prev
|| op
->texture
->target
!= prev
->target
868 || (!is_same_fixup(new_format
->color_fixup
, old_format
->color_fixup
)
869 && !(can_use_texture_swizzle(gl_info
, new_format
) && can_use_texture_swizzle(gl_info
, old_format
)))
870 || (new_fmt_flags
& WINED3DFMT_FLAG_SHADOW
) != (old_fmt_flags
& WINED3DFMT_FLAG_SHADOW
))
871 device_invalidate_state(cs
->device
, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL
));
873 if (!prev
&& op
->stage
< d3d_info
->limits
.ffp_blend_stages
)
875 /* The source arguments for color and alpha ops have different
876 * meanings when a NULL texture is bound, so the COLOR_OP and
877 * ALPHA_OP have to be dirtified. */
878 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_COLOR_OP
));
879 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_ALPHA_OP
));
882 if (!op
->stage
&& op
->texture
->async
.color_key_flags
& WINED3D_CKEY_SRC_BLT
)
883 new_use_color_key
= TRUE
;
888 if (InterlockedDecrement(&prev
->resource
.bind_count
) && prev
->sampler
== op
->stage
)
892 /* Search for other stages the texture is bound to. Shouldn't
893 * happen if applications bind textures to a single stage only. */
894 TRACE("Searching for other stages the texture is bound to.\n");
895 for (i
= 0; i
< MAX_COMBINED_SAMPLERS
; ++i
)
897 if (cs
->state
.textures
[i
] == prev
)
899 TRACE("Texture is also bound to stage %u.\n", i
);
906 if (!op
->texture
&& op
->stage
< d3d_info
->limits
.ffp_blend_stages
)
908 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_COLOR_OP
));
909 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_ALPHA_OP
));
912 if (!op
->stage
&& prev
->async
.color_key_flags
& WINED3D_CKEY_SRC_BLT
)
913 old_use_color_key
= TRUE
;
916 device_invalidate_state(cs
->device
, STATE_SAMPLER(op
->stage
));
918 if (new_use_color_key
!= old_use_color_key
)
919 device_invalidate_state(cs
->device
, STATE_RENDER(WINED3D_RS_COLORKEYENABLE
));
921 if (new_use_color_key
)
922 device_invalidate_state(cs
->device
, STATE_COLOR_KEY
);
925 void wined3d_cs_emit_set_texture(struct wined3d_cs
*cs
, UINT stage
, struct wined3d_texture
*texture
)
927 struct wined3d_cs_set_texture
*op
;
929 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
930 op
->opcode
= WINED3D_CS_OP_SET_TEXTURE
;
932 op
->texture
= texture
;
937 static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs
*cs
, const void *data
)
939 const struct wined3d_cs_set_shader_resource_view
*op
= data
;
941 cs
->state
.shader_resource_view
[op
->type
][op
->view_idx
] = op
->view
;
942 device_invalidate_state(cs
->device
, STATE_SHADER_RESOURCE_BINDING
);
945 void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs
*cs
, unsigned int view_idx
,
946 struct wined3d_unordered_access_view
*view
)
948 struct wined3d_cs_set_unordered_access_view
*op
;
950 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
951 op
->opcode
= WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW
;
952 op
->view_idx
= view_idx
;
958 static void wined3d_cs_exec_set_unordered_access_view(struct wined3d_cs
*cs
, const void *data
)
960 const struct wined3d_cs_set_unordered_access_view
*op
= data
;
961 struct wined3d_unordered_access_view
*prev
;
963 prev
= cs
->state
.unordered_access_view
[op
->view_idx
];
964 cs
->state
.unordered_access_view
[op
->view_idx
] = op
->view
;
967 InterlockedIncrement(&op
->view
->resource
->bind_count
);
969 InterlockedDecrement(&prev
->resource
->bind_count
);
971 device_invalidate_state(cs
->device
, STATE_UNORDERED_ACCESS_VIEW_BINDING
);
974 void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs
*cs
, enum wined3d_shader_type type
,
975 UINT view_idx
, struct wined3d_shader_resource_view
*view
)
977 struct wined3d_cs_set_shader_resource_view
*op
;
979 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
980 op
->opcode
= WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW
;
982 op
->view_idx
= view_idx
;
988 static void wined3d_cs_exec_set_sampler(struct wined3d_cs
*cs
, const void *data
)
990 const struct wined3d_cs_set_sampler
*op
= data
;
992 cs
->state
.sampler
[op
->type
][op
->sampler_idx
] = op
->sampler
;
993 device_invalidate_state(cs
->device
, STATE_SHADER_RESOURCE_BINDING
);
996 void wined3d_cs_emit_set_sampler(struct wined3d_cs
*cs
, enum wined3d_shader_type type
,
997 UINT sampler_idx
, struct wined3d_sampler
*sampler
)
999 struct wined3d_cs_set_sampler
*op
;
1001 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1002 op
->opcode
= WINED3D_CS_OP_SET_SAMPLER
;
1004 op
->sampler_idx
= sampler_idx
;
1005 op
->sampler
= sampler
;
1007 cs
->ops
->submit(cs
);
1010 static void wined3d_cs_exec_set_shader(struct wined3d_cs
*cs
, const void *data
)
1012 const struct wined3d_cs_set_shader
*op
= data
;
1014 cs
->state
.shader
[op
->type
] = op
->shader
;
1015 device_invalidate_state(cs
->device
, STATE_SHADER(op
->type
));
1016 device_invalidate_state(cs
->device
, STATE_SHADER_RESOURCE_BINDING
);
1019 void wined3d_cs_emit_set_shader(struct wined3d_cs
*cs
, enum wined3d_shader_type type
, struct wined3d_shader
*shader
)
1021 struct wined3d_cs_set_shader
*op
;
1023 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1024 op
->opcode
= WINED3D_CS_OP_SET_SHADER
;
1026 op
->shader
= shader
;
1028 cs
->ops
->submit(cs
);
1031 static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs
*cs
, const void *data
)
1033 const struct wined3d_cs_set_rasterizer_state
*op
= data
;
1035 cs
->state
.rasterizer_state
= op
->state
;
1036 device_invalidate_state(cs
->device
, STATE_FRONTFACE
);
1039 void wined3d_cs_emit_set_rasterizer_state(struct wined3d_cs
*cs
,
1040 struct wined3d_rasterizer_state
*rasterizer_state
)
1042 struct wined3d_cs_set_rasterizer_state
*op
;
1044 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1045 op
->opcode
= WINED3D_CS_OP_SET_RASTERIZER_STATE
;
1046 op
->state
= rasterizer_state
;
1048 cs
->ops
->submit(cs
);
1051 static void wined3d_cs_exec_set_render_state(struct wined3d_cs
*cs
, const void *data
)
1053 const struct wined3d_cs_set_render_state
*op
= data
;
1055 cs
->state
.render_states
[op
->state
] = op
->value
;
1056 device_invalidate_state(cs
->device
, STATE_RENDER(op
->state
));
1059 void wined3d_cs_emit_set_render_state(struct wined3d_cs
*cs
, enum wined3d_render_state state
, DWORD value
)
1061 struct wined3d_cs_set_render_state
*op
;
1063 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1064 op
->opcode
= WINED3D_CS_OP_SET_RENDER_STATE
;
1068 cs
->ops
->submit(cs
);
1071 static void wined3d_cs_exec_set_texture_state(struct wined3d_cs
*cs
, const void *data
)
1073 const struct wined3d_cs_set_texture_state
*op
= data
;
1075 cs
->state
.texture_states
[op
->stage
][op
->state
] = op
->value
;
1076 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, op
->state
));
1079 void wined3d_cs_emit_set_texture_state(struct wined3d_cs
*cs
, UINT stage
,
1080 enum wined3d_texture_stage_state state
, DWORD value
)
1082 struct wined3d_cs_set_texture_state
*op
;
1084 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1085 op
->opcode
= WINED3D_CS_OP_SET_TEXTURE_STATE
;
1090 cs
->ops
->submit(cs
);
1093 static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs
*cs
, const void *data
)
1095 const struct wined3d_cs_set_sampler_state
*op
= data
;
1097 cs
->state
.sampler_states
[op
->sampler_idx
][op
->state
] = op
->value
;
1098 device_invalidate_state(cs
->device
, STATE_SAMPLER(op
->sampler_idx
));
1101 void wined3d_cs_emit_set_sampler_state(struct wined3d_cs
*cs
, UINT sampler_idx
,
1102 enum wined3d_sampler_state state
, DWORD value
)
1104 struct wined3d_cs_set_sampler_state
*op
;
1106 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1107 op
->opcode
= WINED3D_CS_OP_SET_SAMPLER_STATE
;
1108 op
->sampler_idx
= sampler_idx
;
1112 cs
->ops
->submit(cs
);
1115 static void wined3d_cs_exec_set_transform(struct wined3d_cs
*cs
, const void *data
)
1117 const struct wined3d_cs_set_transform
*op
= data
;
1119 cs
->state
.transforms
[op
->state
] = op
->matrix
;
1120 if (op
->state
< WINED3D_TS_WORLD_MATRIX(cs
->device
->adapter
->d3d_info
.limits
.ffp_vertex_blend_matrices
))
1121 device_invalidate_state(cs
->device
, STATE_TRANSFORM(op
->state
));
1124 void wined3d_cs_emit_set_transform(struct wined3d_cs
*cs
, enum wined3d_transform_state state
,
1125 const struct wined3d_matrix
*matrix
)
1127 struct wined3d_cs_set_transform
*op
;
1129 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1130 op
->opcode
= WINED3D_CS_OP_SET_TRANSFORM
;
1132 op
->matrix
= *matrix
;
1134 cs
->ops
->submit(cs
);
1137 static void wined3d_cs_exec_set_clip_plane(struct wined3d_cs
*cs
, const void *data
)
1139 const struct wined3d_cs_set_clip_plane
*op
= data
;
1141 cs
->state
.clip_planes
[op
->plane_idx
] = op
->plane
;
1142 device_invalidate_state(cs
->device
, STATE_CLIPPLANE(op
->plane_idx
));
1145 void wined3d_cs_emit_set_clip_plane(struct wined3d_cs
*cs
, UINT plane_idx
, const struct wined3d_vec4
*plane
)
1147 struct wined3d_cs_set_clip_plane
*op
;
1149 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1150 op
->opcode
= WINED3D_CS_OP_SET_CLIP_PLANE
;
1151 op
->plane_idx
= plane_idx
;
1154 cs
->ops
->submit(cs
);
1157 static void wined3d_cs_exec_set_color_key(struct wined3d_cs
*cs
, const void *data
)
1159 const struct wined3d_cs_set_color_key
*op
= data
;
1160 struct wined3d_texture
*texture
= op
->texture
;
1166 case WINED3D_CKEY_DST_BLT
:
1167 texture
->async
.dst_blt_color_key
= op
->color_key
;
1168 texture
->async
.color_key_flags
|= WINED3D_CKEY_DST_BLT
;
1171 case WINED3D_CKEY_DST_OVERLAY
:
1172 texture
->async
.dst_overlay_color_key
= op
->color_key
;
1173 texture
->async
.color_key_flags
|= WINED3D_CKEY_DST_OVERLAY
;
1176 case WINED3D_CKEY_SRC_BLT
:
1177 if (texture
== cs
->state
.textures
[0])
1179 device_invalidate_state(cs
->device
, STATE_COLOR_KEY
);
1180 if (!(texture
->async
.color_key_flags
& WINED3D_CKEY_SRC_BLT
))
1181 device_invalidate_state(cs
->device
, STATE_RENDER(WINED3D_RS_COLORKEYENABLE
));
1184 texture
->async
.src_blt_color_key
= op
->color_key
;
1185 texture
->async
.color_key_flags
|= WINED3D_CKEY_SRC_BLT
;
1188 case WINED3D_CKEY_SRC_OVERLAY
:
1189 texture
->async
.src_overlay_color_key
= op
->color_key
;
1190 texture
->async
.color_key_flags
|= WINED3D_CKEY_SRC_OVERLAY
;
1198 case WINED3D_CKEY_DST_BLT
:
1199 texture
->async
.color_key_flags
&= ~WINED3D_CKEY_DST_BLT
;
1202 case WINED3D_CKEY_DST_OVERLAY
:
1203 texture
->async
.color_key_flags
&= ~WINED3D_CKEY_DST_OVERLAY
;
1206 case WINED3D_CKEY_SRC_BLT
:
1207 if (texture
== cs
->state
.textures
[0] && texture
->async
.color_key_flags
& WINED3D_CKEY_SRC_BLT
)
1208 device_invalidate_state(cs
->device
, STATE_RENDER(WINED3D_RS_COLORKEYENABLE
));
1210 texture
->async
.color_key_flags
&= ~WINED3D_CKEY_SRC_BLT
;
1213 case WINED3D_CKEY_SRC_OVERLAY
:
1214 texture
->async
.color_key_flags
&= ~WINED3D_CKEY_SRC_OVERLAY
;
1220 void wined3d_cs_emit_set_color_key(struct wined3d_cs
*cs
, struct wined3d_texture
*texture
,
1221 WORD flags
, const struct wined3d_color_key
*color_key
)
1223 struct wined3d_cs_set_color_key
*op
;
1225 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1226 op
->opcode
= WINED3D_CS_OP_SET_COLOR_KEY
;
1227 op
->texture
= texture
;
1231 op
->color_key
= *color_key
;
1237 cs
->ops
->submit(cs
);
1240 static void wined3d_cs_exec_set_material(struct wined3d_cs
*cs
, const void *data
)
1242 const struct wined3d_cs_set_material
*op
= data
;
1244 cs
->state
.material
= op
->material
;
1245 device_invalidate_state(cs
->device
, STATE_MATERIAL
);
1248 void wined3d_cs_emit_set_material(struct wined3d_cs
*cs
, const struct wined3d_material
*material
)
1250 struct wined3d_cs_set_material
*op
;
1252 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1253 op
->opcode
= WINED3D_CS_OP_SET_MATERIAL
;
1254 op
->material
= *material
;
1256 cs
->ops
->submit(cs
);
1259 static void wined3d_cs_exec_reset_state(struct wined3d_cs
*cs
, const void *data
)
1261 struct wined3d_adapter
*adapter
= cs
->device
->adapter
;
1263 state_cleanup(&cs
->state
);
1264 memset(&cs
->state
, 0, sizeof(cs
->state
));
1265 state_init(&cs
->state
, &cs
->fb
, &adapter
->gl_info
, &adapter
->d3d_info
,
1266 WINED3D_STATE_NO_REF
| WINED3D_STATE_INIT_DEFAULT
);
1269 void wined3d_cs_emit_reset_state(struct wined3d_cs
*cs
)
1271 struct wined3d_cs_reset_state
*op
;
1273 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1274 op
->opcode
= WINED3D_CS_OP_RESET_STATE
;
1276 cs
->ops
->submit(cs
);
1279 static void wined3d_cs_exec_destroy_object(struct wined3d_cs
*cs
, const void *data
)
1281 const struct wined3d_cs_destroy_object
*op
= data
;
1283 op
->callback(op
->object
);
1286 void wined3d_cs_emit_destroy_object(struct wined3d_cs
*cs
, void (*callback
)(void *object
), void *object
)
1288 struct wined3d_cs_destroy_object
*op
;
1290 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1291 op
->opcode
= WINED3D_CS_OP_DESTROY_OBJECT
;
1292 op
->callback
= callback
;
1293 op
->object
= object
;
1295 cs
->ops
->submit(cs
);
1298 static void wined3d_cs_exec_query_issue(struct wined3d_cs
*cs
, const void *data
)
1300 const struct wined3d_cs_query_issue
*op
= data
;
1301 struct wined3d_query
*query
= op
->query
;
1303 query
->query_ops
->query_issue(query
, op
->flags
);
1306 void wined3d_cs_emit_query_issue(struct wined3d_cs
*cs
, struct wined3d_query
*query
, DWORD flags
)
1308 struct wined3d_cs_query_issue
*op
;
1310 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1311 op
->opcode
= WINED3D_CS_OP_QUERY_ISSUE
;
1315 cs
->ops
->submit(cs
);
1318 static void wined3d_cs_exec_preload_resource(struct wined3d_cs
*cs
, const void *data
)
1320 const struct wined3d_cs_preload_resource
*op
= data
;
1321 struct wined3d_resource
*resource
= op
->resource
;
1323 resource
->resource_ops
->resource_preload(resource
);
1324 wined3d_resource_release(resource
);
1327 void wined3d_cs_emit_preload_resource(struct wined3d_cs
*cs
, struct wined3d_resource
*resource
)
1329 struct wined3d_cs_preload_resource
*op
;
1331 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1332 op
->opcode
= WINED3D_CS_OP_PRELOAD_RESOURCE
;
1333 op
->resource
= resource
;
1335 wined3d_resource_acquire(resource
);
1337 cs
->ops
->submit(cs
);
1340 static void wined3d_cs_exec_unload_resource(struct wined3d_cs
*cs
, const void *data
)
1342 const struct wined3d_cs_unload_resource
*op
= data
;
1343 struct wined3d_resource
*resource
= op
->resource
;
1345 resource
->resource_ops
->resource_unload(resource
);
1346 wined3d_resource_release(resource
);
1349 void wined3d_cs_emit_unload_resource(struct wined3d_cs
*cs
, struct wined3d_resource
*resource
)
1351 struct wined3d_cs_unload_resource
*op
;
1353 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1354 op
->opcode
= WINED3D_CS_OP_UNLOAD_RESOURCE
;
1355 op
->resource
= resource
;
1357 wined3d_resource_acquire(resource
);
1359 cs
->ops
->submit(cs
);
1362 static void wined3d_cs_exec_map(struct wined3d_cs
*cs
, const void *data
)
1364 const struct wined3d_cs_map
*op
= data
;
1365 struct wined3d_resource
*resource
= op
->resource
;
1367 *op
->hr
= resource
->resource_ops
->resource_sub_resource_map(resource
,
1368 op
->sub_resource_idx
, op
->map_desc
, op
->box
, op
->flags
);
1371 HRESULT
wined3d_cs_map(struct wined3d_cs
*cs
, struct wined3d_resource
*resource
, unsigned int sub_resource_idx
,
1372 struct wined3d_map_desc
*map_desc
, const struct wined3d_box
*box
, unsigned int flags
)
1374 struct wined3d_cs_map
*op
;
1377 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1378 op
->opcode
= WINED3D_CS_OP_MAP
;
1379 op
->resource
= resource
;
1380 op
->sub_resource_idx
= sub_resource_idx
;
1381 op
->map_desc
= map_desc
;
1386 cs
->ops
->submit(cs
);
1391 static void wined3d_cs_exec_unmap(struct wined3d_cs
*cs
, const void *data
)
1393 const struct wined3d_cs_unmap
*op
= data
;
1394 struct wined3d_resource
*resource
= op
->resource
;
1396 *op
->hr
= resource
->resource_ops
->resource_sub_resource_unmap(resource
, op
->sub_resource_idx
);
1399 HRESULT
wined3d_cs_unmap(struct wined3d_cs
*cs
, struct wined3d_resource
*resource
, unsigned int sub_resource_idx
)
1401 struct wined3d_cs_unmap
*op
;
1404 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1405 op
->opcode
= WINED3D_CS_OP_UNMAP
;
1406 op
->resource
= resource
;
1407 op
->sub_resource_idx
= sub_resource_idx
;
1410 cs
->ops
->submit(cs
);
1415 static void (* const wined3d_cs_op_handlers
[])(struct wined3d_cs
*cs
, const void *data
) =
1417 /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present
,
1418 /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear
,
1419 /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw
,
1420 /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication
,
1421 /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport
,
1422 /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect
,
1423 /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view
,
1424 /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view
,
1425 /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration
,
1426 /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source
,
1427 /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq
,
1428 /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output
,
1429 /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer
,
1430 /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer
,
1431 /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture
,
1432 /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view
,
1433 /* WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_set_unordered_access_view
,
1434 /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler
,
1435 /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader
,
1436 /* WINED3D_CS_OP_SET_RASTERIZER_STATE */ wined3d_cs_exec_set_rasterizer_state
,
1437 /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state
,
1438 /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state
,
1439 /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state
,
1440 /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform
,
1441 /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane
,
1442 /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key
,
1443 /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material
,
1444 /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state
,
1445 /* WINED3D_CS_OP_DESTROY_OBJECT */ wined3d_cs_exec_destroy_object
,
1446 /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue
,
1447 /* WINED3D_CS_OP_PRELOAD_RESOURCE */ wined3d_cs_exec_preload_resource
,
1448 /* WINED3D_CS_OP_UNLOAD_RESOURCE */ wined3d_cs_exec_unload_resource
,
1449 /* WINED3D_CS_OP_MAP */ wined3d_cs_exec_map
,
1450 /* WINED3D_CS_OP_UNMAP */ wined3d_cs_exec_unmap
,
1453 static void *wined3d_cs_st_require_space(struct wined3d_cs
*cs
, size_t size
)
1455 if (size
> cs
->data_size
)
1459 size
= max( size
, cs
->data_size
* 2 );
1460 if (!(new_data
= HeapReAlloc(GetProcessHeap(), 0, cs
->data
, size
)))
1463 cs
->data_size
= size
;
1464 cs
->data
= new_data
;
1470 static void wined3d_cs_st_submit(struct wined3d_cs
*cs
)
1472 enum wined3d_cs_op opcode
= *(const enum wined3d_cs_op
*)cs
->data
;
1474 wined3d_cs_op_handlers
[opcode
](cs
, cs
->data
);
1477 static void wined3d_cs_st_push_constants(struct wined3d_cs
*cs
, enum wined3d_push_constants p
,
1478 unsigned int start_idx
, unsigned int count
, const void *constants
)
1480 struct wined3d_device
*device
= cs
->device
;
1481 unsigned int context_count
;
1491 push_constant_info
[] =
1493 /* WINED3D_PUSH_CONSTANTS_VS_F */
1494 {FIELD_OFFSET(struct wined3d_state
, vs_consts_f
), sizeof(struct wined3d_vec4
), WINED3D_SHADER_CONST_VS_F
},
1495 /* WINED3D_PUSH_CONSTANTS_PS_F */
1496 {FIELD_OFFSET(struct wined3d_state
, ps_consts_f
), sizeof(struct wined3d_vec4
), WINED3D_SHADER_CONST_PS_F
},
1497 /* WINED3D_PUSH_CONSTANTS_VS_I */
1498 {FIELD_OFFSET(struct wined3d_state
, vs_consts_i
), sizeof(struct wined3d_ivec4
), WINED3D_SHADER_CONST_VS_I
},
1499 /* WINED3D_PUSH_CONSTANTS_PS_I */
1500 {FIELD_OFFSET(struct wined3d_state
, ps_consts_i
), sizeof(struct wined3d_ivec4
), WINED3D_SHADER_CONST_PS_I
},
1501 /* WINED3D_PUSH_CONSTANTS_VS_B */
1502 {FIELD_OFFSET(struct wined3d_state
, vs_consts_b
), sizeof(BOOL
), WINED3D_SHADER_CONST_VS_B
},
1503 /* WINED3D_PUSH_CONSTANTS_PS_B */
1504 {FIELD_OFFSET(struct wined3d_state
, ps_consts_b
), sizeof(BOOL
), WINED3D_SHADER_CONST_PS_B
},
1507 if (p
== WINED3D_PUSH_CONSTANTS_VS_F
)
1508 device
->shader_backend
->shader_update_float_vertex_constants(device
, start_idx
, count
);
1509 else if (p
== WINED3D_PUSH_CONSTANTS_PS_F
)
1510 device
->shader_backend
->shader_update_float_pixel_constants(device
, start_idx
, count
);
1512 offset
= push_constant_info
[p
].offset
+ start_idx
* push_constant_info
[p
].size
;
1513 memcpy((BYTE
*)&cs
->state
+ offset
, constants
, count
* push_constant_info
[p
].size
);
1514 for (i
= 0, context_count
= device
->context_count
; i
< context_count
; ++i
)
1516 device
->contexts
[i
]->constant_update_mask
|= push_constant_info
[p
].mask
;
1520 static const struct wined3d_cs_ops wined3d_cs_st_ops
=
1522 wined3d_cs_st_require_space
,
1523 wined3d_cs_st_submit
,
1524 wined3d_cs_st_push_constants
,
1527 struct wined3d_cs
*wined3d_cs_create(struct wined3d_device
*device
)
1529 const struct wined3d_gl_info
*gl_info
= &device
->adapter
->gl_info
;
1530 struct wined3d_cs
*cs
;
1532 if (!(cs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*cs
))))
1535 if (!(cs
->fb
.render_targets
= wined3d_calloc(gl_info
->limits
.buffers
, sizeof(*cs
->fb
.render_targets
))))
1537 HeapFree(GetProcessHeap(), 0, cs
);
1541 state_init(&cs
->state
, &cs
->fb
, gl_info
, &device
->adapter
->d3d_info
,
1542 WINED3D_STATE_NO_REF
| WINED3D_STATE_INIT_DEFAULT
);
1544 cs
->ops
= &wined3d_cs_st_ops
;
1545 cs
->device
= device
;
1547 cs
->data_size
= WINED3D_INITIAL_CS_SIZE
;
1548 if (!(cs
->data
= HeapAlloc(GetProcessHeap(), 0, cs
->data_size
)))
1550 state_cleanup(&cs
->state
);
1551 HeapFree(GetProcessHeap(), 0, cs
->fb
.render_targets
);
1552 HeapFree(GetProcessHeap(), 0, cs
);
1559 void wined3d_cs_destroy(struct wined3d_cs
*cs
)
1561 state_cleanup(&cs
->state
);
1562 HeapFree(GetProcessHeap(), 0, cs
->fb
.render_targets
);
1563 HeapFree(GetProcessHeap(), 0, cs
->data
);
1564 HeapFree(GetProcessHeap(), 0, cs
);