Signed-off-by: Henri Verbeet <hverbeet(a)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
{
--
2.20.1