Commit 53d15279 authored by Matteo Bruni's avatar Matteo Bruni Committed by Alexandre Julliard

wined3d: Avoid glBegin() / glEnd() in check_fbo_compat() when possible.

parent 22c51eea
...@@ -250,19 +250,21 @@ const GLenum magLookup[] = ...@@ -250,19 +250,21 @@ const GLenum magLookup[] =
GL_NEAREST, GL_NEAREST, GL_LINEAR, 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) 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"); 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)) if (!wglMakeCurrent(NULL, NULL))
ERR("Failed to disable caps GL context.\n"); 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_ ...@@ -309,7 +311,7 @@ static BOOL wined3d_caps_gl_ctx_create_attribs(struct wined3d_caps_gl_ctx *caps_
return TRUE; 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; PIXELFORMATDESCRIPTOR pfd;
int iPixelFormat; int iPixelFormat;
...@@ -367,6 +369,7 @@ static BOOL wined3d_caps_gl_ctx_create(struct wined3d_caps_gl_ctx *ctx) ...@@ -367,6 +369,7 @@ static BOOL wined3d_caps_gl_ctx_create(struct wined3d_caps_gl_ctx *ctx)
goto fail; goto fail;
} }
ctx->gl_info = &adapter->gl_info;
return TRUE; return TRUE;
fail: fail:
...@@ -5840,7 +5843,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal) ...@@ -5840,7 +5843,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal)
TRACE("Allocated LUID %08x:%08x for adapter %p.\n", TRACE("Allocated LUID %08x:%08x for adapter %p.\n",
adapter->luid.HighPart, adapter->luid.LowPart, adapter); 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); ERR("Failed to get a GL context for adapter %p.\n", adapter);
return FALSE; return FALSE;
...@@ -5887,7 +5890,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal) ...@@ -5887,7 +5890,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal)
return FALSE; 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"); ERR("Failed to initialize GL format info.\n");
wined3d_caps_gl_ctx_destroy(&caps_gl_ctx); wined3d_caps_gl_ctx_destroy(&caps_gl_ctx);
......
...@@ -333,7 +333,7 @@ static const char *get_info_log_line(const char **ptr) ...@@ -333,7 +333,7 @@ static const char *get_info_log_line(const char **ptr)
} }
/* Context activation is done by the caller. */ /* 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; int length = 0;
char *log; char *log;
...@@ -453,7 +453,7 @@ static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_inf ...@@ -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. */ /* 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; GLint tmp;
......
...@@ -1557,13 +1557,133 @@ static void create_and_bind_fbo_attachment(const struct wined3d_gl_info *gl_info ...@@ -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()); 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. */ /* 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 /* Check if the default internal format is supported as a frame buffer
* target, otherwise fall back to the render target internal. * target, otherwise fall back to the render target internal.
* *
* Try to stick to the standard format if possible, this limits precision differences. */ * 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; GLenum status, rt_internal = format->rtInternal;
GLuint object, color_rb; GLuint object, color_rb;
enum wined3d_gl_resource_type type; enum wined3d_gl_resource_type type;
...@@ -1697,32 +1817,13 @@ static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined ...@@ -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); gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1);
else else
gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16); 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); gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* Draw a full-black quad */ draw_test_quad(ctx, NULL, &black);
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();
gl_info->gl_ops.gl.p_glEnable(GL_BLEND); 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); draw_test_quad(ctx, NULL, &half_transparent_red);
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();
gl_info->gl_ops.gl.p_glDisable(GL_BLEND); 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 ...@@ -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. */ /* 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; unsigned int i, type;
GLuint fbo; GLuint fbo;
...@@ -2002,7 +2104,7 @@ static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info) ...@@ -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) if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{ {
TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id)); 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 else
{ {
...@@ -2582,7 +2684,7 @@ BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info) ...@@ -2582,7 +2684,7 @@ BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
} }
/* Context activation is done by the caller. */ /* 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; struct wined3d_gl_info *gl_info = &adapter->gl_info;
...@@ -2593,7 +2695,7 @@ BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter) ...@@ -2593,7 +2695,7 @@ BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter)
if (!init_format_vertex_info(gl_info)) goto fail; if (!init_format_vertex_info(gl_info)) goto fail;
apply_format_fixups(adapter, gl_info); 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); init_format_filter_info(gl_info, adapter->driver_info.vendor);
return TRUE; return TRUE;
......
...@@ -1794,7 +1794,21 @@ struct wined3d_adapter ...@@ -1794,7 +1794,21 @@ struct wined3d_adapter
const struct blit_shader *blitter; 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; UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount) DECLSPEC_HIDDEN;
BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
...@@ -3103,6 +3117,9 @@ struct ps_np2fixup_info { ...@@ -3103,6 +3117,9 @@ struct ps_np2fixup_info {
WORD num_consts; 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 struct wined3d_palette
{ {
LONG ref; LONG ref;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment