Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- dlls/wined3d/adapter_gl.c | 2 + dlls/wined3d/buffer.c | 26 ------------ dlls/wined3d/context_gl.c | 72 ++++++++++++++++++++++++++++------ dlls/wined3d/resource.c | 5 +-- dlls/wined3d/view.c | 25 +++++++++++- dlls/wined3d/wined3d_private.h | 9 +++++ 6 files changed, 95 insertions(+), 44 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index 4781622d530..b6be5854714 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -4867,6 +4867,7 @@ static void adapter_gl_destroy_shader_resource_view(struct wined3d_shader_resour * the refcount on a device that's in the process of being destroyed. */ if (swapchain_count) wined3d_device_incref(device); + list_remove(&view_gl->bo_user.entry); wined3d_shader_resource_view_cleanup(&view_gl->v); wined3d_view_gl_destroy(device, &view_gl->gl_view, NULL, view_gl); if (swapchain_count) @@ -4913,6 +4914,7 @@ static void adapter_gl_destroy_unordered_access_view(struct wined3d_unordered_ac * the refcount on a device that's in the process of being destroyed. */ if (swapchain_count) wined3d_device_incref(device); + list_remove(&view_gl->bo_user.entry); wined3d_unordered_access_view_cleanup(&view_gl->v); wined3d_view_gl_destroy(device, &view_gl->gl_view, &view_gl->counter_bo, view_gl); if (swapchain_count) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index e179f202cb8..acedc1a183e 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -714,29 +714,6 @@ void * CDECL wined3d_buffer_get_parent(const struct wined3d_buffer *buffer) return buffer->resource.parent; }
-/* The caller provides a context and binds the buffer */ -static void wined3d_buffer_gl_sync_apple(struct wined3d_buffer_gl *buffer_gl, - uint32_t flags, struct wined3d_context_gl *context_gl) -{ - const struct wined3d_gl_info *gl_info = context_gl->gl_info; - struct wined3d_bo_gl *bo = &buffer_gl->bo; - - /* No fencing needs to be done if the app promises not to overwrite - * existing data. */ - if (flags & WINED3D_MAP_NOOVERWRITE) - return; - - if (flags & WINED3D_MAP_DISCARD) - { - wined3d_buffer_gl_bind(buffer_gl, context_gl); - - GL_EXTCALL(glBufferData(bo->binding, buffer_gl->b.resource.size, NULL, bo->usage)); - checkGLcall("glBufferData"); - bo->command_fence_id = 0; - return; - } -} - static void buffer_mark_used(struct wined3d_buffer *buffer) { buffer->flags &= ~WINED3D_BUFFER_DISCARD; @@ -954,9 +931,6 @@ static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resourc if (buffer->flags & WINED3D_BUFFER_DISCARD) flags &= ~WINED3D_MAP_DISCARD;
- if (buffer->flags & WINED3D_BUFFER_APPLESYNC) - wined3d_buffer_gl_sync_apple(wined3d_buffer_gl(buffer), flags, wined3d_context_gl(context)); - addr.buffer_object = buffer->buffer_object; addr.addr = 0; buffer->map_ptr = wined3d_context_map_bo_address(context, &addr, resource->size, flags); diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index 305ca0507ff..f2f6185ecc6 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -2650,20 +2650,39 @@ void wined3d_context_gl_submit_command_fence(struct wined3d_context_gl *context_ wined3d_context_gl_poll_fences(context_gl); }
-void *wined3d_context_gl_map_bo_address(struct wined3d_context_gl *context_gl, - const struct wined3d_bo_address *data, size_t size, uint32_t flags) +static void *wined3d_bo_gl_map(struct wined3d_bo_gl *bo, + struct wined3d_context_gl *context_gl, size_t offset, size_t size, uint32_t flags) { struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device); const struct wined3d_gl_info *gl_info; - struct wined3d_bo_gl *bo; - BYTE *memory; + struct wined3d_bo_user *bo_user; + struct wined3d_bo_gl tmp; + uint8_t *map_ptr;
- if (!(bo = (struct wined3d_bo_gl *)data->buffer_object)) - return data->addr; - - if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)) + if (flags & WINED3D_MAP_NOOVERWRITE) goto map;
+ if ((flags & WINED3D_MAP_DISCARD) && bo->command_fence_id > device_gl->completed_fence_id) + { + if (wined3d_context_gl_create_bo(context_gl, bo->size, + bo->binding, bo->usage, bo->coherent, bo->flags, &tmp)) + { + list_move_head(&tmp.users, &bo->users); + wined3d_context_gl_destroy_bo(context_gl, bo); + *bo = tmp; + list_init(&bo->users); + list_move_head(&bo->users, &tmp.users); + LIST_FOR_EACH_ENTRY(bo_user, &bo->users, struct wined3d_bo_user, entry) + { + bo_user->valid = false; + } + + goto map; + } + + ERR("Failed to create new buffer object.\n"); + } + if (bo->command_fence_id == device_gl->current_fence_id) wined3d_context_gl_submit_command_fence(context_gl); wined3d_context_gl_wait_command_fence(context_gl, bo->command_fence_id); @@ -2674,19 +2693,33 @@ map:
if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) { - memory = GL_EXTCALL(glMapBufferRange(bo->binding, (INT_PTR)data->addr, - size, wined3d_resource_gl_map_flags(flags))); + map_ptr = GL_EXTCALL(glMapBufferRange(bo->binding, offset, size, wined3d_resource_gl_map_flags(flags))); } else { - memory = GL_EXTCALL(glMapBuffer(bo->binding, wined3d_resource_gl_legacy_map_flags(flags))); - memory += (INT_PTR)data->addr; + map_ptr = GL_EXTCALL(glMapBuffer(bo->binding, wined3d_resource_gl_legacy_map_flags(flags))); + map_ptr += offset; }
wined3d_context_gl_bind_bo(context_gl, bo->binding, 0); checkGLcall("Map buffer object");
- return memory; + return map_ptr; +} + +void *wined3d_context_gl_map_bo_address(struct wined3d_context_gl *context_gl, + const struct wined3d_bo_address *data, size_t size, uint32_t flags) +{ + struct wined3d_bo_gl *bo; + void *map_ptr; + + if (!(bo = (struct wined3d_bo_gl *)data->buffer_object)) + return data->addr; + + if (!(map_ptr = wined3d_bo_gl_map(bo, context_gl, (uintptr_t)data->addr, size, flags))) + ERR("Failed to map bo.\n"); + + return map_ptr; }
void wined3d_context_gl_unmap_bo_address(struct wined3d_context_gl *context_gl, @@ -2821,8 +2854,11 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei
TRACE("Created buffer object %u.\n", id); bo->id = id; + bo->size = size; bo->binding = binding; bo->usage = usage; + bo->flags = flags; + bo->coherent = coherent; list_init(&bo->users); bo->command_fence_id = 0;
@@ -3698,6 +3734,7 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_ const struct wined3d_state *state, unsigned int shader_mask) { struct wined3d_shader_sampler_map_entry *entry; + struct wined3d_shader_resource_view_gl *srv_gl; struct wined3d_shader_resource_view *view; struct wined3d_buffer_gl *buffer_gl; struct wined3d_shader *shader; @@ -3735,6 +3772,10 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_ buffer_gl = wined3d_buffer_gl(buffer_from_resource(view->resource)); wined3d_buffer_load(&buffer_gl->b, &context_gl->c, state); wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo); + + srv_gl = wined3d_shader_resource_view_gl(view); + if (!srv_gl->bo_user.valid) + wined3d_shader_resource_view_gl_update(srv_gl, context_gl); } else { @@ -3747,6 +3788,7 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_ static void context_gl_load_unordered_access_resources(struct wined3d_context_gl *context_gl, const struct wined3d_shader *shader, struct wined3d_unordered_access_view * const *views) { + struct wined3d_unordered_access_view_gl *uav_gl; struct wined3d_unordered_access_view *view; struct wined3d_buffer_gl *buffer_gl; struct wined3d_texture *texture; @@ -3768,6 +3810,10 @@ static void context_gl_load_unordered_access_resources(struct wined3d_context_gl wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER); wined3d_unordered_access_view_invalidate_location(view, ~WINED3D_LOCATION_BUFFER); wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo); + + uav_gl = wined3d_unordered_access_view_gl(view); + if (!uav_gl->bo_user.valid) + wined3d_unordered_access_view_gl_update(uav_gl, context_gl); } else { diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index f6e233d8057..2b2088ab771 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -451,12 +451,9 @@ GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) ret |= GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT; if (d3d_flags & WINED3D_MAP_READ) ret |= GL_MAP_READ_BIT; - else if (!(d3d_flags & WINED3D_MAP_DISCARD)) + else ret |= GL_MAP_UNSYNCHRONIZED_BIT;
- if (d3d_flags & WINED3D_MAP_DISCARD) - ret |= GL_MAP_INVALIDATE_BUFFER_BIT; - return ret; }
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index 1abbbac4fb4..f2c8ceab461 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -268,7 +268,8 @@ static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_c wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER);
view->target = GL_TEXTURE_BUFFER; - gl_info->gl_ops.gl.p_glGenTextures(1, &view->name); + if (!view->name) + gl_info->gl_ops.gl.p_glGenTextures(1, &view->name);
wined3d_context_gl_bind_texture(context_gl, GL_TEXTURE_BUFFER, view->name); if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE]) @@ -916,6 +917,14 @@ void * CDECL wined3d_shader_resource_view_get_parent(const struct wined3d_shader return view->parent; }
+void wined3d_shader_resource_view_gl_update(struct wined3d_shader_resource_view_gl *srv_gl, + struct wined3d_context_gl *context_gl) +{ + create_buffer_view(&srv_gl->gl_view, &context_gl->c, &srv_gl->v.desc, + buffer_from_resource(srv_gl->v.resource), srv_gl->v.format); + srv_gl->bo_user.valid = true; +} + static void wined3d_shader_resource_view_gl_cs_init(void *object) { struct wined3d_shader_resource_view_gl *view_gl = object; @@ -936,6 +945,8 @@ static void wined3d_shader_resource_view_gl_cs_init(void *object)
context = context_acquire(resource->device, NULL, 0); create_buffer_view(&view_gl->gl_view, context, desc, buffer, view_format); + view_gl->bo_user.valid = true; + list_add_head(&wined3d_buffer_gl(buffer)->bo.users, &view_gl->bo_user.entry); context_release(context); } else @@ -1006,6 +1017,7 @@ HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view if (FAILED(hr = wined3d_shader_resource_view_init(&view_gl->v, desc, resource, parent, parent_ops))) return hr;
+ list_init(&view_gl->bo_user.entry); wined3d_cs_init_object(resource->device->cs, wined3d_shader_resource_view_gl_cs_init, view_gl);
return hr; @@ -1394,6 +1406,14 @@ void wined3d_unordered_access_view_copy_counter(struct wined3d_unordered_access_ wined3d_buffer_invalidate_location(buffer, ~dst_location); }
+void wined3d_unordered_access_view_gl_update(struct wined3d_unordered_access_view_gl *uav_gl, + struct wined3d_context_gl *context_gl) +{ + create_buffer_view(&uav_gl->gl_view, &context_gl->c, &uav_gl->v.desc, + buffer_from_resource(uav_gl->v.resource), uav_gl->v.format); + uav_gl->bo_user.valid = true; +} + static void wined3d_unordered_access_view_gl_cs_init(void *object) { struct wined3d_unordered_access_view_gl *view_gl = object; @@ -1410,6 +1430,8 @@ static void wined3d_unordered_access_view_gl_cs_init(void *object)
context_gl = wined3d_context_gl(context_acquire(resource->device, NULL, 0)); create_buffer_view(&view_gl->gl_view, &context_gl->c, desc, buffer, view_gl->v.format); + view_gl->bo_user.valid = true; + list_add_head(&wined3d_buffer_gl(buffer)->bo.users, &view_gl->bo_user.entry); if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_BUFFER_APPEND)) { struct wined3d_bo_gl *bo = &view_gl->counter_bo; @@ -1470,6 +1492,7 @@ HRESULT wined3d_unordered_access_view_gl_init(struct wined3d_unordered_access_vi if (FAILED(hr = wined3d_unordered_access_view_init(&view_gl->v, desc, resource, parent, parent_ops))) return hr;
+ list_init(&view_gl->bo_user.entry); wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_gl_cs_init, view_gl);
return hr; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 67a55c4dedd..a82defbbe7f 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1572,9 +1572,12 @@ do { \ struct wined3d_bo_gl { GLuint id; + GLsizeiptr size; GLenum binding; GLenum usage;
+ GLbitfield flags; + bool coherent; struct list users; uint64_t command_fence_id; }; @@ -5014,6 +5017,7 @@ void shader_resource_view_generate_mipmaps(struct wined3d_shader_resource_view * struct wined3d_shader_resource_view_gl { struct wined3d_shader_resource_view v; + struct wined3d_bo_user bo_user; struct wined3d_gl_view gl_view; };
@@ -5028,6 +5032,8 @@ void wined3d_shader_resource_view_gl_bind(struct wined3d_shader_resource_view_gl HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view_gl *view_gl, const struct wined3d_view_desc *desc, struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; +void wined3d_shader_resource_view_gl_update(struct wined3d_shader_resource_view_gl *srv_gl, + struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
struct wined3d_view_vk { @@ -5083,6 +5089,7 @@ void wined3d_unordered_access_view_set_counter(struct wined3d_unordered_access_v struct wined3d_unordered_access_view_gl { struct wined3d_unordered_access_view v; + struct wined3d_bo_user bo_user; struct wined3d_gl_view gl_view; struct wined3d_bo_gl counter_bo; }; @@ -5098,6 +5105,8 @@ void wined3d_unordered_access_view_gl_clear_uint(struct wined3d_unordered_access HRESULT wined3d_unordered_access_view_gl_init(struct wined3d_unordered_access_view_gl *view_gl, const struct wined3d_view_desc *desc, struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; +void wined3d_unordered_access_view_gl_update(struct wined3d_unordered_access_view_gl *uav_gl, + struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
struct wined3d_unordered_access_view_vk {