wined3d: Send render state updates through the command stream.
[wine.git] / dlls / wined3d / cs.c
blobf295aa75d7c9d38268ba56874d22617a1fad4524
1 /*
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
19 #include "config.h"
20 #include "wine/port.h"
21 #include "wined3d_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
25 #define WINED3D_INITIAL_CS_SIZE 4096
27 enum wined3d_cs_op
29 WINED3D_CS_OP_PRESENT,
30 WINED3D_CS_OP_CLEAR,
31 WINED3D_CS_OP_DRAW,
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;
52 const RECT *src_rect;
53 const RECT *dst_rect;
54 const RGNDATA *dirty_region;
55 DWORD flags;
58 struct wined3d_cs_clear
60 enum wined3d_cs_op opcode;
61 DWORD rect_count;
62 const RECT *rects;
63 DWORD flags;
64 const struct wined3d_color *color;
65 float depth;
66 DWORD stencil;
69 struct wined3d_cs_draw
71 enum wined3d_cs_op opcode;
72 UINT start_idx;
73 UINT index_count;
74 UINT start_instance;
75 UINT instance_count;
76 BOOL indexed;
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;
88 const RECT *rect;
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;
113 UINT stream_idx;
114 struct wined3d_buffer *buffer;
115 UINT offset;
116 UINT stride;
119 struct wined3d_cs_set_stream_source_freq
121 enum wined3d_cs_op opcode;
122 UINT stream_idx;
123 UINT frequency;
124 UINT flags;
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;
137 UINT stage;
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;
151 DWORD value;
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;
179 op->flags = flags;
181 cs->ops->submit(cs);
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;
188 RECT draw_rect;
190 device = cs->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;
205 op->rects = rects;
206 op->flags = flags;
207 op->color = color;
208 op->depth = depth;
209 op->stencil = stencil;
211 cs->ops->submit(cs);
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;
235 cs->ops->submit(cs);
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;
254 cs->ops->submit(cs);
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;
271 op->rect = rect;
273 cs->ops->submit(cs);
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;
294 cs->ops->submit(cs);
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;
344 cs->ops->submit(cs);
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;
363 cs->ops->submit(cs);
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;
378 if (op->buffer)
379 InterlockedIncrement(&op->buffer->resource.bind_count);
380 if (prev)
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;
394 op->buffer = buffer;
395 op->offset = offset;
396 op->stride = stride;
398 cs->ops->submit(cs);
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;
421 op->flags = flags;
423 cs->ops->submit(cs);
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;
435 if (op->buffer)
436 InterlockedIncrement(&op->buffer->resource.bind_count);
437 if (prev)
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;
450 op->buffer = buffer;
451 op->format_id = format_id;
453 cs->ops->submit(cs);
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;
465 if (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));
483 if (prev)
485 if (InterlockedDecrement(&prev->resource.bind_count) && prev->sampler == op->stage)
487 unsigned int i;
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);
497 prev->sampler = i;
498 break;
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;
519 op->stage = stage;
520 op->texture = texture;
522 cs->ops->submit(cs);
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;
539 op->shader = shader;
541 cs->ops->submit(cs);
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;
558 op->shader = shader;
560 cs->ops->submit(cs);
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;
577 op->shader = shader;
579 cs->ops->submit(cs);
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;
596 op->state = state;
597 op->value = value;
599 cs->ops->submit(cs);
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)
626 void *new_data;
628 size = max( size, cs->data_size * 2 );
629 if (!(new_data = HeapReAlloc(GetProcessHeap(), 0, cs->data, size)))
630 return NULL;
632 cs->data_size = size;
633 cs->data = new_data;
636 return cs->data;
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))))
658 return NULL;
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);
664 return NULL;
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);
672 return NULL;
675 cs->ops = &wined3d_cs_st_ops;
676 cs->device = device;
678 cs->data_size = WINED3D_INITIAL_CS_SIZE;
679 if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size)))
681 HeapFree(GetProcessHeap(), 0, cs);
682 return NULL;
685 return 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);