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_VIEWPORT
,
33 WINED3D_CS_OP_SET_SCISSOR_RECT
,
34 WINED3D_CS_OP_SET_RENDER_TARGET
,
35 WINED3D_CS_OP_SET_DEPTH_STENCIL
,
36 WINED3D_CS_OP_SET_VERTEX_DECLARATION
,
37 WINED3D_CS_OP_SET_STREAM_SOURCE
,
38 WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ
,
39 WINED3D_CS_OP_SET_INDEX_BUFFER
,
40 WINED3D_CS_OP_SET_TEXTURE
,
41 WINED3D_CS_OP_SET_VERTEX_SHADER
,
42 WINED3D_CS_OP_SET_GEOMETRY_SHADER
,
43 WINED3D_CS_OP_SET_PIXEL_SHADER
,
44 WINED3D_CS_OP_SET_RENDER_STATE
,
47 struct wined3d_cs_present
49 enum wined3d_cs_op opcode
;
50 HWND dst_window_override
;
51 struct wined3d_swapchain
*swapchain
;
54 const RGNDATA
*dirty_region
;
58 struct wined3d_cs_clear
60 enum wined3d_cs_op opcode
;
64 const struct wined3d_color
*color
;
69 struct wined3d_cs_draw
71 enum wined3d_cs_op opcode
;
79 struct wined3d_cs_set_viewport
81 enum wined3d_cs_op opcode
;
82 const struct wined3d_viewport
*viewport
;
85 struct wined3d_cs_set_scissor_rect
87 enum wined3d_cs_op opcode
;
91 struct wined3d_cs_set_render_target
93 enum wined3d_cs_op opcode
;
94 UINT render_target_idx
;
95 struct wined3d_surface
*render_target
;
98 struct wined3d_cs_set_depth_stencil
100 enum wined3d_cs_op opcode
;
101 struct wined3d_surface
*depth_stencil
;
104 struct wined3d_cs_set_vertex_declaration
106 enum wined3d_cs_op opcode
;
107 struct wined3d_vertex_declaration
*declaration
;
110 struct wined3d_cs_set_stream_source
112 enum wined3d_cs_op opcode
;
114 struct wined3d_buffer
*buffer
;
119 struct wined3d_cs_set_stream_source_freq
121 enum wined3d_cs_op opcode
;
127 struct wined3d_cs_set_index_buffer
129 enum wined3d_cs_op opcode
;
130 struct wined3d_buffer
*buffer
;
131 enum wined3d_format_id format_id
;
134 struct wined3d_cs_set_texture
136 enum wined3d_cs_op opcode
;
138 struct wined3d_texture
*texture
;
141 struct wined3d_cs_set_shader
143 enum wined3d_cs_op opcode
;
144 struct wined3d_shader
*shader
;
147 struct wined3d_cs_set_render_state
149 enum wined3d_cs_op opcode
;
150 enum wined3d_render_state state
;
154 static void wined3d_cs_exec_present(struct wined3d_cs
*cs
, const void *data
)
156 const struct wined3d_cs_present
*op
= data
;
157 struct wined3d_swapchain
*swapchain
;
159 swapchain
= op
->swapchain
;
160 wined3d_swapchain_set_window(swapchain
, op
->dst_window_override
);
162 swapchain
->swapchain_ops
->swapchain_present(swapchain
,
163 op
->src_rect
, op
->dst_rect
, op
->dirty_region
, op
->flags
);
166 void wined3d_cs_emit_present(struct wined3d_cs
*cs
, struct wined3d_swapchain
*swapchain
,
167 const RECT
*src_rect
, const RECT
*dst_rect
, HWND dst_window_override
,
168 const RGNDATA
*dirty_region
, DWORD flags
)
170 struct wined3d_cs_present
*op
;
172 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
173 op
->opcode
= WINED3D_CS_OP_PRESENT
;
174 op
->dst_window_override
= dst_window_override
;
175 op
->swapchain
= swapchain
;
176 op
->src_rect
= src_rect
;
177 op
->dst_rect
= dst_rect
;
178 op
->dirty_region
= dirty_region
;
184 static void wined3d_cs_exec_clear(struct wined3d_cs
*cs
, const void *data
)
186 const struct wined3d_cs_clear
*op
= data
;
187 struct wined3d_device
*device
;
191 wined3d_get_draw_rect(&device
->state
, &draw_rect
);
192 device_clear_render_targets(device
, device
->adapter
->gl_info
.limits
.buffers
,
193 &device
->fb
, op
->rect_count
, op
->rects
, &draw_rect
, op
->flags
,
194 op
->color
, op
->depth
, op
->stencil
);
197 void wined3d_cs_emit_clear(struct wined3d_cs
*cs
, DWORD rect_count
, const RECT
*rects
,
198 DWORD flags
, const struct wined3d_color
*color
, float depth
, DWORD stencil
)
200 struct wined3d_cs_clear
*op
;
202 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
203 op
->opcode
= WINED3D_CS_OP_CLEAR
;
204 op
->rect_count
= rect_count
;
209 op
->stencil
= stencil
;
214 static void wined3d_cs_exec_draw(struct wined3d_cs
*cs
, const void *data
)
216 const struct wined3d_cs_draw
*op
= data
;
218 draw_primitive(cs
->device
, op
->start_idx
, op
->index_count
,
219 op
->start_instance
, op
->instance_count
, op
->indexed
);
222 void wined3d_cs_emit_draw(struct wined3d_cs
*cs
, UINT start_idx
, UINT index_count
,
223 UINT start_instance
, UINT instance_count
, BOOL indexed
)
225 struct wined3d_cs_draw
*op
;
227 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
228 op
->opcode
= WINED3D_CS_OP_DRAW
;
229 op
->start_idx
= start_idx
;
230 op
->index_count
= index_count
;
231 op
->start_instance
= start_instance
;
232 op
->instance_count
= instance_count
;
233 op
->indexed
= indexed
;
238 static void wined3d_cs_exec_set_viewport(struct wined3d_cs
*cs
, const void *data
)
240 const struct wined3d_cs_set_viewport
*op
= data
;
242 cs
->state
.viewport
= *op
->viewport
;
243 device_invalidate_state(cs
->device
, STATE_VIEWPORT
);
246 void wined3d_cs_emit_set_viewport(struct wined3d_cs
*cs
, const struct wined3d_viewport
*viewport
)
248 struct wined3d_cs_set_viewport
*op
;
250 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
251 op
->opcode
= WINED3D_CS_OP_SET_VIEWPORT
;
252 op
->viewport
= viewport
;
257 static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs
*cs
, const void *data
)
259 const struct wined3d_cs_set_scissor_rect
*op
= data
;
261 cs
->state
.scissor_rect
= *op
->rect
;
262 device_invalidate_state(cs
->device
, STATE_SCISSORRECT
);
265 void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs
*cs
, const RECT
*rect
)
267 struct wined3d_cs_set_scissor_rect
*op
;
269 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
270 op
->opcode
= WINED3D_CS_OP_SET_SCISSOR_RECT
;
276 static void wined3d_cs_exec_set_render_target(struct wined3d_cs
*cs
, const void *data
)
278 const struct wined3d_cs_set_render_target
*op
= data
;
280 cs
->state
.fb
->render_targets
[op
->render_target_idx
] = op
->render_target
;
281 device_invalidate_state(cs
->device
, STATE_FRAMEBUFFER
);
284 void wined3d_cs_emit_set_render_target(struct wined3d_cs
*cs
, UINT render_target_idx
,
285 struct wined3d_surface
*render_target
)
287 struct wined3d_cs_set_render_target
*op
;
289 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
290 op
->opcode
= WINED3D_CS_OP_SET_RENDER_TARGET
;
291 op
->render_target_idx
= render_target_idx
;
292 op
->render_target
= render_target
;
297 static void wined3d_cs_exec_set_depth_stencil(struct wined3d_cs
*cs
, const void *data
)
299 const struct wined3d_cs_set_depth_stencil
*op
= data
;
300 struct wined3d_device
*device
= cs
->device
;
301 struct wined3d_surface
*prev
;
303 if ((prev
= cs
->state
.fb
->depth_stencil
))
305 if (device
->swapchains
[0]->desc
.flags
& WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
306 || prev
->flags
& SFLAG_DISCARD
)
308 surface_modify_ds_location(prev
, SFLAG_DISCARDED
,
309 prev
->resource
.width
, prev
->resource
.height
);
310 if (prev
== device
->onscreen_depth_stencil
)
312 wined3d_surface_decref(device
->onscreen_depth_stencil
);
313 device
->onscreen_depth_stencil
= NULL
;
318 cs
->fb
.depth_stencil
= op
->depth_stencil
;
320 if (!prev
!= !op
->depth_stencil
)
322 /* Swapping NULL / non NULL depth stencil affects the depth and tests */
323 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_ZENABLE
));
324 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_STENCILENABLE
));
325 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK
));
326 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_DEPTHBIAS
));
328 else if (prev
&& prev
->resource
.format
->depth_size
!= op
->depth_stencil
->resource
.format
->depth_size
)
330 device_invalidate_state(device
, STATE_RENDER(WINED3D_RS_DEPTHBIAS
));
333 device_invalidate_state(device
, STATE_FRAMEBUFFER
);
336 void wined3d_cs_emit_set_depth_stencil(struct wined3d_cs
*cs
, struct wined3d_surface
*depth_stencil
)
338 struct wined3d_cs_set_depth_stencil
*op
;
340 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
341 op
->opcode
= WINED3D_CS_OP_SET_DEPTH_STENCIL
;
342 op
->depth_stencil
= depth_stencil
;
347 static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs
*cs
, const void *data
)
349 const struct wined3d_cs_set_vertex_declaration
*op
= data
;
351 cs
->state
.vertex_declaration
= op
->declaration
;
352 device_invalidate_state(cs
->device
, STATE_VDECL
);
355 void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs
*cs
, struct wined3d_vertex_declaration
*declaration
)
357 struct wined3d_cs_set_vertex_declaration
*op
;
359 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
360 op
->opcode
= WINED3D_CS_OP_SET_VERTEX_DECLARATION
;
361 op
->declaration
= declaration
;
366 static void wined3d_cs_exec_set_stream_source(struct wined3d_cs
*cs
, const void *data
)
368 const struct wined3d_cs_set_stream_source
*op
= data
;
369 struct wined3d_stream_state
*stream
;
370 struct wined3d_buffer
*prev
;
372 stream
= &cs
->state
.streams
[op
->stream_idx
];
373 prev
= stream
->buffer
;
374 stream
->buffer
= op
->buffer
;
375 stream
->offset
= op
->offset
;
376 stream
->stride
= op
->stride
;
379 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
381 InterlockedDecrement(&prev
->resource
.bind_count
);
383 device_invalidate_state(cs
->device
, STATE_STREAMSRC
);
386 void wined3d_cs_emit_set_stream_source(struct wined3d_cs
*cs
, UINT stream_idx
,
387 struct wined3d_buffer
*buffer
, UINT offset
, UINT stride
)
389 struct wined3d_cs_set_stream_source
*op
;
391 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
392 op
->opcode
= WINED3D_CS_OP_SET_STREAM_SOURCE
;
393 op
->stream_idx
= stream_idx
;
401 static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs
*cs
, const void *data
)
403 const struct wined3d_cs_set_stream_source_freq
*op
= data
;
404 struct wined3d_stream_state
*stream
;
406 stream
= &cs
->state
.streams
[op
->stream_idx
];
407 stream
->frequency
= op
->frequency
;
408 stream
->flags
= op
->flags
;
410 device_invalidate_state(cs
->device
, STATE_STREAMSRC
);
413 void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs
*cs
, UINT stream_idx
, UINT frequency
, UINT flags
)
415 struct wined3d_cs_set_stream_source_freq
*op
;
417 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
418 op
->opcode
= WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ
;
419 op
->stream_idx
= stream_idx
;
420 op
->frequency
= frequency
;
426 static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs
*cs
, const void *data
)
428 const struct wined3d_cs_set_index_buffer
*op
= data
;
429 struct wined3d_buffer
*prev
;
431 prev
= cs
->state
.index_buffer
;
432 cs
->state
.index_buffer
= op
->buffer
;
433 cs
->state
.index_format
= op
->format_id
;
436 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
438 InterlockedDecrement(&prev
->resource
.bind_count
);
440 device_invalidate_state(cs
->device
, STATE_INDEXBUFFER
);
443 void wined3d_cs_emit_set_index_buffer(struct wined3d_cs
*cs
, struct wined3d_buffer
*buffer
,
444 enum wined3d_format_id format_id
)
446 struct wined3d_cs_set_index_buffer
*op
;
448 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
449 op
->opcode
= WINED3D_CS_OP_SET_INDEX_BUFFER
;
451 op
->format_id
= format_id
;
456 static void wined3d_cs_exec_set_texture(struct wined3d_cs
*cs
, const void *data
)
458 const struct wined3d_d3d_info
*d3d_info
= &cs
->device
->adapter
->d3d_info
;
459 const struct wined3d_cs_set_texture
*op
= data
;
460 struct wined3d_texture
*prev
;
462 prev
= cs
->state
.textures
[op
->stage
];
463 cs
->state
.textures
[op
->stage
] = op
->texture
;
467 if (InterlockedIncrement(&op
->texture
->resource
.bind_count
) == 1)
468 op
->texture
->sampler
= op
->stage
;
470 if (!prev
|| op
->texture
->target
!= prev
->target
)
471 device_invalidate_state(cs
->device
, STATE_PIXELSHADER
);
473 if (!prev
&& op
->stage
< d3d_info
->limits
.ffp_blend_stages
)
475 /* The source arguments for color and alpha ops have different
476 * meanings when a NULL texture is bound, so the COLOR_OP and
477 * ALPHA_OP have to be dirtified. */
478 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_COLOR_OP
));
479 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_ALPHA_OP
));
485 if (InterlockedDecrement(&prev
->resource
.bind_count
) && prev
->sampler
== op
->stage
)
489 /* Search for other stages the texture is bound to. Shouldn't
490 * happen if applications bind textures to a single stage only. */
491 TRACE("Searching for other stages the texture is bound to.\n");
492 for (i
= 0; i
< MAX_COMBINED_SAMPLERS
; ++i
)
494 if (cs
->state
.textures
[i
] == prev
)
496 TRACE("Texture is also bound to stage %u.\n", i
);
503 if (!op
->texture
&& op
->stage
< d3d_info
->limits
.ffp_blend_stages
)
505 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_COLOR_OP
));
506 device_invalidate_state(cs
->device
, STATE_TEXTURESTAGE(op
->stage
, WINED3D_TSS_ALPHA_OP
));
510 device_invalidate_state(cs
->device
, STATE_SAMPLER(op
->stage
));
513 void wined3d_cs_emit_set_texture(struct wined3d_cs
*cs
, UINT stage
, struct wined3d_texture
*texture
)
515 struct wined3d_cs_set_texture
*op
;
517 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
518 op
->opcode
= WINED3D_CS_OP_SET_TEXTURE
;
520 op
->texture
= texture
;
525 static void wined3d_cs_exec_set_vertex_shader(struct wined3d_cs
*cs
, const void *data
)
527 const struct wined3d_cs_set_shader
*op
= data
;
529 cs
->state
.vertex_shader
= op
->shader
;
530 device_invalidate_state(cs
->device
, STATE_VSHADER
);
533 void wined3d_cs_emit_set_vertex_shader(struct wined3d_cs
*cs
, struct wined3d_shader
*shader
)
535 struct wined3d_cs_set_shader
*op
;
537 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
538 op
->opcode
= WINED3D_CS_OP_SET_VERTEX_SHADER
;
544 static void wined3d_cs_exec_set_geometry_shader(struct wined3d_cs
*cs
, const void *data
)
546 const struct wined3d_cs_set_shader
*op
= data
;
548 cs
->state
.geometry_shader
= op
->shader
;
549 device_invalidate_state(cs
->device
, STATE_GEOMETRY_SHADER
);
552 void wined3d_cs_emit_set_geometry_shader(struct wined3d_cs
*cs
, struct wined3d_shader
*shader
)
554 struct wined3d_cs_set_shader
*op
;
556 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
557 op
->opcode
= WINED3D_CS_OP_SET_GEOMETRY_SHADER
;
563 static void wined3d_cs_exec_set_pixel_shader(struct wined3d_cs
*cs
, const void *data
)
565 const struct wined3d_cs_set_shader
*op
= data
;
567 cs
->state
.pixel_shader
= op
->shader
;
568 device_invalidate_state(cs
->device
, STATE_PIXELSHADER
);
571 void wined3d_cs_emit_set_pixel_shader(struct wined3d_cs
*cs
, struct wined3d_shader
*shader
)
573 struct wined3d_cs_set_shader
*op
;
575 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
576 op
->opcode
= WINED3D_CS_OP_SET_PIXEL_SHADER
;
582 static void wined3d_cs_exec_set_render_state(struct wined3d_cs
*cs
, const void *data
)
584 const struct wined3d_cs_set_render_state
*op
= data
;
586 cs
->state
.render_states
[op
->state
] = op
->value
;
587 device_invalidate_state(cs
->device
, STATE_RENDER(op
->state
));
590 void wined3d_cs_emit_set_render_state(struct wined3d_cs
*cs
, enum wined3d_render_state state
, DWORD value
)
592 struct wined3d_cs_set_render_state
*op
;
594 op
= cs
->ops
->require_space(cs
, sizeof(*op
));
595 op
->opcode
= WINED3D_CS_OP_SET_RENDER_STATE
;
602 static void (* const wined3d_cs_op_handlers
[])(struct wined3d_cs
*cs
, const void *data
) =
604 /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present
,
605 /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear
,
606 /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw
,
607 /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport
,
608 /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect
,
609 /* WINED3D_CS_OP_SET_RENDER_TARGET */ wined3d_cs_exec_set_render_target
,
610 /* WINED3D_CS_OP_SET_DEPTH_STENCIL */ wined3d_cs_exec_set_depth_stencil
,
611 /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration
,
612 /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source
,
613 /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq
,
614 /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer
,
615 /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture
,
616 /* WINED3D_CS_OP_SET_VERTEX_SHADER */ wined3d_cs_exec_set_vertex_shader
,
617 /* WINED3D_CS_OP_SET_GEOMETRY_SHADER */ wined3d_cs_exec_set_geometry_shader
,
618 /* WINED3D_CS_OP_SET_PIXEL_SHADER */ wined3d_cs_exec_set_pixel_shader
,
619 /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state
,
622 static void *wined3d_cs_st_require_space(struct wined3d_cs
*cs
, size_t size
)
624 if (size
> cs
->data_size
)
628 size
= max( size
, cs
->data_size
* 2 );
629 if (!(new_data
= HeapReAlloc(GetProcessHeap(), 0, cs
->data
, size
)))
632 cs
->data_size
= size
;
639 static void wined3d_cs_st_submit(struct wined3d_cs
*cs
)
641 enum wined3d_cs_op opcode
= *(const enum wined3d_cs_op
*)cs
->data
;
643 wined3d_cs_op_handlers
[opcode
](cs
, cs
->data
);
646 static const struct wined3d_cs_ops wined3d_cs_st_ops
=
648 wined3d_cs_st_require_space
,
649 wined3d_cs_st_submit
,
652 struct wined3d_cs
*wined3d_cs_create(struct wined3d_device
*device
)
654 const struct wined3d_gl_info
*gl_info
= &device
->adapter
->gl_info
;
655 struct wined3d_cs
*cs
;
657 if (!(cs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*cs
))))
660 if (!(cs
->fb
.render_targets
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
661 sizeof(*cs
->fb
.render_targets
) * gl_info
->limits
.buffers
)))
663 HeapFree(GetProcessHeap(), 0, cs
);
667 if (FAILED(state_init(&cs
->state
, &cs
->fb
, gl_info
, &device
->adapter
->d3d_info
,
668 WINED3D_STATE_NO_REF
| WINED3D_STATE_INIT_DEFAULT
)))
670 HeapFree(GetProcessHeap(), 0, cs
->fb
.render_targets
);
671 HeapFree(GetProcessHeap(), 0, cs
);
675 cs
->ops
= &wined3d_cs_st_ops
;
678 cs
->data_size
= WINED3D_INITIAL_CS_SIZE
;
679 if (!(cs
->data
= HeapAlloc(GetProcessHeap(), 0, cs
->data_size
)))
681 HeapFree(GetProcessHeap(), 0, cs
);
688 void wined3d_cs_destroy(struct wined3d_cs
*cs
)
690 state_cleanup(&cs
->state
);
691 HeapFree(GetProcessHeap(), 0, cs
->fb
.render_targets
);
692 HeapFree(GetProcessHeap(), 0, cs
);