Module: wine Branch: master Commit: 7096e1e02d900bb47c819fde223ec91dd7dbb733 URL: https://source.winehq.org/git/wine.git/?a=commit;h=7096e1e02d900bb47c819fde2...
Author: Józef Kucia jkucia@codeweavers.com Date: Thu Mar 1 19:36:52 2018 +0100
wined3d: Implement draw calls with no attachments.
Supported when ARB_framebuffer_no_attachments is available.
It was reported that no attachments framebuffers trigger GPU hangs in The Witcher 3 on some system configurations with radeonsi driver. MESA_EXTENSION_OVERRIDE=-GL_ARB_framebuffer_no_attachments can be used as a workaround until it's fixed.
Signed-off-by: Józef Kucia jkucia@codeweavers.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/wined3d/context.c | 35 ++++++++++++++++++++++++++++------- dlls/wined3d/directx.c | 13 +++++++++++++ dlls/wined3d/state.c | 13 ++++--------- dlls/wined3d/wined3d_private.h | 3 +++ 4 files changed, 48 insertions(+), 16 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 975a79c..c73e4d1 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -700,8 +700,8 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, static void context_apply_fbo_entry(struct wined3d_context *context, GLenum target, struct fbo_entry *entry) { const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int i; GLuint read_binding, draw_binding; + unsigned int i;
if (entry->flags & WINED3D_FBO_ENTRY_FLAG_ATTACHED) { @@ -713,6 +713,16 @@ static void context_apply_fbo_entry(struct wined3d_context *context, GLenum targ draw_binding = context->fbo_draw_binding; context_bind_fbo(context, GL_FRAMEBUFFER, entry->id);
+ if (gl_info->supported[ARB_FRAMEBUFFER_NO_ATTACHMENTS]) + { + GL_EXTCALL(glFramebufferParameteri(GL_FRAMEBUFFER, + GL_FRAMEBUFFER_DEFAULT_WIDTH, gl_info->limits.framebuffer_width)); + GL_EXTCALL(glFramebufferParameteri(GL_FRAMEBUFFER, + GL_FRAMEBUFFER_DEFAULT_HEIGHT, gl_info->limits.framebuffer_height)); + GL_EXTCALL(glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_LAYERS, 1)); + GL_EXTCALL(glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_SAMPLES, 1)); + } + /* Apply render targets */ for (i = 0; i < gl_info->limits.buffers; ++i) { @@ -2996,12 +3006,13 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine context_invalidate_state(context, STATE_FRAMEBUFFER); }
-static BOOL context_validate_rt_config(UINT rt_count, struct wined3d_rendertarget_view * const *rts, +static BOOL have_framebuffer_attachment(unsigned int rt_count, struct wined3d_rendertarget_view * const *rts, const struct wined3d_rendertarget_view *ds) { unsigned int i;
- if (ds) return TRUE; + if (ds) + return TRUE;
for (i = 0; i < rt_count; ++i) { @@ -3009,7 +3020,6 @@ static BOOL context_validate_rt_config(UINT rt_count, struct wined3d_rendertarge return TRUE; }
- WARN("Invalid render target config, need at least one attachment.\n"); return FALSE; }
@@ -3026,8 +3036,11 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != state->fb || rt_count != gl_info->limits.buffers) { - if (!context_validate_rt_config(rt_count, rts, dsv)) + if (!have_framebuffer_attachment(rt_count, rts, dsv)) + { + WARN("Invalid render target config, need at least one attachment.\n"); return FALSE; + }
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { @@ -3908,8 +3921,16 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, unsigned int i; WORD map;
- if (!context_validate_rt_config(gl_info->limits.buffers, fb->render_targets, fb->depth_stencil)) - return FALSE; + if (!have_framebuffer_attachment(gl_info->limits.buffers, fb->render_targets, fb->depth_stencil)) + { + if (!gl_info->supported[ARB_FRAMEBUFFER_NO_ATTACHMENTS]) + { + FIXME("OpenGL implementation does not support framebuffers with no attachments.\n"); + return FALSE; + } + + context_set_render_offscreen(context, TRUE); + }
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && isStateDirty(context, STATE_FRAMEBUFFER)) { diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index a95ded3..b73966a 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -3779,6 +3779,19 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) gl_info->limits.samples = gl_max; }
+ if (gl_info->supported[ARB_FRAMEBUFFER_NO_ATTACHMENTS]) + { + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAMEBUFFER_WIDTH, &gl_max); + gl_info->limits.framebuffer_width = gl_max; + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAMEBUFFER_HEIGHT, &gl_max); + gl_info->limits.framebuffer_height = gl_max; + } + else + { + gl_info->limits.framebuffer_width = gl_info->limits.texture_size; + gl_info->limits.framebuffer_height = gl_info->limits.texture_size; + } + gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = min(gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL], MAX_GL_FRAGMENT_SAMPLERS); sampler_count = 0; diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 407ad62..fd858c5 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -4671,17 +4671,15 @@ static void viewport_miscpart(struct wined3d_context *context, const struct wine } else if (depth_stencil) { - width = depth_stencil->width; height = depth_stencil->height; } else { - FIXME("No attachments draw calls not supported.\n"); - return; + height = gl_info->limits.framebuffer_height; }
gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z); - checkGLcall("glDepthRange"); + /* Note: GL requires lower left, DirectX supplies upper left. This is * reversed when using offscreen rendering. */ y = context->render_offscreen ? vp.y : height - (vp.y + vp.height); @@ -4690,7 +4688,7 @@ static void viewport_miscpart(struct wined3d_context *context, const struct wine GL_EXTCALL(glViewportIndexedf(0, vp.x, y, vp.width, vp.height)); else gl_info->gl_ops.gl.p_glViewport(vp.x, y, vp.width, vp.height); - checkGLcall("glViewport"); + checkGLcall("setting clip space and viewport"); }
static void viewport_miscpart_cc(struct wined3d_context *context, @@ -4717,17 +4715,14 @@ static void viewport_miscpart_cc(struct wined3d_context *context, } else if (depth_stencil) { - width = depth_stencil->width; height = depth_stencil->height; } else { - FIXME("No attachments draw calls not supported.\n"); - return; + height = gl_info->limits.framebuffer_height; }
gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z); - checkGLcall("glDepthRange");
if (context->render_offscreen) { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index f085f2d..1c4c3ef 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2533,6 +2533,9 @@ struct wined3d_gl_limits
unsigned int texture_buffer_offset_alignment;
+ unsigned int framebuffer_width; + unsigned int framebuffer_height; + UINT glsl_varyings; UINT glsl_vs_float_constants; UINT glsl_ps_float_constants;