[15/23] wined3d: Support for geometry shader samplers.

Andrew Wesie awesie at gmail.com
Sun Nov 13 12:35:15 CST 2016


Signed-off-by: Andrew Wesie <awesie at gmail.com>
---
 dlls/wined3d/context.c         | 90 ++++++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/directx.c         |  1 +
 dlls/wined3d/glsl_shader.c     |  3 ++
 dlls/wined3d/wined3d_gl.h      |  1 +
 dlls/wined3d/wined3d_private.h |  8 +++-
 5 files changed, 102 insertions(+), 1 deletion(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 88d34e6..ac6852f 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -2984,10 +2984,87 @@ static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, cons
     }
 }
 
+static BOOL context_unit_free_for_gs(const struct wined3d_context *context,
+        const struct wined3d_state *state, DWORD unit)
+{
+    const struct wined3d_shader_resource_info *ps_resource_info = NULL, *vs_resource_info = NULL;
+    DWORD current_mapping = context->rev_tex_unit_map[unit];
+
+    if (use_ps(state))
+        ps_resource_info = state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info;
+    if (use_vs(state))
+        vs_resource_info = state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_info;
+
+    /* Not currently used */
+    if (current_mapping == WINED3D_UNMAPPED_STAGE)
+        return TRUE;
+
+    if (current_mapping < MAX_FRAGMENT_SAMPLERS)
+    {
+        /* Used by a fragment sampler */
+        if (!ps_resource_info)
+        {
+            /* No pixel shader, check fixed function */
+            return current_mapping >= MAX_TEXTURES || !(context->fixed_function_usage_map & (1u << current_mapping));
+        }
+
+        /* Pixel shader, check the shader's sampler map */
+        return !ps_resource_info[current_mapping].type;
+    }
+
+    current_mapping -= MAX_FRAGMENT_SAMPLERS;
+    if (current_mapping < MAX_VERTEX_SAMPLERS)
+    {
+        /* Used by a vertex sampler, check the shader's sampler map */
+        return !vs_resource_info || !vs_resource_info[current_mapping].type;
+    }
+
+    return TRUE;
+}
+
+static void context_map_gsamplers(struct wined3d_context *context, const struct wined3d_state *state)
+{
+    const struct wined3d_shader_resource_info *gs_resource_info =
+            state->shader[WINED3D_SHADER_TYPE_GEOMETRY]->reg_maps.resource_info;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    int start = min(MAX_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS, gl_info->limits.combined_samplers) - 1;
+    int i;
+
+    if (gl_info->limits.combined_samplers >= MAX_COMBINED_SAMPLERS)
+        return;
+
+    for (i = 0; i < MAX_GEOMETRY_SAMPLERS; ++i)
+    {
+        DWORD gsampler_idx = i + MAX_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS;
+        if (gs_resource_info[i].type)
+        {
+            while (start >= 0)
+            {
+                if (context_unit_free_for_gs(context, state, start))
+                {
+                    if (context->tex_unit_map[gsampler_idx] != start)
+                    {
+                        context_map_stage(context, gsampler_idx, start);
+                        context_invalidate_state(context, STATE_SAMPLER(gsampler_idx));
+                    }
+
+                    --start;
+                    break;
+                }
+
+                --start;
+            }
+            if (context->tex_unit_map[gsampler_idx] == WINED3D_UNMAPPED_STAGE)
+                WARN("Couldn't find a free texture unit for vertex sampler %u.\n", i);
+        }
+    }
+}
+
 static void context_update_tex_unit_map(struct wined3d_context *context, const struct wined3d_state *state)
 {
     BOOL vs = use_vs(state);
     BOOL ps = use_ps(state);
+    BOOL gs = use_gs(state);
 
     /* Try to go for a 1:1 mapping of the samplers when possible. Pixel shaders
      * need a 1:1 map at the moment.
@@ -3001,6 +3078,9 @@ static void context_update_tex_unit_map(struct wined3d_context *context, const s
 
     if (vs)
         context_map_vsamplers(context, ps, state);
+
+    if (gs)
+        context_map_gsamplers(context, state);
 }
 
 /* Context activation is done by the caller. */
@@ -3260,6 +3340,15 @@ static void context_preload_textures(struct wined3d_context *context, const stru
 {
     unsigned int i;
 
+    if (use_gs(state))
+    {
+        for (i = 0; i < MAX_GEOMETRY_SAMPLERS; ++i)
+        {
+            if (state->shader[WINED3D_SHADER_TYPE_GEOMETRY]->reg_maps.resource_info[i].type)
+                context_preload_texture(context, state, MAX_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS + i);
+        }
+    }
+
     if (use_vs(state))
     {
         for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i)
@@ -3346,6 +3435,7 @@ static void context_bind_shader_resources(struct wined3d_context *context, const
     {
         {WINED3D_SHADER_TYPE_PIXEL,     0,                      MAX_FRAGMENT_SAMPLERS},
         {WINED3D_SHADER_TYPE_VERTEX,    MAX_FRAGMENT_SAMPLERS,  MAX_VERTEX_SAMPLERS},
+        {WINED3D_SHADER_TYPE_GEOMETRY,  MAX_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS, MAX_GEOMETRY_SAMPLERS},
     };
 
     for (i = 0; i < ARRAY_SIZE(shader_types); ++i)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index fe6b499..e94d071 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -197,6 +197,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_EXT_framebuffer_blit",             EXT_FRAMEBUFFER_BLIT          },
     {"GL_EXT_framebuffer_multisample",      EXT_FRAMEBUFFER_MULTISAMPLE   },
     {"GL_EXT_framebuffer_object",           EXT_FRAMEBUFFER_OBJECT        },
+    {"GL_EXT_geometry_shader4",             EXT_GEOMETRY_SHADER4          },
     {"GL_EXT_gpu_program_parameters",       EXT_GPU_PROGRAM_PARAMETERS    },
     {"GL_EXT_gpu_shader4",                  EXT_GPU_SHADER4               },
     {"GL_EXT_packed_depth_stencil",         EXT_PACKED_DEPTH_STENCIL      },
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 27a5533..f6befe5 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -551,6 +551,7 @@ static void shader_glsl_load_samplers(const struct wined3d_gl_info *gl_info,
     {
         {WINED3D_SHADER_TYPE_PIXEL,     0,                      MAX_FRAGMENT_SAMPLERS},
         {WINED3D_SHADER_TYPE_VERTEX,    MAX_FRAGMENT_SAMPLERS,  MAX_VERTEX_SAMPLERS},
+        {WINED3D_SHADER_TYPE_GEOMETRY,  MAX_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS, MAX_GEOMETRY_SAMPLERS},
     };
 
     for (i = 0; i < ARRAY_SIZE(sampler_info); ++i)
@@ -5891,6 +5892,8 @@ static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer,
         shader_addline(buffer, "#extension GL_ARB_texture_query_levels : enable\n");
     if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT])
         shader_addline(buffer, "#extension GL_ARB_uniform_buffer_object : enable\n");
+    if (gl_info->supported[EXT_GEOMETRY_SHADER4])
+        shader_addline(buffer, "#extension GL_EXT_geometry_shader4 : enable\n");
     if (gl_info->supported[EXT_GPU_SHADER4])
         shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n");
     if (gl_info->supported[EXT_TEXTURE_ARRAY])
diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h
index 48a7509..bb37487 100644
--- a/dlls/wined3d/wined3d_gl.h
+++ b/dlls/wined3d/wined3d_gl.h
@@ -129,6 +129,7 @@ enum wined3d_gl_extension
     EXT_FRAMEBUFFER_BLIT,
     EXT_FRAMEBUFFER_MULTISAMPLE,
     EXT_FRAMEBUFFER_OBJECT,
+    EXT_GEOMETRY_SHADER4,
     EXT_GPU_PROGRAM_PARAMETERS,
     EXT_GPU_SHADER4,
     EXT_PACKED_DEPTH_STENCIL,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 97f3265..93d5c5f 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -177,8 +177,9 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup
 #define MAX_STREAMS                 16
 #define MAX_TEXTURES                8
 #define MAX_FRAGMENT_SAMPLERS       32
+#define MAX_GEOMETRY_SAMPLERS       16
 #define MAX_VERTEX_SAMPLERS         32
-#define MAX_COMBINED_SAMPLERS       (MAX_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS)
+#define MAX_COMBINED_SAMPLERS       (MAX_FRAGMENT_SAMPLERS + MAX_GEOMETRY_SAMPLERS + MAX_VERTEX_SAMPLERS)
 #define MAX_ACTIVE_LIGHTS           8
 #define MAX_CLIP_DISTANCES          WINED3DMAXUSERCLIPPLANES
 #define MAX_CONSTANT_BUFFERS        15
@@ -3752,6 +3753,11 @@ static inline BOOL use_ps(const struct wined3d_state *state)
     return !!state->shader[WINED3D_SHADER_TYPE_PIXEL];
 }
 
+static inline BOOL use_gs(const struct wined3d_state *state)
+{
+    return !!state->shader[WINED3D_SHADER_TYPE_GEOMETRY];
+}
+
 static inline void context_apply_state(struct wined3d_context *context,
         const struct wined3d_state *state, DWORD state_id)
 {
-- 
2.7.4




More information about the wine-patches mailing list