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
,
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
;
55 const RGNDATA
*dirty_region
;
59 struct wined3d_cs_clear
61 enum wined3d_cs_op opcode
;
65 const struct wined3d_color
*color
;
70 struct wined3d_cs_draw
72 enum wined3d_cs_op opcode
;
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
;
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
;
115 struct wined3d_buffer
*buffer
;
120 struct wined3d_cs_set_stream_source_freq
122 enum wined3d_cs_op opcode
;
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
;
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
;
155 struct wined3d_cs_set_texture_state
157 enum wined3d_cs_op opcode
;
159 enum wined3d_texture_stage_state state
;
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
;
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
;
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
;
218 op
->stencil
= stencil
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
388 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
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
;
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
;
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
;
445 InterlockedIncrement(&op
->buffer
->resource
.bind_count
);
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
;
460 op
->format_id
= format_id
;
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
;
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
));
494 if (InterlockedDecrement(&prev
->resource
.bind_count
) && prev
->sampler
== op
->stage
)
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
);
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
;
529 op
->texture
= texture
;
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
;
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
;
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
;
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
;
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
;
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
)
660 size
= max( size
, cs
->data_size
* 2 );
661 if (!(new_data
= HeapReAlloc(GetProcessHeap(), 0, cs
->data
, size
)))
664 cs
->data_size
= size
;
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
))))
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
);
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
);
707 cs
->ops
= &wined3d_cs_st_ops
;
710 cs
->data_size
= WINED3D_INITIAL_CS_SIZE
;
711 if (!(cs
->data
= HeapAlloc(GetProcessHeap(), 0, cs
->data_size
)))
713 HeapFree(GetProcessHeap(), 0, 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
);