2 * Copyright 2013 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "wine/port.h"
21 #include "wined3d_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
25 #define WINED3D_INITIAL_CS_SIZE 4096
29 WINED3D_CS_OP_PRESENT
,
32 WINED3D_CS_OP_SET_PREDICATION
,
33 WINED3D_CS_OP_SET_VIEWPORT
,
34 WINED3D_CS_OP_SET_SCISSOR_RECT
,
35 WINED3D_CS_OP_SET_RENDERTARGET_VIEW
,
36 WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW
,
37 WINED3D_CS_OP_SET_VERTEX_DECLARATION
,
38 WINED3D_CS_OP_SET_STREAM_SOURCE
,
39 WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ
,
40 WINED3D_CS_OP_SET_STREAM_OUTPUT
,
41 WINED3D_CS_OP_SET_INDEX_BUFFER
,
42 WINED3D_CS_OP_SET_CONSTANT_BUFFER
,
43 WINED3D_CS_OP_SET_TEXTURE
,
44 WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW
,
45 WINED3D_CS_OP_SET_SAMPLER
,
46 WINED3D_CS_OP_SET_SHADER
,
47 WINED3D_CS_OP_SET_RASTERIZER_STATE
,
48 WINED3D_CS_OP_SET_RENDER_STATE
,
49 WINED3D_CS_OP_SET_TEXTURE_STATE
,
50 WINED3D_CS_OP_SET_SAMPLER_STATE
,
51 WINED3D_CS_OP_SET_TRANSFORM
,
52 WINED3D_CS_OP_SET_CLIP_PLANE
,
53 WINED3D_CS_OP_SET_COLOR_KEY
,
54 WINED3D_CS_OP_SET_MATERIAL
,
55 WINED3D_CS_OP_RESET_STATE
,
56 WINED3D_CS_OP_DESTROY_OBJECT
,
57 WINED3D_CS_OP_QUERY_ISSUE
,
58 WINED3D_CS_OP_PRELOAD_RESOURCE
,
59 WINED3D_CS_OP_UNLOAD_RESOURCE
,
64 struct wined3d_cs_present
66 enum wined3d_cs_op opcode
;
67 HWND dst_window_override
;
68 struct wined3d_swapchain
*swapchain
;
74 struct wined3d_cs_clear
76 enum wined3d_cs_op opcode
;
78 struct wined3d_color color
;
81 unsigned int rect_count
;
85 struct wined3d_cs_draw
87 enum wined3d_cs_op opcode
;
89 unsigned int start_idx
;
90 unsigned int index_count
;
91 unsigned int start_instance
;
92 unsigned int instance_count
;
96 struct wined3d_cs_set_predication
98 enum wined3d_cs_op opcode
;
99 struct wined3d_query
*predicate
;
103 struct wined3d_cs_set_viewport
105 enum wined3d_cs_op opcode
;
106 struct wined3d_viewport viewport
;
109 struct wined3d_cs_set_scissor_rect
111 enum wined3d_cs_op opcode
;
115 struct wined3d_cs_set_rendertarget_view
117 enum wined3d_cs_op opcode
;
118 unsigned int view_idx
;
119 struct wined3d_rendertarget_view
*view
;
122 struct wined3d_cs_set_depth_stencil_view
124 enum wined3d_cs_op opcode
;
125 struct wined3d_rendertarget_view
*view
;
128 struct wined3d_cs_set_vertex_declaration
130 enum wined3d_cs_op opcode
;
131 struct wined3d_vertex_declaration
*declaration
;
134 struct wined3d_cs_set_stream_source
136 enum wined3d_cs_op opcode
;
138 struct wined3d_buffer
*buffer
;
143 struct wined3d_cs_set_stream_source_freq
145 enum wined3d_cs_op opcode
;
151 struct wined3d_cs_set_stream_output
153 enum wined3d_cs_op opcode
;
155 struct wined3d_buffer
*buffer
;
159 struct wined3d_cs_set_index_buffer
161 enum wined3d_cs_op opcode
;
162 struct wined3d_buffer
*buffer
;
163 enum wined3d_format_id format_id
;
167 struct wined3d_cs_set_constant_buffer
169 enum wined3d_cs_op opcode
;
170 enum wined3d_shader_type type
;
172 struct wined3d_buffer
*buffer
;
175 struct wined3d_cs_set_texture
177 enum wined3d_cs_op opcode
;
179 struct wined3d_texture
*texture
;
182 struct wined3d_cs_set_color_key
184 enum wined3d_cs_op opcode
;
185 struct wined3d_texture
*texture
;
188 struct wined3d_color_key color_key
;
191 struct wined3d_cs_set_shader_resource_view
193 enum wined3d_cs_op opcode
;
194 enum wined3d_shader_type type
;
196 struct wined3d_shader_resource_view
*view
;
199 struct wined3d_cs_set_sampler
201 enum wined3d_cs_op opcode
;
202 enum wined3d_shader_type type
;
204 struct wined3d_sampler
*sampler
;
207 struct wined3d_cs_set_shader
209 enum wined3d_cs_op opcode
;
210 enum wined3d_shader_type type
;
211 struct wined3d_shader
*shader
;
214 struct wined3d_cs_set_rasterizer_state
216 enum wined3d_cs_op opcode
;
217 struct wined3d_rasterizer_state
*state
;
220 struct wined3d_cs_set_render_state
222 enum wined3d_cs_op opcode
;
223 enum wined3d_render_state state
;
227 struct wined3d_cs_set_texture_state
229 enum wined3d_cs_op opcode
;
231 enum wined3d_texture_stage_state state
;
235 struct wined3d_cs_set_sampler_state
237 enum wined3d_cs_op opcode
;
239 enum wined3d_sampler_state state
;
243 struct wined3d_cs_set_transform
245 enum wined3d_cs_op opcode
;
246 enum wined3d_transform_state state
;
247 struct wined3d_matrix matrix
;
250 struct wined3d_cs_set_clip_plane
252 enum wined3d_cs_op opcode
;
254 struct wined3d_vec4 plane
;
257 struct wined3d_cs_set_material
259 enum wined3d_cs_op opcode
;
260 struct wined3d_material material
;
263 struct wined3d_cs_reset_state
265 enum wined3d_cs_op opcode
;
268 struct wined3d_cs_destroy_object
270 enum wined3d_cs_op opcode
;
271 void (*callback
)(void *object
);
275 struct wined3d_cs_query_issue
277 enum wined3d_cs_op opcode
;
278 struct wined3d_query
*query
;
282 struct wined3d_cs_preload_resource
284 enum wined3d_cs_op opcode
;
285 struct wined3d_resource
*resource
;
288 struct wined3d_cs_unload_resource
290 enum wined3d_cs_op opcode
;
291 struct wined3d_resource
*resource
;
294 struct wined3d_cs_map
296 enum wined3d_cs_op opcode
;
297 struct wined3d_resource
*resource
;
298 unsigned int sub_resource_idx
;
299 struct wined3d_map_desc
*map_desc
;
300 const struct wined3d_box
*box
;
305 struct wined3d_cs_unmap
307 enum wined3d_cs_op opcode
;
308 struct wined3d_resource
*resource
;
309 unsigned int sub_resource_idx
;
313 static void wined3d_cs_exec_present(struct wined3d_cs
*cs
, const void *data
)
315 const struct wined3d_cs_present
*op
= data
;
316 struct wined3d_swapchain
*swapchain
;
319 swapchain
= op
->swapchain
;
320 wined3d_swapchain_set_window(swapchain
, op
->dst_window_override
);
322 swapchain
->swapchain_ops
->swapchain_present(swapchain
, &op
->src_rect
, &op
->dst_rect
, op
->flags
);
324 wined3d_resource_release(&swapchain
->front_buffer
->resource
);
325 for (i
= 0; i
< swapchain
->desc
.backbuffer_count
; ++i
)
327 wined3d_resource_release(&swapchain
->back_buffers
[i
]->resource
);
331 void wined3d_cs_emit_present(struct wined3d_cs
*cs
, struct wined3d_swapchain
*swapchain
,
332 const RECT
*src_rect
, const RECT
*dst_rect
, HWND dst_window_override
, DWORD flags
)
334 struct wined3d_cs_present
*op
;
337 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
338 op
->opcode
= WINED3D_CS_OP_PRESENT
;
339 op
->dst_window_override
= dst_window_override
;
340 op
->swapchain
= swapchain
;
341 op
->src_rect
= *src_rect
;
342 op
->dst_rect
= *dst_rect
;
345 wined3d_resource_acquire(&swapchain
->front_buffer
->resource
);
346 for (i
= 0; i
< swapchain
->desc
.backbuffer_count
; ++i
)
348 wined3d_resource_acquire(&swapchain
->back_buffers
[i
]->resource
);
354 static void wined3d_cs_exec_clear(struct wined3d_cs
*cs
, const void *data
)
356 const struct wined3d_cs_clear
*op
= data
;
357 const struct wined3d_state
*state
;
358 struct wined3d_device
*device
;
363 state
= &device
->state
;
364 wined3d_get_draw_rect(state
, &draw_rect
);
365 device_clear_render_targets(device
, device
->adapter
->gl_info
.limits
.buffers
,
366 &device
->fb
, op
->rect_count
, op
->rects
, &draw_rect
, op
->flags
,
367 &op
->color
, op
->depth
, op
->stencil
);
369 if (op
->flags
& WINED3DCLEAR_TARGET
)
371 for (i
= 0; i
< device
->adapter
->gl_info
.limits
.buffers
; ++i
)
373 if (state
->fb
->render_targets
[i
])
374 wined3d_resource_release(state
->fb
->render_targets
[i
]->resource
);
377 if (op
->flags
& (WINED3DCLEAR_ZBUFFER
| WINED3DCLEAR_STENCIL
))
378 wined3d_resource_release(state
->fb
->depth_stencil
->resource
);
381 void wined3d_cs_emit_clear(struct wined3d_cs
*cs
, DWORD rect_count
, const RECT
*rects
,
382 DWORD flags
, const struct wined3d_color
*color
, float depth
, DWORD stencil
)
384 const struct wined3d_state
*state
= &cs
->device
->state
;
385 struct wined3d_cs_clear
*op
;
388 op
= cs
->ops
->require_space(cs
, FIELD_OFFSET(struct wined3d_cs_clear
, rects
[rect_count
]));
389 op
->opcode
= WINED3D_CS_OP_CLEAR
;
393 op
->stencil
= stencil
;
394 op
->rect_count
= rect_count
;
395 memcpy(op
->rects
, rects
, sizeof(*rects
) * rect_count
);
397 if (flags
& WINED3DCLEAR_TARGET
)
399 for (i
= 0; i
< cs
->device
->adapter
->gl_info
.limits
.buffers
; ++i
)
401 if (state
->fb
->render_targets
[i
])
402 wined3d_resource_acquire(state
->fb
->render_targets
[i
]->resource
);
405 if (flags
& (WINED3DCLEAR_ZBUFFER
| WINED3DCLEAR_STENCIL
))
406 wined3d_resource_acquire(state
->fb
->depth_stencil
->resource
);
411 static void wined3d_cs_exec_draw(struct wined3d_cs
*cs
, const void *data
)
413 struct wined3d_state
*state
= &cs
->device
->state
;
414 struct wined3d_shader_sampler_map_entry
*entry
;
415 struct wined3d_shader_resource_view
*view
;
416 const struct wined3d_cs_draw
*op
= data
;
417 struct wined3d_shader
*shader
;
420 if (!cs
->device
->adapter
->gl_info
.supported
[ARB_DRAW_ELEMENTS_BASE_VERTEX
]
421 && state
->load_base_vertex_index
!= op
->base_vertex_idx
)
423 state
->load_base_vertex_index
= op
->base_vertex_idx
;
424 device_invalidate_state(cs
->device
, STATE_BASEVERTEXINDEX
);
427 draw_primitive(cs
->device
, state
, op
->base_vertex_idx
, op
->start_idx
,
428 op
->index_count
, op
->start_instance
, op
->instance_count
, op
->indexed
);
431 wined3d_resource_release(&state
->index_buffer
->resource
);
432 for (i
= 0; i
< ARRAY_SIZE(state
->streams
); ++i
)
434 if (state
->streams
[i
].buffer
)
435 wined3d_resource_release(&state
->streams
[i
].buffer
->resource
);
437 for (i
= 0; i
< ARRAY_SIZE(state
->textures
); ++i
)
439 if (state
->textures
[i
])
440 wined3d_resource_release(&state
->textures
[i
]->resource
);
442 for (i
= 0; i
< cs
->device
->adapter
->gl_info
.limits
.buffers
; ++i
)
444 if (state
->fb
->render_targets
[i
])
445 wined3d_resource_release(state
->fb
->render_targets
[i
]->resource
);
447 if (state
->fb
->depth_stencil
)
448 wined3d_resource_release(state
->fb
->depth_stencil
->resource
);
449 for (i
= 0; i
< WINED3D_SHADER_TYPE_COUNT
; ++i
)
451 if (!(shader
= state
->shader
[i
]))
454 for (j
= 0; j
< WINED3D_MAX_CBS
; ++j
)
457 wined3d_resource_release(&state
->cb
[i
][j
]->resource
);
460 for (j
= 0; j
< shader
->reg_maps
.sampler_map
.count
; ++j
)
462 entry
= &shader
->reg_maps
.sampler_map
.entries
[j
];
464 if (!(view
= state
->shader_resource_view
[i
][entry
->resource_idx
]))
467 wined3d_resource_release(view
->resource
);
472 void wined3d_cs_emit_draw(struct wined3d_cs
*cs
, int base_vertex_idx
, unsigned int start_idx
,
473 unsigned int index_count
, unsigned int start_instance
, unsigned int instance_count
, BOOL indexed
)
475 const struct wined3d_state
*state
= &cs
->device
->state
;
476 struct wined3d_shader_sampler_map_entry
*entry
;
477 struct wined3d_shader_resource_view
*view
;
478 struct wined3d_shader
*shader
;
479 struct wined3d_cs_draw
*op
;
482 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
483 op
->opcode
= WINED3D_CS_OP_DRAW
;
484 op
->base_vertex_idx
= base_vertex_idx
;
485 op
->start_idx
= start_idx
;
486 op
->index_count
= index_count
;
487 op
->start_instance
= start_instance
;
488 op
->instance_count
= instance_count
;
489 op
->indexed
= indexed
;
492 wined3d_resource_acquire(&state
->index_buffer
->resource
);
493 for (i
= 0; i
< ARRAY_SIZE(state
->streams
); ++i
)
495 if (state
->streams
[i
].buffer
)
496 wined3d_resource_acquire(&state
->streams
[i
].buffer
->resource
);
498 for (i
= 0; i
< ARRAY_SIZE(state
->textures
); ++i
)
500 if (state
->textures
[i
])
501 wined3d_resource_acquire(&state
->textures
[i
]->resource
);
503 for (i
= 0; i
< cs
->device
->adapter
->gl_info
.limits
.buffers
; ++i
)
505 if (state
->fb
->render_targets
[i
])
506 wined3d_resource_acquire(state
->fb
->render_targets
[i
]->resource
);
508 if (state
->fb
->depth_stencil
)
509 wined3d_resource_acquire(state
->fb
->depth_stencil
->resource
);
510 for (i
= 0; i
< WINED3D_SHADER_TYPE_COUNT
; ++i
)
512 if (!(shader
= state
->shader
[i
]))
515 for (j
= 0; j
< WINED3D_MAX_CBS
; ++j
)
518 wined3d_resource_acquire(&state
->cb
[i
][j
]->resource
);
521 for (j
= 0; j
< shader
->reg_maps
.sampler_map
.count
; ++j
)
523 entry
= &shader
->reg_maps
.sampler_map
.entries
[j
];
525 if (!(view
= state
->shader_resource_view
[i
][entry
->resource_idx
]))
528 wined3d_resource_acquire(view
->resource
);
535 static void wined3d_cs_exec_set_predication(struct wined3d_cs
*cs
, const void *data
)
537 const struct wined3d_cs_set_predication
*op
= data
;
539 cs
->state
.predicate
= op
->predicate
;
540 cs
->state
.predicate_value
= op
->value
;
543 void wined3d_cs_emit_set_predication(struct wined3d_cs
*cs
, struct wined3d_query
*predicate
, BOOL value
)
545 struct wined3d_cs_set_predication
*op
;
547 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
548 op
->opcode
= WINED3D_CS_OP_SET_PREDICATION
;
549 op
->predicate
= predicate
;
555 static void wined3d_cs_exec_set_viewport(struct wined3d_cs
*cs
, const void *data
)
557 const struct wined3d_cs_set_viewport
*op
= data
;
559 cs
->state
.viewport
= op
->viewport
;
560 device_invalidate_state(cs
->device
, STATE_VIEWPORT
);
563 void wined3d_cs_emit_set_viewport(struct wined3d_cs
*cs
, const struct wined3d_viewport
*viewport
)
565 struct wined3d_cs_set_viewport
*op
;
567 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
568 op
->opcode
= WINED3D_CS_OP_SET_VIEWPORT
;
569 op
->viewport
= *viewport
;
574 static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs
*cs
, const void *data
)
576 const struct wined3d_cs_set_scissor_rect
*op
= data
;
578 cs
->state
.scissor_rect
= op
->rect
;
579 device_invalidate_state(cs
->device
, STATE_SCISSORRECT
);
582 void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs
*cs
, const RECT
*rect
)
584 struct wined3d_cs_set_scissor_rect
*op
;
586 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
587 op
->opcode
= WINED3D_CS_OP_SET_SCISSOR_RECT
;
593 static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs
*cs
, const void *data
)
595 const struct wined3d_cs_set_rendertarget_view
*op
= data
;
597 cs
->state
.fb
->render_targets
[op
->view_idx
] = op
->view
;
598 device_invalidate_state(cs
->device
, STATE_FRAMEBUFFER
);
601 void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs
*cs
, unsigned int view_idx
,
602 struct wined3d_rendertarget_view
*view
)
604 struct wined3d_cs_set_rendertarget_view
*op
;
606 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
607 op
->opcode
= WINED3D_CS_OP_SET_RENDERTARGET_VIEW
;
608 op
->view_idx
= view_idx
;
614 static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs
*cs
, const void *data
)
616 const struct wined3d_cs_set_depth_stencil_view
*op
= data
;
617 struct wined3d_device
*device
= cs
->device
;
618 struct wined3d_rendertarget_view
*prev
;
620 if ((prev
= cs
->state
.fb
->depth_stencil
))
622 struct wined3d_surface
*prev_surface
= wined3d_rendertarget_view_get_surface(prev
);
624 if (prev_surface
&& (device
->swapchains
[0]->desc
.flags
& WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL
625 || prev_surface
->container
->flags
& WINED3D_TEXTURE_DISCARD
))
627 surface_modify_ds_location(prev_surface
, WINED3D_LOCATION_DISCARDED
, prev
->width
, prev
->height
);
628 if (prev_surface
== device
->onscreen_depth_stencil
)
630 wined3d_texture_decref(device
->onscreen_depth_stencil
->container
);
631 device
->onscreen_depth_stencil
= NULL
;
636 cs
->fb
.depth_stencil
= op
->view
;
638 if (!prev
!= !op
->view
)
640 /* Swapping NULL / non NULL depth stencil affects the depth and tests */
641 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_ZENABLE
));
642 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_STENCILENABLE
));
643 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK
));
644 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_DEPTHBIAS
));
646 else if (prev
&& (prev
->format_flags
& WINED3DFMT_FLAG_FLOAT
)
647 != (op
->view
->format_flags
& WINED3DFMT_FLAG_FLOAT
))
649 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_DEPTHBIAS
));
652 device_invalidate_state(device
, STATE_FRAMEBUFFER
);
655 void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs
*cs
, struct wined3d_rendertarget_view
*view
)
657 struct wined3d_cs_set_depth_stencil_view
*op
;
659 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
660 op
->opcode
= WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW
;
666 static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs
*cs
, const void *data
)
668 const struct wined3d_cs_set_vertex_declaration
*op
= data
;
670 cs
->state
.vertex_declaration
= op
->declaration
;
671 device_invalidate_state(cs
->device
, STATE_VDECL
);
674 void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs
*cs
, struct wined3d_vertex_declaration
*declaration
)
676 struct wined3d_cs_set_vertex_declaration
*op
;
678 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
679 op
->opcode
= WINED3D_CS_OP_SET_VERTEX_DECLARATION
;
680 op
->declaration
= declaration
;
685 static void wined3d_cs_exec_set_stream_source(struct wined3d_cs
*cs
, const void *data
)
687 const struct wined3d_cs_set_stream_source
*op
= data
;
688 struct wined3d_stream_state
*stream
;
689 struct wined3d_buffer
*prev
;
691 stream
= &cs
->state
.streams
[op
->stream_idx
];
692 prev
= stream
->buffer
;
693 stream
->buffer
= op
->buffer
;
694 stream
->offset
= op
->offset
;
695 stream
->stride
= op
->stride
;
698 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
700 InterlockedDecrement(&prev
->resource
.bind_count
);
702 device_invalidate_state(cs
->device
, STATE_STREAMSRC
);
705 void wined3d_cs_emit_set_stream_source(struct wined3d_cs
*cs
, UINT stream_idx
,
706 struct wined3d_buffer
*buffer
, UINT offset
, UINT stride
)
708 struct wined3d_cs_set_stream_source
*op
;
710 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
711 op
->opcode
= WINED3D_CS_OP_SET_STREAM_SOURCE
;
712 op
->stream_idx
= stream_idx
;
720 static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs
*cs
, const void *data
)
722 const struct wined3d_cs_set_stream_source_freq
*op
= data
;
723 struct wined3d_stream_state
*stream
;
725 stream
= &cs
->state
.streams
[op
->stream_idx
];
726 stream
->frequency
= op
->frequency
;
727 stream
->flags
= op
->flags
;
729 device_invalidate_state(cs
->device
, STATE_STREAMSRC
);
732 void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs
*cs
, UINT stream_idx
, UINT frequency
, UINT flags
)
734 struct wined3d_cs_set_stream_source_freq
*op
;
736 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
737 op
->opcode
= WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ
;
738 op
->stream_idx
= stream_idx
;
739 op
->frequency
= frequency
;
745 static void wined3d_cs_exec_set_stream_output(struct wined3d_cs
*cs
, const void *data
)
747 const struct wined3d_cs_set_stream_output
*op
= data
;
748 struct wined3d_stream_output
*stream
;
749 struct wined3d_buffer
*prev
;
751 stream
= &cs
->state
.stream_output
[op
->stream_idx
];
752 prev
= stream
->buffer
;
753 stream
->buffer
= op
->buffer
;
754 stream
->offset
= op
->offset
;
757 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
759 InterlockedDecrement(&prev
->resource
.bind_count
);
762 void wined3d_cs_emit_set_stream_output(struct wined3d_cs
*cs
, UINT stream_idx
,
763 struct wined3d_buffer
*buffer
, UINT offset
)
765 struct wined3d_cs_set_stream_output
*op
;
767 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
768 op
->opcode
= WINED3D_CS_OP_SET_STREAM_OUTPUT
;
769 op
->stream_idx
= stream_idx
;
776 static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs
*cs
, const void *data
)
778 const struct wined3d_cs_set_index_buffer
*op
= data
;
779 struct wined3d_buffer
*prev
;
781 prev
= cs
->state
.index_buffer
;
782 cs
->state
.index_buffer
= op
->buffer
;
783 cs
->state
.index_format
= op
->format_id
;
784 cs
->state
.index_offset
= op
->offset
;
787 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
789 InterlockedDecrement(&prev
->resource
.bind_count
);
791 device_invalidate_state(cs
->device
, STATE_INDEXBUFFER
);
794 void wined3d_cs_emit_set_index_buffer(struct wined3d_cs
*cs
, struct wined3d_buffer
*buffer
,
795 enum wined3d_format_id format_id
, unsigned int offset
)
797 struct wined3d_cs_set_index_buffer
*op
;
799 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
800 op
->opcode
= WINED3D_CS_OP_SET_INDEX_BUFFER
;
802 op
->format_id
= format_id
;
808 static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs
*cs
, const void *data
)
810 const struct wined3d_cs_set_constant_buffer
*op
= data
;
811 struct wined3d_buffer
*prev
;
813 prev
= cs
->state
.cb
[op
->type
][op
->cb_idx
];
814 cs
->state
.cb
[op
->type
][op
->cb_idx
] = op
->buffer
;
817 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
819 InterlockedDecrement(&prev
->resource
.bind_count
);
821 device_invalidate_state(cs
->device
, STATE_CONSTANT_BUFFER(op
->type
));
824 void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs
*cs
, enum wined3d_shader_type type
,
825 UINT cb_idx
, struct wined3d_buffer
*buffer
)
827 struct wined3d_cs_set_constant_buffer
*op
;
829 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
830 op
->opcode
= WINED3D_CS_OP_SET_CONSTANT_BUFFER
;
838 static void wined3d_cs_exec_set_texture(struct wined3d_cs
*cs
, const void *data
)
840 const struct wined3d_gl_info
*gl_info
= &cs
->device
->adapter
->gl_info
;
841 const struct wined3d_d3d_info
*d3d_info
= &cs
->device
->adapter
->d3d_info
;
842 const struct wined3d_cs_set_texture
*op
= data
;
843 struct wined3d_texture
*prev
;
844 BOOL old_use_color_key
= FALSE
, new_use_color_key
= FALSE
;
846 prev
= cs
->state
.textures
[op
->stage
];
847 cs
->state
.textures
[op
->stage
] = op
->texture
;
851 const struct wined3d_format
*new_format
= op
->texture
->resource
.format
;
852 const struct wined3d_format
*old_format
= prev
? prev
->resource
.format
: NULL
;
853 unsigned int old_fmt_flags
= prev
? prev
->resource
.format_flags
: 0;
854 unsigned int new_fmt_flags
= op
->texture
->resource
.format_flags
;
856 if (InterlockedIncrement(&op
->texture
->resource
.bind_count
) == 1)
857 op
->texture
->sampler
= op
->stage
;
859 if (!prev
|| op
->texture
->target
!= prev
->target
860 || (!is_same_fixup(new_format
->color_fixup
, old_format
->color_fixup
)
861 && !(can_use_texture_swizzle(gl_info
, new_format
) && can_use_texture_swizzle(gl_info
, old_format
)))
862 || (new_fmt_flags
& WINED3DFMT_FLAG_SHADOW
) != (old_fmt_flags
& WINED3DFMT_FLAG_SHADOW
))
863 device_invalidate_state(cs
->device
, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL
));
865 if (!prev
&& op
->stage
< d3d_info
->limits
.ffp_blend_stages
)
867 /* The source arguments for color and alpha ops have different
868 * meanings when a NULL texture is bound, so the COLOR_OP and
869 * ALPHA_OP have to be dirtified. */
870 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_COLOR_OP
));
871 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_ALPHA_OP
));
874 if (!op
->stage
&& op
->texture
->async
.color_key_flags
& WINED3D_CKEY_SRC_BLT
)
875 new_use_color_key
= TRUE
;
880 if (InterlockedDecrement(&prev
->resource
.bind_count
) && prev
->sampler
== op
->stage
)
884 /* Search for other stages the texture is bound to. Shouldn't
885 * happen if applications bind textures to a single stage only. */
886 TRACE("Searching for other stages the texture is bound to.\n");
887 for (i
= 0; i
< MAX_COMBINED_SAMPLERS
; ++i
)
889 if (cs
->state
.textures
[i
] == prev
)
891 TRACE("Texture is also bound to stage %u.\n", i
);
898 if (!op
->texture
&& op
->stage
< d3d_info
->limits
.ffp_blend_stages
)
900 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_COLOR_OP
));
901 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_ALPHA_OP
));
904 if (!op
->stage
&& prev
->async
.color_key_flags
& WINED3D_CKEY_SRC_BLT
)
905 old_use_color_key
= TRUE
;
908 device_invalidate_state(cs
->device
, STATE_SAMPLER(op
->stage
));
910 if (new_use_color_key
!= old_use_color_key
)
911 device_invalidate_state(cs
->device
, STATE_RENDER(WINED3D_RS_COLORKEYENABLE
));
913 if (new_use_color_key
)
914 device_invalidate_state(cs
->device
, STATE_COLOR_KEY
);
917 void wined3d_cs_emit_set_texture(struct wined3d_cs
*cs
, UINT stage
, struct wined3d_texture
*texture
)
919 struct wined3d_cs_set_texture
*op
;
921 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
922 op
->opcode
= WINED3D_CS_OP_SET_TEXTURE
;
924 op
->texture
= texture
;
929 static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs
*cs
, const void *data
)
931 const struct wined3d_cs_set_shader_resource_view
*op
= data
;
933 cs
->state
.shader_resource_view
[op
->type
][op
->view_idx
] = op
->view
;
934 device_invalidate_state(cs
->device
, STATE_SHADER_RESOURCE_BINDING
);
937 void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs
*cs
, enum wined3d_shader_type type
,
938 UINT view_idx
, struct wined3d_shader_resource_view
*view
)
940 struct wined3d_cs_set_shader_resource_view
*op
;
942 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
943 op
->opcode
= WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW
;
945 op
->view_idx
= view_idx
;
951 static void wined3d_cs_exec_set_sampler(struct wined3d_cs
*cs
, const void *data
)
953 const struct wined3d_cs_set_sampler
*op
= data
;
955 cs
->state
.sampler
[op
->type
][op
->sampler_idx
] = op
->sampler
;
956 device_invalidate_state(cs
->device
, STATE_SHADER_RESOURCE_BINDING
);
959 void wined3d_cs_emit_set_sampler(struct wined3d_cs
*cs
, enum wined3d_shader_type type
,
960 UINT sampler_idx
, struct wined3d_sampler
*sampler
)
962 struct wined3d_cs_set_sampler
*op
;
964 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
965 op
->opcode
= WINED3D_CS_OP_SET_SAMPLER
;
967 op
->sampler_idx
= sampler_idx
;
968 op
->sampler
= sampler
;
973 static void wined3d_cs_exec_set_shader(struct wined3d_cs
*cs
, const void *data
)
975 const struct wined3d_cs_set_shader
*op
= data
;
977 cs
->state
.shader
[op
->type
] = op
->shader
;
978 device_invalidate_state(cs
->device
, STATE_SHADER(op
->type
));
979 device_invalidate_state(cs
->device
, STATE_SHADER_RESOURCE_BINDING
);
982 void wined3d_cs_emit_set_shader(struct wined3d_cs
*cs
, enum wined3d_shader_type type
, struct wined3d_shader
*shader
)
984 struct wined3d_cs_set_shader
*op
;
986 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
987 op
->opcode
= WINED3D_CS_OP_SET_SHADER
;
994 static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs
*cs
, const void *data
)
996 const struct wined3d_cs_set_rasterizer_state
*op
= data
;
998 cs
->state
.rasterizer_state
= op
->state
;
999 device_invalidate_state(cs
->device
, STATE_FRONTFACE
);
1002 void wined3d_cs_emit_set_rasterizer_state(struct wined3d_cs
*cs
,
1003 struct wined3d_rasterizer_state
*rasterizer_state
)
1005 struct wined3d_cs_set_rasterizer_state
*op
;
1007 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1008 op
->opcode
= WINED3D_CS_OP_SET_RASTERIZER_STATE
;
1009 op
->state
= rasterizer_state
;
1011 cs
->ops
->submit(cs
);
1014 static void wined3d_cs_exec_set_render_state(struct wined3d_cs
*cs
, const void *data
)
1016 const struct wined3d_cs_set_render_state
*op
= data
;
1018 cs
->state
.render_states
[op
->state
] = op
->value
;
1019 device_invalidate_state(cs
->device
, STATE_RENDER(op
->state
));
1022 void wined3d_cs_emit_set_render_state(struct wined3d_cs
*cs
, enum wined3d_render_state state
, DWORD value
)
1024 struct wined3d_cs_set_render_state
*op
;
1026 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1027 op
->opcode
= WINED3D_CS_OP_SET_RENDER_STATE
;
1031 cs
->ops
->submit(cs
);
1034 static void wined3d_cs_exec_set_texture_state(struct wined3d_cs
*cs
, const void *data
)
1036 const struct wined3d_cs_set_texture_state
*op
= data
;
1038 cs
->state
.texture_states
[op
->stage
][op
->state
] = op
->value
;
1039 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, op
->state
));
1042 void wined3d_cs_emit_set_texture_state(struct wined3d_cs
*cs
, UINT stage
,
1043 enum wined3d_texture_stage_state state
, DWORD value
)
1045 struct wined3d_cs_set_texture_state
*op
;
1047 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1048 op
->opcode
= WINED3D_CS_OP_SET_TEXTURE_STATE
;
1053 cs
->ops
->submit(cs
);
1056 static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs
*cs
, const void *data
)
1058 const struct wined3d_cs_set_sampler_state
*op
= data
;
1060 cs
->state
.sampler_states
[op
->sampler_idx
][op
->state
] = op
->value
;
1061 device_invalidate_state(cs
->device
, STATE_SAMPLER(op
->sampler_idx
));
1064 void wined3d_cs_emit_set_sampler_state(struct wined3d_cs
*cs
, UINT sampler_idx
,
1065 enum wined3d_sampler_state state
, DWORD value
)
1067 struct wined3d_cs_set_sampler_state
*op
;
1069 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1070 op
->opcode
= WINED3D_CS_OP_SET_SAMPLER_STATE
;
1071 op
->sampler_idx
= sampler_idx
;
1075 cs
->ops
->submit(cs
);
1078 static void wined3d_cs_exec_set_transform(struct wined3d_cs
*cs
, const void *data
)
1080 const struct wined3d_cs_set_transform
*op
= data
;
1082 cs
->state
.transforms
[op
->state
] = op
->matrix
;
1083 if (op
->state
< WINED3D_TS_WORLD_MATRIX(cs
->device
->adapter
->d3d_info
.limits
.ffp_vertex_blend_matrices
))
1084 device_invalidate_state(cs
->device
, STATE_TRANSFORM(op
->state
));
1087 void wined3d_cs_emit_set_transform(struct wined3d_cs
*cs
, enum wined3d_transform_state state
,
1088 const struct wined3d_matrix
*matrix
)
1090 struct wined3d_cs_set_transform
*op
;
1092 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1093 op
->opcode
= WINED3D_CS_OP_SET_TRANSFORM
;
1095 op
->matrix
= *matrix
;
1097 cs
->ops
->submit(cs
);
1100 static void wined3d_cs_exec_set_clip_plane(struct wined3d_cs
*cs
, const void *data
)
1102 const struct wined3d_cs_set_clip_plane
*op
= data
;
1104 cs
->state
.clip_planes
[op
->plane_idx
] = op
->plane
;
1105 device_invalidate_state(cs
->device
, STATE_CLIPPLANE(op
->plane_idx
));
1108 void wined3d_cs_emit_set_clip_plane(struct wined3d_cs
*cs
, UINT plane_idx
, const struct wined3d_vec4
*plane
)
1110 struct wined3d_cs_set_clip_plane
*op
;
1112 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1113 op
->opcode
= WINED3D_CS_OP_SET_CLIP_PLANE
;
1114 op
->plane_idx
= plane_idx
;
1117 cs
->ops
->submit(cs
);
1120 static void wined3d_cs_exec_set_color_key(struct wined3d_cs
*cs
, const void *data
)
1122 const struct wined3d_cs_set_color_key
*op
= data
;
1123 struct wined3d_texture
*texture
= op
->texture
;
1129 case WINED3D_CKEY_DST_BLT
:
1130 texture
->async
.dst_blt_color_key
= op
->color_key
;
1131 texture
->async
.color_key_flags
|= WINED3D_CKEY_DST_BLT
;
1134 case WINED3D_CKEY_DST_OVERLAY
:
1135 texture
->async
.dst_overlay_color_key
= op
->color_key
;
1136 texture
->async
.color_key_flags
|= WINED3D_CKEY_DST_OVERLAY
;
1139 case WINED3D_CKEY_SRC_BLT
:
1140 if (texture
== cs
->state
.textures
[0])
1142 device_invalidate_state(cs
->device
, STATE_COLOR_KEY
);
1143 if (!(texture
->async
.color_key_flags
& WINED3D_CKEY_SRC_BLT
))
1144 device_invalidate_state(cs
->device
, STATE_RENDER(WINED3D_RS_COLORKEYENABLE
));
1147 texture
->async
.src_blt_color_key
= op
->color_key
;
1148 texture
->async
.color_key_flags
|= WINED3D_CKEY_SRC_BLT
;
1151 case WINED3D_CKEY_SRC_OVERLAY
:
1152 texture
->async
.src_overlay_color_key
= op
->color_key
;
1153 texture
->async
.color_key_flags
|= WINED3D_CKEY_SRC_OVERLAY
;
1161 case WINED3D_CKEY_DST_BLT
:
1162 texture
->async
.color_key_flags
&= ~WINED3D_CKEY_DST_BLT
;
1165 case WINED3D_CKEY_DST_OVERLAY
:
1166 texture
->async
.color_key_flags
&= ~WINED3D_CKEY_DST_OVERLAY
;
1169 case WINED3D_CKEY_SRC_BLT
:
1170 if (texture
== cs
->state
.textures
[0] && texture
->async
.color_key_flags
& WINED3D_CKEY_SRC_BLT
)
1171 device_invalidate_state(cs
->device
, STATE_RENDER(WINED3D_RS_COLORKEYENABLE
));
1173 texture
->async
.color_key_flags
&= ~WINED3D_CKEY_SRC_BLT
;
1176 case WINED3D_CKEY_SRC_OVERLAY
:
1177 texture
->async
.color_key_flags
&= ~WINED3D_CKEY_SRC_OVERLAY
;
1183 void wined3d_cs_emit_set_color_key(struct wined3d_cs
*cs
, struct wined3d_texture
*texture
,
1184 WORD flags
, const struct wined3d_color_key
*color_key
)
1186 struct wined3d_cs_set_color_key
*op
;
1188 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1189 op
->opcode
= WINED3D_CS_OP_SET_COLOR_KEY
;
1190 op
->texture
= texture
;
1194 op
->color_key
= *color_key
;
1200 cs
->ops
->submit(cs
);
1203 static void wined3d_cs_exec_set_material(struct wined3d_cs
*cs
, const void *data
)
1205 const struct wined3d_cs_set_material
*op
= data
;
1207 cs
->state
.material
= op
->material
;
1208 device_invalidate_state(cs
->device
, STATE_MATERIAL
);
1211 void wined3d_cs_emit_set_material(struct wined3d_cs
*cs
, const struct wined3d_material
*material
)
1213 struct wined3d_cs_set_material
*op
;
1215 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1216 op
->opcode
= WINED3D_CS_OP_SET_MATERIAL
;
1217 op
->material
= *material
;
1219 cs
->ops
->submit(cs
);
1222 static void wined3d_cs_exec_reset_state(struct wined3d_cs
*cs
, const void *data
)
1224 struct wined3d_adapter
*adapter
= cs
->device
->adapter
;
1226 state_cleanup(&cs
->state
);
1227 memset(&cs
->state
, 0, sizeof(cs
->state
));
1228 state_init(&cs
->state
, &cs
->fb
, &adapter
->gl_info
, &adapter
->d3d_info
,
1229 WINED3D_STATE_NO_REF
| WINED3D_STATE_INIT_DEFAULT
);
1232 void wined3d_cs_emit_reset_state(struct wined3d_cs
*cs
)
1234 struct wined3d_cs_reset_state
*op
;
1236 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1237 op
->opcode
= WINED3D_CS_OP_RESET_STATE
;
1239 cs
->ops
->submit(cs
);
1242 static void wined3d_cs_exec_destroy_object(struct wined3d_cs
*cs
, const void *data
)
1244 const struct wined3d_cs_destroy_object
*op
= data
;
1246 op
->callback(op
->object
);
1249 void wined3d_cs_emit_destroy_object(struct wined3d_cs
*cs
, void (*callback
)(void *object
), void *object
)
1251 struct wined3d_cs_destroy_object
*op
;
1253 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1254 op
->opcode
= WINED3D_CS_OP_DESTROY_OBJECT
;
1255 op
->callback
= callback
;
1256 op
->object
= object
;
1258 cs
->ops
->submit(cs
);
1261 static void wined3d_cs_exec_query_issue(struct wined3d_cs
*cs
, const void *data
)
1263 const struct wined3d_cs_query_issue
*op
= data
;
1264 struct wined3d_query
*query
= op
->query
;
1266 query
->query_ops
->query_issue(query
, op
->flags
);
1269 void wined3d_cs_emit_query_issue(struct wined3d_cs
*cs
, struct wined3d_query
*query
, DWORD flags
)
1271 struct wined3d_cs_query_issue
*op
;
1273 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1274 op
->opcode
= WINED3D_CS_OP_QUERY_ISSUE
;
1278 cs
->ops
->submit(cs
);
1281 static void wined3d_cs_exec_preload_resource(struct wined3d_cs
*cs
, const void *data
)
1283 const struct wined3d_cs_preload_resource
*op
= data
;
1284 struct wined3d_resource
*resource
= op
->resource
;
1286 resource
->resource_ops
->resource_preload(resource
);
1287 wined3d_resource_release(resource
);
1290 void wined3d_cs_emit_preload_resource(struct wined3d_cs
*cs
, struct wined3d_resource
*resource
)
1292 struct wined3d_cs_preload_resource
*op
;
1294 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1295 op
->opcode
= WINED3D_CS_OP_PRELOAD_RESOURCE
;
1296 op
->resource
= resource
;
1298 wined3d_resource_acquire(resource
);
1300 cs
->ops
->submit(cs
);
1303 static void wined3d_cs_exec_unload_resource(struct wined3d_cs
*cs
, const void *data
)
1305 const struct wined3d_cs_unload_resource
*op
= data
;
1306 struct wined3d_resource
*resource
= op
->resource
;
1308 resource
->resource_ops
->resource_unload(resource
);
1309 wined3d_resource_release(resource
);
1312 void wined3d_cs_emit_unload_resource(struct wined3d_cs
*cs
, struct wined3d_resource
*resource
)
1314 struct wined3d_cs_unload_resource
*op
;
1316 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1317 op
->opcode
= WINED3D_CS_OP_UNLOAD_RESOURCE
;
1318 op
->resource
= resource
;
1320 wined3d_resource_acquire(resource
);
1322 cs
->ops
->submit(cs
);
1325 static void wined3d_cs_exec_map(struct wined3d_cs
*cs
, const void *data
)
1327 const struct wined3d_cs_map
*op
= data
;
1328 struct wined3d_resource
*resource
= op
->resource
;
1330 *op
->hr
= resource
->resource_ops
->resource_sub_resource_map(resource
,
1331 op
->sub_resource_idx
, op
->map_desc
, op
->box
, op
->flags
);
1334 HRESULT
wined3d_cs_map(struct wined3d_cs
*cs
, struct wined3d_resource
*resource
, unsigned int sub_resource_idx
,
1335 struct wined3d_map_desc
*map_desc
, const struct wined3d_box
*box
, unsigned int flags
)
1337 struct wined3d_cs_map
*op
;
1340 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1341 op
->opcode
= WINED3D_CS_OP_MAP
;
1342 op
->resource
= resource
;
1343 op
->sub_resource_idx
= sub_resource_idx
;
1344 op
->map_desc
= map_desc
;
1349 cs
->ops
->submit(cs
);
1354 static void wined3d_cs_exec_unmap(struct wined3d_cs
*cs
, const void *data
)
1356 const struct wined3d_cs_unmap
*op
= data
;
1357 struct wined3d_resource
*resource
= op
->resource
;
1359 *op
->hr
= resource
->resource_ops
->resource_sub_resource_unmap(resource
, op
->sub_resource_idx
);
1362 HRESULT
wined3d_cs_unmap(struct wined3d_cs
*cs
, struct wined3d_resource
*resource
, unsigned int sub_resource_idx
)
1364 struct wined3d_cs_unmap
*op
;
1367 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1368 op
->opcode
= WINED3D_CS_OP_UNMAP
;
1369 op
->resource
= resource
;
1370 op
->sub_resource_idx
= sub_resource_idx
;
1373 cs
->ops
->submit(cs
);
1378 static void (* const wined3d_cs_op_handlers
[])(struct wined3d_cs
*cs
, const void *data
) =
1380 /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present
,
1381 /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear
,
1382 /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw
,
1383 /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication
,
1384 /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport
,
1385 /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect
,
1386 /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view
,
1387 /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view
,
1388 /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration
,
1389 /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source
,
1390 /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq
,
1391 /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output
,
1392 /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer
,
1393 /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer
,
1394 /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture
,
1395 /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view
,
1396 /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler
,
1397 /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader
,
1398 /* WINED3D_CS_OP_SET_RASTERIZER_STATE */ wined3d_cs_exec_set_rasterizer_state
,
1399 /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state
,
1400 /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state
,
1401 /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state
,
1402 /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform
,
1403 /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane
,
1404 /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key
,
1405 /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material
,
1406 /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state
,
1407 /* WINED3D_CS_OP_DESTROY_OBJECT */ wined3d_cs_exec_destroy_object
,
1408 /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue
,
1409 /* WINED3D_CS_OP_PRELOAD_RESOURCE */ wined3d_cs_exec_preload_resource
,
1410 /* WINED3D_CS_OP_UNLOAD_RESOURCE */ wined3d_cs_exec_unload_resource
,
1411 /* WINED3D_CS_OP_MAP */ wined3d_cs_exec_map
,
1412 /* WINED3D_CS_OP_UNMAP */ wined3d_cs_exec_unmap
,
1415 static void *wined3d_cs_st_require_space(struct wined3d_cs
*cs
, size_t size
)
1417 if (size
> cs
->data_size
)
1421 size
= max( size
, cs
->data_size
* 2 );
1422 if (!(new_data
= HeapReAlloc(GetProcessHeap(), 0, cs
->data
, size
)))
1425 cs
->data_size
= size
;
1426 cs
->data
= new_data
;
1432 static void wined3d_cs_st_submit(struct wined3d_cs
*cs
)
1434 enum wined3d_cs_op opcode
= *(const enum wined3d_cs_op
*)cs
->data
;
1436 wined3d_cs_op_handlers
[opcode
](cs
, cs
->data
);
1439 static void wined3d_cs_st_push_constants(struct wined3d_cs
*cs
, enum wined3d_push_constants p
,
1440 unsigned int start_idx
, unsigned int count
, const void *constants
)
1442 struct wined3d_device
*device
= cs
->device
;
1443 unsigned int context_count
;
1453 push_constant_info
[] =
1455 /* WINED3D_PUSH_CONSTANTS_VS_F */
1456 {FIELD_OFFSET(struct wined3d_state
, vs_consts_f
), sizeof(struct wined3d_vec4
), WINED3D_SHADER_CONST_VS_F
},
1457 /* WINED3D_PUSH_CONSTANTS_PS_F */
1458 {FIELD_OFFSET(struct wined3d_state
, ps_consts_f
), sizeof(struct wined3d_vec4
), WINED3D_SHADER_CONST_PS_F
},
1459 /* WINED3D_PUSH_CONSTANTS_VS_I */
1460 {FIELD_OFFSET(struct wined3d_state
, vs_consts_i
), sizeof(struct wined3d_ivec4
), WINED3D_SHADER_CONST_VS_I
},
1461 /* WINED3D_PUSH_CONSTANTS_PS_I */
1462 {FIELD_OFFSET(struct wined3d_state
, ps_consts_i
), sizeof(struct wined3d_ivec4
), WINED3D_SHADER_CONST_PS_I
},
1463 /* WINED3D_PUSH_CONSTANTS_VS_B */
1464 {FIELD_OFFSET(struct wined3d_state
, vs_consts_b
), sizeof(BOOL
), WINED3D_SHADER_CONST_VS_B
},
1465 /* WINED3D_PUSH_CONSTANTS_PS_B */
1466 {FIELD_OFFSET(struct wined3d_state
, ps_consts_b
), sizeof(BOOL
), WINED3D_SHADER_CONST_PS_B
},
1469 if (p
== WINED3D_PUSH_CONSTANTS_VS_F
)
1470 device
->shader_backend
->shader_update_float_vertex_constants(device
, start_idx
, count
);
1471 else if (p
== WINED3D_PUSH_CONSTANTS_PS_F
)
1472 device
->shader_backend
->shader_update_float_pixel_constants(device
, start_idx
, count
);
1474 offset
= push_constant_info
[p
].offset
+ start_idx
* push_constant_info
[p
].size
;
1475 memcpy((BYTE
*)&cs
->state
+ offset
, constants
, count
* push_constant_info
[p
].size
);
1476 for (i
= 0, context_count
= device
->context_count
; i
< context_count
; ++i
)
1478 device
->contexts
[i
]->constant_update_mask
|= push_constant_info
[p
].mask
;
1482 static const struct wined3d_cs_ops wined3d_cs_st_ops
=
1484 wined3d_cs_st_require_space
,
1485 wined3d_cs_st_submit
,
1486 wined3d_cs_st_push_constants
,
1489 struct wined3d_cs
*wined3d_cs_create(struct wined3d_device
*device
)
1491 const struct wined3d_gl_info
*gl_info
= &device
->adapter
->gl_info
;
1492 struct wined3d_cs
*cs
;
1494 if (!(cs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*cs
))))
1497 if (!(cs
->fb
.render_targets
= wined3d_calloc(gl_info
->limits
.buffers
, sizeof(*cs
->fb
.render_targets
))))
1499 HeapFree(GetProcessHeap(), 0, cs
);
1503 state_init(&cs
->state
, &cs
->fb
, gl_info
, &device
->adapter
->d3d_info
,
1504 WINED3D_STATE_NO_REF
| WINED3D_STATE_INIT_DEFAULT
);
1506 cs
->ops
= &wined3d_cs_st_ops
;
1507 cs
->device
= device
;
1509 cs
->data_size
= WINED3D_INITIAL_CS_SIZE
;
1510 if (!(cs
->data
= HeapAlloc(GetProcessHeap(), 0, cs
->data_size
)))
1512 state_cleanup(&cs
->state
);
1513 HeapFree(GetProcessHeap(), 0, cs
->fb
.render_targets
);
1514 HeapFree(GetProcessHeap(), 0, cs
);
1521 void wined3d_cs_destroy(struct wined3d_cs
*cs
)
1523 state_cleanup(&cs
->state
);
1524 HeapFree(GetProcessHeap(), 0, cs
->fb
.render_targets
);
1525 HeapFree(GetProcessHeap(), 0, cs
->data
);
1526 HeapFree(GetProcessHeap(), 0, cs
);