[PATCH 1/5] wined3d: Avoid glBegin() / glEnd() in check_fbo_compat() when possible.
Matteo Bruni
mbruni at codeweavers.com
Mon Jul 27 07:29:53 CDT 2015
---
draw_test_quad() should be ready to be used by find_polyoffset_scale(),
although I haven't actually tried.
Those glDelete[Program|Buffers]() in wined3d_caps_gl_ctx_destroy()
aren't strictly necessary since the "caps" GL context isn't shared with
any other.
---
dlls/wined3d/directx.c | 27 +++----
dlls/wined3d/glsl_shader.c | 4 +-
dlls/wined3d/utils.c | 156 ++++++++++++++++++++++++++++++++++-------
dlls/wined3d/wined3d_private.h | 19 ++++-
4 files changed, 164 insertions(+), 42 deletions(-)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 61c3059..5880799 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -250,19 +250,21 @@ const GLenum magLookup[] =
GL_NEAREST, GL_NEAREST, GL_LINEAR,
};
-struct wined3d_caps_gl_ctx
-{
- HDC dc;
- HWND wnd;
- HGLRC gl_ctx;
- HDC restore_dc;
- HGLRC restore_gl_ctx;
-};
-
static void wined3d_caps_gl_ctx_destroy(const struct wined3d_caps_gl_ctx *ctx)
{
+ const struct wined3d_gl_info *gl_info = ctx->gl_info;
+
TRACE("Destroying caps GL context.\n");
+ /* Both glDeleteProgram and glDeleteBuffers silently ignore 0 IDs but
+ * this function might be called before the relevant function pointers
+ * in gl_info are initialized. */
+ if (ctx->test_program_id || ctx->test_vbo)
+ {
+ GL_EXTCALL(glDeleteProgram(ctx->test_program_id));
+ GL_EXTCALL(glDeleteBuffers(1, &ctx->test_vbo));
+ }
+
if (!wglMakeCurrent(NULL, NULL))
ERR("Failed to disable caps GL context.\n");
@@ -309,7 +311,7 @@ static BOOL wined3d_caps_gl_ctx_create_attribs(struct wined3d_caps_gl_ctx *caps_
return TRUE;
}
-static BOOL wined3d_caps_gl_ctx_create(struct wined3d_caps_gl_ctx *ctx)
+static BOOL wined3d_caps_gl_ctx_create(struct wined3d_adapter *adapter, struct wined3d_caps_gl_ctx *ctx)
{
PIXELFORMATDESCRIPTOR pfd;
int iPixelFormat;
@@ -367,6 +369,7 @@ static BOOL wined3d_caps_gl_ctx_create(struct wined3d_caps_gl_ctx *ctx)
goto fail;
}
+ ctx->gl_info = &adapter->gl_info;
return TRUE;
fail:
@@ -5840,7 +5843,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal)
TRACE("Allocated LUID %08x:%08x for adapter %p.\n",
adapter->luid.HighPart, adapter->luid.LowPart, adapter);
- if (!wined3d_caps_gl_ctx_create(&caps_gl_ctx))
+ if (!wined3d_caps_gl_ctx_create(adapter, &caps_gl_ctx))
{
ERR("Failed to get a GL context for adapter %p.\n", adapter);
return FALSE;
@@ -5887,7 +5890,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal)
return FALSE;
}
- if (!wined3d_adapter_init_format_info(adapter))
+ if (!wined3d_adapter_init_format_info(adapter, &caps_gl_ctx))
{
ERR("Failed to initialize GL format info.\n");
wined3d_caps_gl_ctx_destroy(&caps_gl_ctx);
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 3c92781..301dc6f 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -333,7 +333,7 @@ static const char *get_info_log_line(const char **ptr)
}
/* Context activation is done by the caller. */
-static void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLuint id, BOOL program)
+void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLuint id, BOOL program)
{
int length = 0;
char *log;
@@ -453,7 +453,7 @@ static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_inf
}
/* Context activation is done by the caller. */
-static void shader_glsl_validate_link(const struct wined3d_gl_info *gl_info, GLuint program)
+void shader_glsl_validate_link(const struct wined3d_gl_info *gl_info, GLuint program)
{
GLint tmp;
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 48f6671..6c871f1 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -1557,13 +1557,133 @@ static void create_and_bind_fbo_attachment(const struct wined3d_gl_info *gl_info
while (gl_info->gl_ops.gl.p_glGetError());
}
+static void draw_test_quad(struct wined3d_caps_gl_ctx *ctx, const struct wined3d_vec3 *geometry,
+ const struct wined3d_color *color)
+{
+ const struct wined3d_gl_info *gl_info = ctx->gl_info;
+ static const struct wined3d_vec3 default_geometry[] =
+ {
+ {-1.0f, -1.0f, 0.0f},
+ { 1.0f, -1.0f, 0.0f},
+ {-1.0f, 1.0f, 0.0f},
+ { 1.0f, 1.0f, 0.0f},
+ };
+ static const char vs_core_header[] =
+ "#version 150\n"
+ "in vec4 pos;\n"
+ "in vec4 color;\n"
+ "out vec4 out_color;\n"
+ "\n";
+ static const char vs_legacy_header[] =
+ "#version 120\n"
+ "attribute vec4 pos;\n"
+ "attribute vec4 color;\n"
+ "varying vec4 out_color;\n"
+ "\n";
+ static const char vs_body[] =
+ "void main()\n"
+ "{\n"
+ " gl_Position = pos;\n"
+ " out_color = color;\n"
+ "}\n";
+ static const char fs_core[] =
+ "#version 150\n"
+ "in vec4 out_color;\n"
+ "out vec4 fragment_color;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " fragment_color = out_color;\n"
+ "}\n";
+ static const char fs_legacy[] =
+ "#version 120\n"
+ "varying vec4 out_color;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragData[0] = out_color;\n"
+ "}\n";
+ const char *source[2];
+ GLuint vs_id, fs_id;
+ unsigned int i;
+
+ if (!geometry)
+ geometry = default_geometry;
+
+ if (!gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] || !gl_info->supported[ARB_VERTEX_SHADER]
+ || !gl_info->supported[ARB_FRAGMENT_SHADER])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+
+ gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
+ gl_info->gl_ops.gl.p_glColor4f(color->r, color->g, color->b, color->a);
+ for (i = 0; i < 4; ++i)
+ gl_info->gl_ops.gl.p_glVertex3fv(&geometry[i].x);
+ gl_info->gl_ops.gl.p_glEnd();
+ checkGLcall("Drawing a quad");
+ return;
+ }
+
+ if (!ctx->test_vbo)
+ GL_EXTCALL(glGenBuffers(1, &ctx->test_vbo));
+ GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, ctx->test_vbo));
+ GL_EXTCALL(glBufferData(GL_ARRAY_BUFFER, sizeof(struct wined3d_vec3) * 4, geometry, GL_STREAM_DRAW));
+ GL_EXTCALL(glVertexAttribPointer(0, 3, GL_FLOAT, FALSE, 0, NULL));
+ GL_EXTCALL(glVertexAttrib4f(1, color->r, color->g, color->b, color->a));
+ GL_EXTCALL(glEnableVertexAttribArray(0));
+ GL_EXTCALL(glDisableVertexAttribArray(1));
+
+ if (!ctx->test_program_id)
+ {
+ ctx->test_program_id = GL_EXTCALL(glCreateProgram());
+
+ vs_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
+ source[0] = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? vs_legacy_header : vs_core_header;
+ source[1] = vs_body;
+ GL_EXTCALL(glShaderSource(vs_id, 2, source, NULL));
+ GL_EXTCALL(glAttachShader(ctx->test_program_id, vs_id));
+ GL_EXTCALL(glDeleteShader(vs_id));
+
+ fs_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER));
+ source[0] = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? fs_legacy : fs_core;
+ GL_EXTCALL(glShaderSource(fs_id, 1, source, NULL));
+ GL_EXTCALL(glAttachShader(ctx->test_program_id, fs_id));
+ GL_EXTCALL(glDeleteShader(fs_id));
+
+ GL_EXTCALL(glBindAttribLocation(ctx->test_program_id, 0, "pos"));
+ GL_EXTCALL(glBindAttribLocation(ctx->test_program_id, 1, "color"));
+
+ GL_EXTCALL(glCompileShader(vs_id));
+ print_glsl_info_log(gl_info, vs_id, FALSE);
+ GL_EXTCALL(glCompileShader(fs_id));
+ print_glsl_info_log(gl_info, fs_id, FALSE);
+ GL_EXTCALL(glLinkProgram(ctx->test_program_id));
+ shader_glsl_validate_link(gl_info, ctx->test_program_id);
+ }
+ GL_EXTCALL(glUseProgram(ctx->test_program_id));
+
+ gl_info->gl_ops.gl.p_glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ GL_EXTCALL(glUseProgram(0));
+ GL_EXTCALL(glDisableVertexAttribArray(0));
+ GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
+ checkGLcall("Drawing a quad");
+}
+
/* Context activation is done by the caller. */
-static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
+static void check_fbo_compat(struct wined3d_caps_gl_ctx *ctx, struct wined3d_format *format)
{
/* Check if the default internal format is supported as a frame buffer
* target, otherwise fall back to the render target internal.
*
* Try to stick to the standard format if possible, this limits precision differences. */
+ static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 1.0f};
+ static const struct wined3d_color half_transparent_red = {1.0f, 0.0f, 0.0f, 0.5f};
+ const struct wined3d_gl_info *gl_info = ctx->gl_info;
GLenum status, rt_internal = format->rtInternal;
GLuint object, color_rb;
enum wined3d_gl_resource_type type;
@@ -1697,32 +1817,13 @@ static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined
gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1);
else
gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16);
- gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
- gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
- gl_info->gl_ops.gl.p_glLoadIdentity();
- gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
- gl_info->gl_ops.gl.p_glLoadIdentity();
-
gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- /* Draw a full-black quad */
- gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
- gl_info->gl_ops.gl.p_glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
- gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
- gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
- gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
- gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
- gl_info->gl_ops.gl.p_glEnd();
+ draw_test_quad(ctx, NULL, &black);
gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
- /* Draw a half-transparent red quad */
- gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
- gl_info->gl_ops.gl.p_glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
- gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
- gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
- gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
- gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
- gl_info->gl_ops.gl.p_glEnd();
+
+ draw_test_quad(ctx, NULL, &half_transparent_red);
gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
@@ -1868,8 +1969,9 @@ static void query_format_flag(struct wined3d_gl_info *gl_info, struct wined3d_fo
}
/* Context activation is done by the caller. */
-static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
+static void init_format_fbo_compat_info(struct wined3d_caps_gl_ctx *ctx)
{
+ const struct wined3d_gl_info *gl_info = ctx->gl_info;
unsigned int i, type;
GLuint fbo;
@@ -2002,7 +2104,7 @@ static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
- check_fbo_compat(gl_info, format);
+ check_fbo_compat(ctx, format);
}
else
{
@@ -2582,7 +2684,7 @@ BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
}
/* Context activation is done by the caller. */
-BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter)
+BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter, struct wined3d_caps_gl_ctx *ctx)
{
struct wined3d_gl_info *gl_info = &adapter->gl_info;
@@ -2593,7 +2695,7 @@ BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter)
if (!init_format_vertex_info(gl_info)) goto fail;
apply_format_fixups(adapter, gl_info);
- init_format_fbo_compat_info(gl_info);
+ init_format_fbo_compat_info(ctx);
init_format_filter_info(gl_info, adapter->driver_info.vendor);
return TRUE;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 8dd9e80..27dacb8 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1794,7 +1794,21 @@ struct wined3d_adapter
const struct blit_shader *blitter;
};
-BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter) DECLSPEC_HIDDEN;
+struct wined3d_caps_gl_ctx
+{
+ HDC dc;
+ HWND wnd;
+ HGLRC gl_ctx;
+ HDC restore_dc;
+ HGLRC restore_gl_ctx;
+
+ const struct wined3d_gl_info *gl_info;
+ GLuint test_vbo;
+ GLuint test_program_id;
+};
+
+BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter,
+ struct wined3d_caps_gl_ctx *ctx) DECLSPEC_HIDDEN;
UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount) DECLSPEC_HIDDEN;
BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
@@ -3103,6 +3117,9 @@ struct ps_np2fixup_info {
WORD num_consts;
};
+void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLuint id, BOOL program) DECLSPEC_HIDDEN;
+void shader_glsl_validate_link(const struct wined3d_gl_info *gl_info, GLuint program) DECLSPEC_HIDDEN;
+
struct wined3d_palette
{
LONG ref;
--
2.3.6
More information about the wine-patches
mailing list