[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