[PATCH 2/8] wined3d: Honor buffer ranges for shader resource views.

Józef Kucia jkucia at codeweavers.com
Tue Feb 14 06:15:07 CST 2017


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/wined3d/directx.c         | 11 +++++++++++
 dlls/wined3d/view.c            | 45 ++++++++++++++++++++++++++++++++----------
 dlls/wined3d/wined3d_gl.h      |  1 +
 dlls/wined3d/wined3d_private.h |  2 ++
 4 files changed, 49 insertions(+), 10 deletions(-)

diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 9285fee..0f44e09 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -158,6 +158,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_ARB_sync",                         ARB_SYNC                      },
     {"GL_ARB_texture_border_clamp",         ARB_TEXTURE_BORDER_CLAMP      },
     {"GL_ARB_texture_buffer_object",        ARB_TEXTURE_BUFFER_OBJECT     },
+    {"GL_ARB_texture_buffer_range",         ARB_TEXTURE_BUFFER_RANGE      },
     {"GL_ARB_texture_compression",          ARB_TEXTURE_COMPRESSION       },
     {"GL_ARB_texture_compression_bptc",     ARB_TEXTURE_COMPRESSION_BPTC  },
     {"GL_ARB_texture_compression_rgtc",     ARB_TEXTURE_COMPRESSION_RGTC  },
@@ -2795,6 +2796,8 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
     USE_GL_FUNC(glWaitSync)
     /* GL_ARB_texture_buffer_object */
     USE_GL_FUNC(glTexBufferARB)
+    /* GL_ARB_texture_buffer_range */
+    USE_GL_FUNC(glTexBufferRange)
     /* GL_ARB_texture_compression */
     USE_GL_FUNC(glCompressedTexImage2DARB)
     USE_GL_FUNC(glCompressedTexImage3DARB)
@@ -3351,6 +3354,7 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info)
     gl_info->limits.vertex_samplers = 0;
     gl_info->limits.combined_samplers = gl_info->limits.fragment_samplers + gl_info->limits.vertex_samplers;
     gl_info->limits.vertex_attribs = 16;
+    gl_info->limits.texture_buffer_offset_alignment = 1;
     gl_info->limits.glsl_vs_float_constants = 0;
     gl_info->limits.glsl_ps_float_constants = 0;
     gl_info->limits.arb_vs_float_constants = 0;
@@ -3576,6 +3580,12 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info)
         gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &gl_max);
         TRACE("Max uniform buffer bindings: %d.\n", gl_max);
     }
+    if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE])
+    {
+        gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &gl_max);
+        gl_info->limits.texture_buffer_offset_alignment = gl_max;
+        TRACE("Minimum required texture buffer offset alignment %d.\n", gl_max);
+    }
 
     if (gl_info->supported[NV_LIGHT_MAX_EXPONENT])
         gl_info->gl_ops.gl.p_glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess);
@@ -3693,6 +3703,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD
         {ARB_INTERNALFORMAT_QUERY2,        MAKEDWORD_VERSION(4, 3)},
         {ARB_SHADER_IMAGE_SIZE,            MAKEDWORD_VERSION(4, 3)},
         {ARB_STENCIL_TEXTURING,            MAKEDWORD_VERSION(4, 3)},
+        {ARB_TEXTURE_BUFFER_RANGE,         MAKEDWORD_VERSION(4, 3)},
         {ARB_TEXTURE_QUERY_LEVELS,         MAKEDWORD_VERSION(4, 3)},
         {ARB_TEXTURE_VIEW,                 MAKEDWORD_VERSION(4, 3)},
 
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index c3e6d49..c1a92be 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -130,7 +130,8 @@ static void create_texture_view(struct wined3d_gl_view *view, GLenum view_target
 }
 
 static void create_buffer_texture(struct wined3d_gl_view *view,
-        struct wined3d_buffer *buffer, const struct wined3d_format *view_format)
+        struct wined3d_buffer *buffer, const struct wined3d_format *view_format,
+        unsigned int offset, unsigned int size)
 {
     const struct wined3d_gl_info *gl_info;
     struct wined3d_context *context;
@@ -144,13 +145,31 @@ static void create_buffer_texture(struct wined3d_gl_view *view,
         return;
     }
 
+    if ((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);
+        context_release(context);
+        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);
 
     context_bind_texture(context, GL_TEXTURE_BUFFER, view->name);
-    GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER, view_format->glInternal, buffer->buffer_object));
+    if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE])
+    {
+        GL_EXTCALL(glTexBufferRange(GL_TEXTURE_BUFFER, view_format->glInternal,
+                buffer->buffer_object, offset, size));
+    }
+    else
+    {
+        if (!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));
+    }
     checkGLcall("Create buffer texture");
 
     context_invalidate_state(context, STATE_SHADER_RESOURCE_BINDING);
@@ -464,14 +483,20 @@ static HRESULT wined3d_shader_resource_view_init(struct wined3d_shader_resource_
         }
         else
         {
-            /* FIXME: Support for buffer offsets can be implemented using ARB_texture_buffer_range. */
-            if (desc->u.buffer.start_idx
-                    || desc->u.buffer.count * view_format->byte_count != buffer->resource.size)
-            {
-                FIXME("Ignoring buffer range %u-%u.\n", desc->u.buffer.start_idx, desc->u.buffer.count);
-            }
-
-            create_buffer_texture(&view->gl_view, buffer, view_format);
+            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);
         }
     }
     else
diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h
index 72d617e..e500df6 100644
--- a/dlls/wined3d/wined3d_gl.h
+++ b/dlls/wined3d/wined3d_gl.h
@@ -91,6 +91,7 @@ enum wined3d_gl_extension
     ARB_SYNC,
     ARB_TEXTURE_BORDER_CLAMP,
     ARB_TEXTURE_BUFFER_OBJECT,
+    ARB_TEXTURE_BUFFER_RANGE,
     ARB_TEXTURE_COMPRESSION,
     ARB_TEXTURE_COMPRESSION_BPTC,
     ARB_TEXTURE_COMPRESSION_RGTC,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index f6252a2..61954ab 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2208,6 +2208,8 @@ struct wined3d_gl_limits
     UINT samples;
     UINT vertex_attribs;
 
+    unsigned int texture_buffer_offset_alignment;
+
     UINT glsl_varyings;
     UINT glsl_vs_float_constants;
     UINT glsl_ps_float_constants;
-- 
2.10.2




More information about the wine-patches mailing list