mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 22:30:12 +01:00
st/mesa: move check_program_state code into _mesa_update_state
_mesa_update_state() receives the _NEW_PROGRAM flag, so we can handle any shader changes there. There may be some overhead reduction because gfx_shaders_may_be_dirty is removed. Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19859>
This commit is contained in:
parent
0311827337
commit
aaa4b0e618
11 changed files with 109 additions and 148 deletions
|
|
@ -296,8 +296,7 @@ prepare_compute(struct gl_context *ctx)
|
||||||
_mesa_update_state(ctx);
|
_mesa_update_state(ctx);
|
||||||
|
|
||||||
if ((st->dirty | ctx->NewDriverState) & st->active_states &
|
if ((st->dirty | ctx->NewDriverState) & st->active_states &
|
||||||
ST_PIPELINE_COMPUTE_STATE_MASK ||
|
ST_PIPELINE_COMPUTE_STATE_MASK)
|
||||||
st->compute_shader_may_be_dirty)
|
|
||||||
st_validate_state(st, ST_PIPELINE_COMPUTE);
|
st_validate_state(st, ST_PIPELINE_COMPUTE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3581,7 +3581,6 @@ struct gl_context
|
||||||
|
|
||||||
GLuint TextureStateTimestamp; /**< detect changes to shared state */
|
GLuint TextureStateTimestamp; /**< detect changes to shared state */
|
||||||
|
|
||||||
GLboolean LastVertexStageDirty; /**< the last vertex stage has changed */
|
|
||||||
GLboolean PointSizeIsSet; /**< the glPointSize value in the shader is set */
|
GLboolean PointSizeIsSet; /**< the glPointSize value in the shader is set */
|
||||||
|
|
||||||
/** \name For debugging/development only */
|
/** \name For debugging/development only */
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@
|
||||||
#include "blend.h"
|
#include "blend.h"
|
||||||
|
|
||||||
#include "state_tracker/st_context.h"
|
#include "state_tracker/st_context.h"
|
||||||
|
#include "state_tracker/st_util.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
_mesa_update_allow_draw_out_of_order(struct gl_context *ctx)
|
_mesa_update_allow_draw_out_of_order(struct gl_context *ctx)
|
||||||
|
|
@ -184,6 +185,12 @@ update_program(struct gl_context *ctx)
|
||||||
const struct gl_program *prevTCP = ctx->TessCtrlProgram._Current;
|
const struct gl_program *prevTCP = ctx->TessCtrlProgram._Current;
|
||||||
const struct gl_program *prevTEP = ctx->TessEvalProgram._Current;
|
const struct gl_program *prevTEP = ctx->TessEvalProgram._Current;
|
||||||
const struct gl_program *prevCP = ctx->ComputeProgram._Current;
|
const struct gl_program *prevCP = ctx->ComputeProgram._Current;
|
||||||
|
uint64_t prev_vp_affected_states = prevVP ? prevVP->affected_states : 0;
|
||||||
|
uint64_t prev_tcp_affected_states = prevTCP ? prevTCP->affected_states : 0;
|
||||||
|
uint64_t prev_tep_affected_states = prevTEP ? prevTEP->affected_states : 0;
|
||||||
|
uint64_t prev_gp_affected_states = prevGP ? prevGP->affected_states : 0;
|
||||||
|
uint64_t prev_fp_affected_states = prevFP ? prevFP->affected_states : 0;
|
||||||
|
uint64_t prev_cp_affected_states = prevCP ? prevCP->affected_states : 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current
|
* Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current
|
||||||
|
|
@ -259,24 +266,105 @@ update_program(struct gl_context *ctx)
|
||||||
_mesa_reference_program(ctx, &ctx->ComputeProgram._Current, csProg);
|
_mesa_reference_program(ctx, &ctx->ComputeProgram._Current, csProg);
|
||||||
|
|
||||||
bool vp_changed = ctx->VertexProgram._Current != prevVP;
|
bool vp_changed = ctx->VertexProgram._Current != prevVP;
|
||||||
|
bool tcp_changed = ctx->TessCtrlProgram._Current != prevTCP;
|
||||||
bool tep_changed = ctx->TessEvalProgram._Current != prevTEP;
|
bool tep_changed = ctx->TessEvalProgram._Current != prevTEP;
|
||||||
bool gp_changed = ctx->GeometryProgram._Current != prevGP;
|
bool gp_changed = ctx->GeometryProgram._Current != prevGP;
|
||||||
if (ctx->GeometryProgram._Current) {
|
bool fp_changed = ctx->FragmentProgram._Current != prevFP;
|
||||||
ctx->LastVertexStageDirty |= gp_changed;
|
bool cp_changed = ctx->ComputeProgram._Current != prevCP;
|
||||||
} else if (ctx->TessEvalProgram._Current) {
|
|
||||||
ctx->LastVertexStageDirty |= gp_changed | tep_changed;
|
/* Set NewDriverState depending on which shaders have changed. */
|
||||||
} else {
|
uint64_t dirty = 0;
|
||||||
ctx->LastVertexStageDirty |= gp_changed | tep_changed | vp_changed;
|
|
||||||
|
/* Flag states used by both new and old shaders to rebind shader resources
|
||||||
|
* (because shaders pack them and reorder them) and to unbind shader
|
||||||
|
* resources properly when transitioning to shaders that don't use them.
|
||||||
|
*/
|
||||||
|
if (vp_changed) {
|
||||||
|
ctx->Array.NewVertexElements = true;
|
||||||
|
dirty |= prev_vp_affected_states;
|
||||||
|
if (ctx->VertexProgram._Current)
|
||||||
|
dirty |= ST_NEW_VERTEX_PROGRAM(ctx, ctx->VertexProgram._Current);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Let the driver know what's happening:
|
if (tcp_changed) {
|
||||||
|
dirty |= prev_tcp_affected_states;
|
||||||
|
if (ctx->TessCtrlProgram._Current)
|
||||||
|
dirty |= ctx->TessCtrlProgram._Current->affected_states;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tep_changed) {
|
||||||
|
dirty |= prev_tep_affected_states;
|
||||||
|
if (ctx->TessEvalProgram._Current)
|
||||||
|
dirty |= ctx->TessEvalProgram._Current->affected_states;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gp_changed) {
|
||||||
|
dirty |= prev_gp_affected_states;
|
||||||
|
if (ctx->GeometryProgram._Current)
|
||||||
|
dirty |= ctx->GeometryProgram._Current->affected_states;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fp_changed) {
|
||||||
|
dirty |= prev_fp_affected_states;
|
||||||
|
if (ctx->FragmentProgram._Current)
|
||||||
|
dirty |= ctx->FragmentProgram._Current->affected_states;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cp_changed) {
|
||||||
|
dirty |= prev_cp_affected_states;
|
||||||
|
if (ctx->ComputeProgram._Current)
|
||||||
|
dirty |= ctx->ComputeProgram._Current->affected_states;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gl_program *last_vertex_stage;
|
||||||
|
bool last_vertex_stage_dirty;
|
||||||
|
|
||||||
|
if (ctx->GeometryProgram._Current) {
|
||||||
|
last_vertex_stage = ctx->GeometryProgram._Current;
|
||||||
|
last_vertex_stage_dirty = gp_changed;
|
||||||
|
} else if (ctx->TessEvalProgram._Current) {
|
||||||
|
last_vertex_stage = ctx->TessEvalProgram._Current;
|
||||||
|
last_vertex_stage_dirty = gp_changed | tep_changed;
|
||||||
|
} else {
|
||||||
|
last_vertex_stage = ctx->VertexProgram._Current;
|
||||||
|
last_vertex_stage_dirty = gp_changed | tep_changed | vp_changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find out the number of viewports. This determines how many scissors
|
||||||
|
* and viewport states we need to update.
|
||||||
*/
|
*/
|
||||||
if (ctx->FragmentProgram._Current != prevFP ||
|
struct st_context *st = ctx->st;
|
||||||
ctx->VertexProgram._Current != prevVP ||
|
unsigned num_viewports = 1;
|
||||||
ctx->GeometryProgram._Current != prevGP ||
|
|
||||||
ctx->TessEvalProgram._Current != prevTEP ||
|
if (last_vertex_stage &&
|
||||||
ctx->TessCtrlProgram._Current != prevTCP ||
|
last_vertex_stage->info.outputs_written & (
|
||||||
ctx->ComputeProgram._Current != prevCP)
|
VARYING_BIT_VIEWPORT | VARYING_BIT_VIEWPORT_MASK))
|
||||||
|
num_viewports = ctx->Const.MaxViewports;
|
||||||
|
|
||||||
|
if (st->state.num_viewports != num_viewports) {
|
||||||
|
st->state.num_viewports = num_viewports;
|
||||||
|
dirty |= ST_NEW_VIEWPORT;
|
||||||
|
|
||||||
|
if (ctx->Scissor.EnableFlags & u_bit_consecutive(0, num_viewports))
|
||||||
|
dirty |= ST_NEW_SCISSOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (st->lower_point_size && last_vertex_stage_dirty &&
|
||||||
|
!ctx->VertexProgram.PointSizeEnabled && !ctx->PointSizeIsSet) {
|
||||||
|
if (ctx->GeometryProgram._Current) {
|
||||||
|
st->dirty |= ST_NEW_GS_CONSTANTS;
|
||||||
|
} else if (ctx->TessEvalProgram._Current) {
|
||||||
|
st->dirty |= ST_NEW_TES_CONSTANTS;
|
||||||
|
} else {
|
||||||
|
st->dirty |= ST_NEW_VS_CONSTANTS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->NewDriverState |= dirty;
|
||||||
|
|
||||||
|
/* Let the driver know what's happening: */
|
||||||
|
if (fp_changed || vp_changed || gp_changed || tep_changed ||
|
||||||
|
tcp_changed || cp_changed)
|
||||||
return _NEW_PROGRAM;
|
return _NEW_PROGRAM;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -65,104 +65,11 @@ void st_init_atoms( struct st_context *st )
|
||||||
call_once(&flag, init_atoms_once);
|
call_once(&flag, init_atoms_once);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void st_destroy_atoms( struct st_context *st )
|
void st_destroy_atoms( struct st_context *st )
|
||||||
{
|
{
|
||||||
/* no-op */
|
/* no-op */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Too complex to figure out, just check every time:
|
|
||||||
*/
|
|
||||||
static void check_program_state( struct st_context *st )
|
|
||||||
{
|
|
||||||
struct gl_context *ctx = st->ctx;
|
|
||||||
struct gl_program *old_vp = st->vp;
|
|
||||||
struct gl_program *old_tcp = st->tcp;
|
|
||||||
struct gl_program *old_tep = st->tep;
|
|
||||||
struct gl_program *old_gp = st->gp;
|
|
||||||
struct gl_program *old_fp = st->fp;
|
|
||||||
|
|
||||||
struct gl_program *new_vp = ctx->VertexProgram._Current;
|
|
||||||
struct gl_program *new_tcp = ctx->TessCtrlProgram._Current;
|
|
||||||
struct gl_program *new_tep = ctx->TessEvalProgram._Current;
|
|
||||||
struct gl_program *new_gp = ctx->GeometryProgram._Current;
|
|
||||||
struct gl_program *new_fp = ctx->FragmentProgram._Current;
|
|
||||||
uint64_t dirty = 0;
|
|
||||||
unsigned num_viewports = 1;
|
|
||||||
|
|
||||||
/* Flag states used by both new and old shaders to unbind shader resources
|
|
||||||
* properly when transitioning to shaders that don't use them.
|
|
||||||
*/
|
|
||||||
if (unlikely(new_vp != old_vp)) {
|
|
||||||
ctx->Array.NewVertexElements = true;
|
|
||||||
if (old_vp)
|
|
||||||
dirty |= old_vp->affected_states;
|
|
||||||
if (new_vp)
|
|
||||||
dirty |= ST_NEW_VERTEX_PROGRAM(st, new_vp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(new_tcp != old_tcp)) {
|
|
||||||
if (old_tcp)
|
|
||||||
dirty |= old_tcp->affected_states;
|
|
||||||
if (new_tcp)
|
|
||||||
dirty |= new_tcp->affected_states;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(new_tep != old_tep)) {
|
|
||||||
if (old_tep)
|
|
||||||
dirty |= old_tep->affected_states;
|
|
||||||
if (new_tep)
|
|
||||||
dirty |= new_tep->affected_states;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(new_gp != old_gp)) {
|
|
||||||
if (old_gp)
|
|
||||||
dirty |= old_gp->affected_states;
|
|
||||||
if (new_gp)
|
|
||||||
dirty |= new_gp->affected_states;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(new_fp != old_fp)) {
|
|
||||||
if (old_fp)
|
|
||||||
dirty |= old_fp->affected_states;
|
|
||||||
if (new_fp)
|
|
||||||
dirty |= new_fp->affected_states;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find out the number of viewports. This determines how many scissors
|
|
||||||
* and viewport states we need to update.
|
|
||||||
*/
|
|
||||||
struct gl_program *last_prim_shader = new_gp ? new_gp :
|
|
||||||
new_tep ? new_tep : new_vp;
|
|
||||||
if (last_prim_shader &&
|
|
||||||
last_prim_shader->info.outputs_written & (
|
|
||||||
VARYING_BIT_VIEWPORT | VARYING_BIT_VIEWPORT_MASK))
|
|
||||||
num_viewports = ctx->Const.MaxViewports;
|
|
||||||
|
|
||||||
if (st->state.num_viewports != num_viewports) {
|
|
||||||
st->state.num_viewports = num_viewports;
|
|
||||||
dirty |= ST_NEW_VIEWPORT;
|
|
||||||
|
|
||||||
if (ctx->Scissor.EnableFlags & u_bit_consecutive(0, num_viewports))
|
|
||||||
dirty |= ST_NEW_SCISSOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (st->lower_point_size && st->ctx->LastVertexStageDirty &&
|
|
||||||
!st->ctx->VertexProgram.PointSizeEnabled && !st->ctx->PointSizeIsSet) {
|
|
||||||
if (new_gp) {
|
|
||||||
st->dirty |= ST_NEW_GS_CONSTANTS;
|
|
||||||
} else if (new_tep) {
|
|
||||||
st->dirty |= ST_NEW_TES_CONSTANTS;
|
|
||||||
} else {
|
|
||||||
st->dirty |= ST_NEW_VS_CONSTANTS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
st->ctx->LastVertexStageDirty = false;
|
|
||||||
|
|
||||||
st->dirty |= dirty;
|
|
||||||
}
|
|
||||||
|
|
||||||
void st_update_edgeflags(struct st_context *st, bool per_vertex_edgeflags)
|
void st_update_edgeflags(struct st_context *st, bool per_vertex_edgeflags)
|
||||||
{
|
{
|
||||||
bool edgeflags_enabled = st->ctx->Polygon.FrontMode != GL_FILL ||
|
bool edgeflags_enabled = st->ctx->Polygon.FrontMode != GL_FILL ||
|
||||||
|
|
@ -174,7 +81,7 @@ void st_update_edgeflags(struct st_context *st, bool per_vertex_edgeflags)
|
||||||
|
|
||||||
struct gl_program *vp = st->ctx->VertexProgram._Current;
|
struct gl_program *vp = st->ctx->VertexProgram._Current;
|
||||||
if (vp)
|
if (vp)
|
||||||
st->dirty |= ST_NEW_VERTEX_PROGRAM(st, vp);
|
st->dirty |= ST_NEW_VERTEX_PROGRAM(st->ctx, vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool edgeflag_culls_prims = edgeflags_enabled && !vertdata_edgeflags &&
|
bool edgeflag_culls_prims = edgeflags_enabled && !vertdata_edgeflags &&
|
||||||
|
|
@ -214,11 +121,6 @@ void st_validate_state( struct st_context *st, enum st_pipeline pipeline )
|
||||||
if (st->ctx->API == API_OPENGL_COMPAT)
|
if (st->ctx->API == API_OPENGL_COMPAT)
|
||||||
check_attrib_edgeflag(st);
|
check_attrib_edgeflag(st);
|
||||||
|
|
||||||
if (st->gfx_shaders_may_be_dirty) {
|
|
||||||
check_program_state(st);
|
|
||||||
st->gfx_shaders_may_be_dirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pipeline == ST_PIPELINE_RENDER)
|
if (pipeline == ST_PIPELINE_RENDER)
|
||||||
pipeline_mask = ST_PIPELINE_RENDER_STATE_MASK;
|
pipeline_mask = ST_PIPELINE_RENDER_STATE_MASK;
|
||||||
else
|
else
|
||||||
|
|
@ -230,11 +132,6 @@ void st_validate_state( struct st_context *st, enum st_pipeline pipeline )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ST_PIPELINE_META:
|
case ST_PIPELINE_META:
|
||||||
if (st->gfx_shaders_may_be_dirty) {
|
|
||||||
check_program_state(st);
|
|
||||||
st->gfx_shaders_may_be_dirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pipeline_mask = ST_PIPELINE_META_STATE_MASK;
|
pipeline_mask = ST_PIPELINE_META_STATE_MASK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -243,18 +140,6 @@ void st_validate_state( struct st_context *st, enum st_pipeline pipeline )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ST_PIPELINE_COMPUTE: {
|
case ST_PIPELINE_COMPUTE: {
|
||||||
struct gl_program *old_cp = st->cp;
|
|
||||||
struct gl_program *new_cp = ctx->ComputeProgram._Current;
|
|
||||||
|
|
||||||
if (new_cp != old_cp) {
|
|
||||||
if (old_cp)
|
|
||||||
st->dirty |= old_cp->affected_states;
|
|
||||||
assert(new_cp);
|
|
||||||
st->dirty |= new_cp->affected_states;
|
|
||||||
}
|
|
||||||
|
|
||||||
st->compute_shader_may_be_dirty = false;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We add the ST_NEW_FB_STATE bit here as well, because glBindFramebuffer
|
* We add the ST_NEW_FB_STATE bit here as well, because glBindFramebuffer
|
||||||
* acts as a barrier that breaks feedback loops between the framebuffer
|
* acts as a barrier that breaks feedback loops between the framebuffer
|
||||||
|
|
|
||||||
|
|
@ -120,8 +120,8 @@ enum {
|
||||||
ST_NEW_SAMPLE_STATE | \
|
ST_NEW_SAMPLE_STATE | \
|
||||||
ST_NEW_SAMPLE_SHADING)
|
ST_NEW_SAMPLE_SHADING)
|
||||||
|
|
||||||
#define ST_NEW_VERTEX_PROGRAM(st, p) ((p)->affected_states | \
|
#define ST_NEW_VERTEX_PROGRAM(ctx, p) ((p)->affected_states | \
|
||||||
(st_user_clip_planes_enabled(st->ctx) ? \
|
(st_user_clip_planes_enabled(ctx) ? \
|
||||||
ST_NEW_CLIP_STATE : 0))
|
ST_NEW_CLIP_STATE : 0))
|
||||||
|
|
||||||
#define ST_NEW_CONSTANTS (ST_NEW_VS_CONSTANTS | \
|
#define ST_NEW_CONSTANTS (ST_NEW_VS_CONSTANTS | \
|
||||||
|
|
|
||||||
|
|
@ -618,8 +618,7 @@ st_Bitmap(struct gl_context *ctx, GLint x, GLint y,
|
||||||
* explicitly uploaded in the draw_bitmap_quad() function.
|
* explicitly uploaded in the draw_bitmap_quad() function.
|
||||||
*/
|
*/
|
||||||
if ((st->dirty | ctx->NewDriverState) & st->active_states &
|
if ((st->dirty | ctx->NewDriverState) & st->active_states &
|
||||||
~ST_NEW_CONSTANTS & ST_PIPELINE_RENDER_STATE_MASK ||
|
~ST_NEW_CONSTANTS & ST_PIPELINE_RENDER_STATE_MASK) {
|
||||||
st->gfx_shaders_may_be_dirty) {
|
|
||||||
st_validate_state(st, ST_PIPELINE_META);
|
st_validate_state(st, ST_PIPELINE_META);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -313,7 +313,7 @@ st_RenderMode(struct gl_context *ctx, GLenum newMode )
|
||||||
ctx->Driver.DrawGalliumMultiMode = st_feedback_draw_vbo_multi_mode;
|
ctx->Driver.DrawGalliumMultiMode = st_feedback_draw_vbo_multi_mode;
|
||||||
/* need to generate/use a vertex program that emits pos/color/tex */
|
/* need to generate/use a vertex program that emits pos/color/tex */
|
||||||
if (vp)
|
if (vp)
|
||||||
st->dirty |= ST_NEW_VERTEX_PROGRAM(st, vp);
|
st->dirty |= ST_NEW_VERTEX_PROGRAM(ctx, vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore geometry shader states when leaving GL_SELECT mode. */
|
/* Restore geometry shader states when leaving GL_SELECT mode. */
|
||||||
|
|
|
||||||
|
|
@ -185,8 +185,6 @@ st_invalidate_state(struct gl_context *ctx)
|
||||||
|
|
||||||
/* Which shaders are dirty will be determined manually. */
|
/* Which shaders are dirty will be determined manually. */
|
||||||
if (new_state & _NEW_PROGRAM) {
|
if (new_state & _NEW_PROGRAM) {
|
||||||
st->gfx_shaders_may_be_dirty = true;
|
|
||||||
st->compute_shader_may_be_dirty = true;
|
|
||||||
/* This will mask out unused shader resources. */
|
/* This will mask out unused shader resources. */
|
||||||
st->active_states = st_get_active_states(ctx);
|
st->active_states = st_get_active_states(ctx);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -249,12 +249,6 @@ struct st_context
|
||||||
/** This masks out unused shader resources. Only valid in draw calls. */
|
/** This masks out unused shader resources. Only valid in draw calls. */
|
||||||
uint64_t active_states;
|
uint64_t active_states;
|
||||||
|
|
||||||
/* If true, further analysis of states is required to know if something
|
|
||||||
* has changed. Used mainly for shaders.
|
|
||||||
*/
|
|
||||||
bool gfx_shaders_may_be_dirty;
|
|
||||||
bool compute_shader_may_be_dirty;
|
|
||||||
|
|
||||||
GLboolean vertdata_edgeflags;
|
GLboolean vertdata_edgeflags;
|
||||||
GLboolean edgeflag_culls_prims;
|
GLboolean edgeflag_culls_prims;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,8 +86,7 @@ prepare_draw(struct st_context *st, struct gl_context *ctx, uint64_t state_mask,
|
||||||
st_invalidate_readpix_cache(st);
|
st_invalidate_readpix_cache(st);
|
||||||
|
|
||||||
/* Validate state. */
|
/* Validate state. */
|
||||||
if ((st->dirty | ctx->NewDriverState) & st->active_states & state_mask ||
|
if ((st->dirty | ctx->NewDriverState) & st->active_states & state_mask) {
|
||||||
st->gfx_shaders_may_be_dirty) {
|
|
||||||
st_validate_state(st, pipeline);
|
st_validate_state(st, pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1314,7 +1314,7 @@ st_finalize_program(struct st_context *st, struct gl_program *prog)
|
||||||
if (st->current_program[prog->info.stage] == prog) {
|
if (st->current_program[prog->info.stage] == prog) {
|
||||||
if (prog->info.stage == MESA_SHADER_VERTEX) {
|
if (prog->info.stage == MESA_SHADER_VERTEX) {
|
||||||
st->ctx->Array.NewVertexElements = true;
|
st->ctx->Array.NewVertexElements = true;
|
||||||
st->dirty |= ST_NEW_VERTEX_PROGRAM(st, prog);
|
st->dirty |= ST_NEW_VERTEX_PROGRAM(st->ctx, prog);
|
||||||
} else {
|
} else {
|
||||||
st->dirty |= prog->affected_states;
|
st->dirty |= prog->affected_states;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue