2 * Copyright 2009, 2011 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
21 #include "wine/port.h"
23 #include "wined3d_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
27 static BOOL
is_stencil_view_format(const struct wined3d_format
*format
)
29 return format
->id
== WINED3DFMT_X24_TYPELESS_G8_UINT
30 || format
->id
== WINED3DFMT_X32_TYPELESS_G8X24_UINT
;
33 static GLenum
get_texture_view_target(const struct wined3d_view_desc
*desc
,
34 const struct wined3d_texture
*texture
)
38 GLenum texture_target
;
39 unsigned int view_flags
;
44 {GL_TEXTURE_2D
, 0, GL_TEXTURE_2D
},
45 {GL_TEXTURE_2D
, WINED3D_VIEW_TEXTURE_ARRAY
, GL_TEXTURE_2D_ARRAY
},
46 {GL_TEXTURE_2D_ARRAY
, 0, GL_TEXTURE_2D
},
47 {GL_TEXTURE_2D_ARRAY
, WINED3D_VIEW_TEXTURE_ARRAY
, GL_TEXTURE_2D_ARRAY
},
48 {GL_TEXTURE_2D_ARRAY
, WINED3D_VIEW_TEXTURE_CUBE
, GL_TEXTURE_CUBE_MAP
},
49 {GL_TEXTURE_3D
, 0, GL_TEXTURE_3D
},
53 for (i
= 0; i
< ARRAY_SIZE(view_types
); ++i
)
55 if (view_types
[i
].texture_target
== texture
->target
&& view_types
[i
].view_flags
== desc
->flags
)
56 return view_types
[i
].view_target
;
59 FIXME("Unhandled view flags %#x for texture target %#x.\n", desc
->flags
, texture
->target
);
60 return texture
->target
;
63 static void create_texture_view(struct wined3d_gl_view
*view
, GLenum view_target
,
64 const struct wined3d_view_desc
*desc
, struct wined3d_texture
*texture
,
65 const struct wined3d_format
*view_format
)
67 const struct wined3d_gl_info
*gl_info
;
68 unsigned int layer_idx
, layer_count
;
69 struct wined3d_context
*context
;
70 struct gl_texture
*gl_texture
;
72 view
->target
= view_target
;
74 context
= context_acquire(texture
->resource
.device
, NULL
);
75 gl_info
= context
->gl_info
;
77 if (!gl_info
->supported
[ARB_TEXTURE_VIEW
])
79 context_release(context
);
80 FIXME("OpenGL implementation does not support texture views.\n");
84 wined3d_texture_prepare_texture(texture
, context
, FALSE
);
85 gl_texture
= wined3d_texture_get_gl_texture(texture
, FALSE
);
87 layer_idx
= desc
->u
.texture
.layer_idx
;
88 layer_count
= desc
->u
.texture
.layer_count
;
89 if (view_target
== GL_TEXTURE_3D
&& (layer_idx
|| layer_count
!= 1))
91 FIXME("Depth slice (%u-%u) not supported.\n", layer_idx
, layer_count
);
96 gl_info
->gl_ops
.gl
.p_glGenTextures(1, &view
->name
);
97 GL_EXTCALL(glTextureView(view
->name
, view
->target
, gl_texture
->name
, view_format
->glInternal
,
98 desc
->u
.texture
.level_idx
, desc
->u
.texture
.level_count
,
99 layer_idx
, layer_count
));
100 checkGLcall("Create texture view");
102 if (is_stencil_view_format(view_format
))
104 static const GLint swizzle
[] = {GL_ZERO
, GL_RED
, GL_ZERO
, GL_ZERO
};
106 if (!gl_info
->supported
[ARB_STENCIL_TEXTURING
])
108 context_release(context
);
109 FIXME("OpenGL implementation does not support stencil texturing.\n");
113 context_bind_texture(context
, view
->target
, view
->name
);
114 gl_info
->gl_ops
.gl
.p_glTexParameteriv(view
->target
, GL_TEXTURE_SWIZZLE_RGBA
, swizzle
);
115 gl_info
->gl_ops
.gl
.p_glTexParameteri(view
->target
, GL_DEPTH_STENCIL_TEXTURE_MODE
, GL_STENCIL_INDEX
);
116 checkGLcall("Initialize stencil view");
118 context_invalidate_state(context
, STATE_SHADER_RESOURCE_BINDING
);
121 context_release(context
);
124 static void create_buffer_texture(struct wined3d_gl_view
*view
,
125 struct wined3d_buffer
*buffer
, const struct wined3d_format
*view_format
)
127 const struct wined3d_gl_info
*gl_info
;
128 struct wined3d_context
*context
;
130 context
= context_acquire(buffer
->resource
.device
, NULL
);
131 gl_info
= context
->gl_info
;
132 if (!gl_info
->supported
[ARB_TEXTURE_BUFFER_OBJECT
])
134 FIXME("OpenGL implementation does not support buffer textures.\n");
135 context_release(context
);
139 wined3d_buffer_load_location(buffer
, context
, WINED3D_LOCATION_BUFFER
);
141 view
->target
= GL_TEXTURE_BUFFER
;
142 gl_info
->gl_ops
.gl
.p_glGenTextures(1, &view
->name
);
144 context_bind_texture(context
, GL_TEXTURE_BUFFER
, view
->name
);
145 GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER
, view_format
->glInternal
, buffer
->buffer_object
));
146 checkGLcall("Create buffer texture");
148 context_invalidate_state(context
, STATE_SHADER_RESOURCE_BINDING
);
150 context_release(context
);
153 ULONG CDECL
wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view
*view
)
155 ULONG refcount
= InterlockedIncrement(&view
->refcount
);
157 TRACE("%p increasing refcount to %u.\n", view
, refcount
);
162 static void wined3d_rendertarget_view_destroy_object(void *object
)
164 HeapFree(GetProcessHeap(), 0, object
);
167 ULONG CDECL
wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view
*view
)
169 ULONG refcount
= InterlockedDecrement(&view
->refcount
);
171 TRACE("%p decreasing refcount to %u.\n", view
, refcount
);
175 struct wined3d_resource
*resource
= view
->resource
;
176 struct wined3d_device
*device
= resource
->device
;
178 /* Call wined3d_object_destroyed() before releasing the resource,
179 * since releasing the resource may end up destroying the parent. */
180 view
->parent_ops
->wined3d_object_destroyed(view
->parent
);
181 wined3d_cs_emit_destroy_object(device
->cs
, wined3d_rendertarget_view_destroy_object
, view
);
182 wined3d_resource_decref(resource
);
188 void * CDECL
wined3d_rendertarget_view_get_parent(const struct wined3d_rendertarget_view
*view
)
190 TRACE("view %p.\n", view
);
195 void * CDECL
wined3d_rendertarget_view_get_sub_resource_parent(const struct wined3d_rendertarget_view
*view
)
197 struct wined3d_texture
*texture
;
199 TRACE("view %p.\n", view
);
201 if (view
->resource
->type
== WINED3D_RTYPE_BUFFER
)
202 return wined3d_buffer_get_parent(buffer_from_resource(view
->resource
));
204 texture
= texture_from_resource(view
->resource
);
206 return texture
->sub_resources
[view
->sub_resource_idx
].parent
;
209 void CDECL
wined3d_rendertarget_view_set_parent(struct wined3d_rendertarget_view
*view
, void *parent
)
211 TRACE("view %p, parent %p.\n", view
, parent
);
213 view
->parent
= parent
;
216 struct wined3d_resource
* CDECL
wined3d_rendertarget_view_get_resource(const struct wined3d_rendertarget_view
*view
)
218 TRACE("view %p.\n", view
);
220 return view
->resource
;
223 void wined3d_rendertarget_view_get_drawable_size(const struct wined3d_rendertarget_view
*view
,
224 const struct wined3d_context
*context
, unsigned int *width
, unsigned int *height
)
226 const struct wined3d_texture
*texture
;
228 if (view
->resource
->type
!= WINED3D_RTYPE_TEXTURE_2D
)
230 FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(view
->resource
->type
));
236 texture
= texture_from_resource(view
->resource
);
237 if (texture
->swapchain
)
239 /* The drawable size of an onscreen drawable is the surface size.
240 * (Actually: The window size, but the surface is created in window
242 *width
= context
->current_rt
.texture
->resource
.width
;
243 *height
= context
->current_rt
.texture
->resource
.height
;
245 else if (wined3d_settings
.offscreen_rendering_mode
== ORM_BACKBUFFER
)
247 const struct wined3d_swapchain
*swapchain
= context
->swapchain
;
249 /* The drawable size of a backbuffer / aux buffer offscreen target is
250 * the size of the current context's drawable, which is the size of
251 * the back buffer of the swapchain the active context belongs to. */
252 *width
= swapchain
->desc
.backbuffer_width
;
253 *height
= swapchain
->desc
.backbuffer_height
;
257 struct wined3d_surface
*rt
;
259 /* The drawable size of an FBO target is the OpenGL texture size,
260 * which is the power of two size. */
261 rt
= context
->current_rt
.texture
->sub_resources
[context
->current_rt
.sub_resource_idx
].u
.surface
;
262 *width
= wined3d_texture_get_level_pow2_width(rt
->container
, rt
->texture_level
);
263 *height
= wined3d_texture_get_level_pow2_height(rt
->container
, rt
->texture_level
);
267 static HRESULT
wined3d_rendertarget_view_init(struct wined3d_rendertarget_view
*view
,
268 const struct wined3d_view_desc
*desc
, struct wined3d_resource
*resource
,
269 void *parent
, const struct wined3d_parent_ops
*parent_ops
)
271 const struct wined3d_gl_info
*gl_info
= &resource
->device
->adapter
->gl_info
;
274 view
->parent
= parent
;
275 view
->parent_ops
= parent_ops
;
277 view
->format
= wined3d_get_format(gl_info
, desc
->format_id
, resource
->usage
);
278 view
->format_flags
= view
->format
->flags
[resource
->gl_type
];
280 if (wined3d_format_is_typeless(view
->format
))
282 WARN("Trying to create view for typeless format %s.\n", debug_d3dformat(view
->format
->id
));
286 if (resource
->type
== WINED3D_RTYPE_BUFFER
)
288 view
->sub_resource_idx
= 0;
289 view
->buffer_offset
= desc
->u
.buffer
.start_idx
;
290 view
->width
= desc
->u
.buffer
.count
;
296 struct wined3d_texture
*texture
= texture_from_resource(resource
);
297 unsigned int depth_or_layer_count
;
299 if (resource
->type
== WINED3D_RTYPE_TEXTURE_3D
)
300 depth_or_layer_count
= wined3d_texture_get_level_depth(texture
, desc
->u
.texture
.level_idx
);
302 depth_or_layer_count
= texture
->layer_count
;
304 if (desc
->u
.texture
.level_idx
>= texture
->level_count
305 || desc
->u
.texture
.level_count
!= 1
306 || desc
->u
.texture
.layer_idx
>= depth_or_layer_count
307 || !desc
->u
.texture
.layer_count
308 || desc
->u
.texture
.layer_count
> depth_or_layer_count
- desc
->u
.texture
.layer_idx
)
311 view
->sub_resource_idx
= desc
->u
.texture
.level_idx
;
312 if (resource
->type
!= WINED3D_RTYPE_TEXTURE_3D
)
313 view
->sub_resource_idx
+= desc
->u
.texture
.layer_idx
* texture
->level_count
;
314 view
->buffer_offset
= 0;
315 view
->width
= wined3d_texture_get_level_width(texture
, desc
->u
.texture
.level_idx
);
316 view
->height
= wined3d_texture_get_level_height(texture
, desc
->u
.texture
.level_idx
);
317 view
->depth
= desc
->u
.texture
.layer_count
;
319 wined3d_resource_incref(view
->resource
= resource
);
324 HRESULT CDECL
wined3d_rendertarget_view_create(const struct wined3d_view_desc
*desc
,
325 struct wined3d_resource
*resource
, void *parent
, const struct wined3d_parent_ops
*parent_ops
,
326 struct wined3d_rendertarget_view
**view
)
328 struct wined3d_rendertarget_view
*object
;
331 TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n",
332 desc
, resource
, parent
, parent_ops
, view
);
334 if (!(object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
))))
335 return E_OUTOFMEMORY
;
337 if (FAILED(hr
= wined3d_rendertarget_view_init(object
, desc
, resource
, parent
, parent_ops
)))
339 HeapFree(GetProcessHeap(), 0, object
);
340 WARN("Failed to initialise view, hr %#x.\n", hr
);
344 TRACE("Created render target view %p.\n", object
);
350 HRESULT CDECL
wined3d_rendertarget_view_create_from_sub_resource(struct wined3d_texture
*texture
,
351 unsigned int sub_resource_idx
, void *parent
, const struct wined3d_parent_ops
*parent_ops
,
352 struct wined3d_rendertarget_view
**view
)
354 struct wined3d_view_desc desc
;
356 TRACE("texture %p, sub_resource_idx %u, parent %p, parent_ops %p, view %p.\n",
357 texture
, sub_resource_idx
, parent
, parent_ops
, view
);
359 desc
.format_id
= texture
->resource
.format
->id
;
361 desc
.u
.texture
.level_idx
= sub_resource_idx
% texture
->level_count
;
362 desc
.u
.texture
.level_count
= 1;
363 desc
.u
.texture
.layer_idx
= sub_resource_idx
/ texture
->level_count
;
364 desc
.u
.texture
.layer_count
= 1;
366 return wined3d_rendertarget_view_create(&desc
, &texture
->resource
, parent
, parent_ops
, view
);
369 ULONG CDECL
wined3d_shader_resource_view_incref(struct wined3d_shader_resource_view
*view
)
371 ULONG refcount
= InterlockedIncrement(&view
->refcount
);
373 TRACE("%p increasing refcount to %u.\n", view
, refcount
);
378 static void wined3d_shader_resource_view_destroy_object(void *object
)
380 struct wined3d_shader_resource_view
*view
= object
;
382 if (view
->gl_view
.name
)
384 const struct wined3d_gl_info
*gl_info
;
385 struct wined3d_context
*context
;
387 context
= context_acquire(view
->resource
->device
, NULL
);
388 gl_info
= context
->gl_info
;
389 gl_info
->gl_ops
.gl
.p_glDeleteTextures(1, &view
->gl_view
.name
);
390 checkGLcall("glDeleteTextures");
391 context_release(context
);
394 HeapFree(GetProcessHeap(), 0, view
);
397 ULONG CDECL
wined3d_shader_resource_view_decref(struct wined3d_shader_resource_view
*view
)
399 ULONG refcount
= InterlockedDecrement(&view
->refcount
);
401 TRACE("%p decreasing refcount to %u.\n", view
, refcount
);
405 struct wined3d_resource
*resource
= view
->resource
;
406 struct wined3d_device
*device
= resource
->device
;
408 /* Call wined3d_object_destroyed() before releasing the resource,
409 * since releasing the resource may end up destroying the parent. */
410 view
->parent_ops
->wined3d_object_destroyed(view
->parent
);
411 wined3d_cs_emit_destroy_object(device
->cs
, wined3d_shader_resource_view_destroy_object
, view
);
412 wined3d_resource_decref(resource
);
418 void * CDECL
wined3d_shader_resource_view_get_parent(const struct wined3d_shader_resource_view
*view
)
420 TRACE("view %p.\n", view
);
425 static HRESULT
wined3d_shader_resource_view_init(struct wined3d_shader_resource_view
*view
,
426 const struct wined3d_view_desc
*desc
, struct wined3d_resource
*resource
,
427 void *parent
, const struct wined3d_parent_ops
*parent_ops
)
429 const struct wined3d_gl_info
*gl_info
= &resource
->device
->adapter
->gl_info
;
430 const struct wined3d_format
*view_format
;
433 view_format
= wined3d_get_format(gl_info
, desc
->format_id
, resource
->usage
);
434 if (wined3d_format_is_typeless(view_format
)
435 && !(view_format
->id
== WINED3DFMT_R32_TYPELESS
&& (desc
->flags
& WINED3D_VIEW_BUFFER_RAW
)))
437 WARN("Trying to create view for typeless format %s.\n", debug_d3dformat(view_format
->id
));
442 view
->parent
= parent
;
443 view
->parent_ops
= parent_ops
;
445 if (resource
->type
== WINED3D_RTYPE_BUFFER
)
447 struct wined3d_buffer
*buffer
= buffer_from_resource(resource
);
449 if (desc
->format_id
== WINED3DFMT_UNKNOWN
)
451 FIXME("Structured buffer views not supported.\n");
453 else if (desc
->flags
& WINED3D_VIEW_BUFFER_RAW
)
455 FIXME("Raw buffer views not supported.\n");
459 /* FIXME: Support for buffer offsets can be implemented using ARB_texture_buffer_range. */
460 if (desc
->u
.buffer
.start_idx
461 || desc
->u
.buffer
.count
* view_format
->byte_count
!= buffer
->resource
.size
)
463 FIXME("Ignoring buffer range %u-%u.\n", desc
->u
.buffer
.start_idx
, desc
->u
.buffer
.count
);
466 create_buffer_texture(&view
->gl_view
, buffer
, view_format
);
471 struct wined3d_texture
*texture
= texture_from_resource(resource
);
473 if (!desc
->u
.texture
.level_count
474 || desc
->u
.texture
.level_idx
>= texture
->level_count
475 || desc
->u
.texture
.level_count
> texture
->level_count
- desc
->u
.texture
.level_idx
476 || !desc
->u
.texture
.layer_count
477 || desc
->u
.texture
.layer_idx
>= texture
->layer_count
478 || desc
->u
.texture
.layer_count
> texture
->layer_count
- desc
->u
.texture
.layer_idx
)
481 view_target
= get_texture_view_target(desc
, texture
);
483 if (resource
->format
->id
== view_format
->id
&& texture
->target
== view_target
484 && !desc
->u
.texture
.level_idx
&& desc
->u
.texture
.level_count
== texture
->level_count
485 && !desc
->u
.texture
.layer_idx
&& desc
->u
.texture
.layer_count
== texture
->layer_count
486 && !is_stencil_view_format(view_format
))
488 TRACE("Creating identity shader resource view.\n");
490 else if (texture
->swapchain
&& texture
->swapchain
->desc
.backbuffer_count
> 1)
492 FIXME("Swapchain shader resource views not supported.\n");
494 else if (resource
->format
->typeless_id
== view_format
->typeless_id
495 && resource
->format
->gl_view_class
== view_format
->gl_view_class
)
497 create_texture_view(&view
->gl_view
, view_target
, desc
, texture
, view_format
);
501 FIXME("Shader resource view not supported, resource format %s, view format %s.\n",
502 debug_d3dformat(resource
->format
->id
), debug_d3dformat(view_format
->id
));
505 wined3d_resource_incref(view
->resource
= resource
);
510 HRESULT CDECL
wined3d_shader_resource_view_create(const struct wined3d_view_desc
*desc
,
511 struct wined3d_resource
*resource
, void *parent
, const struct wined3d_parent_ops
*parent_ops
,
512 struct wined3d_shader_resource_view
**view
)
514 struct wined3d_shader_resource_view
*object
;
517 TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n",
518 desc
, resource
, parent
, parent_ops
, view
);
520 if (!(object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
))))
521 return E_OUTOFMEMORY
;
523 if (FAILED(hr
= wined3d_shader_resource_view_init(object
, desc
, resource
, parent
, parent_ops
)))
525 HeapFree(GetProcessHeap(), 0, object
);
526 WARN("Failed to initialise view, hr %#x.\n", hr
);
530 TRACE("Created shader resource view %p.\n", object
);
536 void wined3d_shader_resource_view_bind(struct wined3d_shader_resource_view
*view
,
537 struct wined3d_context
*context
)
539 struct wined3d_texture
*texture
;
541 if (view
->gl_view
.name
)
543 context_bind_texture(context
, view
->gl_view
.target
, view
->gl_view
.name
);
547 if (view
->resource
->type
== WINED3D_RTYPE_BUFFER
)
549 FIXME("Buffer shader resources not supported.\n");
553 texture
= wined3d_texture_from_resource(view
->resource
);
554 wined3d_texture_bind(texture
, context
, FALSE
);
557 ULONG CDECL
wined3d_unordered_access_view_incref(struct wined3d_unordered_access_view
*view
)
559 ULONG refcount
= InterlockedIncrement(&view
->refcount
);
561 TRACE("%p increasing refcount to %u.\n", view
, refcount
);
566 static void wined3d_unordered_access_view_destroy_object(void *object
)
568 HeapFree(GetProcessHeap(), 0, object
);
571 ULONG CDECL
wined3d_unordered_access_view_decref(struct wined3d_unordered_access_view
*view
)
573 ULONG refcount
= InterlockedDecrement(&view
->refcount
);
575 TRACE("%p decreasing refcount to %u.\n", view
, refcount
);
579 struct wined3d_resource
*resource
= view
->resource
;
580 struct wined3d_device
*device
= resource
->device
;
582 /* Call wined3d_object_destroyed() before releasing the resource,
583 * since releasing the resource may end up destroying the parent. */
584 view
->parent_ops
->wined3d_object_destroyed(view
->parent
);
585 wined3d_cs_emit_destroy_object(device
->cs
, wined3d_unordered_access_view_destroy_object
, view
);
586 wined3d_resource_decref(resource
);
592 void * CDECL
wined3d_unordered_access_view_get_parent(const struct wined3d_unordered_access_view
*view
)
594 TRACE("view %p.\n", view
);
599 void wined3d_unordered_access_view_invalidate_location(struct wined3d_unordered_access_view
*view
,
602 struct wined3d_resource
*resource
= view
->resource
;
603 unsigned int i
, sub_resource_idx
, layer_count
;
604 struct wined3d_texture
*texture
;
606 if (resource
->type
== WINED3D_RTYPE_BUFFER
)
608 FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource
->type
));
612 texture
= texture_from_resource(resource
);
614 sub_resource_idx
= view
->layer_idx
* texture
->level_count
+ view
->level_idx
;
615 layer_count
= (resource
->type
!= WINED3D_RTYPE_TEXTURE_3D
) ? view
->layer_count
: 1;
616 for (i
= 0; i
< layer_count
; ++i
, sub_resource_idx
+= texture
->level_count
)
617 wined3d_texture_invalidate_location(texture
, sub_resource_idx
, location
);
620 static HRESULT
wined3d_unordered_access_view_init(struct wined3d_unordered_access_view
*view
,
621 const struct wined3d_view_desc
*desc
, struct wined3d_resource
*resource
,
622 void *parent
, const struct wined3d_parent_ops
*parent_ops
)
624 const struct wined3d_gl_info
*gl_info
= &resource
->device
->adapter
->gl_info
;
627 view
->parent
= parent
;
628 view
->parent_ops
= parent_ops
;
630 view
->format
= wined3d_get_format(gl_info
, desc
->format_id
, resource
->usage
);
632 if (wined3d_format_is_typeless(view
->format
)
633 && !(view
->format
->id
== WINED3DFMT_R32_TYPELESS
&& (desc
->flags
& WINED3D_VIEW_BUFFER_RAW
)))
635 WARN("Trying to create view for typeless format %s.\n", debug_d3dformat(view
->format
->id
));
639 if (resource
->type
== WINED3D_RTYPE_BUFFER
)
641 FIXME("Buffer unordered access views not supported.\n");
645 struct wined3d_texture
*texture
= texture_from_resource(resource
);
646 unsigned int depth_or_layer_count
;
648 if (resource
->type
== WINED3D_RTYPE_TEXTURE_3D
)
649 depth_or_layer_count
= wined3d_texture_get_level_depth(texture
, desc
->u
.texture
.level_idx
);
651 depth_or_layer_count
= texture
->layer_count
;
653 if (desc
->u
.texture
.level_idx
>= texture
->level_count
654 || desc
->u
.texture
.level_count
!= 1
655 || desc
->u
.texture
.layer_idx
>= depth_or_layer_count
656 || !desc
->u
.texture
.layer_count
657 || desc
->u
.texture
.layer_count
> depth_or_layer_count
- desc
->u
.texture
.layer_idx
)
660 if (desc
->u
.texture
.layer_idx
|| desc
->u
.texture
.layer_count
!= depth_or_layer_count
)
662 create_texture_view(&view
->gl_view
, get_texture_view_target(desc
, texture
),
663 desc
, texture
, view
->format
);
666 view
->layer_idx
= desc
->u
.texture
.layer_idx
;
667 view
->layer_count
= desc
->u
.texture
.layer_count
;
668 view
->level_idx
= desc
->u
.texture
.level_idx
;
670 wined3d_resource_incref(view
->resource
= resource
);
675 HRESULT CDECL
wined3d_unordered_access_view_create(const struct wined3d_view_desc
*desc
,
676 struct wined3d_resource
*resource
, void *parent
, const struct wined3d_parent_ops
*parent_ops
,
677 struct wined3d_unordered_access_view
**view
)
679 struct wined3d_unordered_access_view
*object
;
682 TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n",
683 desc
, resource
, parent
, parent_ops
, view
);
685 if (!(object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
))))
686 return E_OUTOFMEMORY
;
688 if (FAILED(hr
= wined3d_unordered_access_view_init(object
, desc
, resource
, parent
, parent_ops
)))
690 HeapFree(GetProcessHeap(), 0, object
);
691 WARN("Failed to initialise view, hr %#x.\n", hr
);
695 TRACE("Created unordered access view %p.\n", object
);