diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 59a1367630c..1d9e7ad5fb3 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -3416,7 +3416,8 @@ static void context_bind_unordered_access_views(struct wined3d_context *context, { const struct wined3d_gl_info *gl_info = context->gl_info; struct wined3d_unordered_access_view *view; - struct wined3d_texture *texture; + struct wined3d_texture *texture = NULL; + struct wined3d_buffer *buffer; GLuint texture_name; unsigned int i; GLint level; @@ -3440,26 +3441,35 @@ static void context_bind_unordered_access_views(struct wined3d_context *context, if (view->resource->type == WINED3D_RTYPE_BUFFER) { - FIXME("Buffer unordered access views not implemented.\n"); - continue; + buffer = buffer_from_resource(view->resource); + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER); + wined3d_unordered_access_view_invalidate_location(view, ~WINED3D_LOCATION_BUFFER); + } + else + { + texture = texture_from_resource(view->resource); + wined3d_texture_load(texture, context, FALSE); + wined3d_unordered_access_view_invalidate_location(view, ~WINED3D_LOCATION_TEXTURE_RGB); } context->uses_uavs = 1; - texture = texture_from_resource(view->resource); - wined3d_texture_load(texture, context, FALSE); - wined3d_unordered_access_view_invalidate_location(view, ~WINED3D_LOCATION_TEXTURE_RGB); - if (view->gl_view.name) { texture_name = view->gl_view.name; level = 0; } - else + else if (texture) { texture_name = wined3d_texture_get_gl_texture(texture, FALSE)->name; level = view->level_idx; } + else + { + FIXME("Unsupported buffer unordered access view.\n"); + GL_EXTCALL(glBindImageTexture(i, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R8)); + continue; + } GL_EXTCALL(glBindImageTexture(i, texture_name, level, GL_TRUE, 0, GL_READ_WRITE, view->format->glInternal)); diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index c1a92bed1f8..48db879b2d4 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -177,6 +177,39 @@ static void create_buffer_texture(struct wined3d_gl_view *view, context_release(context); } +static HRESULT create_buffer_view(struct wined3d_gl_view *view, + const struct wined3d_view_desc *desc, struct wined3d_buffer *buffer, + const struct wined3d_format *view_format) +{ + unsigned int offset, size; + + if (desc->format_id == WINED3DFMT_UNKNOWN) + { + FIXME("Structured buffer views not supported.\n"); + return WINED3D_OK; + } + + if (desc->flags & WINED3D_VIEW_BUFFER_RAW) + { + FIXME("Raw buffer views not supported.\n"); + return WINED3D_OK; + } + + if (desc->u.buffer.start_idx > ~0u / view_format->byte_count + || desc->u.buffer.count > ~0u / view_format->byte_count) + return E_INVALIDARG; + + offset = desc->u.buffer.start_idx * view_format->byte_count; + size = desc->u.buffer.count * view_format->byte_count; + + if (offset >= buffer->resource.size + || size > buffer->resource.size - offset) + return E_INVALIDARG; + + create_buffer_texture(view, buffer, view_format, offset, size); + return WINED3D_OK; +} + ULONG CDECL wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *view) { ULONG refcount = InterlockedIncrement(&view->refcount); @@ -472,32 +505,10 @@ static HRESULT wined3d_shader_resource_view_init(struct wined3d_shader_resource_ if (resource->type == WINED3D_RTYPE_BUFFER) { struct wined3d_buffer *buffer = buffer_from_resource(resource); + HRESULT hr; - if (desc->format_id == WINED3DFMT_UNKNOWN) - { - FIXME("Structured buffer views not supported.\n"); - } - else if (desc->flags & WINED3D_VIEW_BUFFER_RAW) - { - FIXME("Raw buffer views not supported.\n"); - } - else - { - unsigned int offset, size; - - if (desc->u.buffer.start_idx > ~0u / view_format->byte_count - || desc->u.buffer.count > ~0u / view_format->byte_count) - return E_INVALIDARG; - - offset = desc->u.buffer.start_idx * view_format->byte_count; - size = desc->u.buffer.count * view_format->byte_count; - - if (offset >= buffer->resource.size - || size > buffer->resource.size - offset) - return E_INVALIDARG; - - create_buffer_texture(&view->gl_view, buffer, view_format, offset, size); - } + if (FAILED(hr = create_buffer_view(&view->gl_view, desc, buffer, view_format))) + return hr; } else { @@ -638,7 +649,7 @@ void wined3d_unordered_access_view_invalidate_location(struct wined3d_unordered_ if (resource->type == WINED3D_RTYPE_BUFFER) { - FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type)); + wined3d_buffer_invalidate_location(buffer_from_resource(resource), location); return; } @@ -671,7 +682,11 @@ static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_acces if (resource->type == WINED3D_RTYPE_BUFFER) { - FIXME("Buffer unordered access views not supported.\n"); + struct wined3d_buffer *buffer = buffer_from_resource(resource); + HRESULT hr; + + if (FAILED(hr = create_buffer_view(&view->gl_view, desc, buffer, view->format))) + return hr; } else {