mesa: allow out-of-order drawing to optimize immediate mode if it's safe
This increases performance by 11-13% in Viewperf11/Catia - first scene. Set allow_draw_out_of_order=true to enable this. Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4152>
This commit is contained in:
@@ -31,6 +31,7 @@ DRI_CONF_SECTION_DEBUG
|
||||
DRI_CONF_FORCE_GLSL_ABS_SQRT("false")
|
||||
DRI_CONF_GLSL_CORRECT_DERIVATIVES_AFTER_DISCARD("false")
|
||||
DRI_CONF_ALLOW_GLSL_LAYOUT_QUALIFIER_ON_FUNCTION_PARAMETERS("false")
|
||||
DRI_CONF_ALLOW_DRAW_OUT_OF_ORDER("false")
|
||||
DRI_CONF_FORCE_COMPAT_PROFILE("false")
|
||||
DRI_CONF_FORCE_GL_VENDOR()
|
||||
DRI_CONF_SECTION_END
|
||||
|
@@ -234,6 +234,7 @@ struct st_config_options
|
||||
bool force_glsl_abs_sqrt;
|
||||
bool allow_glsl_cross_stage_interpolation_mismatch;
|
||||
bool allow_glsl_layout_qualifier_on_function_parameters;
|
||||
bool allow_draw_out_of_order;
|
||||
char *force_gl_vendor;
|
||||
unsigned char config_options_sha1[20];
|
||||
};
|
||||
|
@@ -92,6 +92,8 @@ dri_fill_st_options(struct dri_screen *screen)
|
||||
driQueryOptionb(optionCache, "allow_glsl_cross_stage_interpolation_mismatch");
|
||||
options->allow_glsl_layout_qualifier_on_function_parameters =
|
||||
driQueryOptionb(optionCache, "allow_glsl_layout_qualifier_on_function_parameters");
|
||||
options->allow_draw_out_of_order =
|
||||
driQueryOptionb(optionCache, "allow_draw_out_of_order");
|
||||
|
||||
char *vendor_str = driQueryOptionstr(optionCache, "force_gl_vendor");
|
||||
/* not an empty string */
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include "enums.h"
|
||||
#include "macros.h"
|
||||
#include "mtypes.h"
|
||||
#include "state.h"
|
||||
|
||||
|
||||
|
||||
@@ -905,6 +906,7 @@ logic_op(struct gl_context *ctx, GLenum opcode, bool no_error)
|
||||
ctx->NewDriverState |= ctx->DriverFlags.NewLogicOp;
|
||||
ctx->Color.LogicOp = opcode;
|
||||
ctx->Color._LogicOp = color_logicop_mapping[opcode & 0x0f];
|
||||
_mesa_update_allow_draw_out_of_order(ctx);
|
||||
|
||||
if (ctx->Driver.LogicOpcode)
|
||||
ctx->Driver.LogicOpcode(ctx, ctx->Color._LogicOp);
|
||||
@@ -991,6 +993,7 @@ _mesa_ColorMask( GLboolean red, GLboolean green,
|
||||
FLUSH_VERTICES(ctx, ctx->DriverFlags.NewColorMask ? 0 : _NEW_COLOR);
|
||||
ctx->NewDriverState |= ctx->DriverFlags.NewColorMask;
|
||||
ctx->Color.ColorMask = mask;
|
||||
_mesa_update_allow_draw_out_of_order(ctx);
|
||||
|
||||
if (ctx->Driver.ColorMask)
|
||||
ctx->Driver.ColorMask( ctx, red, green, blue, alpha );
|
||||
@@ -1027,6 +1030,7 @@ _mesa_ColorMaski(GLuint buf, GLboolean red, GLboolean green,
|
||||
ctx->NewDriverState |= ctx->DriverFlags.NewColorMask;
|
||||
ctx->Color.ColorMask &= ~(0xf << (4 * buf));
|
||||
ctx->Color.ColorMask |= mask << (4 * buf);
|
||||
_mesa_update_allow_draw_out_of_order(ctx);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1765,6 +1765,7 @@ _mesa_make_current( struct gl_context *newCtx,
|
||||
* changed since the last time this FBO was bound).
|
||||
*/
|
||||
_mesa_update_draw_buffers(newCtx);
|
||||
_mesa_update_allow_draw_out_of_order(newCtx);
|
||||
}
|
||||
if (!newCtx->ReadBuffer || _mesa_is_winsys_fbo(newCtx->ReadBuffer)) {
|
||||
_mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
|
||||
|
@@ -244,8 +244,14 @@ do { \
|
||||
do { \
|
||||
if (MESA_VERBOSE & VERBOSE_STATE) \
|
||||
_mesa_debug(ctx, "FLUSH_FOR_DRAW in %s\n", __func__); \
|
||||
if (ctx->Driver.NeedFlush) \
|
||||
if (ctx->Driver.NeedFlush) { \
|
||||
if (ctx->_AllowDrawOutOfOrder) { \
|
||||
if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) \
|
||||
vbo_exec_FlushVertices(ctx, FLUSH_UPDATE_CURRENT); \
|
||||
} else { \
|
||||
vbo_exec_FlushVertices(ctx, ctx->Driver.NeedFlush); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include "enums.h"
|
||||
#include "macros.h"
|
||||
#include "mtypes.h"
|
||||
#include "state.h"
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
@@ -83,6 +84,7 @@ depth_func(struct gl_context *ctx, GLenum func, bool no_error)
|
||||
FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepth ? 0 : _NEW_DEPTH);
|
||||
ctx->NewDriverState |= ctx->DriverFlags.NewDepth;
|
||||
ctx->Depth.Func = func;
|
||||
_mesa_update_allow_draw_out_of_order(ctx);
|
||||
|
||||
if (ctx->Driver.DepthFunc)
|
||||
ctx->Driver.DepthFunc(ctx, func);
|
||||
@@ -128,6 +130,7 @@ _mesa_DepthMask( GLboolean flag )
|
||||
FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepth ? 0 : _NEW_DEPTH);
|
||||
ctx->NewDriverState |= ctx->DriverFlags.NewDepth;
|
||||
ctx->Depth.Mask = flag;
|
||||
_mesa_update_allow_draw_out_of_order(ctx);
|
||||
|
||||
if (ctx->Driver.DepthMask)
|
||||
ctx->Driver.DepthMask( ctx, flag );
|
||||
|
@@ -425,6 +425,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
|
||||
_mesa_flush_vertices_for_blend_adv(ctx, newEnabled,
|
||||
ctx->Color._AdvancedBlendMode);
|
||||
ctx->Color.BlendEnabled = newEnabled;
|
||||
_mesa_update_allow_draw_out_of_order(ctx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -499,6 +500,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
|
||||
FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepth ? 0 : _NEW_DEPTH);
|
||||
ctx->NewDriverState |= ctx->DriverFlags.NewDepth;
|
||||
ctx->Depth.Test = state;
|
||||
_mesa_update_allow_draw_out_of_order(ctx);
|
||||
break;
|
||||
case GL_DEBUG_OUTPUT:
|
||||
case GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB:
|
||||
@@ -604,6 +606,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
|
||||
FLUSH_VERTICES(ctx, ctx->DriverFlags.NewLogicOp ? 0 : _NEW_COLOR);
|
||||
ctx->NewDriverState |= ctx->DriverFlags.NewLogicOp;
|
||||
ctx->Color.ColorLogicOpEnabled = state;
|
||||
_mesa_update_allow_draw_out_of_order(ctx);
|
||||
break;
|
||||
case GL_MAP1_COLOR_4:
|
||||
if (ctx->API != API_OPENGL_COMPAT)
|
||||
@@ -840,6 +843,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
|
||||
FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL);
|
||||
ctx->NewDriverState |= ctx->DriverFlags.NewStencil;
|
||||
ctx->Stencil.Enabled = state;
|
||||
_mesa_update_allow_draw_out_of_order(ctx);
|
||||
break;
|
||||
case GL_TEXTURE_1D:
|
||||
if (ctx->API != API_OPENGL_COMPAT)
|
||||
@@ -1349,6 +1353,7 @@ _mesa_set_enablei(struct gl_context *ctx, GLenum cap,
|
||||
_mesa_flush_vertices_for_blend_adv(ctx, enabled,
|
||||
ctx->Color._AdvancedBlendMode);
|
||||
ctx->Color.BlendEnabled = enabled;
|
||||
_mesa_update_allow_draw_out_of_order(ctx);
|
||||
}
|
||||
break;
|
||||
case GL_SCISSOR_TEST:
|
||||
|
@@ -3042,6 +3042,7 @@ _mesa_bind_framebuffers(struct gl_context *ctx,
|
||||
check_begin_texture_render(ctx, newDrawFb);
|
||||
|
||||
_mesa_reference_framebuffer(&ctx->DrawBuffer, newDrawFb);
|
||||
_mesa_update_allow_draw_out_of_order(ctx);
|
||||
}
|
||||
|
||||
if ((bindDrawBuf || bindReadBuf) && ctx->Driver.BindFramebuffer) {
|
||||
|
@@ -502,6 +502,7 @@ _mesa_update_framebuffer_visual(struct gl_context *ctx,
|
||||
}
|
||||
|
||||
compute_depth_max(fb);
|
||||
_mesa_update_allow_draw_out_of_order(ctx);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -4182,6 +4182,9 @@ struct gl_constants
|
||||
/** Whether the driver can handle MultiDrawElements with non-VBO indices. */
|
||||
bool MultiDrawWithUserIndices;
|
||||
|
||||
/** Whether out-of-order draw (Begin/End) optimizations are allowed. */
|
||||
bool AllowDrawOutOfOrder;
|
||||
|
||||
/** GL_ARB_gl_spirv */
|
||||
struct spirv_supported_capabilities SpirVCapabilities;
|
||||
|
||||
@@ -5144,6 +5147,7 @@ struct gl_context
|
||||
struct gl_driver_flags DriverFlags;
|
||||
|
||||
GLboolean ViewportInitialized; /**< has viewport size been initialized? */
|
||||
GLboolean _AllowDrawOutOfOrder;
|
||||
|
||||
GLbitfield varying_vp_inputs; /**< mask of VERT_BIT_* flags */
|
||||
|
||||
|
@@ -534,6 +534,7 @@ _mesa_bind_pipeline(struct gl_context *ctx,
|
||||
}
|
||||
|
||||
_mesa_update_vertex_processing_mode(ctx);
|
||||
_mesa_update_allow_draw_out_of_order(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -2547,6 +2547,7 @@ _mesa_use_program(struct gl_context *ctx, gl_shader_stage stage,
|
||||
&shTarget->ReferencedPrograms[stage],
|
||||
shProg);
|
||||
_mesa_reference_program(ctx, target, prog);
|
||||
_mesa_update_allow_draw_out_of_order(ctx);
|
||||
if (stage == MESA_SHADER_VERTEX)
|
||||
_mesa_update_vertex_processing_mode(ctx);
|
||||
return;
|
||||
|
@@ -56,6 +56,97 @@
|
||||
#include "blend.h"
|
||||
|
||||
|
||||
void
|
||||
_mesa_update_allow_draw_out_of_order(struct gl_context *ctx)
|
||||
{
|
||||
/* Out-of-order drawing is useful when vertex array draws and immediate
|
||||
* mode are interleaved.
|
||||
*
|
||||
* Example with 3 draws:
|
||||
* glBegin();
|
||||
* glVertex();
|
||||
* glEnd();
|
||||
* glDrawElements();
|
||||
* glBegin();
|
||||
* glVertex();
|
||||
* glEnd();
|
||||
*
|
||||
* Out-of-order drawing changes the execution order like this:
|
||||
* glDrawElements();
|
||||
* glBegin();
|
||||
* glVertex();
|
||||
* glVertex();
|
||||
* glEnd();
|
||||
*
|
||||
* If out-of-order draws are enabled, immediate mode vertices are not
|
||||
* flushed before glDrawElements, resulting in fewer draws and lower CPU
|
||||
* overhead. This helps workstation applications.
|
||||
*
|
||||
* This is a simplified version of out-of-order determination to catch
|
||||
* common cases.
|
||||
*
|
||||
* RadeonSI has a complete and more complicated out-of-order determination
|
||||
* for driver-internal reasons.
|
||||
*/
|
||||
/* Only the compatibility profile with immediate mode needs this. */
|
||||
if (ctx->API != API_OPENGL_COMPAT || !ctx->Const.AllowDrawOutOfOrder)
|
||||
return;
|
||||
|
||||
/* If all of these are NULL, GLSL is disabled. */
|
||||
struct gl_program *vs =
|
||||
ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX];
|
||||
struct gl_program *tcs =
|
||||
ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL];
|
||||
struct gl_program *tes =
|
||||
ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
|
||||
struct gl_program *gs =
|
||||
ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY];
|
||||
struct gl_program *fs =
|
||||
ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT];
|
||||
GLenum16 depth_func = ctx->Depth.Func;
|
||||
|
||||
/* Z fighting and any primitives with equal Z shouldn't be reordered
|
||||
* with LESS/LEQUAL/GREATER/GEQUAL functions.
|
||||
*
|
||||
* When drawing 2 primitive with equal Z:
|
||||
* - with LEQUAL/GEQUAL, the last primitive wins the Z test.
|
||||
* - with LESS/GREATER, the first primitive wins the Z test.
|
||||
*
|
||||
* Here we ignore that on the basis that such cases don't occur in real
|
||||
* apps, and we they do occur, they occur with blending where out-of-order
|
||||
* drawing is always disabled.
|
||||
*/
|
||||
bool previous_state = ctx->_AllowDrawOutOfOrder;
|
||||
ctx->_AllowDrawOutOfOrder =
|
||||
ctx->DrawBuffer &&
|
||||
ctx->DrawBuffer->Visual.depthBits &&
|
||||
ctx->Depth.Test &&
|
||||
ctx->Depth.Mask &&
|
||||
(depth_func == GL_NEVER ||
|
||||
depth_func == GL_LESS ||
|
||||
depth_func == GL_LEQUAL ||
|
||||
depth_func == GL_GREATER ||
|
||||
depth_func == GL_GEQUAL) &&
|
||||
(!ctx->DrawBuffer->Visual.stencilBits ||
|
||||
!ctx->Stencil.Enabled) &&
|
||||
(!ctx->Color.ColorMask ||
|
||||
(!ctx->Color.BlendEnabled &&
|
||||
(!ctx->Color.ColorLogicOpEnabled ||
|
||||
ctx->Color._LogicOp == COLOR_LOGICOP_COPY))) &&
|
||||
(!vs || !vs->info.writes_memory) &&
|
||||
(!tes || !tes->info.writes_memory) &&
|
||||
(!tcs || !tcs->info.writes_memory) &&
|
||||
(!gs || !gs->info.writes_memory) &&
|
||||
(!fs || !fs->info.writes_memory || !fs->info.fs.early_fragment_tests);
|
||||
|
||||
/* If we are disabling out-of-order drawing, we need to flush queued
|
||||
* vertices.
|
||||
*/
|
||||
if (previous_state && !ctx->_AllowDrawOutOfOrder)
|
||||
FLUSH_VERTICES(ctx, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the ctx->*Program._Current pointers to point to the
|
||||
* current/active programs.
|
||||
|
@@ -28,6 +28,9 @@
|
||||
|
||||
#include "mtypes.h"
|
||||
|
||||
extern void
|
||||
_mesa_update_allow_draw_out_of_order(struct gl_context *ctx);
|
||||
|
||||
extern void
|
||||
_mesa_update_state(struct gl_context *ctx);
|
||||
|
||||
|
@@ -1718,4 +1718,6 @@ void st_init_extensions(struct pipe_screen *screen,
|
||||
consts->SpirVExtensions = CALLOC_STRUCT(spirv_supported_extensions);
|
||||
_mesa_fill_supported_spirv_extensions(consts->SpirVExtensions, spirv_caps);
|
||||
}
|
||||
|
||||
consts->AllowDrawOutOfOrder = options->allow_draw_out_of_order;
|
||||
}
|
||||
|
@@ -145,6 +145,11 @@ DRI_CONF_OPT_BEGIN_B(allow_glsl_layout_qualifier_on_function_parameters, def) \
|
||||
DRI_CONF_DESC(en,gettext("Allow layout qualifiers on function parameters.")) \
|
||||
DRI_CONF_OPT_END
|
||||
|
||||
#define DRI_CONF_ALLOW_DRAW_OUT_OF_ORDER(def) \
|
||||
DRI_CONF_OPT_BEGIN_B(allow_draw_out_of_order, def) \
|
||||
DRI_CONF_DESC(en,gettext("Allow out-of-order draw optimizations. Set when Z fighting doesn't have to be accurate.")) \
|
||||
DRI_CONF_OPT_END
|
||||
|
||||
#define DRI_CONF_FORCE_GL_VENDOR(def) \
|
||||
DRI_CONF_OPT_BEGIN(force_gl_vendor, string, def) \
|
||||
DRI_CONF_DESC(en,gettext("Allow GPU vendor to be overridden.")) \
|
||||
|
Reference in New Issue
Block a user