wined3d: Send texture state updates through the command stream.
[wine.git] / dlls / wined3d / cs.c
blob3ddfeb127ea71954cbd447b18511cb9fb27ac44f
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,
45 WINED3D_CS_OP_SET_TEXTURE_STATE,
48 struct wined3d_cs_present
50 enum wined3d_cs_op opcode;
51 HWND dst_window_override;
52 struct wined3d_swapchain *swapchain;
53 const RECT *src_rect;
54 const RECT *dst_rect;
55 const RGNDATA *dirty_region;
56 DWORD flags;
59 struct wined3d_cs_clear
61 enum wined3d_cs_op opcode;
62 DWORD rect_count;
63 const RECT *rects;
64 DWORD flags;
65 const struct wined3d_color *color;
66 float depth;
67 DWORD stencil;
70 struct wined3d_cs_draw
72 enum wined3d_cs_op opcode;
73 UINT start_idx;
74 UINT index_count;
75 UINT start_instance;
76 UINT instance_count;
77 BOOL indexed;
80 struct wined3d_cs_set_viewport
82 enum wined3d_cs_op opcode;
83 const struct wined3d_viewport *viewport;
86 struct wined3d_cs_set_scissor_rect
88 enum wined3d_cs_op opcode;
89 const RECT *rect;
92 struct wined3d_cs_set_render_target
94 enum wined3d_cs_op opcode;
95 UINT render_target_idx;
96 struct wined3d_surface *render_target;
99 struct wined3d_cs_set_depth_stencil
101 enum wined3d_cs_op opcode;
102 struct wined3d_surface *depth_stencil;
105 struct wined3d_cs_set_vertex_declaration
107 enum wined3d_cs_op opcode;
108 struct wined3d_vertex_declaration *declaration;
111 struct wined3d_cs_set_stream_source
113 enum wined3d_cs_op opcode;
114 UINT stream_idx;
115 struct wined3d_buffer *buffer;
116 UINT offset;
117 UINT stride;
120 struct wined3d_cs_set_stream_source_freq
122 enum wined3d_cs_op opcode;
123 UINT stream_idx;
124 UINT frequency;
125 UINT flags;
128 struct wined3d_cs_set_index_buffer
130 enum wined3d_cs_op opcode;
131 struct wined3d_buffer *buffer;
132 enum wined3d_format_id format_id;
135 struct wined3d_cs_set_texture
137 enum wined3d_cs_op opcode;
138 UINT stage;
139 struct wined3d_texture *texture;
142 struct wined3d_cs_set_shader
144 enum wined3d_cs_op opcode;
145 struct wined3d_shader *shader;
148 struct wined3d_cs_set_render_state
150 enum wined3d_cs_op opcode;
151 enum wined3d_render_state state;
152 DWORD value;
155 struct wined3d_cs_set_texture_state
157 enum wined3d_cs_op opcode;
158 UINT stage;
159 enum wined3d_texture_stage_state state;
160 DWORD value;
163 static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data)
165 const struct wined3d_cs_present *op = data;
166 struct wined3d_swapchain *swapchain;
168 swapchain = op->swapchain;
169 wined3d_swapchain_set_window(swapchain, op->dst_window_override);
171 swapchain->swapchain_ops->swapchain_present(swapchain,
172 op->src_rect, op->dst_rect, op->dirty_region, op->flags);
175 void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain,
176 const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
177 const RGNDATA *dirty_region, DWORD flags)
179 struct wined3d_cs_present *op;
181 op = cs->ops->require_space(cs, sizeof(*op));
182 op->opcode = WINED3D_CS_OP_PRESENT;
183 op->dst_window_override = dst_window_override;
184 op->swapchain = swapchain;
185 op->src_rect = src_rect;
186 op->dst_rect = dst_rect;
187 op->dirty_region = dirty_region;
188 op->flags = flags;
190 cs->ops->submit(cs);
193 static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data)
195 const struct wined3d_cs_clear *op = data;
196 struct wined3d_device *device;
197 RECT draw_rect;
199 device = cs->device;
200 wined3d_get_draw_rect(&device->state, &draw_rect);
201 device_clear_render_targets(device, device->adapter->gl_info.limits.buffers,
202 &device->fb, op->rect_count, op->rects, &draw_rect, op->flags,
203 op->color, op->depth, op->stencil);
206 void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects,
207 DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil)
209 struct wined3d_cs_clear *op;
211 op = cs->ops->require_space(cs, sizeof(*op));
212 op->opcode = WINED3D_CS_OP_CLEAR;
213 op->rect_count = rect_count;
214 op->rects = rects;
215 op->flags = flags;
216 op->color = color;
217 op->depth = depth;
218 op->stencil = stencil;
220 cs->ops->submit(cs);
223 static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data)
225 const struct wined3d_cs_draw *op = data;
227 draw_primitive(cs->device, op->start_idx, op->index_count,
228 op->start_instance, op->instance_count, op->indexed);
231 void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_count,
232 UINT start_instance, UINT instance_count, BOOL indexed)
234 struct wined3d_cs_draw *op;
236 op = cs->ops->require_space(cs, sizeof(*op));
237 op->opcode = WINED3D_CS_OP_DRAW;
238 op->start_idx = start_idx;
239 op->index_count = index_count;
240 op->start_instance = start_instance;
241 op->instance_count = instance_count;
242 op->indexed = indexed;
244 cs->ops->submit(cs);
247 static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data)
249 const struct wined3d_cs_set_viewport *op = data;
251 cs->state.viewport = *op->viewport;
252 device_invalidate_state(cs->device, STATE_VIEWPORT);
255 void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport)
257 struct wined3d_cs_set_viewport *op;
259 op = cs->ops->require_space(cs, sizeof(*op));
260 op->opcode = WINED3D_CS_OP_SET_VIEWPORT;
261 op->viewport = viewport;
263 cs->ops->submit(cs);
266 static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data)
268 const struct wined3d_cs_set_scissor_rect *op = data;
270 cs->state.scissor_rect = *op->rect;
271 device_invalidate_state(cs->device, STATE_SCISSORRECT);
274 void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect)
276 struct wined3d_cs_set_scissor_rect *op;
278 op = cs->ops->require_space(cs, sizeof(*op));
279 op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT;
280 op->rect = rect;
282 cs->ops->submit(cs);
285 static void wined3d_cs_exec_set_render_target(struct wined3d_cs *cs, const void *data)
287 const struct wined3d_cs_set_render_target *op = data;
289 cs->state.fb->render_targets[op->render_target_idx] = op->render_target;
290 device_invalidate_state(cs->device, STATE_FRAMEBUFFER);
293 void wined3d_cs_emit_set_render_target(struct wined3d_cs *cs, UINT render_target_idx,
294 struct wined3d_surface *render_target)
296 struct wined3d_cs_set_render_target *op;
298 op = cs->ops->require_space(cs, sizeof(*op));
299 op->opcode = WINED3D_CS_OP_SET_RENDER_TARGET;
300 op->render_target_idx = render_target_idx;
301 op->render_target = render_target;
303 cs->ops->submit(cs);
306 static void wined3d_cs_exec_set_depth_stencil(struct wined3d_cs *cs, const void *data)
308 const struct wined3d_cs_set_depth_stencil *op = data;
309 struct wined3d_device *device = cs->device;
310 struct wined3d_surface *prev;
312 if ((prev = cs->state.fb->depth_stencil))
314 if (device->swapchains[0]->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
315 || prev->flags & SFLAG_DISCARD)
317 surface_modify_ds_location(prev, SFLAG_DISCARDED,
318 prev->resource.width, prev->resource.height);
319 if (prev == device->onscreen_depth_stencil)
321 wined3d_surface_decref(device->onscreen_depth_stencil);
322 device->onscreen_depth_stencil = NULL;
327 cs->fb.depth_stencil = op->depth_stencil;
329 if (!prev != !op->depth_stencil)
331 /* Swapping NULL / non NULL depth stencil affects the depth and tests */
332 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_ZENABLE));
333 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILENABLE));
334 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK));
335 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
337 else if (prev && prev->resource.format->depth_size != op->depth_stencil->resource.format->depth_size)
339 device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
342 device_invalidate_state(device, STATE_FRAMEBUFFER);
345 void wined3d_cs_emit_set_depth_stencil(struct wined3d_cs *cs, struct wined3d_surface *depth_stencil)
347 struct wined3d_cs_set_depth_stencil *op;
349 op = cs->ops->require_space(cs, sizeof(*op));
350 op->opcode = WINED3D_CS_OP_SET_DEPTH_STENCIL;
351 op->depth_stencil = depth_stencil;
353 cs->ops->submit(cs);
356 static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data)
358 const struct wined3d_cs_set_vertex_declaration *op = data;
360 cs->state.vertex_declaration = op->declaration;
361 device_invalidate_state(cs->device, STATE_VDECL);
364 void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3d_vertex_declaration *declaration)
366 struct wined3d_cs_set_vertex_declaration *op;
368 op = cs->ops->require_space(cs, sizeof(*op));
369 op->opcode = WINED3D_CS_OP_SET_VERTEX_DECLARATION;
370 op->declaration = declaration;
372 cs->ops->submit(cs);
375 static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data)
377 const struct wined3d_cs_set_stream_source *op = data;
378 struct wined3d_stream_state *stream;
379 struct wined3d_buffer *prev;
381 stream = &cs->state.streams[op->stream_idx];
382 prev = stream->buffer;
383 stream->buffer = op->buffer;
384 stream->offset = op->offset;
385 stream->stride = op->stride;
387 if (op->buffer)
388 InterlockedIncrement(&op->buffer->resource.bind_count);
389 if (prev)
390 InterlockedDecrement(&prev->resource.bind_count);
392 device_invalidate_state(cs->device, STATE_STREAMSRC);
395 void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx,
396 struct wined3d_buffer *buffer, UINT offset, UINT stride)
398 struct wined3d_cs_set_stream_source *op;
400 op = cs->ops->require_space(cs, sizeof(*op));
401 op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE;
402 op->stream_idx = stream_idx;
403 op->buffer = buffer;
404 op->offset = offset;
405 op->stride = stride;
407 cs->ops->submit(cs);
410 static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data)
412 const struct wined3d_cs_set_stream_source_freq *op = data;
413 struct wined3d_stream_state *stream;
415 stream = &cs->state.streams[op->stream_idx];
416 stream->frequency = op->frequency;
417 stream->flags = op->flags;
419 device_invalidate_state(cs->device, STATE_STREAMSRC);
422 void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx, UINT frequency, UINT flags)
424 struct wined3d_cs_set_stream_source_freq *op;
426 op = cs->ops->require_space(cs, sizeof(*op));
427 op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ;
428 op->stream_idx = stream_idx;
429 op->frequency = frequency;
430 op->flags = flags;
432 cs->ops->submit(cs);
435 static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data)
437 const struct wined3d_cs_set_index_buffer *op = data;
438 struct wined3d_buffer *prev;
440 prev = cs->state.index_buffer;
441 cs->state.index_buffer = op->buffer;
442 cs->state.index_format = op->format_id;
444 if (op->buffer)
445 InterlockedIncrement(&op->buffer->resource.bind_count);
446 if (prev)
447 InterlockedDecrement(&prev->resource.bind_count);
449 device_invalidate_state(cs->device, STATE_INDEXBUFFER);
452 void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer,
453 enum wined3d_format_id format_id)
455 struct wined3d_cs_set_index_buffer *op;
457 op = cs->ops->require_space(cs, sizeof(*op));
458 op->opcode = WINED3D_CS_OP_SET_INDEX_BUFFER;
459 op->buffer = buffer;
460 op->format_id = format_id;
462 cs->ops->submit(cs);
465 static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data)
467 const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info;
468 const struct wined3d_cs_set_texture *op = data;
469 struct wined3d_texture *prev;
471 prev = cs->state.textures[op->stage];
472 cs->state.textures[op->stage] = op->texture;
474 if (op->texture)
476 if (InterlockedIncrement(&op->texture->resource.bind_count) == 1)
477 op->texture->sampler = op->stage;
479 if (!prev || op->texture->target != prev->target)
480 device_invalidate_state(cs->device, STATE_PIXELSHADER);
482 if (!prev && op->stage < d3d_info->limits.ffp_blend_stages)
484 /* The source arguments for color and alpha ops have different
485 * meanings when a NULL texture is bound, so the COLOR_OP and
486 * ALPHA_OP have to be dirtified. */
487 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP));
488 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP));
492 if (prev)
494 if (InterlockedDecrement(&prev->resource.bind_count) && prev->sampler == op->stage)
496 unsigned int i;
498 /* Search for other stages the texture is bound to. Shouldn't
499 * happen if applications bind textures to a single stage only. */
500 TRACE("Searching for other stages the texture is bound to.\n");
501 for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
503 if (cs->state.textures[i] == prev)
505 TRACE("Texture is also bound to stage %u.\n", i);
506 prev->sampler = i;
507 break;
512 if (!op->texture && op->stage < d3d_info->limits.ffp_blend_stages)
514 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP));
515 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP));
519 device_invalidate_state(cs->device, STATE_SAMPLER(op->stage));
522 void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined3d_texture *texture)
524 struct wined3d_cs_set_texture *op;
526 op = cs->ops->require_space(cs, sizeof(*op));
527 op->opcode = WINED3D_CS_OP_SET_TEXTURE;
528 op->stage = stage;
529 op->texture = texture;
531 cs->ops->submit(cs);
534 static void wined3d_cs_exec_set_vertex_shader(struct wined3d_cs *cs, const void *data)
536 const struct wined3d_cs_set_shader *op = data;
538 cs->state.vertex_shader = op->shader;
539 device_invalidate_state(cs->device, STATE_VSHADER);
542 void wined3d_cs_emit_set_vertex_shader(struct wined3d_cs *cs, struct wined3d_shader *shader)
544 struct wined3d_cs_set_shader *op;
546 op = cs->ops->require_space(cs, sizeof(*op));
547 op->opcode = WINED3D_CS_OP_SET_VERTEX_SHADER;
548 op->shader = shader;
550 cs->ops->submit(cs);
553 static void wined3d_cs_exec_set_geometry_shader(struct wined3d_cs *cs, const void *data)
555 const struct wined3d_cs_set_shader *op = data;
557 cs->state.geometry_shader = op->shader;
558 device_invalidate_state(cs->device, STATE_GEOMETRY_SHADER);
561 void wined3d_cs_emit_set_geometry_shader(struct wined3d_cs *cs, struct wined3d_shader *shader)
563 struct wined3d_cs_set_shader *op;
565 op = cs->ops->require_space(cs, sizeof(*op));
566 op->opcode = WINED3D_CS_OP_SET_GEOMETRY_SHADER;
567 op->shader = shader;
569 cs->ops->submit(cs);
572 static void wined3d_cs_exec_set_pixel_shader(struct wined3d_cs *cs, const void *data)
574 const struct wined3d_cs_set_shader *op = data;
576 cs->state.pixel_shader = op->shader;
577 device_invalidate_state(cs->device, STATE_PIXELSHADER);
580 void wined3d_cs_emit_set_pixel_shader(struct wined3d_cs *cs, struct wined3d_shader *shader)
582 struct wined3d_cs_set_shader *op;
584 op = cs->ops->require_space(cs, sizeof(*op));
585 op->opcode = WINED3D_CS_OP_SET_PIXEL_SHADER;
586 op->shader = shader;
588 cs->ops->submit(cs);
591 static void wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data)
593 const struct wined3d_cs_set_render_state *op = data;
595 cs->state.render_states[op->state] = op->value;
596 device_invalidate_state(cs->device, STATE_RENDER(op->state));
599 void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render_state state, DWORD value)
601 struct wined3d_cs_set_render_state *op;
603 op = cs->ops->require_space(cs, sizeof(*op));
604 op->opcode = WINED3D_CS_OP_SET_RENDER_STATE;
605 op->state = state;
606 op->value = value;
608 cs->ops->submit(cs);
611 static void wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data)
613 const struct wined3d_cs_set_texture_state *op = data;
615 cs->state.texture_states[op->stage][op->state] = op->value;
616 device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, op->state));
619 void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage,
620 enum wined3d_texture_stage_state state, DWORD value)
622 struct wined3d_cs_set_texture_state *op;
624 op = cs->ops->require_space(cs, sizeof(*op));
625 op->opcode = WINED3D_CS_OP_SET_TEXTURE_STATE;
626 op->stage = stage;
627 op->state = state;
628 op->value = value;
630 cs->ops->submit(cs);
633 static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) =
635 /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present,
636 /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear,
637 /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw,
638 /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport,
639 /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect,
640 /* WINED3D_CS_OP_SET_RENDER_TARGET */ wined3d_cs_exec_set_render_target,
641 /* WINED3D_CS_OP_SET_DEPTH_STENCIL */ wined3d_cs_exec_set_depth_stencil,
642 /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration,
643 /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source,
644 /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq,
645 /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer,
646 /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture,
647 /* WINED3D_CS_OP_SET_VERTEX_SHADER */ wined3d_cs_exec_set_vertex_shader,
648 /* WINED3D_CS_OP_SET_GEOMETRY_SHADER */ wined3d_cs_exec_set_geometry_shader,
649 /* WINED3D_CS_OP_SET_PIXEL_SHADER */ wined3d_cs_exec_set_pixel_shader,
650 /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state,
651 /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state,
654 static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size)
656 if (size > cs->data_size)
658 void *new_data;
660 size = max( size, cs->data_size * 2 );
661 if (!(new_data = HeapReAlloc(GetProcessHeap(), 0, cs->data, size)))
662 return NULL;
664 cs->data_size = size;
665 cs->data = new_data;
668 return cs->data;
671 static void wined3d_cs_st_submit(struct wined3d_cs *cs)
673 enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)cs->data;
675 wined3d_cs_op_handlers[opcode](cs, cs->data);
678 static const struct wined3d_cs_ops wined3d_cs_st_ops =
680 wined3d_cs_st_require_space,
681 wined3d_cs_st_submit,
684 struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
686 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
687 struct wined3d_cs *cs;
689 if (!(cs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cs))))
690 return NULL;
692 if (!(cs->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
693 sizeof(*cs->fb.render_targets) * gl_info->limits.buffers)))
695 HeapFree(GetProcessHeap(), 0, cs);
696 return NULL;
699 if (FAILED(state_init(&cs->state, &cs->fb, gl_info, &device->adapter->d3d_info,
700 WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT)))
702 HeapFree(GetProcessHeap(), 0, cs->fb.render_targets);
703 HeapFree(GetProcessHeap(), 0, cs);
704 return NULL;
707 cs->ops = &wined3d_cs_st_ops;
708 cs->device = device;
710 cs->data_size = WINED3D_INITIAL_CS_SIZE;
711 if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size)))
713 HeapFree(GetProcessHeap(), 0, cs);
714 return NULL;
717 return cs;
720 void wined3d_cs_destroy(struct wined3d_cs *cs)
722 state_cleanup(&cs->state);
723 HeapFree(GetProcessHeap(), 0, cs->fb.render_targets);
724 HeapFree(GetProcessHeap(), 0, cs);