mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 06:48:06 +02:00
mesa: completely rewrite the edge flag state update logic
This removes the edge flag logic from st_validate_state, which was always executed and added overhead there. Now it's done only when needed. Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19953>
This commit is contained in:
parent
b6e800af7d
commit
a5851ca8b1
15 changed files with 107 additions and 63 deletions
|
|
@ -314,16 +314,6 @@ _mesa_draw_current_attrib(const struct gl_context *ctx, gl_vert_attrib attr)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if we have the VERT_ATTRIB_EDGEFLAG array enabled.
|
||||
*/
|
||||
static inline bool
|
||||
_mesa_draw_edge_flag_array_enabled(const struct gl_context *ctx)
|
||||
{
|
||||
return ctx->Array._DrawVAOEnabledAttribs & VERT_BIT_EDGEFLAG;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1313,6 +1313,8 @@ restore_array_attrib(struct gl_context *ctx,
|
|||
src->VAO->IndexBufferObj ?
|
||||
src->VAO->IndexBufferObj->Name : 0);
|
||||
}
|
||||
|
||||
_mesa_update_edgeflag_state_vao(ctx);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ _mesa_set_draw_vao(struct gl_context *ctx, struct gl_vertex_array_object *vao)
|
|||
|
||||
if (*ptr != vao) {
|
||||
_mesa_reference_vao_(ctx, ptr, vao);
|
||||
_mesa_update_edgeflag_state_vao(ctx);
|
||||
ctx->Array.NewVAO = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -135,6 +136,7 @@ _mesa_restore_draw_vao(struct gl_context *ctx,
|
|||
{
|
||||
_mesa_reference_vao(ctx, &ctx->Array._DrawVAO, NULL);
|
||||
ctx->Array._DrawVAO = saved;
|
||||
_mesa_update_edgeflag_state_vao(ctx);
|
||||
ctx->Array.NewVAO = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1753,6 +1753,18 @@ struct gl_array_attrib
|
|||
*/
|
||||
GLbitfield _DrawVAOEnabledAttribs;
|
||||
|
||||
/**
|
||||
* Whether per-vertex edge flags are enabled and should be processed by
|
||||
* the vertex shader.
|
||||
*/
|
||||
bool _PerVertexEdgeFlagsEnabled;
|
||||
|
||||
/**
|
||||
* Whether all edge flags are false, causing all points and lines generated
|
||||
* by polygon mode to be not drawn. (i.e. culled)
|
||||
*/
|
||||
bool _PolygonModeAlwaysCulls;
|
||||
|
||||
/**
|
||||
* Whether the VAO has been changed.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "polygon.h"
|
||||
#include "mtypes.h"
|
||||
#include "api_exec_decl.h"
|
||||
#include "varray.h"
|
||||
|
||||
#include "state_tracker/st_context.h"
|
||||
|
||||
|
|
@ -193,6 +194,7 @@ polygon_mode(struct gl_context *ctx, GLenum face, GLenum mode, bool no_error)
|
|||
GL_POLYGON_BIT);
|
||||
ctx->NewDriverState |= ST_NEW_RASTERIZER;
|
||||
ctx->Polygon.FrontMode = mode;
|
||||
_mesa_update_edgeflag_state_vao(ctx);
|
||||
break;
|
||||
case GL_FRONT_AND_BACK:
|
||||
if (ctx->Polygon.FrontMode == mode && ctx->Polygon.BackMode == mode)
|
||||
|
|
@ -202,6 +204,7 @@ polygon_mode(struct gl_context *ctx, GLenum face, GLenum mode, bool no_error)
|
|||
ctx->NewDriverState |= ST_NEW_RASTERIZER;
|
||||
ctx->Polygon.FrontMode = mode;
|
||||
ctx->Polygon.BackMode = mode;
|
||||
_mesa_update_edgeflag_state_vao(ctx);
|
||||
break;
|
||||
case GL_BACK:
|
||||
if (!no_error && ctx->API == API_OPENGL_CORE) {
|
||||
|
|
@ -214,6 +217,7 @@ polygon_mode(struct gl_context *ctx, GLenum face, GLenum mode, bool no_error)
|
|||
GL_POLYGON_BIT);
|
||||
ctx->NewDriverState |= ST_NEW_RASTERIZER;
|
||||
ctx->Polygon.BackMode = mode;
|
||||
_mesa_update_edgeflag_state_vao(ctx);
|
||||
break;
|
||||
default:
|
||||
if (!no_error)
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@
|
|||
#include "main/dispatch.h"
|
||||
#include "api_exec_decl.h"
|
||||
|
||||
#include "state_tracker/st_atom.h"
|
||||
#include "state_tracker/st_util.h"
|
||||
|
||||
|
||||
/** Used to do error checking for GL_EXT_vertex_array_bgra */
|
||||
#define BGRA_OR_4 5
|
||||
|
|
@ -1993,6 +1996,62 @@ _mesa_VertexAttribLPointer(GLuint index, GLint size, GLenum type,
|
|||
stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the per-vertex edge flag enablement according to the "enable"
|
||||
* parameter. If "enable" is false, the zero-stride edge flag attribute value
|
||||
* will be used instead.
|
||||
*
|
||||
* This is used by VAOs, glBegin/End and display lists.
|
||||
*/
|
||||
void
|
||||
_mesa_update_edgeflag_state_explicit(struct gl_context *ctx,
|
||||
bool per_vertex_enable)
|
||||
{
|
||||
if (ctx->API != API_OPENGL_COMPAT)
|
||||
return;
|
||||
|
||||
/* Edge flags take effect only if the polygon mode is not FILL, and they
|
||||
* determine whether a line or point is drawn with that polygon mode.
|
||||
*/
|
||||
bool edgeflags_have_effect = ctx->Polygon.FrontMode != GL_FILL ||
|
||||
ctx->Polygon.BackMode != GL_FILL;
|
||||
per_vertex_enable &= edgeflags_have_effect;
|
||||
|
||||
if (per_vertex_enable != ctx->Array._PerVertexEdgeFlagsEnabled) {
|
||||
ctx->Array._PerVertexEdgeFlagsEnabled = per_vertex_enable;
|
||||
|
||||
struct gl_program *vp = ctx->VertexProgram._Current;
|
||||
if (vp) {
|
||||
ctx->NewDriverState |= ST_NEW_VS_STATE |
|
||||
ST_NEW_VERTEX_ARRAYS;
|
||||
ctx->Array.NewVertexElements = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there are no per-vertex edge flags and the zero-stride edge flag is
|
||||
* false, all front and back points and lines generated by polygon mode
|
||||
* are not drawn.
|
||||
*/
|
||||
bool polygon_mode_always_culls = edgeflags_have_effect &&
|
||||
!ctx->Array._PerVertexEdgeFlagsEnabled &&
|
||||
!ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0];
|
||||
if (polygon_mode_always_culls != ctx->Array._PolygonModeAlwaysCulls) {
|
||||
ctx->Array._PolygonModeAlwaysCulls = polygon_mode_always_culls;
|
||||
ctx->NewDriverState |= ST_NEW_RASTERIZER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the edge flag state using the current VAO and the zero-stride
|
||||
* edge flag attribute value if per-vertex edge flags are disabled.
|
||||
*/
|
||||
void
|
||||
_mesa_update_edgeflag_state_vao(struct gl_context *ctx)
|
||||
{
|
||||
_mesa_update_edgeflag_state_explicit(ctx,
|
||||
ctx->Array._DrawVAO->Enabled &
|
||||
VERT_BIT_EDGEFLAG);
|
||||
}
|
||||
|
||||
void
|
||||
_mesa_enable_vertex_array_attribs(struct gl_context *ctx,
|
||||
|
|
@ -2015,6 +2074,9 @@ _mesa_enable_vertex_array_attribs(struct gl_context *ctx,
|
|||
if (attrib_bits & (VERT_BIT_POS|VERT_BIT_GENERIC0))
|
||||
update_attribute_map_mode(ctx, vao);
|
||||
|
||||
if (attrib_bits & VERT_BIT_EDGEFLAG)
|
||||
_mesa_update_edgeflag_state_vao(ctx);
|
||||
|
||||
vao->_EnabledWithMapMode =
|
||||
_mesa_vao_enable_to_vp_inputs(vao->_AttributeMapMode, vao->Enabled);
|
||||
}
|
||||
|
|
@ -2116,6 +2178,9 @@ _mesa_disable_vertex_array_attribs(struct gl_context *ctx,
|
|||
if (attrib_bits & (VERT_BIT_POS|VERT_BIT_GENERIC0))
|
||||
update_attribute_map_mode(ctx, vao);
|
||||
|
||||
if (attrib_bits & VERT_BIT_EDGEFLAG)
|
||||
_mesa_update_edgeflag_state_vao(ctx);
|
||||
|
||||
vao->_EnabledWithMapMode =
|
||||
_mesa_vao_enable_to_vp_inputs(vao->_AttributeMapMode, vao->Enabled);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -168,4 +168,11 @@ _mesa_init_varray(struct gl_context *ctx);
|
|||
extern void
|
||||
_mesa_free_varray_data(struct gl_context *ctx);
|
||||
|
||||
void
|
||||
_mesa_update_edgeflag_state_explicit(struct gl_context *ctx,
|
||||
bool per_vertex_enable);
|
||||
|
||||
void
|
||||
_mesa_update_edgeflag_state_vao(struct gl_context *ctx);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -70,33 +70,6 @@ void st_destroy_atoms( struct st_context *st )
|
|||
/* no-op */
|
||||
}
|
||||
|
||||
void st_update_edgeflags(struct st_context *st, bool per_vertex_edgeflags)
|
||||
{
|
||||
bool edgeflags_enabled = st->ctx->Polygon.FrontMode != GL_FILL ||
|
||||
st->ctx->Polygon.BackMode != GL_FILL;
|
||||
bool vertdata_edgeflags = edgeflags_enabled && per_vertex_edgeflags;
|
||||
|
||||
if (vertdata_edgeflags != st->vertdata_edgeflags) {
|
||||
st->vertdata_edgeflags = vertdata_edgeflags;
|
||||
|
||||
struct gl_program *vp = st->ctx->VertexProgram._Current;
|
||||
if (vp)
|
||||
st->dirty |= ST_NEW_VERTEX_PROGRAM(st->ctx, vp);
|
||||
}
|
||||
|
||||
bool edgeflag_culls_prims = edgeflags_enabled && !vertdata_edgeflags &&
|
||||
!st->ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0];
|
||||
if (edgeflag_culls_prims != st->edgeflag_culls_prims) {
|
||||
st->edgeflag_culls_prims = edgeflag_culls_prims;
|
||||
st->dirty |= ST_NEW_RASTERIZER;
|
||||
}
|
||||
}
|
||||
|
||||
static void check_attrib_edgeflag(struct st_context *st)
|
||||
{
|
||||
st_update_edgeflags(st, _mesa_draw_edge_flag_array_enabled(st->ctx));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Update all derived state:
|
||||
*/
|
||||
|
|
@ -118,9 +91,6 @@ void st_validate_state( struct st_context *st, enum st_pipeline pipeline )
|
|||
switch (pipeline) {
|
||||
case ST_PIPELINE_RENDER:
|
||||
case ST_PIPELINE_RENDER_NO_VARRAYS:
|
||||
if (st->ctx->API == API_OPENGL_COMPAT)
|
||||
check_attrib_edgeflag(st);
|
||||
|
||||
if (pipeline == ST_PIPELINE_RENDER)
|
||||
pipeline_mask = ST_PIPELINE_RENDER_STATE_MASK;
|
||||
else
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ enum st_pipeline {
|
|||
void st_init_atoms( struct st_context *st );
|
||||
void st_destroy_atoms( struct st_context *st );
|
||||
void st_validate_state( struct st_context *st, enum st_pipeline pipeline );
|
||||
void st_update_edgeflags(struct st_context *st, bool per_vertex_edgeflags);
|
||||
|
||||
void
|
||||
st_setup_arrays(struct st_context *st,
|
||||
|
|
|
|||
|
|
@ -287,8 +287,7 @@ st_update_rasterizer(struct st_context *st)
|
|||
raster->tile_raster_order_increasing_y = ctx->TileRasterOrderIncreasingY;
|
||||
}
|
||||
|
||||
if (st->edgeflag_culls_prims) {
|
||||
/* All edge flags are FALSE. Cull the affected faces. */
|
||||
if (ctx->Array._PolygonModeAlwaysCulls) {
|
||||
if (raster->fill_front != PIPE_POLYGON_MODE_FILL)
|
||||
raster->cull_face |= PIPE_FACE_FRONT;
|
||||
if (raster->fill_back != PIPE_POLYGON_MODE_FILL)
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ st_update_vp( struct st_context *st )
|
|||
assert(vp->Target == GL_VERTEX_PROGRAM_ARB);
|
||||
|
||||
if (st->shader_has_one_variant[MESA_SHADER_VERTEX] &&
|
||||
!st->vertdata_edgeflags) {
|
||||
!st->ctx->Array._PerVertexEdgeFlagsEnabled) {
|
||||
st->vp_variant = st_common_variant(vp->variants);
|
||||
} else {
|
||||
struct st_common_variant_key key;
|
||||
|
|
@ -210,7 +210,7 @@ st_update_vp( struct st_context *st )
|
|||
* the input to the output. We'll need to use similar logic to set
|
||||
* up the extra vertex_element input for edgeflags.
|
||||
*/
|
||||
key.passthrough_edgeflags = st->vertdata_edgeflags;
|
||||
key.passthrough_edgeflags = st->ctx->Array._PerVertexEdgeFlagsEnabled;
|
||||
|
||||
key.clamp_color = st->clamp_vert_color_in_shader &&
|
||||
st->ctx->Light._ClampVertexColor &&
|
||||
|
|
|
|||
|
|
@ -254,9 +254,6 @@ struct st_context
|
|||
/** This masks out unused shader resources. Only valid in draw calls. */
|
||||
uint64_t active_states;
|
||||
|
||||
GLboolean vertdata_edgeflags;
|
||||
GLboolean edgeflag_culls_prims;
|
||||
|
||||
/**
|
||||
* The number of currently active queries (excluding timer queries).
|
||||
* This is used to know if we need to pause any queries for meta ops.
|
||||
|
|
|
|||
|
|
@ -349,12 +349,6 @@ st_draw_gallium_vertex_state(struct gl_context *ctx,
|
|||
bool per_vertex_edgeflags)
|
||||
{
|
||||
struct st_context *st = st_context(ctx);
|
||||
bool old_vertdata_edgeflags = st->vertdata_edgeflags;
|
||||
|
||||
/* We don't flag any other states to make st_validate state update edge
|
||||
* flags, so we need to update them here.
|
||||
*/
|
||||
st_update_edgeflags(st, per_vertex_edgeflags);
|
||||
|
||||
prepare_draw(st, ctx, ST_PIPELINE_RENDER_STATE_MASK_NO_VARRAYS,
|
||||
ST_PIPELINE_RENDER_NO_VARRAYS);
|
||||
|
|
@ -383,15 +377,6 @@ st_draw_gallium_vertex_state(struct gl_context *ctx,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If per-vertex edge flags are different than the non-display-list state,
|
||||
* just flag ST_NEW_VERTEX_ARRAY, which will also completely revalidate
|
||||
* edge flags in st_validate_state.
|
||||
*/
|
||||
if (st->vertdata_edgeflags != old_vertdata_edgeflags) {
|
||||
ctx->Array.NewVertexElements = true;
|
||||
st->dirty |= ST_NEW_VERTEX_ARRAYS;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -211,6 +211,9 @@ vbo_exec_copy_to_current(struct vbo_exec_context *exec)
|
|||
i == VBO_ATTRIB_MAT_BACK_SHININESS)
|
||||
ctx->NewState |= _NEW_FF_VERT_PROGRAM;
|
||||
} else {
|
||||
if (i == VBO_ATTRIB_EDGEFLAG)
|
||||
_mesa_update_edgeflag_state_vao(ctx);
|
||||
|
||||
ctx->NewState |= _NEW_CURRENT_ATTRIB;
|
||||
ctx->PopAttribState |= GL_CURRENT_BIT;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ copy_vao(struct gl_context *ctx, const struct gl_vertex_array_object *vao,
|
|||
current_index == VBO_ATTRIB_MAT_BACK_SHININESS)
|
||||
ctx->NewState |= _NEW_FF_VERT_PROGRAM;
|
||||
|
||||
if (current_index == VBO_ATTRIB_EDGEFLAG)
|
||||
_mesa_update_edgeflag_state_vao(ctx);
|
||||
|
||||
ctx->NewState |= state;
|
||||
ctx->PopAttribState |= pop_state;
|
||||
}
|
||||
|
|
@ -270,6 +273,9 @@ vbo_save_playback_vertex_list_gallium(struct gl_context *ctx,
|
|||
info.take_vertex_state_ownership = true;
|
||||
}
|
||||
|
||||
/* Set edge flags. */
|
||||
_mesa_update_edgeflag_state_explicit(ctx, enabled & VERT_BIT_EDGEFLAG);
|
||||
|
||||
/* Fast path using a pre-built gallium vertex buffer state. */
|
||||
if (node->modes || node->num_draws > 1) {
|
||||
ctx->Driver.DrawGalliumVertexState(ctx, state, info,
|
||||
|
|
@ -284,6 +290,9 @@ vbo_save_playback_vertex_list_gallium(struct gl_context *ctx,
|
|||
enabled & VERT_ATTRIB_EDGEFLAG);
|
||||
}
|
||||
|
||||
/* Restore edge flag state. */
|
||||
_mesa_update_edgeflag_state_vao(ctx);
|
||||
|
||||
if (copy_to_current)
|
||||
playback_copy_to_current(ctx, node);
|
||||
return DONE;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue