mf/session: Implement support for sinks that provide sample allocators.
[wine.git] / dlls / wined3d / view.c
bloba690bd4ae6ba1aa7c9a1e80c05e45475862f3d90
1 /*
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
20 #include "config.h"
21 #include "wine/port.h"
23 #include "wined3d_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
27 #define WINED3D_VIEW_CUBE_ARRAY (WINED3D_VIEW_TEXTURE_CUBE | WINED3D_VIEW_TEXTURE_ARRAY)
29 static BOOL is_stencil_view_format(const struct wined3d_format *format)
31 return format->id == WINED3DFMT_X24_TYPELESS_G8_UINT
32 || format->id == WINED3DFMT_X32_TYPELESS_G8X24_UINT;
35 static GLenum get_texture_view_target(const struct wined3d_gl_info *gl_info,
36 const struct wined3d_view_desc *desc, const struct wined3d_texture_gl *texture_gl)
38 static const struct
40 GLenum texture_target;
41 unsigned int view_flags;
42 GLenum view_target;
43 enum wined3d_gl_extension extension;
45 view_types[] =
47 {GL_TEXTURE_CUBE_MAP, 0, GL_TEXTURE_CUBE_MAP},
48 {GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_RECTANGLE},
49 {GL_TEXTURE_3D, 0, GL_TEXTURE_3D},
51 {GL_TEXTURE_2D, 0, GL_TEXTURE_2D},
52 {GL_TEXTURE_2D, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_ARRAY},
53 {GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_2D},
54 {GL_TEXTURE_2D_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_ARRAY},
55 {GL_TEXTURE_2D_ARRAY, WINED3D_VIEW_TEXTURE_CUBE, GL_TEXTURE_CUBE_MAP},
56 {GL_TEXTURE_2D_ARRAY, WINED3D_VIEW_CUBE_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY, ARB_TEXTURE_CUBE_MAP_ARRAY},
58 {GL_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_2D_MULTISAMPLE},
59 {GL_TEXTURE_2D_MULTISAMPLE, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY},
60 {GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0, GL_TEXTURE_2D_MULTISAMPLE},
61 {GL_TEXTURE_2D_MULTISAMPLE_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY},
63 {GL_TEXTURE_1D, 0, GL_TEXTURE_1D},
64 {GL_TEXTURE_1D, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY},
65 {GL_TEXTURE_1D_ARRAY, 0, GL_TEXTURE_1D},
66 {GL_TEXTURE_1D_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY},
68 unsigned int flags = desc->flags & (WINED3D_VIEW_BUFFER_RAW | WINED3D_VIEW_BUFFER_APPEND
69 | WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_TEXTURE_CUBE | WINED3D_VIEW_TEXTURE_ARRAY);
70 unsigned int i;
72 for (i = 0; i < ARRAY_SIZE(view_types); ++i)
74 if (view_types[i].texture_target != texture_gl->target || view_types[i].view_flags != flags)
75 continue;
76 if (gl_info->supported[view_types[i].extension])
77 return view_types[i].view_target;
79 FIXME("Extension %#x not supported.\n", view_types[i].extension);
82 FIXME("Unhandled view flags %#x for texture target %#x.\n", flags, texture_gl->target);
83 return texture_gl->target;
86 static const struct wined3d_format *validate_resource_view(const struct wined3d_view_desc *desc,
87 struct wined3d_resource *resource, BOOL mip_slice, BOOL allow_srgb_toggle)
89 const struct wined3d_adapter *adapter = resource->device->adapter;
90 const struct wined3d_format *format;
92 format = wined3d_get_format(adapter, desc->format_id, resource->bind_flags);
93 if (resource->type == WINED3D_RTYPE_BUFFER && (desc->flags & WINED3D_VIEW_BUFFER_RAW))
95 if (format->id != WINED3DFMT_R32_TYPELESS)
97 WARN("Invalid format %s for raw buffer view.\n", debug_d3dformat(format->id));
98 return NULL;
101 format = wined3d_get_format(adapter, WINED3DFMT_R32_UINT, resource->bind_flags);
104 if (wined3d_format_is_typeless(format))
106 WARN("Trying to create view for typeless format %s.\n", debug_d3dformat(format->id));
107 return NULL;
110 if (resource->type == WINED3D_RTYPE_BUFFER)
112 struct wined3d_buffer *buffer = buffer_from_resource(resource);
113 unsigned int buffer_size, element_size;
115 if (buffer->structure_byte_stride)
117 if (desc->format_id != WINED3DFMT_UNKNOWN)
119 WARN("Invalid format %s for structured buffer view.\n", debug_d3dformat(desc->format_id));
120 return NULL;
123 format = wined3d_get_format(adapter, WINED3DFMT_R32_UINT, resource->bind_flags);
124 element_size = buffer->structure_byte_stride;
126 else
128 element_size = format->byte_count;
131 if (!element_size)
132 return NULL;
134 buffer_size = buffer->resource.size / element_size;
135 if (desc->u.buffer.start_idx >= buffer_size
136 || desc->u.buffer.count > buffer_size - desc->u.buffer.start_idx)
137 return NULL;
139 else
141 struct wined3d_texture *texture = texture_from_resource(resource);
142 unsigned int depth_or_layer_count;
144 if (resource->format->id != format->id && !wined3d_format_is_typeless(resource->format)
145 && (!allow_srgb_toggle || !wined3d_formats_are_srgb_variants(resource->format->id, format->id)))
147 WARN("Trying to create incompatible view for non typeless format %s.\n",
148 debug_d3dformat(format->id));
149 return NULL;
152 if (mip_slice && resource->type == WINED3D_RTYPE_TEXTURE_3D)
153 depth_or_layer_count = wined3d_texture_get_level_depth(texture, desc->u.texture.level_idx);
154 else
155 depth_or_layer_count = texture->layer_count;
157 if (!desc->u.texture.level_count
158 || (mip_slice && desc->u.texture.level_count != 1)
159 || desc->u.texture.level_idx >= texture->level_count
160 || desc->u.texture.level_count > texture->level_count - desc->u.texture.level_idx
161 || !desc->u.texture.layer_count
162 || desc->u.texture.layer_idx >= depth_or_layer_count
163 || desc->u.texture.layer_count > depth_or_layer_count - desc->u.texture.layer_idx)
164 return NULL;
167 return format;
170 static void create_texture_view(struct wined3d_gl_view *view, GLenum view_target,
171 const struct wined3d_view_desc *desc, struct wined3d_texture_gl *texture_gl,
172 const struct wined3d_format *view_format)
174 const struct wined3d_format_gl *view_format_gl;
175 unsigned int level_idx, layer_idx, layer_count;
176 const struct wined3d_gl_info *gl_info;
177 struct wined3d_context_gl *context_gl;
178 struct wined3d_context *context;
179 GLuint texture_name;
181 view_format_gl = wined3d_format_gl(view_format);
182 view->target = view_target;
184 context = context_acquire(texture_gl->t.resource.device, NULL, 0);
185 context_gl = wined3d_context_gl(context);
186 gl_info = context_gl->gl_info;
188 if (!gl_info->supported[ARB_TEXTURE_VIEW])
190 context_release(context);
191 FIXME("OpenGL implementation does not support texture views.\n");
192 return;
195 wined3d_texture_gl_prepare_texture(texture_gl, context_gl, FALSE);
196 texture_name = wined3d_texture_gl_get_texture_name(texture_gl, context, FALSE);
198 level_idx = desc->u.texture.level_idx;
199 layer_idx = desc->u.texture.layer_idx;
200 layer_count = desc->u.texture.layer_count;
201 if (view_target == GL_TEXTURE_3D)
203 if (layer_idx || layer_count != wined3d_texture_get_level_depth(&texture_gl->t, level_idx))
204 FIXME("Depth slice (%u-%u) not supported.\n", layer_idx, layer_count);
205 layer_idx = 0;
206 layer_count = 1;
209 gl_info->gl_ops.gl.p_glGenTextures(1, &view->name);
210 GL_EXTCALL(glTextureView(view->name, view->target, texture_name, view_format_gl->internal,
211 level_idx, desc->u.texture.level_count, layer_idx, layer_count));
212 checkGLcall("create texture view");
214 if (is_stencil_view_format(view_format))
216 static const GLint swizzle[] = {GL_ZERO, GL_RED, GL_ZERO, GL_ZERO};
218 if (!gl_info->supported[ARB_STENCIL_TEXTURING])
220 context_release(context);
221 FIXME("OpenGL implementation does not support stencil texturing.\n");
222 return;
225 wined3d_context_gl_bind_texture(context_gl, view->target, view->name);
226 gl_info->gl_ops.gl.p_glTexParameteriv(view->target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
227 gl_info->gl_ops.gl.p_glTexParameteri(view->target, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
228 checkGLcall("initialize stencil view");
230 context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING);
231 context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
233 else if (!is_identity_fixup(view_format->color_fixup) && can_use_texture_swizzle(context->d3d_info, view_format))
235 GLint swizzle[4];
237 wined3d_context_gl_bind_texture(context_gl, view->target, view->name);
238 wined3d_gl_texture_swizzle_from_color_fixup(swizzle, view_format->color_fixup);
239 gl_info->gl_ops.gl.p_glTexParameteriv(view->target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
240 checkGLcall("set format swizzle");
242 context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING);
243 context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
246 context_release(context);
249 static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_context_gl *context_gl,
250 struct wined3d_buffer_gl *buffer_gl, const struct wined3d_format_gl *view_format_gl,
251 unsigned int offset, unsigned int size)
253 const struct wined3d_gl_info *gl_info = context_gl->gl_info;
255 if (!gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT])
257 FIXME("OpenGL implementation does not support buffer textures.\n");
258 return;
261 if ((offset & (gl_info->limits.texture_buffer_offset_alignment - 1)))
263 FIXME("Buffer offset %u is not %u byte aligned.\n",
264 offset, gl_info->limits.texture_buffer_offset_alignment);
265 return;
268 wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER);
270 view->target = GL_TEXTURE_BUFFER;
271 gl_info->gl_ops.gl.p_glGenTextures(1, &view->name);
273 wined3d_context_gl_bind_texture(context_gl, GL_TEXTURE_BUFFER, view->name);
274 if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE])
276 GL_EXTCALL(glTexBufferRange(GL_TEXTURE_BUFFER, view_format_gl->internal, buffer_gl->bo.id, offset, size));
278 else
280 if (offset || size != buffer_gl->b.resource.size)
281 FIXME("OpenGL implementation does not support ARB_texture_buffer_range.\n");
282 GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER, view_format_gl->internal, buffer_gl->bo.id));
284 checkGLcall("Create buffer texture");
286 context_invalidate_compute_state(&context_gl->c, STATE_COMPUTE_SHADER_RESOURCE_BINDING);
287 context_invalidate_state(&context_gl->c, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
290 static void get_buffer_view_range(const struct wined3d_buffer *buffer,
291 const struct wined3d_view_desc *desc, const struct wined3d_format *view_format,
292 unsigned int *offset, unsigned int *size)
294 if (desc->format_id == WINED3DFMT_UNKNOWN)
296 *offset = desc->u.buffer.start_idx * buffer->structure_byte_stride;
297 *size = desc->u.buffer.count * buffer->structure_byte_stride;
299 else
301 *offset = desc->u.buffer.start_idx * view_format->byte_count;
302 *size = desc->u.buffer.count * view_format->byte_count;
306 static void create_buffer_view(struct wined3d_gl_view *view, struct wined3d_context *context,
307 const struct wined3d_view_desc *desc, struct wined3d_buffer *buffer,
308 const struct wined3d_format *view_format)
310 unsigned int offset, size;
312 get_buffer_view_range(buffer, desc, view_format, &offset, &size);
313 create_buffer_texture(view, wined3d_context_gl(context),
314 wined3d_buffer_gl(buffer), wined3d_format_gl(view_format), offset, size);
317 static void wined3d_view_invalidate_location(struct wined3d_resource *resource,
318 const struct wined3d_view_desc *desc, DWORD location)
320 unsigned int i, sub_resource_idx, layer_count;
321 struct wined3d_texture *texture;
323 if (resource->type == WINED3D_RTYPE_BUFFER)
325 wined3d_buffer_invalidate_location(buffer_from_resource(resource), location);
326 return;
329 texture = texture_from_resource(resource);
331 sub_resource_idx = desc->u.texture.layer_idx * texture->level_count + desc->u.texture.level_idx;
332 layer_count = resource->type != WINED3D_RTYPE_TEXTURE_3D ? desc->u.texture.layer_count : 1;
333 for (i = 0; i < layer_count; ++i, sub_resource_idx += texture->level_count)
334 wined3d_texture_invalidate_location(texture, sub_resource_idx, location);
337 ULONG CDECL wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *view)
339 ULONG refcount = InterlockedIncrement(&view->refcount);
341 TRACE("%p increasing refcount to %u.\n", view, refcount);
343 return refcount;
346 void wined3d_rendertarget_view_cleanup(struct wined3d_rendertarget_view *view)
348 /* Call wined3d_object_destroyed() before releasing the resource,
349 * since releasing the resource may end up destroying the parent. */
350 view->parent_ops->wined3d_object_destroyed(view->parent);
351 wined3d_resource_decref(view->resource);
354 ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *view)
356 ULONG refcount = InterlockedDecrement(&view->refcount);
358 TRACE("%p decreasing refcount to %u.\n", view, refcount);
360 if (!refcount)
361 view->resource->device->adapter->adapter_ops->adapter_destroy_rendertarget_view(view);
363 return refcount;
366 void * CDECL wined3d_rendertarget_view_get_parent(const struct wined3d_rendertarget_view *view)
368 TRACE("view %p.\n", view);
370 return view->parent;
373 void * CDECL wined3d_rendertarget_view_get_sub_resource_parent(const struct wined3d_rendertarget_view *view)
375 struct wined3d_texture *texture;
377 TRACE("view %p.\n", view);
379 if (view->resource->type == WINED3D_RTYPE_BUFFER)
380 return wined3d_buffer_get_parent(buffer_from_resource(view->resource));
382 texture = texture_from_resource(view->resource);
384 return texture->sub_resources[view->sub_resource_idx].parent;
387 void CDECL wined3d_rendertarget_view_set_parent(struct wined3d_rendertarget_view *view, void *parent)
389 TRACE("view %p, parent %p.\n", view, parent);
391 view->parent = parent;
394 struct wined3d_resource * CDECL wined3d_rendertarget_view_get_resource(const struct wined3d_rendertarget_view *view)
396 TRACE("view %p.\n", view);
398 return view->resource;
401 void wined3d_rendertarget_view_get_drawable_size(const struct wined3d_rendertarget_view *view,
402 const struct wined3d_context *context, unsigned int *width, unsigned int *height)
404 const struct wined3d_texture *texture;
406 if (view->resource->type != WINED3D_RTYPE_TEXTURE_2D)
408 *width = view->width;
409 *height = view->height;
410 return;
413 texture = texture_from_resource(view->resource);
414 if (texture->swapchain)
416 /* The drawable size of an onscreen drawable is the surface size.
417 * (Actually: The window size, but the surface is created in window
418 * size.) */
419 *width = texture->resource.width;
420 *height = texture->resource.height;
422 else if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER)
424 const struct wined3d_swapchain_desc *desc = &context->swapchain->state.desc;
426 /* The drawable size of a backbuffer / aux buffer offscreen target is
427 * the size of the current context's drawable, which is the size of
428 * the back buffer of the swapchain the active context belongs to. */
429 *width = desc->backbuffer_width;
430 *height = desc->backbuffer_height;
432 else
434 unsigned int level_idx = view->sub_resource_idx % texture->level_count;
436 /* The drawable size of an FBO target is the OpenGL texture size,
437 * which is the power of two size. */
438 *width = wined3d_texture_get_level_pow2_width(texture, level_idx);
439 *height = wined3d_texture_get_level_pow2_height(texture, level_idx);
443 void wined3d_rendertarget_view_prepare_location(struct wined3d_rendertarget_view *view,
444 struct wined3d_context *context, DWORD location)
446 struct wined3d_resource *resource = view->resource;
447 unsigned int i, sub_resource_idx, layer_count;
448 struct wined3d_texture *texture;
450 if (resource->type == WINED3D_RTYPE_BUFFER)
452 FIXME("Not implemented for resources %s.\n", debug_d3dresourcetype(resource->type));
453 return;
456 texture = texture_from_resource(resource);
457 sub_resource_idx = view->sub_resource_idx;
458 layer_count = resource->type != WINED3D_RTYPE_TEXTURE_3D ? view->layer_count : 1;
459 for (i = 0; i < layer_count; ++i, sub_resource_idx += texture->level_count)
460 wined3d_texture_prepare_location(texture, sub_resource_idx, context, location);
463 void wined3d_rendertarget_view_load_location(struct wined3d_rendertarget_view *view,
464 struct wined3d_context *context, DWORD location)
466 struct wined3d_resource *resource = view->resource;
467 unsigned int i, sub_resource_idx, layer_count;
468 struct wined3d_texture *texture;
470 if (resource->type == WINED3D_RTYPE_BUFFER)
472 wined3d_buffer_load_location(buffer_from_resource(resource), context, location);
473 return;
476 texture = texture_from_resource(resource);
477 sub_resource_idx = view->sub_resource_idx;
478 layer_count = resource->type != WINED3D_RTYPE_TEXTURE_3D ? view->layer_count : 1;
479 for (i = 0; i < layer_count; ++i, sub_resource_idx += texture->level_count)
480 wined3d_texture_load_location(texture, sub_resource_idx, context, location);
483 void wined3d_rendertarget_view_validate_location(struct wined3d_rendertarget_view *view, DWORD location)
485 struct wined3d_resource *resource = view->resource;
486 unsigned int i, sub_resource_idx, layer_count;
487 struct wined3d_texture *texture;
489 if (resource->type == WINED3D_RTYPE_BUFFER)
491 FIXME("Not implemented for resources %s.\n", debug_d3dresourcetype(resource->type));
492 return;
495 texture = texture_from_resource(resource);
496 sub_resource_idx = view->sub_resource_idx;
497 layer_count = resource->type != WINED3D_RTYPE_TEXTURE_3D ? view->layer_count : 1;
498 for (i = 0; i < layer_count; ++i, sub_resource_idx += texture->level_count)
499 wined3d_texture_validate_location(texture, sub_resource_idx, location);
502 void wined3d_rendertarget_view_invalidate_location(struct wined3d_rendertarget_view *view, DWORD location)
504 wined3d_view_invalidate_location(view->resource, &view->desc, location);
507 static void wined3d_render_target_view_gl_cs_init(void *object)
509 struct wined3d_rendertarget_view_gl *view_gl = object;
510 struct wined3d_resource *resource = view_gl->v.resource;
511 const struct wined3d_view_desc *desc = &view_gl->v.desc;
513 if (resource->type == WINED3D_RTYPE_BUFFER)
515 FIXME("Not implemented for resources %s.\n", debug_d3dresourcetype(resource->type));
517 else
519 struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture_from_resource(resource));
520 unsigned int depth_or_layer_count;
522 if (resource->type == WINED3D_RTYPE_TEXTURE_3D)
523 depth_or_layer_count = wined3d_texture_get_level_depth(&texture_gl->t, desc->u.texture.level_idx);
524 else
525 depth_or_layer_count = texture_gl->t.layer_count;
527 if (resource->format->id != view_gl->v.format->id
528 || (view_gl->v.layer_count != 1 && view_gl->v.layer_count != depth_or_layer_count))
530 GLenum resource_class, view_class;
532 resource_class = wined3d_format_gl(resource->format)->view_class;
533 view_class = wined3d_format_gl(view_gl->v.format)->view_class;
534 if (resource_class != view_class)
536 FIXME("Render target view not supported, resource format %s, view format %s.\n",
537 debug_d3dformat(resource->format->id), debug_d3dformat(view_gl->v.format->id));
538 return;
540 if (texture_gl->t.swapchain && texture_gl->t.swapchain->state.desc.backbuffer_count > 1)
542 FIXME("Swapchain views not supported.\n");
543 return;
546 create_texture_view(&view_gl->gl_view, texture_gl->target, desc, texture_gl, view_gl->v.format);
551 static HRESULT wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *view,
552 const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
553 void *parent, const struct wined3d_parent_ops *parent_ops)
555 BOOL allow_srgb_toggle = FALSE;
557 view->refcount = 1;
558 view->parent = parent;
559 view->parent_ops = parent_ops;
561 if (resource->type != WINED3D_RTYPE_BUFFER)
563 struct wined3d_texture *texture = texture_from_resource(resource);
565 if (texture->swapchain)
566 allow_srgb_toggle = TRUE;
568 if (!(view->format = validate_resource_view(desc, resource, TRUE, allow_srgb_toggle)))
569 return E_INVALIDARG;
570 view->format_flags = view->format->flags[resource->gl_type];
571 view->desc = *desc;
573 if (resource->type == WINED3D_RTYPE_BUFFER)
575 view->sub_resource_idx = 0;
576 view->layer_count = 1;
577 view->width = desc->u.buffer.count;
578 view->height = 1;
580 else
582 struct wined3d_texture *texture = texture_from_resource(resource);
584 view->sub_resource_idx = desc->u.texture.level_idx;
585 if (resource->type != WINED3D_RTYPE_TEXTURE_3D)
586 view->sub_resource_idx += desc->u.texture.layer_idx * texture->level_count;
587 view->layer_count = desc->u.texture.layer_count;
588 view->width = wined3d_texture_get_level_width(texture, desc->u.texture.level_idx);
589 view->height = wined3d_texture_get_level_height(texture, desc->u.texture.level_idx);
592 wined3d_resource_incref(view->resource = resource);
594 return WINED3D_OK;
597 HRESULT wined3d_rendertarget_view_no3d_init(struct wined3d_rendertarget_view *view_no3d,
598 const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
599 void *parent, const struct wined3d_parent_ops *parent_ops)
601 TRACE("view_no3d %p, desc %s, resource %p, parent %p, parent_ops %p.\n",
602 view_no3d, wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops);
604 return wined3d_rendertarget_view_init(view_no3d, desc, resource, parent, parent_ops);
607 HRESULT wined3d_rendertarget_view_gl_init(struct wined3d_rendertarget_view_gl *view_gl,
608 const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
609 void *parent, const struct wined3d_parent_ops *parent_ops)
611 HRESULT hr;
613 TRACE("view_gl %p, desc %s, resource %p, parent %p, parent_ops %p.\n",
614 view_gl, wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops);
616 if (FAILED(hr = wined3d_rendertarget_view_init(&view_gl->v, desc, resource, parent, parent_ops)))
617 return hr;
619 wined3d_cs_init_object(resource->device->cs, wined3d_render_target_view_gl_cs_init, view_gl);
621 return hr;
624 VkImageViewType vk_image_view_type_from_wined3d(enum wined3d_resource_type type, uint32_t flags)
626 switch (type)
628 case WINED3D_RTYPE_TEXTURE_1D:
629 if (flags & WINED3D_VIEW_TEXTURE_ARRAY)
630 return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
631 else
632 return VK_IMAGE_VIEW_TYPE_1D;
634 case WINED3D_RTYPE_TEXTURE_2D:
635 if (flags & WINED3D_VIEW_TEXTURE_CUBE)
637 if (flags & WINED3D_VIEW_TEXTURE_ARRAY)
638 return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
639 else
640 return VK_IMAGE_VIEW_TYPE_CUBE;
642 if (flags & WINED3D_VIEW_TEXTURE_ARRAY)
643 return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
644 else
645 return VK_IMAGE_VIEW_TYPE_2D;
647 case WINED3D_RTYPE_TEXTURE_3D:
648 return VK_IMAGE_VIEW_TYPE_3D;
650 default:
651 ERR("Unhandled resource type %s.\n", debug_d3dresourcetype(type));
652 return ~0u;
656 static VkBufferView wined3d_view_vk_create_buffer_view(struct wined3d_context_vk *context_vk,
657 const struct wined3d_view_desc *desc, struct wined3d_buffer_vk *buffer_vk,
658 const struct wined3d_format_vk *view_format_vk)
660 const struct wined3d_vk_info *vk_info = context_vk->vk_info;
661 VkBufferViewCreateInfo create_info;
662 struct wined3d_device_vk *device_vk;
663 VkBufferView vk_buffer_view;
664 unsigned int offset, size;
665 VkResult vr;
667 get_buffer_view_range(&buffer_vk->b, desc, &view_format_vk->f, &offset, &size);
668 wined3d_buffer_prepare_location(&buffer_vk->b, &context_vk->c, WINED3D_LOCATION_BUFFER);
670 create_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
671 create_info.pNext = NULL;
672 create_info.flags = 0;
673 create_info.buffer = buffer_vk->bo.vk_buffer;
674 create_info.format = view_format_vk->vk_format;
675 create_info.offset = buffer_vk->bo.buffer_offset + offset;
676 create_info.range = size;
678 device_vk = wined3d_device_vk(buffer_vk->b.resource.device);
679 if ((vr = VK_CALL(vkCreateBufferView(device_vk->vk_device, &create_info, NULL, &vk_buffer_view))) < 0)
681 ERR("Failed to create buffer view, vr %s.\n", wined3d_debug_vkresult(vr));
682 return VK_NULL_HANDLE;
685 return vk_buffer_view;
688 static VkImageView wined3d_view_vk_create_texture_view(struct wined3d_context_vk *context_vk,
689 const struct wined3d_view_desc *desc, struct wined3d_texture_vk *texture_vk,
690 const struct wined3d_format_vk *view_format_vk, struct color_fixup_desc fixup, bool srv)
692 const struct wined3d_resource *resource = &texture_vk->t.resource;
693 const struct wined3d_vk_info *vk_info = context_vk->vk_info;
694 const struct wined3d_format_vk *format_vk;
695 struct wined3d_device_vk *device_vk;
696 VkImageViewCreateInfo create_info;
697 VkImageView vk_image_view;
698 VkResult vr;
700 device_vk = wined3d_device_vk(resource->device);
702 if (!wined3d_texture_vk_prepare_texture(texture_vk, context_vk))
704 ERR("Failed to prepare texture.\n");
705 return VK_NULL_HANDLE;
708 /* Depth formats are a little complicated. For example, the typeless
709 * format corresponding to depth/stencil view format WINED3DFMT_D32_FLOAT
710 * is WINED3DFMT_R32_TYPELESS, and the corresponding shader resource view
711 * format would be WINED3DFMT_R32_FLOAT. Vulkan depth/stencil formats are
712 * only compatible with themselves, so it's not possible to create e.g. a
713 * VK_FORMAT_R32_SFLOAT view on a VK_FORMAT_D32_SFLOAT image. In order to
714 * make it work, we create Vulkan images for WINED3DFMT_R32_TYPELESS
715 * resources with either a depth format (VK_FORMAT_D32_SFLOAT) or a colour
716 * format, depending on whether the bind flags include
717 * WINED3D_BIND_DEPTH_STENCIL or not. In order to then create a Vulkan
718 * view on the image, we then replace the view format here with the
719 * underlying resource format. However, that means it's still not possible
720 * to create e.g. a WINED3DFMT_R32_UINT view on a WINED3DFMT_R32_TYPELESS
721 * depth/stencil resource. */
722 if (resource->bind_flags & WINED3D_BIND_DEPTH_STENCIL)
723 format_vk = wined3d_format_vk(resource->format);
724 else
725 format_vk = view_format_vk;
727 create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
728 create_info.pNext = NULL;
729 create_info.flags = 0;
730 create_info.image = texture_vk->vk_image;
731 create_info.viewType = vk_image_view_type_from_wined3d(resource->type, desc->flags);
732 if (!srv && create_info.viewType == VK_IMAGE_VIEW_TYPE_3D)
734 if (desc->u.texture.layer_count > 1)
735 create_info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
736 else
737 create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
739 create_info.format = format_vk->vk_format;
740 if (is_stencil_view_format(&view_format_vk->f))
742 create_info.components.r = VK_COMPONENT_SWIZZLE_ZERO;
743 create_info.components.g = VK_COMPONENT_SWIZZLE_R;
744 create_info.components.b = VK_COMPONENT_SWIZZLE_ZERO;
745 create_info.components.a = VK_COMPONENT_SWIZZLE_ZERO;
747 else if (is_identity_fixup(fixup) || !can_use_texture_swizzle(context_vk->c.d3d_info, &format_vk->f))
749 create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
750 create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
751 create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
752 create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
754 else
756 wined3d_vk_swizzle_from_color_fixup(&create_info.components, fixup);
758 if ((resource->bind_flags & WINED3D_BIND_DEPTH_STENCIL)
759 && (view_format_vk->f.red_size || view_format_vk->f.green_size))
761 create_info.subresourceRange.aspectMask = 0;
762 if (view_format_vk->f.red_size)
763 create_info.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
764 if (view_format_vk->f.green_size)
765 create_info.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
767 else
769 create_info.subresourceRange.aspectMask = vk_aspect_mask_from_format(&format_vk->f);
771 create_info.subresourceRange.baseMipLevel = desc->u.texture.level_idx;
772 create_info.subresourceRange.levelCount = desc->u.texture.level_count;
773 create_info.subresourceRange.baseArrayLayer = desc->u.texture.layer_idx;
774 create_info.subresourceRange.layerCount = desc->u.texture.layer_count;
775 if ((vr = VK_CALL(vkCreateImageView(device_vk->vk_device, &create_info, NULL, &vk_image_view))) < 0)
777 ERR("Failed to create Vulkan image view, vr %s.\n", wined3d_debug_vkresult(vr));
778 return VK_NULL_HANDLE;
781 return vk_image_view;
784 static void wined3d_render_target_view_vk_cs_init(void *object)
786 struct wined3d_rendertarget_view_vk *view_vk = object;
787 struct wined3d_view_desc *desc = &view_vk->v.desc;
788 const struct wined3d_format_vk *format_vk;
789 struct wined3d_texture_vk *texture_vk;
790 struct wined3d_resource *resource;
791 struct wined3d_context *context;
792 uint32_t default_flags = 0;
794 resource = view_vk->v.resource;
795 if (resource->type == WINED3D_RTYPE_BUFFER)
797 FIXME("Buffer views not implemented.\n");
798 return;
801 texture_vk = wined3d_texture_vk(texture_from_resource(resource));
802 format_vk = wined3d_format_vk(view_vk->v.format);
804 if (texture_vk->t.layer_count > 1)
805 default_flags |= WINED3D_VIEW_TEXTURE_ARRAY;
807 if (resource->format->id == format_vk->f.id && desc->flags == default_flags
808 && !desc->u.texture.level_idx && desc->u.texture.level_count == texture_vk->t.level_count
809 && !desc->u.texture.layer_idx && desc->u.texture.layer_count == texture_vk->t.layer_count
810 && !is_stencil_view_format(&format_vk->f) && resource->type != WINED3D_RTYPE_TEXTURE_3D
811 && is_identity_fixup(format_vk->f.color_fixup))
813 TRACE("Creating identity render target view.\n");
814 return;
817 if (texture_vk->t.swapchain && texture_vk->t.swapchain->state.desc.backbuffer_count > 1)
819 FIXME("Swapchain views not supported.\n");
820 return;
823 context = context_acquire(resource->device, NULL, 0);
824 view_vk->vk_image_view = wined3d_view_vk_create_texture_view(wined3d_context_vk(context),
825 desc, texture_vk, format_vk, COLOR_FIXUP_IDENTITY, false);
826 context_release(context);
828 if (!view_vk->vk_image_view)
829 return;
831 TRACE("Created image view 0x%s.\n", wine_dbgstr_longlong(view_vk->vk_image_view));
834 HRESULT wined3d_rendertarget_view_vk_init(struct wined3d_rendertarget_view_vk *view_vk,
835 const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
836 void *parent, const struct wined3d_parent_ops *parent_ops)
838 HRESULT hr;
840 TRACE("view_vk %p, desc %s, resource %p, parent %p, parent_ops %p.\n",
841 view_vk, wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops);
843 if (FAILED(hr = wined3d_rendertarget_view_init(&view_vk->v, desc, resource, parent, parent_ops)))
844 return hr;
846 wined3d_cs_init_object(resource->device->cs, wined3d_render_target_view_vk_cs_init, view_vk);
848 return hr;
851 HRESULT CDECL wined3d_rendertarget_view_create(const struct wined3d_view_desc *desc,
852 struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
853 struct wined3d_rendertarget_view **view)
855 const struct wined3d_adapter_ops *adapter_ops;
857 TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n",
858 wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view);
860 adapter_ops = resource->device->adapter->adapter_ops;
861 return adapter_ops->adapter_create_rendertarget_view(desc, resource, parent, parent_ops, view);
864 HRESULT CDECL wined3d_rendertarget_view_create_from_sub_resource(struct wined3d_texture *texture,
865 unsigned int sub_resource_idx, void *parent, const struct wined3d_parent_ops *parent_ops,
866 struct wined3d_rendertarget_view **view)
868 struct wined3d_view_desc desc;
870 TRACE("texture %p, sub_resource_idx %u, parent %p, parent_ops %p, view %p.\n",
871 texture, sub_resource_idx, parent, parent_ops, view);
873 desc.format_id = texture->resource.format->id;
874 desc.flags = 0;
875 desc.u.texture.level_idx = sub_resource_idx % texture->level_count;
876 desc.u.texture.level_count = 1;
877 desc.u.texture.layer_idx = sub_resource_idx / texture->level_count;
878 desc.u.texture.layer_count = 1;
880 return wined3d_rendertarget_view_create(&desc, &texture->resource, parent, parent_ops, view);
883 ULONG CDECL wined3d_shader_resource_view_incref(struct wined3d_shader_resource_view *view)
885 ULONG refcount = InterlockedIncrement(&view->refcount);
887 TRACE("%p increasing refcount to %u.\n", view, refcount);
889 return refcount;
892 void wined3d_shader_resource_view_cleanup(struct wined3d_shader_resource_view *view)
894 /* Call wined3d_object_destroyed() before releasing the resource,
895 * since releasing the resource may end up destroying the parent. */
896 view->parent_ops->wined3d_object_destroyed(view->parent);
897 wined3d_resource_decref(view->resource);
900 ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_view *view)
902 ULONG refcount = InterlockedDecrement(&view->refcount);
904 TRACE("%p decreasing refcount to %u.\n", view, refcount);
906 if (!refcount)
907 view->resource->device->adapter->adapter_ops->adapter_destroy_shader_resource_view(view);
909 return refcount;
912 void * CDECL wined3d_shader_resource_view_get_parent(const struct wined3d_shader_resource_view *view)
914 TRACE("view %p.\n", view);
916 return view->parent;
919 static void wined3d_shader_resource_view_gl_cs_init(void *object)
921 struct wined3d_shader_resource_view_gl *view_gl = object;
922 struct wined3d_resource *resource = view_gl->v.resource;
923 const struct wined3d_format *view_format;
924 const struct wined3d_gl_info *gl_info;
925 const struct wined3d_view_desc *desc;
926 GLenum view_target;
928 view_format = view_gl->v.format;
929 gl_info = &resource->device->adapter->gl_info;
930 desc = &view_gl->v.desc;
932 if (resource->type == WINED3D_RTYPE_BUFFER)
934 struct wined3d_buffer *buffer = buffer_from_resource(resource);
935 struct wined3d_context *context;
937 context = context_acquire(resource->device, NULL, 0);
938 create_buffer_view(&view_gl->gl_view, context, desc, buffer, view_format);
939 context_release(context);
941 else
943 struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture_from_resource(resource));
944 GLenum resource_class, view_class;
946 resource_class = wined3d_format_gl(resource->format)->view_class;
947 view_class = wined3d_format_gl(view_format)->view_class;
948 view_target = get_texture_view_target(gl_info, desc, texture_gl);
950 if (resource->format->id == view_format->id && texture_gl->target == view_target
951 && !desc->u.texture.level_idx && desc->u.texture.level_count == texture_gl->t.level_count
952 && !desc->u.texture.layer_idx && desc->u.texture.layer_count == texture_gl->t.layer_count
953 && !is_stencil_view_format(view_format))
955 TRACE("Creating identity shader resource view.\n");
957 else if (texture_gl->t.swapchain && texture_gl->t.swapchain->state.desc.backbuffer_count > 1)
959 FIXME("Swapchain shader resource views not supported.\n");
961 else if (resource->format->typeless_id == view_format->typeless_id
962 && resource_class == view_class)
964 create_texture_view(&view_gl->gl_view, view_target, desc, texture_gl, view_format);
966 else if (wined3d_format_is_depth_view(resource->format->id, view_format->id))
968 create_texture_view(&view_gl->gl_view, view_target, desc, texture_gl, resource->format);
970 else
972 FIXME("Shader resource view not supported, resource format %s, view format %s.\n",
973 debug_d3dformat(resource->format->id), debug_d3dformat(view_format->id));
978 static HRESULT wined3d_shader_resource_view_init(struct wined3d_shader_resource_view *view,
979 const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
980 void *parent, const struct wined3d_parent_ops *parent_ops)
982 view->refcount = 1;
983 view->parent = parent;
984 view->parent_ops = parent_ops;
986 if (!(resource->bind_flags & WINED3D_BIND_SHADER_RESOURCE))
987 return E_INVALIDARG;
988 if (!(view->format = validate_resource_view(desc, resource, FALSE, FALSE)))
989 return E_INVALIDARG;
990 view->desc = *desc;
992 wined3d_resource_incref(view->resource = resource);
994 return WINED3D_OK;
997 HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view_gl *view_gl,
998 const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
999 void *parent, const struct wined3d_parent_ops *parent_ops)
1001 HRESULT hr;
1003 TRACE("view_gl %p, desc %s, resource %p, parent %p, parent_ops %p.\n",
1004 view_gl, wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops);
1006 if (FAILED(hr = wined3d_shader_resource_view_init(&view_gl->v, desc, resource, parent, parent_ops)))
1007 return hr;
1009 wined3d_cs_init_object(resource->device->cs, wined3d_shader_resource_view_gl_cs_init, view_gl);
1011 return hr;
1014 void wined3d_shader_resource_view_vk_update(struct wined3d_shader_resource_view_vk *srv_vk,
1015 struct wined3d_context_vk *context_vk)
1017 const struct wined3d_format_vk *view_format_vk = wined3d_format_vk(srv_vk->v.format);
1018 const struct wined3d_view_desc *desc = &srv_vk->v.desc;
1019 struct wined3d_resource *resource = srv_vk->v.resource;
1020 struct wined3d_view_vk *view_vk = &srv_vk->view_vk;
1021 struct wined3d_buffer_vk *buffer_vk;
1022 VkBufferView vk_buffer_view;
1024 buffer_vk = wined3d_buffer_vk(buffer_from_resource(resource));
1025 wined3d_context_vk_destroy_buffer_view(context_vk, view_vk->u.vk_buffer_view, view_vk->command_buffer_id);
1026 if ((vk_buffer_view = wined3d_view_vk_create_buffer_view(context_vk, desc, buffer_vk, view_format_vk)))
1028 view_vk->u.vk_buffer_view = vk_buffer_view;
1029 view_vk->bo_user.valid = true;
1033 static void wined3d_shader_resource_view_vk_cs_init(void *object)
1035 struct wined3d_shader_resource_view_vk *srv_vk = object;
1036 struct wined3d_view_desc *desc = &srv_vk->v.desc;
1037 struct wined3d_texture_vk *texture_vk;
1038 const struct wined3d_format *format;
1039 struct wined3d_buffer_vk *buffer_vk;
1040 struct wined3d_resource *resource;
1041 struct wined3d_context *context;
1042 VkBufferView vk_buffer_view;
1043 uint32_t default_flags = 0;
1044 VkImageView vk_image_view;
1046 resource = srv_vk->v.resource;
1047 format = srv_vk->v.format;
1049 if (resource->type == WINED3D_RTYPE_BUFFER)
1051 buffer_vk = wined3d_buffer_vk(buffer_from_resource(resource));
1053 context = context_acquire(resource->device, NULL, 0);
1054 vk_buffer_view = wined3d_view_vk_create_buffer_view(wined3d_context_vk(context),
1055 desc, buffer_vk, wined3d_format_vk(format));
1056 context_release(context);
1058 if (!vk_buffer_view)
1059 return;
1061 TRACE("Created buffer view 0x%s.\n", wine_dbgstr_longlong(vk_buffer_view));
1063 srv_vk->view_vk.u.vk_buffer_view = vk_buffer_view;
1064 srv_vk->view_vk.bo_user.valid = true;
1065 list_add_head(&buffer_vk->bo.users, &srv_vk->view_vk.bo_user.entry);
1067 return;
1070 texture_vk = wined3d_texture_vk(texture_from_resource(resource));
1072 if (texture_vk->t.layer_count > 1)
1073 default_flags |= WINED3D_VIEW_TEXTURE_ARRAY;
1075 if (resource->format->id == format->id && desc->flags == default_flags
1076 && !desc->u.texture.level_idx && desc->u.texture.level_count == texture_vk->t.level_count
1077 && !desc->u.texture.layer_idx && desc->u.texture.layer_count == texture_vk->t.layer_count
1078 && !(resource->bind_flags & WINED3D_BIND_DEPTH_STENCIL))
1080 TRACE("Creating identity shader resource view.\n");
1081 return;
1084 if (texture_vk->t.swapchain && texture_vk->t.swapchain->state.desc.backbuffer_count > 1)
1085 FIXME("Swapchain shader resource views not supported.\n");
1087 context = context_acquire(resource->device, NULL, 0);
1088 vk_image_view = wined3d_view_vk_create_texture_view(wined3d_context_vk(context),
1089 desc, texture_vk, wined3d_format_vk(format), format->color_fixup, true);
1090 context_release(context);
1092 if (!vk_image_view)
1093 return;
1095 TRACE("Created image view 0x%s.\n", wine_dbgstr_longlong(vk_image_view));
1097 srv_vk->view_vk.u.vk_image_info.imageView = vk_image_view;
1098 srv_vk->view_vk.u.vk_image_info.sampler = VK_NULL_HANDLE;
1099 srv_vk->view_vk.u.vk_image_info.imageLayout = texture_vk->layout;
1102 HRESULT wined3d_shader_resource_view_vk_init(struct wined3d_shader_resource_view_vk *view_vk,
1103 const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
1104 void *parent, const struct wined3d_parent_ops *parent_ops)
1106 HRESULT hr;
1108 TRACE("view_vk %p, desc %s, resource %p, parent %p, parent_ops %p.\n",
1109 view_vk, wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops);
1111 if (FAILED(hr = wined3d_shader_resource_view_init(&view_vk->v, desc, resource, parent, parent_ops)))
1112 return hr;
1114 list_init(&view_vk->view_vk.bo_user.entry);
1115 wined3d_cs_init_object(resource->device->cs, wined3d_shader_resource_view_vk_cs_init, view_vk);
1117 return hr;
1120 HRESULT CDECL wined3d_shader_resource_view_create(const struct wined3d_view_desc *desc,
1121 struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
1122 struct wined3d_shader_resource_view **view)
1124 const struct wined3d_adapter_ops *adapter_ops;
1126 TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n",
1127 wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view);
1129 adapter_ops = resource->device->adapter->adapter_ops;
1130 return adapter_ops->adapter_create_shader_resource_view(desc, resource, parent, parent_ops, view);
1133 void wined3d_shader_resource_view_gl_bind(struct wined3d_shader_resource_view_gl *view_gl,
1134 unsigned int unit, struct wined3d_sampler_gl *sampler_gl, struct wined3d_context_gl *context_gl)
1136 const struct wined3d_gl_info *gl_info = context_gl->gl_info;
1137 struct wined3d_texture_gl *texture_gl;
1139 wined3d_context_gl_active_texture(context_gl, gl_info, unit);
1141 if (view_gl->gl_view.name)
1143 wined3d_context_gl_bind_texture(context_gl, view_gl->gl_view.target, view_gl->gl_view.name);
1144 wined3d_sampler_gl_bind(sampler_gl, unit, NULL, context_gl);
1145 return;
1148 if (view_gl->v.resource->type == WINED3D_RTYPE_BUFFER)
1150 FIXME("Buffer shader resources not supported.\n");
1151 return;
1154 texture_gl = wined3d_texture_gl(wined3d_texture_from_resource(view_gl->v.resource));
1155 wined3d_texture_gl_bind(texture_gl, context_gl, FALSE);
1156 wined3d_sampler_gl_bind(sampler_gl, unit, texture_gl, context_gl);
1159 /* Context activation is done by the caller. */
1160 static void shader_resource_view_gl_bind_and_dirtify(struct wined3d_shader_resource_view_gl *view_gl,
1161 struct wined3d_context_gl *context_gl)
1163 if (context_gl->active_texture < ARRAY_SIZE(context_gl->rev_tex_unit_map))
1165 unsigned int active_sampler = context_gl->rev_tex_unit_map[context_gl->active_texture];
1166 if (active_sampler != WINED3D_UNMAPPED_STAGE)
1167 context_invalidate_state(&context_gl->c, STATE_SAMPLER(active_sampler));
1169 /* FIXME: Ideally we'd only do this when touching a binding that's used by
1170 * a shader. */
1171 context_invalidate_compute_state(&context_gl->c, STATE_COMPUTE_SHADER_RESOURCE_BINDING);
1172 context_invalidate_state(&context_gl->c, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
1174 wined3d_context_gl_bind_texture(context_gl, view_gl->gl_view.target, view_gl->gl_view.name);
1177 void shader_resource_view_generate_mipmaps(struct wined3d_shader_resource_view *view)
1179 struct wined3d_shader_resource_view_gl *view_gl = wined3d_shader_resource_view_gl(view);
1180 unsigned int i, j, layer_count, level_count, base_level, max_level;
1181 const struct wined3d_gl_info *gl_info;
1182 struct wined3d_texture_gl *texture_gl;
1183 struct wined3d_context_gl *context_gl;
1184 struct wined3d_context *context;
1185 struct gl_texture *gl_tex;
1186 DWORD location;
1187 BOOL srgb;
1189 TRACE("view %p.\n", view);
1191 context = context_acquire(view_gl->v.resource->device, NULL, 0);
1192 context_gl = wined3d_context_gl(context);
1193 gl_info = context_gl->gl_info;
1194 layer_count = view_gl->v.desc.u.texture.layer_count;
1195 level_count = view_gl->v.desc.u.texture.level_count;
1196 base_level = view_gl->v.desc.u.texture.level_idx;
1197 max_level = base_level + level_count - 1;
1199 texture_gl = wined3d_texture_gl(texture_from_resource(view_gl->v.resource));
1200 srgb = !!(texture_gl->t.flags & WINED3D_TEXTURE_IS_SRGB);
1201 location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB;
1202 for (i = 0; i < layer_count; ++i)
1203 wined3d_texture_load_location(&texture_gl->t, i * level_count + base_level, context, location);
1205 if (view_gl->gl_view.name)
1207 shader_resource_view_gl_bind_and_dirtify(view_gl, context_gl);
1209 else
1211 wined3d_texture_gl_bind_and_dirtify(texture_gl, context_gl, srgb);
1212 gl_info->gl_ops.gl.p_glTexParameteri(texture_gl->target, GL_TEXTURE_BASE_LEVEL, base_level);
1213 gl_info->gl_ops.gl.p_glTexParameteri(texture_gl->target, GL_TEXTURE_MAX_LEVEL, max_level);
1216 if (gl_info->supported[ARB_SAMPLER_OBJECTS])
1217 GL_EXTCALL(glBindSampler(context_gl->active_texture, 0));
1218 gl_tex = wined3d_texture_gl_get_gl_texture(texture_gl, srgb);
1219 if (context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL)
1221 gl_info->gl_ops.gl.p_glTexParameteri(texture_gl->target,
1222 GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
1223 gl_tex->sampler_desc.srgb_decode = FALSE;
1226 gl_info->fbo_ops.glGenerateMipmap(texture_gl->target);
1227 checkGLcall("glGenerateMipMap()");
1229 for (i = 0; i < layer_count; ++i)
1231 for (j = base_level + 1; j <= max_level; ++j)
1233 wined3d_texture_validate_location(&texture_gl->t, i * level_count + j, location);
1234 wined3d_texture_invalidate_location(&texture_gl->t, i * level_count + j, ~location);
1238 if (!view_gl->gl_view.name)
1240 gl_tex->base_level = base_level;
1241 gl_info->gl_ops.gl.p_glTexParameteri(texture_gl->target,
1242 GL_TEXTURE_MAX_LEVEL, texture_gl->t.level_count - 1);
1245 context_release(context);
1248 void CDECL wined3d_shader_resource_view_generate_mipmaps(struct wined3d_shader_resource_view *view)
1250 struct wined3d_texture *texture;
1252 TRACE("view %p.\n", view);
1254 if (view->resource->type == WINED3D_RTYPE_BUFFER)
1256 WARN("Called on buffer resource %p.\n", view->resource);
1257 return;
1260 texture = texture_from_resource(view->resource);
1261 if (!(texture->flags & WINED3D_TEXTURE_GENERATE_MIPMAPS))
1263 WARN("Texture without the WINED3D_TEXTURE_GENERATE_MIPMAPS flag, ignoring.\n");
1264 return;
1267 wined3d_cs_emit_generate_mipmaps(view->resource->device->cs, view);
1270 ULONG CDECL wined3d_unordered_access_view_incref(struct wined3d_unordered_access_view *view)
1272 ULONG refcount = InterlockedIncrement(&view->refcount);
1274 TRACE("%p increasing refcount to %u.\n", view, refcount);
1276 return refcount;
1279 void wined3d_unordered_access_view_cleanup(struct wined3d_unordered_access_view *view)
1281 /* Call wined3d_object_destroyed() before releasing the resource,
1282 * since releasing the resource may end up destroying the parent. */
1283 view->parent_ops->wined3d_object_destroyed(view->parent);
1284 wined3d_resource_decref(view->resource);
1287 ULONG CDECL wined3d_unordered_access_view_decref(struct wined3d_unordered_access_view *view)
1289 ULONG refcount = InterlockedDecrement(&view->refcount);
1291 TRACE("%p decreasing refcount to %u.\n", view, refcount);
1293 if (!refcount)
1294 view->resource->device->adapter->adapter_ops->adapter_destroy_unordered_access_view(view);
1296 return refcount;
1299 void * CDECL wined3d_unordered_access_view_get_parent(const struct wined3d_unordered_access_view *view)
1301 TRACE("view %p.\n", view);
1303 return view->parent;
1306 void wined3d_unordered_access_view_invalidate_location(struct wined3d_unordered_access_view *view,
1307 DWORD location)
1309 wined3d_view_invalidate_location(view->resource, &view->desc, location);
1312 void wined3d_unordered_access_view_gl_clear_uint(struct wined3d_unordered_access_view_gl *view_gl,
1313 const struct wined3d_uvec4 *clear_value, struct wined3d_context_gl *context_gl)
1315 const struct wined3d_gl_info *gl_info = context_gl->gl_info;
1316 const struct wined3d_format_gl *format;
1317 struct wined3d_buffer_gl *buffer_gl;
1318 struct wined3d_resource *resource;
1319 unsigned int offset, size;
1321 resource = view_gl->v.resource;
1322 if (resource->type != WINED3D_RTYPE_BUFFER)
1324 FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type));
1325 return;
1328 if (!gl_info->supported[ARB_CLEAR_BUFFER_OBJECT])
1330 FIXME("OpenGL implementation does not support ARB_clear_buffer_object.\n");
1331 return;
1334 format = wined3d_format_gl(view_gl->v.format);
1335 if (format->f.id != WINED3DFMT_R32_UINT && format->f.id != WINED3DFMT_R32_SINT
1336 && format->f.id != WINED3DFMT_R32G32B32A32_UINT
1337 && format->f.id != WINED3DFMT_R32G32B32A32_SINT)
1339 FIXME("Not implemented for format %s.\n", debug_d3dformat(format->f.id));
1340 return;
1343 buffer_gl = wined3d_buffer_gl(buffer_from_resource(resource));
1344 wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER);
1345 wined3d_unordered_access_view_invalidate_location(&view_gl->v, ~WINED3D_LOCATION_BUFFER);
1347 get_buffer_view_range(&buffer_gl->b, &view_gl->v.desc, &format->f, &offset, &size);
1348 wined3d_context_gl_bind_bo(context_gl, buffer_gl->bo.binding, buffer_gl->bo.id);
1349 GL_EXTCALL(glClearBufferSubData(buffer_gl->bo.binding, format->internal,
1350 offset, size, format->format, format->type, clear_value));
1351 checkGLcall("clear unordered access view");
1354 void wined3d_unordered_access_view_set_counter(struct wined3d_unordered_access_view *view,
1355 unsigned int value)
1357 struct wined3d_bo_address dst, src;
1358 struct wined3d_context *context;
1360 if (!view->counter_bo)
1361 return;
1363 context = context_acquire(view->resource->device, NULL, 0);
1365 src.buffer_object = 0;
1366 src.addr = (void *)&value;
1368 dst.buffer_object = view->counter_bo;
1369 dst.addr = NULL;
1371 wined3d_context_copy_bo_address(context, &dst, &src, sizeof(uint32_t));
1373 context_release(context);
1376 void wined3d_unordered_access_view_copy_counter(struct wined3d_unordered_access_view *view,
1377 struct wined3d_buffer *buffer, unsigned int offset, struct wined3d_context *context)
1379 struct wined3d_bo_address dst, src;
1380 DWORD dst_location;
1382 if (!view->counter_bo)
1383 return;
1385 dst_location = wined3d_buffer_get_memory(buffer, &dst, buffer->locations);
1386 dst.addr += offset;
1388 src.buffer_object = view->counter_bo;
1389 src.addr = NULL;
1391 wined3d_context_copy_bo_address(context, &dst, &src, sizeof(uint32_t));
1393 wined3d_buffer_invalidate_location(buffer, ~dst_location);
1396 static void wined3d_unordered_access_view_gl_cs_init(void *object)
1398 struct wined3d_unordered_access_view_gl *view_gl = object;
1399 struct wined3d_resource *resource = view_gl->v.resource;
1400 struct wined3d_view_desc *desc = &view_gl->v.desc;
1401 const struct wined3d_gl_info *gl_info;
1403 gl_info = &resource->device->adapter->gl_info;
1405 if (resource->type == WINED3D_RTYPE_BUFFER)
1407 struct wined3d_buffer *buffer = buffer_from_resource(resource);
1408 struct wined3d_context *context;
1410 context = context_acquire(resource->device, NULL, 0);
1411 gl_info = wined3d_context_gl(context)->gl_info;
1412 create_buffer_view(&view_gl->gl_view, context, desc, buffer, view_gl->v.format);
1413 if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_BUFFER_APPEND))
1415 struct wined3d_bo_gl *bo = &view_gl->counter_bo;
1416 static const GLuint initial_value = 0;
1418 GL_EXTCALL(glGenBuffers(1, &bo->id));
1419 bo->binding = GL_ATOMIC_COUNTER_BUFFER;
1420 GL_EXTCALL(glBindBuffer(bo->binding, bo->id));
1421 GL_EXTCALL(glBufferData(bo->binding, sizeof(initial_value), &initial_value, GL_STATIC_DRAW));
1422 checkGLcall("create atomic counter buffer");
1423 view_gl->v.counter_bo = (uintptr_t)bo;
1425 context_release(context);
1427 else
1429 struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture_from_resource(resource));
1430 unsigned int depth_or_layer_count;
1432 if (resource->type == WINED3D_RTYPE_TEXTURE_3D)
1433 depth_or_layer_count = wined3d_texture_get_level_depth(&texture_gl->t, desc->u.texture.level_idx);
1434 else
1435 depth_or_layer_count = texture_gl->t.layer_count;
1437 if (desc->u.texture.layer_idx || desc->u.texture.layer_count != depth_or_layer_count)
1439 create_texture_view(&view_gl->gl_view, get_texture_view_target(gl_info, desc, texture_gl),
1440 desc, texture_gl, view_gl->v.format);
1445 static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_access_view *view,
1446 const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
1447 void *parent, const struct wined3d_parent_ops *parent_ops)
1449 view->refcount = 1;
1450 view->parent = parent;
1451 view->parent_ops = parent_ops;
1453 if (!(resource->bind_flags & WINED3D_BIND_UNORDERED_ACCESS))
1454 return E_INVALIDARG;
1455 if (!(view->format = validate_resource_view(desc, resource, TRUE, FALSE)))
1456 return E_INVALIDARG;
1457 view->desc = *desc;
1459 wined3d_resource_incref(view->resource = resource);
1461 return WINED3D_OK;
1464 HRESULT wined3d_unordered_access_view_gl_init(struct wined3d_unordered_access_view_gl *view_gl,
1465 const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
1466 void *parent, const struct wined3d_parent_ops *parent_ops)
1468 HRESULT hr;
1470 TRACE("view_gl %p, desc %s, resource %p, parent %p, parent_ops %p.\n",
1471 view_gl, wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops);
1473 if (FAILED(hr = wined3d_unordered_access_view_init(&view_gl->v, desc, resource, parent, parent_ops)))
1474 return hr;
1476 wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_gl_cs_init, view_gl);
1478 return hr;
1481 void wined3d_unordered_access_view_vk_clear_uint(struct wined3d_unordered_access_view_vk *view_vk,
1482 const struct wined3d_uvec4 *clear_value, struct wined3d_context_vk *context_vk)
1484 const struct wined3d_vk_info *vk_info;
1485 const struct wined3d_format *format;
1486 struct wined3d_buffer_vk *buffer_vk;
1487 struct wined3d_resource *resource;
1488 VkCommandBuffer vk_command_buffer;
1489 VkBufferMemoryBarrier vk_barrier;
1490 VkAccessFlags access_mask;
1491 unsigned int offset, size;
1493 TRACE("view_vk %p, clear_value %s, context_vk %p.\n", view_vk, debug_uvec4(clear_value), context_vk);
1495 resource = view_vk->v.resource;
1496 if (resource->type != WINED3D_RTYPE_BUFFER)
1498 FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type));
1499 return;
1502 format = view_vk->v.format;
1503 if (format->id != WINED3DFMT_R32_UINT && format->id != WINED3DFMT_R32_SINT)
1505 FIXME("Not implemented for format %s.\n", debug_d3dformat(format->id));
1506 return;
1509 vk_info = context_vk->vk_info;
1510 buffer_vk = wined3d_buffer_vk(buffer_from_resource(resource));
1511 wined3d_buffer_load_location(&buffer_vk->b, &context_vk->c, WINED3D_LOCATION_BUFFER);
1512 wined3d_buffer_invalidate_location(&buffer_vk->b, ~WINED3D_LOCATION_BUFFER);
1514 get_buffer_view_range(&buffer_vk->b, &view_vk->v.desc, format, &offset, &size);
1516 if (!(vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk)))
1517 return;
1518 wined3d_context_vk_end_current_render_pass(context_vk);
1520 access_mask = vk_access_mask_from_bind_flags(buffer_vk->b.resource.bind_flags);
1521 vk_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
1522 vk_barrier.pNext = NULL;
1523 vk_barrier.srcAccessMask = access_mask;
1524 vk_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1525 vk_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1526 vk_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1527 vk_barrier.buffer = buffer_vk->bo.vk_buffer;
1528 vk_barrier.offset = buffer_vk->bo.buffer_offset + offset;
1529 vk_barrier.size = size;
1530 VK_CALL(vkCmdPipelineBarrier(vk_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
1531 VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1, &vk_barrier, 0, NULL));
1533 VK_CALL(vkCmdFillBuffer(vk_command_buffer, buffer_vk->bo.vk_buffer,
1534 buffer_vk->bo.buffer_offset + offset, size, clear_value->x));
1536 vk_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1537 vk_barrier.dstAccessMask = access_mask;
1538 VK_CALL(vkCmdPipelineBarrier(vk_command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
1539 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, NULL, 1, &vk_barrier, 0, NULL));
1541 wined3d_context_vk_reference_bo(context_vk, &buffer_vk->bo);
1544 void wined3d_unordered_access_view_vk_update(struct wined3d_unordered_access_view_vk *uav_vk,
1545 struct wined3d_context_vk *context_vk)
1547 const struct wined3d_format_vk *view_format_vk = wined3d_format_vk(uav_vk->v.format);
1548 const struct wined3d_view_desc *desc = &uav_vk->v.desc;
1549 struct wined3d_resource *resource = uav_vk->v.resource;
1550 struct wined3d_view_vk *view_vk = &uav_vk->view_vk;
1551 struct wined3d_buffer_vk *buffer_vk;
1552 VkBufferView vk_buffer_view;
1554 buffer_vk = wined3d_buffer_vk(buffer_from_resource(resource));
1555 wined3d_context_vk_destroy_buffer_view(context_vk, view_vk->u.vk_buffer_view, view_vk->command_buffer_id);
1556 if ((vk_buffer_view = wined3d_view_vk_create_buffer_view(context_vk, desc, buffer_vk, view_format_vk)))
1558 view_vk->u.vk_buffer_view = vk_buffer_view;
1559 view_vk->bo_user.valid = true;
1563 static void wined3d_unordered_access_view_vk_cs_init(void *object)
1565 struct wined3d_unordered_access_view_vk *uav_vk = object;
1566 struct wined3d_view_vk *view_vk = &uav_vk->view_vk;
1567 struct wined3d_view_desc *desc = &uav_vk->v.desc;
1568 const struct wined3d_format_vk *format_vk;
1569 const struct wined3d_vk_info *vk_info;
1570 struct wined3d_texture_vk *texture_vk;
1571 struct wined3d_context_vk *context_vk;
1572 struct wined3d_device_vk *device_vk;
1573 struct wined3d_buffer_vk *buffer_vk;
1574 VkBufferViewCreateInfo create_info;
1575 struct wined3d_resource *resource;
1576 VkBufferView vk_buffer_view;
1577 uint32_t default_flags = 0;
1578 VkImageView vk_image_view;
1579 VkResult vr;
1581 resource = uav_vk->v.resource;
1582 device_vk = wined3d_device_vk(resource->device);
1583 format_vk = wined3d_format_vk(uav_vk->v.format);
1585 if (resource->type == WINED3D_RTYPE_BUFFER)
1587 buffer_vk = wined3d_buffer_vk(buffer_from_resource(resource));
1589 context_vk = wined3d_context_vk(context_acquire(&device_vk->d, NULL, 0));
1590 vk_info = context_vk->vk_info;
1592 if ((vk_buffer_view = wined3d_view_vk_create_buffer_view(context_vk, desc, buffer_vk, format_vk)))
1594 TRACE("Created buffer view 0x%s.\n", wine_dbgstr_longlong(vk_buffer_view));
1596 uav_vk->view_vk.u.vk_buffer_view = vk_buffer_view;
1597 uav_vk->view_vk.bo_user.valid = true;
1598 list_add_head(&buffer_vk->bo.users, &view_vk->bo_user.entry);
1601 if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_BUFFER_APPEND))
1603 if (!wined3d_context_vk_create_bo(context_vk, sizeof(uint32_t), VK_BUFFER_USAGE_TRANSFER_SRC_BIT
1604 | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,
1605 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &uav_vk->counter_bo))
1607 ERR("Failed to create counter bo.\n");
1608 context_release(&context_vk->c);
1610 return;
1613 wined3d_context_vk_end_current_render_pass(context_vk);
1614 VK_CALL(vkCmdFillBuffer(wined3d_context_vk_get_command_buffer(context_vk),
1615 uav_vk->counter_bo.vk_buffer, uav_vk->counter_bo.buffer_offset, sizeof(uint32_t), 0));
1616 wined3d_context_vk_reference_bo(context_vk, &uav_vk->counter_bo);
1618 create_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
1619 create_info.pNext = NULL;
1620 create_info.flags = 0;
1621 create_info.buffer = uav_vk->counter_bo.vk_buffer;
1622 create_info.format = VK_FORMAT_R32_UINT;
1623 create_info.offset = uav_vk->counter_bo.buffer_offset;
1624 create_info.range = sizeof(uint32_t);
1625 if ((vr = VK_CALL(vkCreateBufferView(device_vk->vk_device,
1626 &create_info, NULL, &uav_vk->vk_counter_view))) < 0)
1628 ERR("Failed to create counter buffer view, vr %s.\n", wined3d_debug_vkresult(vr));
1630 else
1632 TRACE("Created counter buffer view 0x%s.\n", wine_dbgstr_longlong(uav_vk->vk_counter_view));
1634 uav_vk->v.counter_bo = (uintptr_t)&uav_vk->counter_bo;
1638 context_release(&context_vk->c);
1640 return;
1643 texture_vk = wined3d_texture_vk(texture_from_resource(resource));
1645 if (texture_vk->t.layer_count > 1)
1646 default_flags |= WINED3D_VIEW_TEXTURE_ARRAY;
1648 if (resource->format->id == format_vk->f.id && desc->flags == default_flags
1649 && !desc->u.texture.level_idx && desc->u.texture.level_count == texture_vk->t.level_count
1650 && !desc->u.texture.layer_idx && desc->u.texture.layer_count == texture_vk->t.layer_count
1651 && !(resource->bind_flags & WINED3D_BIND_DEPTH_STENCIL) && resource->type != WINED3D_RTYPE_TEXTURE_3D)
1653 TRACE("Creating identity unordered access view.\n");
1654 return;
1657 if (texture_vk->t.swapchain && texture_vk->t.swapchain->state.desc.backbuffer_count > 1)
1658 FIXME("Swapchain unordered access views not supported.\n");
1660 context_vk = wined3d_context_vk(context_acquire(&device_vk->d, NULL, 0));
1661 vk_image_view = wined3d_view_vk_create_texture_view(context_vk, desc,
1662 texture_vk, format_vk, format_vk->f.color_fixup, false);
1663 context_release(&context_vk->c);
1665 if (!vk_image_view)
1666 return;
1668 TRACE("Created image view 0x%s.\n", wine_dbgstr_longlong(vk_image_view));
1670 view_vk->u.vk_image_info.imageView = vk_image_view;
1671 view_vk->u.vk_image_info.sampler = VK_NULL_HANDLE;
1672 view_vk->u.vk_image_info.imageLayout = texture_vk->layout;
1675 HRESULT wined3d_unordered_access_view_vk_init(struct wined3d_unordered_access_view_vk *view_vk,
1676 const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
1677 void *parent, const struct wined3d_parent_ops *parent_ops)
1679 HRESULT hr;
1681 TRACE("view_vk %p, desc %s, resource %p, parent %p, parent_ops %p.\n",
1682 view_vk, wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops);
1684 if (FAILED(hr = wined3d_unordered_access_view_init(&view_vk->v, desc, resource, parent, parent_ops)))
1685 return hr;
1687 list_init(&view_vk->view_vk.bo_user.entry);
1688 wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_vk_cs_init, view_vk);
1690 return hr;
1693 HRESULT CDECL wined3d_unordered_access_view_create(const struct wined3d_view_desc *desc,
1694 struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
1695 struct wined3d_unordered_access_view **view)
1697 const struct wined3d_adapter_ops *adapter_ops;
1699 TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n",
1700 wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view);
1702 adapter_ops = resource->device->adapter->adapter_ops;
1703 return adapter_ops->adapter_create_unordered_access_view(desc, resource, parent, parent_ops, view);