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_UNLOAD_RESOURCE
,
61 struct wined3d_cs_present
63 enum wined3d_cs_op opcode
;
64 HWND dst_window_override
;
65 struct wined3d_swapchain
*swapchain
;
71 struct wined3d_cs_clear
73 enum wined3d_cs_op opcode
;
75 struct wined3d_color color
;
78 unsigned int rect_count
;
82 struct wined3d_cs_draw
84 enum wined3d_cs_op opcode
;
86 unsigned int start_idx
;
87 unsigned int index_count
;
88 unsigned int start_instance
;
89 unsigned int instance_count
;
93 struct wined3d_cs_set_predication
95 enum wined3d_cs_op opcode
;
96 struct wined3d_query
*predicate
;
100 struct wined3d_cs_set_viewport
102 enum wined3d_cs_op opcode
;
103 struct wined3d_viewport viewport
;
106 struct wined3d_cs_set_scissor_rect
108 enum wined3d_cs_op opcode
;
112 struct wined3d_cs_set_rendertarget_view
114 enum wined3d_cs_op opcode
;
115 unsigned int view_idx
;
116 struct wined3d_rendertarget_view
*view
;
119 struct wined3d_cs_set_depth_stencil_view
121 enum wined3d_cs_op opcode
;
122 struct wined3d_rendertarget_view
*view
;
125 struct wined3d_cs_set_vertex_declaration
127 enum wined3d_cs_op opcode
;
128 struct wined3d_vertex_declaration
*declaration
;
131 struct wined3d_cs_set_stream_source
133 enum wined3d_cs_op opcode
;
135 struct wined3d_buffer
*buffer
;
140 struct wined3d_cs_set_stream_source_freq
142 enum wined3d_cs_op opcode
;
148 struct wined3d_cs_set_stream_output
150 enum wined3d_cs_op opcode
;
152 struct wined3d_buffer
*buffer
;
156 struct wined3d_cs_set_index_buffer
158 enum wined3d_cs_op opcode
;
159 struct wined3d_buffer
*buffer
;
160 enum wined3d_format_id format_id
;
164 struct wined3d_cs_set_constant_buffer
166 enum wined3d_cs_op opcode
;
167 enum wined3d_shader_type type
;
169 struct wined3d_buffer
*buffer
;
172 struct wined3d_cs_set_texture
174 enum wined3d_cs_op opcode
;
176 struct wined3d_texture
*texture
;
179 struct wined3d_cs_set_color_key
181 enum wined3d_cs_op opcode
;
182 struct wined3d_texture
*texture
;
185 struct wined3d_color_key color_key
;
188 struct wined3d_cs_set_shader_resource_view
190 enum wined3d_cs_op opcode
;
191 enum wined3d_shader_type type
;
193 struct wined3d_shader_resource_view
*view
;
196 struct wined3d_cs_set_sampler
198 enum wined3d_cs_op opcode
;
199 enum wined3d_shader_type type
;
201 struct wined3d_sampler
*sampler
;
204 struct wined3d_cs_set_shader
206 enum wined3d_cs_op opcode
;
207 enum wined3d_shader_type type
;
208 struct wined3d_shader
*shader
;
211 struct wined3d_cs_set_rasterizer_state
213 enum wined3d_cs_op opcode
;
214 struct wined3d_rasterizer_state
*state
;
217 struct wined3d_cs_set_render_state
219 enum wined3d_cs_op opcode
;
220 enum wined3d_render_state state
;
224 struct wined3d_cs_set_texture_state
226 enum wined3d_cs_op opcode
;
228 enum wined3d_texture_stage_state state
;
232 struct wined3d_cs_set_sampler_state
234 enum wined3d_cs_op opcode
;
236 enum wined3d_sampler_state state
;
240 struct wined3d_cs_set_transform
242 enum wined3d_cs_op opcode
;
243 enum wined3d_transform_state state
;
244 struct wined3d_matrix matrix
;
247 struct wined3d_cs_set_clip_plane
249 enum wined3d_cs_op opcode
;
251 struct wined3d_vec4 plane
;
254 struct wined3d_cs_set_material
256 enum wined3d_cs_op opcode
;
257 struct wined3d_material material
;
260 struct wined3d_cs_reset_state
262 enum wined3d_cs_op opcode
;
265 struct wined3d_cs_destroy_object
267 enum wined3d_cs_op opcode
;
268 void (*callback
)(void *object
);
272 struct wined3d_cs_query_issue
274 enum wined3d_cs_op opcode
;
275 struct wined3d_query
*query
;
279 struct wined3d_cs_unload_resource
281 enum wined3d_cs_op opcode
;
282 struct wined3d_resource
*resource
;
285 static void wined3d_cs_exec_present(struct wined3d_cs
*cs
, const void *data
)
287 const struct wined3d_cs_present
*op
= data
;
288 struct wined3d_swapchain
*swapchain
;
291 swapchain
= op
->swapchain
;
292 wined3d_swapchain_set_window(swapchain
, op
->dst_window_override
);
294 swapchain
->swapchain_ops
->swapchain_present(swapchain
, &op
->src_rect
, &op
->dst_rect
, op
->flags
);
296 wined3d_resource_release(&swapchain
->front_buffer
->resource
);
297 for (i
= 0; i
< swapchain
->desc
.backbuffer_count
; ++i
)
299 wined3d_resource_release(&swapchain
->back_buffers
[i
]->resource
);
303 void wined3d_cs_emit_present(struct wined3d_cs
*cs
, struct wined3d_swapchain
*swapchain
,
304 const RECT
*src_rect
, const RECT
*dst_rect
, HWND dst_window_override
, DWORD flags
)
306 struct wined3d_cs_present
*op
;
309 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
310 op
->opcode
= WINED3D_CS_OP_PRESENT
;
311 op
->dst_window_override
= dst_window_override
;
312 op
->swapchain
= swapchain
;
313 op
->src_rect
= *src_rect
;
314 op
->dst_rect
= *dst_rect
;
317 wined3d_resource_acquire(&swapchain
->front_buffer
->resource
);
318 for (i
= 0; i
< swapchain
->desc
.backbuffer_count
; ++i
)
320 wined3d_resource_acquire(&swapchain
->back_buffers
[i
]->resource
);
326 static void wined3d_cs_exec_clear(struct wined3d_cs
*cs
, const void *data
)
328 const struct wined3d_cs_clear
*op
= data
;
329 const struct wined3d_state
*state
;
330 struct wined3d_device
*device
;
335 state
= &device
->state
;
336 wined3d_get_draw_rect(state
, &draw_rect
);
337 device_clear_render_targets(device
, device
->adapter
->gl_info
.limits
.buffers
,
338 &device
->fb
, op
->rect_count
, op
->rects
, &draw_rect
, op
->flags
,
339 &op
->color
, op
->depth
, op
->stencil
);
341 if (op
->flags
& WINED3DCLEAR_TARGET
)
343 for (i
= 0; i
< device
->adapter
->gl_info
.limits
.buffers
; ++i
)
345 if (state
->fb
->render_targets
[i
])
346 wined3d_resource_release(state
->fb
->render_targets
[i
]->resource
);
349 if (op
->flags
& (WINED3DCLEAR_ZBUFFER
| WINED3DCLEAR_STENCIL
))
350 wined3d_resource_release(state
->fb
->depth_stencil
->resource
);
353 void wined3d_cs_emit_clear(struct wined3d_cs
*cs
, DWORD rect_count
, const RECT
*rects
,
354 DWORD flags
, const struct wined3d_color
*color
, float depth
, DWORD stencil
)
356 const struct wined3d_state
*state
= &cs
->device
->state
;
357 struct wined3d_cs_clear
*op
;
360 op
= cs
->ops
->require_space(cs
, FIELD_OFFSET(struct wined3d_cs_clear
, rects
[rect_count
]));
361 op
->opcode
= WINED3D_CS_OP_CLEAR
;
365 op
->stencil
= stencil
;
366 op
->rect_count
= rect_count
;
367 memcpy(op
->rects
, rects
, sizeof(*rects
) * rect_count
);
369 if (flags
& WINED3DCLEAR_TARGET
)
371 for (i
= 0; i
< cs
->device
->adapter
->gl_info
.limits
.buffers
; ++i
)
373 if (state
->fb
->render_targets
[i
])
374 wined3d_resource_acquire(state
->fb
->render_targets
[i
]->resource
);
377 if (flags
& (WINED3DCLEAR_ZBUFFER
| WINED3DCLEAR_STENCIL
))
378 wined3d_resource_acquire(state
->fb
->depth_stencil
->resource
);
383 static void wined3d_cs_exec_draw(struct wined3d_cs
*cs
, const void *data
)
385 struct wined3d_state
*state
= &cs
->device
->state
;
386 struct wined3d_shader_sampler_map_entry
*entry
;
387 struct wined3d_shader_resource_view
*view
;
388 const struct wined3d_cs_draw
*op
= data
;
389 struct wined3d_shader
*shader
;
392 if (!cs
->device
->adapter
->gl_info
.supported
[ARB_DRAW_ELEMENTS_BASE_VERTEX
]
393 && state
->load_base_vertex_index
!= op
->base_vertex_idx
)
395 state
->load_base_vertex_index
= op
->base_vertex_idx
;
396 device_invalidate_state(cs
->device
, STATE_BASEVERTEXINDEX
);
399 draw_primitive(cs
->device
, state
, op
->base_vertex_idx
, op
->start_idx
,
400 op
->index_count
, op
->start_instance
, op
->instance_count
, op
->indexed
);
403 wined3d_resource_release(&state
->index_buffer
->resource
);
404 for (i
= 0; i
< ARRAY_SIZE(state
->streams
); ++i
)
406 if (state
->streams
[i
].buffer
)
407 wined3d_resource_release(&state
->streams
[i
].buffer
->resource
);
409 for (i
= 0; i
< ARRAY_SIZE(state
->textures
); ++i
)
411 if (state
->textures
[i
])
412 wined3d_resource_release(&state
->textures
[i
]->resource
);
414 for (i
= 0; i
< cs
->device
->adapter
->gl_info
.limits
.buffers
; ++i
)
416 if (state
->fb
->render_targets
[i
])
417 wined3d_resource_release(state
->fb
->render_targets
[i
]->resource
);
419 if (state
->fb
->depth_stencil
)
420 wined3d_resource_release(state
->fb
->depth_stencil
->resource
);
421 for (i
= 0; i
< WINED3D_SHADER_TYPE_COUNT
; ++i
)
423 if (!(shader
= state
->shader
[i
]))
426 for (j
= 0; j
< WINED3D_MAX_CBS
; ++j
)
429 wined3d_resource_release(&state
->cb
[i
][j
]->resource
);
432 for (j
= 0; j
< shader
->reg_maps
.sampler_map
.count
; ++j
)
434 entry
= &shader
->reg_maps
.sampler_map
.entries
[j
];
436 if (!(view
= state
->shader_resource_view
[i
][entry
->resource_idx
]))
439 wined3d_resource_release(view
->resource
);
444 void wined3d_cs_emit_draw(struct wined3d_cs
*cs
, int base_vertex_idx
, unsigned int start_idx
,
445 unsigned int index_count
, unsigned int start_instance
, unsigned int instance_count
, BOOL indexed
)
447 const struct wined3d_state
*state
= &cs
->device
->state
;
448 struct wined3d_shader_sampler_map_entry
*entry
;
449 struct wined3d_shader_resource_view
*view
;
450 struct wined3d_shader
*shader
;
451 struct wined3d_cs_draw
*op
;
454 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
455 op
->opcode
= WINED3D_CS_OP_DRAW
;
456 op
->base_vertex_idx
= base_vertex_idx
;
457 op
->start_idx
= start_idx
;
458 op
->index_count
= index_count
;
459 op
->start_instance
= start_instance
;
460 op
->instance_count
= instance_count
;
461 op
->indexed
= indexed
;
464 wined3d_resource_acquire(&state
->index_buffer
->resource
);
465 for (i
= 0; i
< ARRAY_SIZE(state
->streams
); ++i
)
467 if (state
->streams
[i
].buffer
)
468 wined3d_resource_acquire(&state
->streams
[i
].buffer
->resource
);
470 for (i
= 0; i
< ARRAY_SIZE(state
->textures
); ++i
)
472 if (state
->textures
[i
])
473 wined3d_resource_acquire(&state
->textures
[i
]->resource
);
475 for (i
= 0; i
< cs
->device
->adapter
->gl_info
.limits
.buffers
; ++i
)
477 if (state
->fb
->render_targets
[i
])
478 wined3d_resource_acquire(state
->fb
->render_targets
[i
]->resource
);
480 if (state
->fb
->depth_stencil
)
481 wined3d_resource_acquire(state
->fb
->depth_stencil
->resource
);
482 for (i
= 0; i
< WINED3D_SHADER_TYPE_COUNT
; ++i
)
484 if (!(shader
= state
->shader
[i
]))
487 for (j
= 0; j
< WINED3D_MAX_CBS
; ++j
)
490 wined3d_resource_acquire(&state
->cb
[i
][j
]->resource
);
493 for (j
= 0; j
< shader
->reg_maps
.sampler_map
.count
; ++j
)
495 entry
= &shader
->reg_maps
.sampler_map
.entries
[j
];
497 if (!(view
= state
->shader_resource_view
[i
][entry
->resource_idx
]))
500 wined3d_resource_acquire(view
->resource
);
507 static void wined3d_cs_exec_set_predication(struct wined3d_cs
*cs
, const void *data
)
509 const struct wined3d_cs_set_predication
*op
= data
;
511 cs
->state
.predicate
= op
->predicate
;
512 cs
->state
.predicate_value
= op
->value
;
515 void wined3d_cs_emit_set_predication(struct wined3d_cs
*cs
, struct wined3d_query
*predicate
, BOOL value
)
517 struct wined3d_cs_set_predication
*op
;
519 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
520 op
->opcode
= WINED3D_CS_OP_SET_PREDICATION
;
521 op
->predicate
= predicate
;
527 static void wined3d_cs_exec_set_viewport(struct wined3d_cs
*cs
, const void *data
)
529 const struct wined3d_cs_set_viewport
*op
= data
;
531 cs
->state
.viewport
= op
->viewport
;
532 device_invalidate_state(cs
->device
, STATE_VIEWPORT
);
535 void wined3d_cs_emit_set_viewport(struct wined3d_cs
*cs
, const struct wined3d_viewport
*viewport
)
537 struct wined3d_cs_set_viewport
*op
;
539 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
540 op
->opcode
= WINED3D_CS_OP_SET_VIEWPORT
;
541 op
->viewport
= *viewport
;
546 static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs
*cs
, const void *data
)
548 const struct wined3d_cs_set_scissor_rect
*op
= data
;
550 cs
->state
.scissor_rect
= op
->rect
;
551 device_invalidate_state(cs
->device
, STATE_SCISSORRECT
);
554 void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs
*cs
, const RECT
*rect
)
556 struct wined3d_cs_set_scissor_rect
*op
;
558 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
559 op
->opcode
= WINED3D_CS_OP_SET_SCISSOR_RECT
;
565 static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs
*cs
, const void *data
)
567 const struct wined3d_cs_set_rendertarget_view
*op
= data
;
569 cs
->state
.fb
->render_targets
[op
->view_idx
] = op
->view
;
570 device_invalidate_state(cs
->device
, STATE_FRAMEBUFFER
);
573 void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs
*cs
, unsigned int view_idx
,
574 struct wined3d_rendertarget_view
*view
)
576 struct wined3d_cs_set_rendertarget_view
*op
;
578 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
579 op
->opcode
= WINED3D_CS_OP_SET_RENDERTARGET_VIEW
;
580 op
->view_idx
= view_idx
;
586 static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs
*cs
, const void *data
)
588 const struct wined3d_cs_set_depth_stencil_view
*op
= data
;
589 struct wined3d_device
*device
= cs
->device
;
590 struct wined3d_rendertarget_view
*prev
;
592 if ((prev
= cs
->state
.fb
->depth_stencil
))
594 struct wined3d_surface
*prev_surface
= wined3d_rendertarget_view_get_surface(prev
);
596 if (prev_surface
&& (device
->swapchains
[0]->desc
.flags
& WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL
597 || prev_surface
->container
->flags
& WINED3D_TEXTURE_DISCARD
))
599 surface_modify_ds_location(prev_surface
, WINED3D_LOCATION_DISCARDED
, prev
->width
, prev
->height
);
600 if (prev_surface
== device
->onscreen_depth_stencil
)
602 wined3d_texture_decref(device
->onscreen_depth_stencil
->container
);
603 device
->onscreen_depth_stencil
= NULL
;
608 cs
->fb
.depth_stencil
= op
->view
;
610 if (!prev
!= !op
->view
)
612 /* Swapping NULL / non NULL depth stencil affects the depth and tests */
613 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_ZENABLE
));
614 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_STENCILENABLE
));
615 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK
));
616 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_DEPTHBIAS
));
618 else if (prev
&& (prev
->format_flags
& WINED3DFMT_FLAG_FLOAT
)
619 != (op
->view
->format_flags
& WINED3DFMT_FLAG_FLOAT
))
621 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_DEPTHBIAS
));
624 device_invalidate_state(device
, STATE_FRAMEBUFFER
);
627 void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs
*cs
, struct wined3d_rendertarget_view
*view
)
629 struct wined3d_cs_set_depth_stencil_view
*op
;
631 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
632 op
->opcode
= WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW
;
638 static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs
*cs
, const void *data
)
640 const struct wined3d_cs_set_vertex_declaration
*op
= data
;
642 cs
->state
.vertex_declaration
= op
->declaration
;
643 device_invalidate_state(cs
->device
, STATE_VDECL
);
646 void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs
*cs
, struct wined3d_vertex_declaration
*declaration
)
648 struct wined3d_cs_set_vertex_declaration
*op
;
650 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
651 op
->opcode
= WINED3D_CS_OP_SET_VERTEX_DECLARATION
;
652 op
->declaration
= declaration
;
657 static void wined3d_cs_exec_set_stream_source(struct wined3d_cs
*cs
, const void *data
)
659 const struct wined3d_cs_set_stream_source
*op
= data
;
660 struct wined3d_stream_state
*stream
;
661 struct wined3d_buffer
*prev
;
663 stream
= &cs
->state
.streams
[op
->stream_idx
];
664 prev
= stream
->buffer
;
665 stream
->buffer
= op
->buffer
;
666 stream
->offset
= op
->offset
;
667 stream
->stride
= op
->stride
;
670 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
672 InterlockedDecrement(&prev
->resource
.bind_count
);
674 device_invalidate_state(cs
->device
, STATE_STREAMSRC
);
677 void wined3d_cs_emit_set_stream_source(struct wined3d_cs
*cs
, UINT stream_idx
,
678 struct wined3d_buffer
*buffer
, UINT offset
, UINT stride
)
680 struct wined3d_cs_set_stream_source
*op
;
682 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
683 op
->opcode
= WINED3D_CS_OP_SET_STREAM_SOURCE
;
684 op
->stream_idx
= stream_idx
;
692 static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs
*cs
, const void *data
)
694 const struct wined3d_cs_set_stream_source_freq
*op
= data
;
695 struct wined3d_stream_state
*stream
;
697 stream
= &cs
->state
.streams
[op
->stream_idx
];
698 stream
->frequency
= op
->frequency
;
699 stream
->flags
= op
->flags
;
701 device_invalidate_state(cs
->device
, STATE_STREAMSRC
);
704 void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs
*cs
, UINT stream_idx
, UINT frequency
, UINT flags
)
706 struct wined3d_cs_set_stream_source_freq
*op
;
708 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
709 op
->opcode
= WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ
;
710 op
->stream_idx
= stream_idx
;
711 op
->frequency
= frequency
;
717 static void wined3d_cs_exec_set_stream_output(struct wined3d_cs
*cs
, const void *data
)
719 const struct wined3d_cs_set_stream_output
*op
= data
;
720 struct wined3d_stream_output
*stream
;
721 struct wined3d_buffer
*prev
;
723 stream
= &cs
->state
.stream_output
[op
->stream_idx
];
724 prev
= stream
->buffer
;
725 stream
->buffer
= op
->buffer
;
726 stream
->offset
= op
->offset
;
729 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
731 InterlockedDecrement(&prev
->resource
.bind_count
);
734 void wined3d_cs_emit_set_stream_output(struct wined3d_cs
*cs
, UINT stream_idx
,
735 struct wined3d_buffer
*buffer
, UINT offset
)
737 struct wined3d_cs_set_stream_output
*op
;
739 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
740 op
->opcode
= WINED3D_CS_OP_SET_STREAM_OUTPUT
;
741 op
->stream_idx
= stream_idx
;
748 static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs
*cs
, const void *data
)
750 const struct wined3d_cs_set_index_buffer
*op
= data
;
751 struct wined3d_buffer
*prev
;
753 prev
= cs
->state
.index_buffer
;
754 cs
->state
.index_buffer
= op
->buffer
;
755 cs
->state
.index_format
= op
->format_id
;
756 cs
->state
.index_offset
= op
->offset
;
759 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
761 InterlockedDecrement(&prev
->resource
.bind_count
);
763 device_invalidate_state(cs
->device
, STATE_INDEXBUFFER
);
766 void wined3d_cs_emit_set_index_buffer(struct wined3d_cs
*cs
, struct wined3d_buffer
*buffer
,
767 enum wined3d_format_id format_id
, unsigned int offset
)
769 struct wined3d_cs_set_index_buffer
*op
;
771 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
772 op
->opcode
= WINED3D_CS_OP_SET_INDEX_BUFFER
;
774 op
->format_id
= format_id
;
780 static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs
*cs
, const void *data
)
782 const struct wined3d_cs_set_constant_buffer
*op
= data
;
783 struct wined3d_buffer
*prev
;
785 prev
= cs
->state
.cb
[op
->type
][op
->cb_idx
];
786 cs
->state
.cb
[op
->type
][op
->cb_idx
] = op
->buffer
;
789 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
791 InterlockedDecrement(&prev
->resource
.bind_count
);
793 device_invalidate_state(cs
->device
, STATE_CONSTANT_BUFFER(op
->type
));
796 void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs
*cs
, enum wined3d_shader_type type
,
797 UINT cb_idx
, struct wined3d_buffer
*buffer
)
799 struct wined3d_cs_set_constant_buffer
*op
;
801 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
802 op
->opcode
= WINED3D_CS_OP_SET_CONSTANT_BUFFER
;
810 static void wined3d_cs_exec_set_texture(struct wined3d_cs
*cs
, const void *data
)
812 const struct wined3d_gl_info
*gl_info
= &cs
->device
->adapter
->gl_info
;
813 const struct wined3d_d3d_info
*d3d_info
= &cs
->device
->adapter
->d3d_info
;
814 const struct wined3d_cs_set_texture
*op
= data
;
815 struct wined3d_texture
*prev
;
816 BOOL old_use_color_key
= FALSE
, new_use_color_key
= FALSE
;
818 prev
= cs
->state
.textures
[op
->stage
];
819 cs
->state
.textures
[op
->stage
] = op
->texture
;
823 const struct wined3d_format
*new_format
= op
->texture
->resource
.format
;
824 const struct wined3d_format
*old_format
= prev
? prev
->resource
.format
: NULL
;
825 unsigned int old_fmt_flags
= prev
? prev
->resource
.format_flags
: 0;
826 unsigned int new_fmt_flags
= op
->texture
->resource
.format_flags
;
828 if (InterlockedIncrement(&op
->texture
->resource
.bind_count
) == 1)
829 op
->texture
->sampler
= op
->stage
;
831 if (!prev
|| op
->texture
->target
!= prev
->target
832 || (!is_same_fixup(new_format
->color_fixup
, old_format
->color_fixup
)
833 && !(can_use_texture_swizzle(gl_info
, new_format
) && can_use_texture_swizzle(gl_info
, old_format
)))
834 || (new_fmt_flags
& WINED3DFMT_FLAG_SHADOW
) != (old_fmt_flags
& WINED3DFMT_FLAG_SHADOW
))
835 device_invalidate_state(cs
->device
, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL
));
837 if (!prev
&& op
->stage
< d3d_info
->limits
.ffp_blend_stages
)
839 /* The source arguments for color and alpha ops have different
840 * meanings when a NULL texture is bound, so the COLOR_OP and
841 * ALPHA_OP have to be dirtified. */
842 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_COLOR_OP
));
843 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_ALPHA_OP
));
846 if (!op
->stage
&& op
->texture
->async
.color_key_flags
& WINED3D_CKEY_SRC_BLT
)
847 new_use_color_key
= TRUE
;
852 if (InterlockedDecrement(&prev
->resource
.bind_count
) && prev
->sampler
== op
->stage
)
856 /* Search for other stages the texture is bound to. Shouldn't
857 * happen if applications bind textures to a single stage only. */
858 TRACE("Searching for other stages the texture is bound to.\n");
859 for (i
= 0; i
< MAX_COMBINED_SAMPLERS
; ++i
)
861 if (cs
->state
.textures
[i
] == prev
)
863 TRACE("Texture is also bound to stage %u.\n", i
);
870 if (!op
->texture
&& op
->stage
< d3d_info
->limits
.ffp_blend_stages
)
872 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_COLOR_OP
));
873 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_ALPHA_OP
));
876 if (!op
->stage
&& prev
->async
.color_key_flags
& WINED3D_CKEY_SRC_BLT
)
877 old_use_color_key
= TRUE
;
880 device_invalidate_state(cs
->device
, STATE_SAMPLER(op
->stage
));
882 if (new_use_color_key
!= old_use_color_key
)
883 device_invalidate_state(cs
->device
, STATE_RENDER(WINED3D_RS_COLORKEYENABLE
));
885 if (new_use_color_key
)
886 device_invalidate_state(cs
->device
, STATE_COLOR_KEY
);
889 void wined3d_cs_emit_set_texture(struct wined3d_cs
*cs
, UINT stage
, struct wined3d_texture
*texture
)
891 struct wined3d_cs_set_texture
*op
;
893 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
894 op
->opcode
= WINED3D_CS_OP_SET_TEXTURE
;
896 op
->texture
= texture
;
901 static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs
*cs
, const void *data
)
903 const struct wined3d_cs_set_shader_resource_view
*op
= data
;
905 cs
->state
.shader_resource_view
[op
->type
][op
->view_idx
] = op
->view
;
906 device_invalidate_state(cs
->device
, STATE_SHADER_RESOURCE_BINDING
);
909 void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs
*cs
, enum wined3d_shader_type type
,
910 UINT view_idx
, struct wined3d_shader_resource_view
*view
)
912 struct wined3d_cs_set_shader_resource_view
*op
;
914 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
915 op
->opcode
= WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW
;
917 op
->view_idx
= view_idx
;
923 static void wined3d_cs_exec_set_sampler(struct wined3d_cs
*cs
, const void *data
)
925 const struct wined3d_cs_set_sampler
*op
= data
;
927 cs
->state
.sampler
[op
->type
][op
->sampler_idx
] = op
->sampler
;
928 device_invalidate_state(cs
->device
, STATE_SHADER_RESOURCE_BINDING
);
931 void wined3d_cs_emit_set_sampler(struct wined3d_cs
*cs
, enum wined3d_shader_type type
,
932 UINT sampler_idx
, struct wined3d_sampler
*sampler
)
934 struct wined3d_cs_set_sampler
*op
;
936 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
937 op
->opcode
= WINED3D_CS_OP_SET_SAMPLER
;
939 op
->sampler_idx
= sampler_idx
;
940 op
->sampler
= sampler
;
945 static void wined3d_cs_exec_set_shader(struct wined3d_cs
*cs
, const void *data
)
947 const struct wined3d_cs_set_shader
*op
= data
;
949 cs
->state
.shader
[op
->type
] = op
->shader
;
950 device_invalidate_state(cs
->device
, STATE_SHADER(op
->type
));
951 device_invalidate_state(cs
->device
, STATE_SHADER_RESOURCE_BINDING
);
954 void wined3d_cs_emit_set_shader(struct wined3d_cs
*cs
, enum wined3d_shader_type type
, struct wined3d_shader
*shader
)
956 struct wined3d_cs_set_shader
*op
;
958 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
959 op
->opcode
= WINED3D_CS_OP_SET_SHADER
;
966 static void wined3d_cs_exec_set_rasterizer_state(struct wined3d_cs
*cs
, const void *data
)
968 const struct wined3d_cs_set_rasterizer_state
*op
= data
;
970 cs
->state
.rasterizer_state
= op
->state
;
971 device_invalidate_state(cs
->device
, STATE_FRONTFACE
);
974 void wined3d_cs_emit_set_rasterizer_state(struct wined3d_cs
*cs
,
975 struct wined3d_rasterizer_state
*rasterizer_state
)
977 struct wined3d_cs_set_rasterizer_state
*op
;
979 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
980 op
->opcode
= WINED3D_CS_OP_SET_RASTERIZER_STATE
;
981 op
->state
= rasterizer_state
;
986 static void wined3d_cs_exec_set_render_state(struct wined3d_cs
*cs
, const void *data
)
988 const struct wined3d_cs_set_render_state
*op
= data
;
990 cs
->state
.render_states
[op
->state
] = op
->value
;
991 device_invalidate_state(cs
->device
, STATE_RENDER(op
->state
));
994 void wined3d_cs_emit_set_render_state(struct wined3d_cs
*cs
, enum wined3d_render_state state
, DWORD value
)
996 struct wined3d_cs_set_render_state
*op
;
998 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
999 op
->opcode
= WINED3D_CS_OP_SET_RENDER_STATE
;
1003 cs
->ops
->submit(cs
);
1006 static void wined3d_cs_exec_set_texture_state(struct wined3d_cs
*cs
, const void *data
)
1008 const struct wined3d_cs_set_texture_state
*op
= data
;
1010 cs
->state
.texture_states
[op
->stage
][op
->state
] = op
->value
;
1011 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, op
->state
));
1014 void wined3d_cs_emit_set_texture_state(struct wined3d_cs
*cs
, UINT stage
,
1015 enum wined3d_texture_stage_state state
, DWORD value
)
1017 struct wined3d_cs_set_texture_state
*op
;
1019 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1020 op
->opcode
= WINED3D_CS_OP_SET_TEXTURE_STATE
;
1025 cs
->ops
->submit(cs
);
1028 static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs
*cs
, const void *data
)
1030 const struct wined3d_cs_set_sampler_state
*op
= data
;
1032 cs
->state
.sampler_states
[op
->sampler_idx
][op
->state
] = op
->value
;
1033 device_invalidate_state(cs
->device
, STATE_SAMPLER(op
->sampler_idx
));
1036 void wined3d_cs_emit_set_sampler_state(struct wined3d_cs
*cs
, UINT sampler_idx
,
1037 enum wined3d_sampler_state state
, DWORD value
)
1039 struct wined3d_cs_set_sampler_state
*op
;
1041 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1042 op
->opcode
= WINED3D_CS_OP_SET_SAMPLER_STATE
;
1043 op
->sampler_idx
= sampler_idx
;
1047 cs
->ops
->submit(cs
);
1050 static void wined3d_cs_exec_set_transform(struct wined3d_cs
*cs
, const void *data
)
1052 const struct wined3d_cs_set_transform
*op
= data
;
1054 cs
->state
.transforms
[op
->state
] = op
->matrix
;
1055 if (op
->state
< WINED3D_TS_WORLD_MATRIX(cs
->device
->adapter
->d3d_info
.limits
.ffp_vertex_blend_matrices
))
1056 device_invalidate_state(cs
->device
, STATE_TRANSFORM(op
->state
));
1059 void wined3d_cs_emit_set_transform(struct wined3d_cs
*cs
, enum wined3d_transform_state state
,
1060 const struct wined3d_matrix
*matrix
)
1062 struct wined3d_cs_set_transform
*op
;
1064 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1065 op
->opcode
= WINED3D_CS_OP_SET_TRANSFORM
;
1067 op
->matrix
= *matrix
;
1069 cs
->ops
->submit(cs
);
1072 static void wined3d_cs_exec_set_clip_plane(struct wined3d_cs
*cs
, const void *data
)
1074 const struct wined3d_cs_set_clip_plane
*op
= data
;
1076 cs
->state
.clip_planes
[op
->plane_idx
] = op
->plane
;
1077 device_invalidate_state(cs
->device
, STATE_CLIPPLANE(op
->plane_idx
));
1080 void wined3d_cs_emit_set_clip_plane(struct wined3d_cs
*cs
, UINT plane_idx
, const struct wined3d_vec4
*plane
)
1082 struct wined3d_cs_set_clip_plane
*op
;
1084 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1085 op
->opcode
= WINED3D_CS_OP_SET_CLIP_PLANE
;
1086 op
->plane_idx
= plane_idx
;
1089 cs
->ops
->submit(cs
);
1092 static void wined3d_cs_exec_set_color_key(struct wined3d_cs
*cs
, const void *data
)
1094 const struct wined3d_cs_set_color_key
*op
= data
;
1095 struct wined3d_texture
*texture
= op
->texture
;
1101 case WINED3D_CKEY_DST_BLT
:
1102 texture
->async
.dst_blt_color_key
= op
->color_key
;
1103 texture
->async
.color_key_flags
|= WINED3D_CKEY_DST_BLT
;
1106 case WINED3D_CKEY_DST_OVERLAY
:
1107 texture
->async
.dst_overlay_color_key
= op
->color_key
;
1108 texture
->async
.color_key_flags
|= WINED3D_CKEY_DST_OVERLAY
;
1111 case WINED3D_CKEY_SRC_BLT
:
1112 if (texture
== cs
->state
.textures
[0])
1114 device_invalidate_state(cs
->device
, STATE_COLOR_KEY
);
1115 if (!(texture
->async
.color_key_flags
& WINED3D_CKEY_SRC_BLT
))
1116 device_invalidate_state(cs
->device
, STATE_RENDER(WINED3D_RS_COLORKEYENABLE
));
1119 texture
->async
.src_blt_color_key
= op
->color_key
;
1120 texture
->async
.color_key_flags
|= WINED3D_CKEY_SRC_BLT
;
1123 case WINED3D_CKEY_SRC_OVERLAY
:
1124 texture
->async
.src_overlay_color_key
= op
->color_key
;
1125 texture
->async
.color_key_flags
|= WINED3D_CKEY_SRC_OVERLAY
;
1133 case WINED3D_CKEY_DST_BLT
:
1134 texture
->async
.color_key_flags
&= ~WINED3D_CKEY_DST_BLT
;
1137 case WINED3D_CKEY_DST_OVERLAY
:
1138 texture
->async
.color_key_flags
&= ~WINED3D_CKEY_DST_OVERLAY
;
1141 case WINED3D_CKEY_SRC_BLT
:
1142 if (texture
== cs
->state
.textures
[0] && texture
->async
.color_key_flags
& WINED3D_CKEY_SRC_BLT
)
1143 device_invalidate_state(cs
->device
, STATE_RENDER(WINED3D_RS_COLORKEYENABLE
));
1145 texture
->async
.color_key_flags
&= ~WINED3D_CKEY_SRC_BLT
;
1148 case WINED3D_CKEY_SRC_OVERLAY
:
1149 texture
->async
.color_key_flags
&= ~WINED3D_CKEY_SRC_OVERLAY
;
1155 void wined3d_cs_emit_set_color_key(struct wined3d_cs
*cs
, struct wined3d_texture
*texture
,
1156 WORD flags
, const struct wined3d_color_key
*color_key
)
1158 struct wined3d_cs_set_color_key
*op
;
1160 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1161 op
->opcode
= WINED3D_CS_OP_SET_COLOR_KEY
;
1162 op
->texture
= texture
;
1166 op
->color_key
= *color_key
;
1172 cs
->ops
->submit(cs
);
1175 static void wined3d_cs_exec_set_material(struct wined3d_cs
*cs
, const void *data
)
1177 const struct wined3d_cs_set_material
*op
= data
;
1179 cs
->state
.material
= op
->material
;
1180 device_invalidate_state(cs
->device
, STATE_MATERIAL
);
1183 void wined3d_cs_emit_set_material(struct wined3d_cs
*cs
, const struct wined3d_material
*material
)
1185 struct wined3d_cs_set_material
*op
;
1187 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1188 op
->opcode
= WINED3D_CS_OP_SET_MATERIAL
;
1189 op
->material
= *material
;
1191 cs
->ops
->submit(cs
);
1194 static void wined3d_cs_exec_reset_state(struct wined3d_cs
*cs
, const void *data
)
1196 struct wined3d_adapter
*adapter
= cs
->device
->adapter
;
1198 state_cleanup(&cs
->state
);
1199 memset(&cs
->state
, 0, sizeof(cs
->state
));
1200 state_init(&cs
->state
, &cs
->fb
, &adapter
->gl_info
, &adapter
->d3d_info
,
1201 WINED3D_STATE_NO_REF
| WINED3D_STATE_INIT_DEFAULT
);
1204 void wined3d_cs_emit_reset_state(struct wined3d_cs
*cs
)
1206 struct wined3d_cs_reset_state
*op
;
1208 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1209 op
->opcode
= WINED3D_CS_OP_RESET_STATE
;
1211 cs
->ops
->submit(cs
);
1214 static void wined3d_cs_exec_destroy_object(struct wined3d_cs
*cs
, const void *data
)
1216 const struct wined3d_cs_destroy_object
*op
= data
;
1218 op
->callback(op
->object
);
1221 void wined3d_cs_emit_destroy_object(struct wined3d_cs
*cs
, void (*callback
)(void *object
), void *object
)
1223 struct wined3d_cs_destroy_object
*op
;
1225 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1226 op
->opcode
= WINED3D_CS_OP_DESTROY_OBJECT
;
1227 op
->callback
= callback
;
1228 op
->object
= object
;
1230 cs
->ops
->submit(cs
);
1233 static void wined3d_cs_exec_query_issue(struct wined3d_cs
*cs
, const void *data
)
1235 const struct wined3d_cs_query_issue
*op
= data
;
1236 struct wined3d_query
*query
= op
->query
;
1238 query
->query_ops
->query_issue(query
, op
->flags
);
1241 void wined3d_cs_emit_query_issue(struct wined3d_cs
*cs
, struct wined3d_query
*query
, DWORD flags
)
1243 struct wined3d_cs_query_issue
*op
;
1245 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1246 op
->opcode
= WINED3D_CS_OP_QUERY_ISSUE
;
1250 cs
->ops
->submit(cs
);
1253 static void wined3d_cs_exec_unload_resource(struct wined3d_cs
*cs
, const void *data
)
1255 const struct wined3d_cs_unload_resource
*op
= data
;
1256 struct wined3d_resource
*resource
= op
->resource
;
1258 resource
->resource_ops
->resource_unload(resource
);
1259 wined3d_resource_release(resource
);
1262 void wined3d_cs_emit_unload_resource(struct wined3d_cs
*cs
, struct wined3d_resource
*resource
)
1264 struct wined3d_cs_unload_resource
*op
;
1266 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
1267 op
->opcode
= WINED3D_CS_OP_UNLOAD_RESOURCE
;
1268 op
->resource
= resource
;
1270 wined3d_resource_acquire(resource
);
1272 cs
->ops
->submit(cs
);
1275 static void (* const wined3d_cs_op_handlers
[])(struct wined3d_cs
*cs
, const void *data
) =
1277 /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present
,
1278 /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear
,
1279 /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw
,
1280 /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication
,
1281 /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport
,
1282 /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect
,
1283 /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view
,
1284 /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view
,
1285 /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration
,
1286 /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source
,
1287 /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq
,
1288 /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output
,
1289 /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer
,
1290 /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer
,
1291 /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture
,
1292 /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view
,
1293 /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler
,
1294 /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader
,
1295 /* WINED3D_CS_OP_SET_RASTERIZER_STATE */ wined3d_cs_exec_set_rasterizer_state
,
1296 /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state
,
1297 /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state
,
1298 /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state
,
1299 /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform
,
1300 /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane
,
1301 /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key
,
1302 /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material
,
1303 /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state
,
1304 /* WINED3D_CS_OP_DESTROY_OBJECT */ wined3d_cs_exec_destroy_object
,
1305 /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue
,
1306 /* WINED3D_CS_OP_UNLOAD_RESOURCE */ wined3d_cs_exec_unload_resource
,
1309 static void *wined3d_cs_st_require_space(struct wined3d_cs
*cs
, size_t size
)
1311 if (size
> cs
->data_size
)
1315 size
= max( size
, cs
->data_size
* 2 );
1316 if (!(new_data
= HeapReAlloc(GetProcessHeap(), 0, cs
->data
, size
)))
1319 cs
->data_size
= size
;
1320 cs
->data
= new_data
;
1326 static void wined3d_cs_st_submit(struct wined3d_cs
*cs
)
1328 enum wined3d_cs_op opcode
= *(const enum wined3d_cs_op
*)cs
->data
;
1330 wined3d_cs_op_handlers
[opcode
](cs
, cs
->data
);
1333 static void wined3d_cs_st_push_constants(struct wined3d_cs
*cs
, enum wined3d_push_constants p
,
1334 unsigned int start_idx
, unsigned int count
, const void *constants
)
1336 struct wined3d_device
*device
= cs
->device
;
1337 unsigned int context_count
;
1347 push_constant_info
[] =
1349 /* WINED3D_PUSH_CONSTANTS_VS_F */
1350 {FIELD_OFFSET(struct wined3d_state
, vs_consts_f
), sizeof(struct wined3d_vec4
), WINED3D_SHADER_CONST_VS_F
},
1351 /* WINED3D_PUSH_CONSTANTS_PS_F */
1352 {FIELD_OFFSET(struct wined3d_state
, ps_consts_f
), sizeof(struct wined3d_vec4
), WINED3D_SHADER_CONST_PS_F
},
1353 /* WINED3D_PUSH_CONSTANTS_VS_I */
1354 {FIELD_OFFSET(struct wined3d_state
, vs_consts_i
), sizeof(struct wined3d_ivec4
), WINED3D_SHADER_CONST_VS_I
},
1355 /* WINED3D_PUSH_CONSTANTS_PS_I */
1356 {FIELD_OFFSET(struct wined3d_state
, ps_consts_i
), sizeof(struct wined3d_ivec4
), WINED3D_SHADER_CONST_PS_I
},
1357 /* WINED3D_PUSH_CONSTANTS_VS_B */
1358 {FIELD_OFFSET(struct wined3d_state
, vs_consts_b
), sizeof(BOOL
), WINED3D_SHADER_CONST_VS_B
},
1359 /* WINED3D_PUSH_CONSTANTS_PS_B */
1360 {FIELD_OFFSET(struct wined3d_state
, ps_consts_b
), sizeof(BOOL
), WINED3D_SHADER_CONST_PS_B
},
1363 if (p
== WINED3D_PUSH_CONSTANTS_VS_F
)
1364 device
->shader_backend
->shader_update_float_vertex_constants(device
, start_idx
, count
);
1365 else if (p
== WINED3D_PUSH_CONSTANTS_PS_F
)
1366 device
->shader_backend
->shader_update_float_pixel_constants(device
, start_idx
, count
);
1368 offset
= push_constant_info
[p
].offset
+ start_idx
* push_constant_info
[p
].size
;
1369 memcpy((BYTE
*)&cs
->state
+ offset
, constants
, count
* push_constant_info
[p
].size
);
1370 for (i
= 0, context_count
= device
->context_count
; i
< context_count
; ++i
)
1372 device
->contexts
[i
]->constant_update_mask
|= push_constant_info
[p
].mask
;
1376 static const struct wined3d_cs_ops wined3d_cs_st_ops
=
1378 wined3d_cs_st_require_space
,
1379 wined3d_cs_st_submit
,
1380 wined3d_cs_st_push_constants
,
1383 struct wined3d_cs
*wined3d_cs_create(struct wined3d_device
*device
)
1385 const struct wined3d_gl_info
*gl_info
= &device
->adapter
->gl_info
;
1386 struct wined3d_cs
*cs
;
1388 if (!(cs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*cs
))))
1391 if (!(cs
->fb
.render_targets
= wined3d_calloc(gl_info
->limits
.buffers
, sizeof(*cs
->fb
.render_targets
))))
1393 HeapFree(GetProcessHeap(), 0, cs
);
1397 state_init(&cs
->state
, &cs
->fb
, gl_info
, &device
->adapter
->d3d_info
,
1398 WINED3D_STATE_NO_REF
| WINED3D_STATE_INIT_DEFAULT
);
1400 cs
->ops
= &wined3d_cs_st_ops
;
1401 cs
->device
= device
;
1403 cs
->data_size
= WINED3D_INITIAL_CS_SIZE
;
1404 if (!(cs
->data
= HeapAlloc(GetProcessHeap(), 0, cs
->data_size
)))
1406 state_cleanup(&cs
->state
);
1407 HeapFree(GetProcessHeap(), 0, cs
->fb
.render_targets
);
1408 HeapFree(GetProcessHeap(), 0, cs
);
1415 void wined3d_cs_destroy(struct wined3d_cs
*cs
)
1417 state_cleanup(&cs
->state
);
1418 HeapFree(GetProcessHeap(), 0, cs
->fb
.render_targets
);
1419 HeapFree(GetProcessHeap(), 0, cs
->data
);
1420 HeapFree(GetProcessHeap(), 0, cs
);