summarylogtreecommitdiffstats
path: root/0005-wined3d-Experimental-support-for-persistent-buffer-t.patch
diff options
context:
space:
mode:
Diffstat (limited to '0005-wined3d-Experimental-support-for-persistent-buffer-t.patch')
-rw-r--r--0005-wined3d-Experimental-support-for-persistent-buffer-t.patch180
1 files changed, 180 insertions, 0 deletions
diff --git a/0005-wined3d-Experimental-support-for-persistent-buffer-t.patch b/0005-wined3d-Experimental-support-for-persistent-buffer-t.patch
new file mode 100644
index 00000000000..a039c7e622c
--- /dev/null
+++ b/0005-wined3d-Experimental-support-for-persistent-buffer-t.patch
@@ -0,0 +1,180 @@
+From 1e4c2e45a18a6eb445c507745f1c7b568c22aca6 Mon Sep 17 00:00:00 2001
+From: Andrew Comminos <andrew@comminos.com>
+Date: Tue, 6 Mar 2018 15:58:05 -0800
+Subject: [PATCH 5/5] wined3d: Experimental support for persistent buffer
+ textures.
+
+Fixes missing models in Overwatch.
+---
+ dlls/wined3d/cs.c | 6 ++++
+ dlls/wined3d/view.c | 79 +++++++++++++++++++++++++++++++++--------------------
+ 2 files changed, 55 insertions(+), 30 deletions(-)
+
+diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
+index e61b8dedbb..63cdb74e02 100644
+--- a/dlls/wined3d/cs.c
++++ b/dlls/wined3d/cs.c
+@@ -2493,6 +2493,12 @@ static void wined3d_cs_exec_discard_buffer(struct wined3d_cs *cs, const void *da
+ device_invalidate_state(cs->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE));
+ }
+
++ if (buffer->bind_flags & WINED3D_BIND_SHADER_RESOURCE)
++ {
++ device_invalidate_state(cs->device, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
++ device_invalidate_state(cs->device, STATE_COMPUTE_SHADER_RESOURCE_BINDING);
++ }
++
+ wined3d_resource_release(&op->buffer->resource);
+ }
+
+diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
+index bed39dbc5f..100b3e34d8 100644
+--- a/dlls/wined3d/view.c
++++ b/dlls/wined3d/view.c
+@@ -227,9 +227,7 @@ static void create_texture_view(struct wined3d_gl_view *view, GLenum view_target
+ context_release(context);
+ }
+
+-static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_context *context,
+- struct wined3d_buffer *buffer, const struct wined3d_format *view_format,
+- unsigned int offset, unsigned int size)
++static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_context *context)
+ {
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+@@ -239,34 +237,58 @@ static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_c
+ return;
+ }
+
+- if ((offset & (gl_info->limits.texture_buffer_offset_alignment - 1)))
++ view->target = GL_TEXTURE_BUFFER;
++ gl_info->gl_ops.gl.p_glGenTextures(1, &view->name);
++
++ context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING);
++ context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
++}
++
++static void bind_buffer_texture(struct wined3d_gl_view *view, struct wined3d_context *context,
++ struct wined3d_buffer *buffer, const struct wined3d_format *view_format,
++ unsigned int offset, unsigned int size)
++{
++ const struct wined3d_gl_info *gl_info = context->gl_info;
++ struct wined3d_bo_address bo_addr;
++ unsigned int addr_offset;
++
++ if (!wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER) &&
++ !wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_PERSISTENT_MAP))
+ {
+- FIXME("Buffer offset %u is not %u byte aligned.\n",
+- offset, gl_info->limits.texture_buffer_offset_alignment);
++ ERR("Failed to load a supported buffer location for %p.\n", buffer);
+ return;
+ }
+
+- wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER);
+
+- view->target = GL_TEXTURE_BUFFER;
+- gl_info->gl_ops.gl.p_glGenTextures(1, &view->name);
++ if (FAILED(wined3d_buffer_get_memory(buffer, &bo_addr, buffer->locations)))
++ {
++ ERR("Failed to get buffer memory to create a buffer texture.\n");
++ return;
++ }
++
++ // TODO(acomminos): use a special heap for texture buffer alignment?
++ addr_offset = offset + bo_addr.addr;
++
++ if ((addr_offset & (gl_info->limits.texture_buffer_offset_alignment - 1)))
++ {
++ FIXME("Buffer offset %u is not %u byte aligned.\n",
++ offset, gl_info->limits.texture_buffer_offset_alignment);
++ return;
++ }
+
+- context_bind_texture(context, GL_TEXTURE_BUFFER, view->name);
+ if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE])
+ {
+ GL_EXTCALL(glTexBufferRange(GL_TEXTURE_BUFFER, view_format->glInternal,
+- buffer->buffer_object, offset, size));
++ bo_addr.buffer_object, addr_offset, size));
+ }
+ else
+ {
+- if (offset || size != buffer->resource.size)
++ if (addr_offset || size != buffer->resource.size)
+ FIXME("OpenGL implementation does not support ARB_texture_buffer_range.\n");
+- GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER, view_format->glInternal, buffer->buffer_object));
++ GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER, view_format->glInternal, bo_addr.buffer_object));
+ }
+- checkGLcall("Create buffer texture");
++ checkGLcall("Bind buffer texture");
+
+- context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING);
+- context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
+ }
+
+ static void get_buffer_view_range(const struct wined3d_buffer *buffer,
+@@ -285,16 +307,6 @@ static void get_buffer_view_range(const struct wined3d_buffer *buffer,
+ }
+ }
+
+-static void create_buffer_view(struct wined3d_gl_view *view, struct wined3d_context *context,
+- const struct wined3d_view_desc *desc, struct wined3d_buffer *buffer,
+- const struct wined3d_format *view_format)
+-{
+- unsigned int offset, size;
+-
+- get_buffer_view_range(buffer, desc, view_format, &offset, &size);
+- create_buffer_texture(view, context, buffer, view_format, offset, size);
+-}
+-
+ static void wined3d_view_invalidate_location(struct wined3d_resource *resource,
+ const struct wined3d_view_desc *desc, DWORD location)
+ {
+@@ -711,11 +723,10 @@ static void wined3d_shader_resource_view_cs_init(void *object)
+
+ if (resource->type == WINED3D_RTYPE_BUFFER)
+ {
+- struct wined3d_buffer *buffer = buffer_from_resource(resource);
+ struct wined3d_context *context;
+
+ context = context_acquire(resource->device, NULL, 0);
+- create_buffer_view(&view->gl_view, context, desc, buffer, view_format);
++ create_buffer_texture(&view->gl_view, context);
+ context_release(context);
+ }
+ else
+@@ -814,7 +825,16 @@ void wined3d_shader_resource_view_bind(struct wined3d_shader_resource_view *view
+
+ if (view->gl_view.name)
+ {
++ // XXX(acomminos): only rebind buffer texture range when needed (i.e. on discards)
+ context_bind_texture(context, view->gl_view.target, view->gl_view.name);
++ if (view->resource->type == WINED3D_RTYPE_BUFFER)
++ {
++ unsigned int offset, size;
++ struct wined3d_buffer *buffer = buffer_from_resource(view->resource);
++ get_buffer_view_range(buffer, &view->desc, view->format, &offset, &size);
++ bind_buffer_texture(&view->gl_view, context, buffer_from_resource(view->resource), view->format, offset, size);
++ }
++
+ wined3d_sampler_bind(sampler, unit, NULL, context);
+ return;
+ }
+@@ -1092,12 +1112,11 @@ static void wined3d_unordered_access_view_cs_init(void *object)
+
+ if (resource->type == WINED3D_RTYPE_BUFFER)
+ {
+- struct wined3d_buffer *buffer = buffer_from_resource(resource);
+ struct wined3d_context *context;
+
+ context = context_acquire(resource->device, NULL, 0);
+ gl_info = context->gl_info;
+- create_buffer_view(&view->gl_view, context, desc, buffer, view->format);
++ create_buffer_texture(&view->gl_view, context);
+ if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_BUFFER_APPEND))
+ {
+ static const GLuint initial_value = 0;
+--
+2.16.2
+