mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 22:49:13 +02:00
st/mesa: determine states used or affected by shaders at compile time
At compile time, each shader determines which ST_NEW flags should be set at shader bind time. This just sets the new field for all shaders. The next commit will use it. v2: small code unification Tested-by: Edmondo Tommasina <edmondo.tommasina@gmail.com> Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com> (v1)
This commit is contained in:
parent
a7d33315a7
commit
8c1775c14c
3 changed files with 189 additions and 3 deletions
|
|
@ -6664,6 +6664,37 @@ get_mesa_program_tgsi(struct gl_context *ctx,
|
|||
return prog;
|
||||
}
|
||||
|
||||
static void
|
||||
set_affected_state_flags(uint64_t *states,
|
||||
struct gl_program *prog,
|
||||
struct gl_linked_shader *shader,
|
||||
uint64_t new_constants,
|
||||
uint64_t new_sampler_views,
|
||||
uint64_t new_samplers,
|
||||
uint64_t new_images,
|
||||
uint64_t new_ubos,
|
||||
uint64_t new_ssbos,
|
||||
uint64_t new_atomics)
|
||||
{
|
||||
if (prog->Parameters->NumParameters)
|
||||
*states |= new_constants;
|
||||
|
||||
if (shader->num_samplers)
|
||||
*states |= new_sampler_views | new_samplers;
|
||||
|
||||
if (shader->NumImages)
|
||||
*states |= new_images;
|
||||
|
||||
if (shader->NumUniformBlocks)
|
||||
*states |= new_ubos;
|
||||
|
||||
if (shader->NumShaderStorageBlocks)
|
||||
*states |= new_ssbos;
|
||||
|
||||
if (shader->NumAtomicBuffers)
|
||||
*states |= new_atomics;
|
||||
}
|
||||
|
||||
static struct gl_program *
|
||||
get_mesa_program(struct gl_context *ctx,
|
||||
struct gl_shader_program *shader_program,
|
||||
|
|
@ -6673,17 +6704,131 @@ get_mesa_program(struct gl_context *ctx,
|
|||
unsigned ptarget = st_shader_stage_to_ptarget(shader->Stage);
|
||||
enum pipe_shader_ir preferred_ir = (enum pipe_shader_ir)
|
||||
pscreen->get_shader_param(pscreen, ptarget, PIPE_SHADER_CAP_PREFERRED_IR);
|
||||
struct gl_program *prog = NULL;
|
||||
|
||||
if (preferred_ir == PIPE_SHADER_IR_NIR) {
|
||||
/* TODO only for GLSL VS/FS for now: */
|
||||
switch (shader->Stage) {
|
||||
case MESA_SHADER_VERTEX:
|
||||
case MESA_SHADER_FRAGMENT:
|
||||
return st_nir_get_mesa_program(ctx, shader_program, shader);
|
||||
prog = st_nir_get_mesa_program(ctx, shader_program, shader);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
prog = get_mesa_program_tgsi(ctx, shader_program, shader);
|
||||
}
|
||||
return get_mesa_program_tgsi(ctx, shader_program, shader);
|
||||
|
||||
if (prog) {
|
||||
uint64_t *states;
|
||||
|
||||
/* This determines which states will be updated when the shader is
|
||||
* bound.
|
||||
*/
|
||||
switch (shader->Stage) {
|
||||
case MESA_SHADER_VERTEX:
|
||||
states = &((struct st_vertex_program*)prog)->affected_states;
|
||||
|
||||
*states = ST_NEW_VS_STATE |
|
||||
ST_NEW_RASTERIZER |
|
||||
ST_NEW_VERTEX_ARRAYS;
|
||||
|
||||
set_affected_state_flags(states, prog, shader,
|
||||
ST_NEW_VS_CONSTANTS,
|
||||
ST_NEW_VS_SAMPLER_VIEWS,
|
||||
ST_NEW_RENDER_SAMPLERS,
|
||||
ST_NEW_VS_IMAGES,
|
||||
ST_NEW_VS_UBOS,
|
||||
ST_NEW_VS_SSBOS,
|
||||
ST_NEW_VS_ATOMICS);
|
||||
break;
|
||||
|
||||
case MESA_SHADER_TESS_CTRL:
|
||||
states = &((struct st_tessctrl_program*)prog)->affected_states;
|
||||
|
||||
*states = ST_NEW_TCS_STATE;
|
||||
|
||||
set_affected_state_flags(states, prog, shader,
|
||||
ST_NEW_TCS_CONSTANTS,
|
||||
ST_NEW_TCS_SAMPLER_VIEWS,
|
||||
ST_NEW_RENDER_SAMPLERS,
|
||||
ST_NEW_TCS_IMAGES,
|
||||
ST_NEW_TCS_UBOS,
|
||||
ST_NEW_TCS_SSBOS,
|
||||
ST_NEW_TCS_ATOMICS);
|
||||
break;
|
||||
|
||||
case MESA_SHADER_TESS_EVAL:
|
||||
states = &((struct st_tesseval_program*)prog)->affected_states;
|
||||
|
||||
*states = ST_NEW_TES_STATE |
|
||||
ST_NEW_RASTERIZER;
|
||||
|
||||
set_affected_state_flags(states, prog, shader,
|
||||
ST_NEW_TES_CONSTANTS,
|
||||
ST_NEW_TES_SAMPLER_VIEWS,
|
||||
ST_NEW_RENDER_SAMPLERS,
|
||||
ST_NEW_TES_IMAGES,
|
||||
ST_NEW_TES_UBOS,
|
||||
ST_NEW_TES_SSBOS,
|
||||
ST_NEW_TES_ATOMICS);
|
||||
break;
|
||||
|
||||
case MESA_SHADER_GEOMETRY:
|
||||
states = &((struct st_geometry_program*)prog)->affected_states;
|
||||
|
||||
*states = ST_NEW_GS_STATE |
|
||||
ST_NEW_RASTERIZER;
|
||||
|
||||
set_affected_state_flags(states, prog, shader,
|
||||
ST_NEW_GS_CONSTANTS,
|
||||
ST_NEW_GS_SAMPLER_VIEWS,
|
||||
ST_NEW_RENDER_SAMPLERS,
|
||||
ST_NEW_GS_IMAGES,
|
||||
ST_NEW_GS_UBOS,
|
||||
ST_NEW_GS_SSBOS,
|
||||
ST_NEW_GS_ATOMICS);
|
||||
break;
|
||||
|
||||
case MESA_SHADER_FRAGMENT:
|
||||
states = &((struct st_fragment_program*)prog)->affected_states;
|
||||
|
||||
/* gl_FragCoord and glDrawPixels always use constants. */
|
||||
*states = ST_NEW_FS_STATE |
|
||||
ST_NEW_SAMPLE_SHADING |
|
||||
ST_NEW_FS_CONSTANTS;
|
||||
|
||||
set_affected_state_flags(states, prog, shader,
|
||||
ST_NEW_FS_CONSTANTS,
|
||||
ST_NEW_FS_SAMPLER_VIEWS,
|
||||
ST_NEW_RENDER_SAMPLERS,
|
||||
ST_NEW_FS_IMAGES,
|
||||
ST_NEW_FS_UBOS,
|
||||
ST_NEW_FS_SSBOS,
|
||||
ST_NEW_FS_ATOMICS);
|
||||
break;
|
||||
|
||||
case MESA_SHADER_COMPUTE:
|
||||
states = &((struct st_compute_program*)prog)->affected_states;
|
||||
|
||||
*states = ST_NEW_CS_STATE;
|
||||
|
||||
set_affected_state_flags(states, prog, shader,
|
||||
ST_NEW_CS_CONSTANTS,
|
||||
ST_NEW_CS_SAMPLER_VIEWS,
|
||||
ST_NEW_CS_SAMPLERS,
|
||||
ST_NEW_CS_IMAGES,
|
||||
ST_NEW_CS_UBOS,
|
||||
ST_NEW_CS_SSBOS,
|
||||
ST_NEW_CS_ATOMICS);
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable("unhandled shader stage");
|
||||
}
|
||||
}
|
||||
|
||||
return prog;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -364,9 +364,23 @@ st_translate_vertex_program(struct st_context *st,
|
|||
output_semantic_name[num_outputs] = TGSI_SEMANTIC_EDGEFLAG;
|
||||
output_semantic_index[num_outputs] = 0;
|
||||
|
||||
if (!stvp->glsl_to_tgsi && !stvp->shader_program)
|
||||
/* ARB_vp: */
|
||||
if (!stvp->glsl_to_tgsi && !stvp->shader_program) {
|
||||
_mesa_remove_output_reads(&stvp->Base.Base, PROGRAM_OUTPUT);
|
||||
|
||||
/* This determines which states will be updated when the assembly
|
||||
* shader is bound.
|
||||
*/
|
||||
stvp->affected_states = ST_NEW_VS_STATE |
|
||||
ST_NEW_RASTERIZER |
|
||||
ST_NEW_VERTEX_ARRAYS;
|
||||
|
||||
if (stvp->Base.Base.Parameters->NumParameters)
|
||||
stvp->affected_states |= ST_NEW_VS_CONSTANTS;
|
||||
|
||||
/* No samplers are allowed in ARB_vp. */
|
||||
}
|
||||
|
||||
if (stvp->shader_program) {
|
||||
nir_shader *nir = st_glsl_to_nir(st, &stvp->Base.Base,
|
||||
stvp->shader_program,
|
||||
|
|
@ -593,10 +607,31 @@ st_translate_fragment_program(struct st_context *st,
|
|||
|
||||
memset(inputSlotToAttr, ~0, sizeof(inputSlotToAttr));
|
||||
|
||||
/* Non-GLSL programs: */
|
||||
if (!stfp->glsl_to_tgsi && !stfp->shader_program) {
|
||||
_mesa_remove_output_reads(&stfp->Base.Base, PROGRAM_OUTPUT);
|
||||
if (st->ctx->Const.GLSLFragCoordIsSysVal)
|
||||
_mesa_program_fragment_position_to_sysval(&stfp->Base.Base);
|
||||
|
||||
/* This determines which states will be updated when the assembly
|
||||
* shader is bound.
|
||||
*
|
||||
* fragment.position and glDrawPixels always use constants.
|
||||
*/
|
||||
stfp->affected_states = ST_NEW_FS_STATE |
|
||||
ST_NEW_SAMPLE_SHADING |
|
||||
ST_NEW_FS_CONSTANTS;
|
||||
|
||||
if (stfp->ati_fs) {
|
||||
/* Just set them for ATI_fs unconditionally. */
|
||||
stfp->affected_states |= ST_NEW_FS_SAMPLER_VIEWS |
|
||||
ST_NEW_RENDER_SAMPLERS;
|
||||
} else {
|
||||
/* ARB_fp */
|
||||
if (stfp->Base.Base.SamplersUsed)
|
||||
stfp->affected_states |= ST_NEW_FS_SAMPLER_VIEWS |
|
||||
ST_NEW_RENDER_SAMPLERS;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ struct st_fragment_program
|
|||
struct pipe_shader_state tgsi;
|
||||
struct glsl_to_tgsi_visitor* glsl_to_tgsi;
|
||||
struct ati_fragment_shader *ati_fs;
|
||||
uint64_t affected_states; /**< ST_NEW_* flags to mark dirty when binding */
|
||||
|
||||
/* used when bypassing glsl_to_tgsi: */
|
||||
struct gl_shader_program *shader_program;
|
||||
|
|
@ -166,6 +167,7 @@ struct st_vertex_program
|
|||
struct gl_vertex_program Base; /**< The Mesa vertex program */
|
||||
struct pipe_shader_state tgsi;
|
||||
struct glsl_to_tgsi_visitor* glsl_to_tgsi;
|
||||
uint64_t affected_states; /**< ST_NEW_* flags to mark dirty when binding */
|
||||
|
||||
/* used when bypassing glsl_to_tgsi: */
|
||||
struct gl_shader_program *shader_program;
|
||||
|
|
@ -214,6 +216,7 @@ struct st_geometry_program
|
|||
struct gl_geometry_program Base; /**< The Mesa geometry program */
|
||||
struct pipe_shader_state tgsi;
|
||||
struct glsl_to_tgsi_visitor* glsl_to_tgsi;
|
||||
uint64_t affected_states; /**< ST_NEW_* flags to mark dirty when binding */
|
||||
|
||||
struct st_basic_variant *variants;
|
||||
};
|
||||
|
|
@ -227,6 +230,7 @@ struct st_tessctrl_program
|
|||
struct gl_tess_ctrl_program Base; /**< The Mesa tess ctrl program */
|
||||
struct pipe_shader_state tgsi;
|
||||
struct glsl_to_tgsi_visitor* glsl_to_tgsi;
|
||||
uint64_t affected_states; /**< ST_NEW_* flags to mark dirty when binding */
|
||||
|
||||
struct st_basic_variant *variants;
|
||||
};
|
||||
|
|
@ -240,6 +244,7 @@ struct st_tesseval_program
|
|||
struct gl_tess_eval_program Base; /**< The Mesa tess eval program */
|
||||
struct pipe_shader_state tgsi;
|
||||
struct glsl_to_tgsi_visitor* glsl_to_tgsi;
|
||||
uint64_t affected_states; /**< ST_NEW_* flags to mark dirty when binding */
|
||||
|
||||
struct st_basic_variant *variants;
|
||||
};
|
||||
|
|
@ -253,6 +258,7 @@ struct st_compute_program
|
|||
struct gl_compute_program Base; /**< The Mesa compute program */
|
||||
struct pipe_compute_state tgsi;
|
||||
struct glsl_to_tgsi_visitor* glsl_to_tgsi;
|
||||
uint64_t affected_states; /**< ST_NEW_* flags to mark dirty when binding */
|
||||
|
||||
struct st_basic_variant *variants;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue