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

This commit is contained in:
Matteo Bruni 2015-07-27 14:29:53 +02:00 committed by Alexandre Julliard
parent 22c51eeabf
commit 53d1527945
4 changed files with 164 additions and 42 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;