st/mesa: add compute shader states
Changes from v2: - use as much common code as possible (eg. st_basic_variant) Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Marek Olšák <marek.olsak@amd.com> Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
parent
08c46025c8
commit
7c79c1e3e2
|
@ -98,7 +98,7 @@ static const struct st_tracked_state *render_atoms[] =
|
|||
*/
|
||||
static const struct st_tracked_state *compute_atoms[] =
|
||||
{
|
||||
/* will be updated in the next commit */
|
||||
&st_update_cp,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ extern const struct st_tracked_state st_update_gp;
|
|||
extern const struct st_tracked_state st_update_tep;
|
||||
extern const struct st_tracked_state st_update_tcp;
|
||||
extern const struct st_tracked_state st_update_vp;
|
||||
extern const struct st_tracked_state st_update_cp;
|
||||
extern const struct st_tracked_state st_update_rasterizer;
|
||||
extern const struct st_tracked_state st_update_polygon_stipple;
|
||||
extern const struct st_tracked_state st_update_viewport;
|
||||
|
|
|
@ -255,3 +255,35 @@ const struct st_tracked_state st_update_tep = {
|
|||
},
|
||||
update_tep /* update */
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void
|
||||
update_cp( struct st_context *st )
|
||||
{
|
||||
struct st_compute_program *stcp;
|
||||
|
||||
if (!st->ctx->ComputeProgram._Current) {
|
||||
cso_set_compute_shader_handle(st->cso_context, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
stcp = st_compute_program(st->ctx->ComputeProgram._Current);
|
||||
assert(stcp->Base.Base.Target == GL_COMPUTE_PROGRAM_NV);
|
||||
|
||||
st->cp_variant = st_get_cp_variant(st, &stcp->tgsi, &stcp->variants);
|
||||
|
||||
st_reference_compprog(st, &st->cp, stcp);
|
||||
|
||||
cso_set_compute_shader_handle(st->cso_context,
|
||||
st->cp_variant->driver_shader);
|
||||
}
|
||||
|
||||
const struct st_tracked_state st_update_cp = {
|
||||
"st_update_cp", /* name */
|
||||
{ /* dirty */
|
||||
0, /* mesa */
|
||||
ST_NEW_COMPUTE_PROGRAM /* st */
|
||||
},
|
||||
update_cp /* update */
|
||||
};
|
||||
|
|
|
@ -74,6 +74,9 @@ st_bind_program(struct gl_context *ctx, GLenum target, struct gl_program *prog)
|
|||
case GL_TESS_EVALUATION_PROGRAM_NV:
|
||||
st->dirty.st |= ST_NEW_TESSEVAL_PROGRAM;
|
||||
break;
|
||||
case GL_COMPUTE_PROGRAM_NV:
|
||||
st->dirty_cp.st |= ST_NEW_COMPUTE_PROGRAM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,6 +95,7 @@ st_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
|
|||
st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
|
||||
st->dirty.st |= ST_NEW_TESSCTRL_PROGRAM;
|
||||
st->dirty.st |= ST_NEW_TESSEVAL_PROGRAM;
|
||||
st->dirty_cp.st |= ST_NEW_COMPUTE_PROGRAM;
|
||||
}
|
||||
|
||||
|
||||
|
@ -123,6 +127,10 @@ st_new_program(struct gl_context *ctx, GLenum target, GLuint id)
|
|||
struct st_tesseval_program *prog = ST_CALLOC_STRUCT(st_tesseval_program);
|
||||
return _mesa_init_gl_program(&prog->Base.Base, target, id);
|
||||
}
|
||||
case GL_COMPUTE_PROGRAM_NV: {
|
||||
struct st_compute_program *prog = ST_CALLOC_STRUCT(st_compute_program);
|
||||
return _mesa_init_gl_program(&prog->Base.Base, target, id);
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
return NULL;
|
||||
|
@ -195,6 +203,17 @@ st_delete_program(struct gl_context *ctx, struct gl_program *prog)
|
|||
free_glsl_to_tgsi_visitor(sttep->glsl_to_tgsi);
|
||||
}
|
||||
break;
|
||||
case GL_COMPUTE_PROGRAM_NV:
|
||||
{
|
||||
struct st_compute_program *stcp =
|
||||
(struct st_compute_program *) prog;
|
||||
|
||||
st_release_cp_variants(st, stcp);
|
||||
|
||||
if (stcp->glsl_to_tgsi)
|
||||
free_glsl_to_tgsi_visitor(stcp->glsl_to_tgsi);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0); /* problem */
|
||||
}
|
||||
|
@ -272,6 +291,17 @@ st_program_string_notify( struct gl_context *ctx,
|
|||
if (st->tep == sttep)
|
||||
st->dirty.st |= ST_NEW_TESSEVAL_PROGRAM;
|
||||
}
|
||||
else if (target == GL_COMPUTE_PROGRAM_NV) {
|
||||
struct st_compute_program *stcp =
|
||||
(struct st_compute_program *) prog;
|
||||
|
||||
st_release_cp_variants(st, stcp);
|
||||
if (!st_translate_compute_program(st, stcp))
|
||||
return false;
|
||||
|
||||
if (st->cp == stcp)
|
||||
st->dirty_cp.st |= ST_NEW_COMPUTE_PROGRAM;
|
||||
}
|
||||
|
||||
if (ST_DEBUG & DEBUG_PRECOMPILE ||
|
||||
st->shader_has_one_variant[stage])
|
||||
|
|
|
@ -446,6 +446,7 @@ void st_destroy_context( struct st_context *st )
|
|||
st_reference_vertprog(st, &st->vp, NULL);
|
||||
st_reference_tesscprog(st, &st->tcp, NULL);
|
||||
st_reference_tesseprog(st, &st->tep, NULL);
|
||||
st_reference_compprog(st, &st->cp, NULL);
|
||||
|
||||
/* release framebuffer surfaces */
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
|
||||
|
|
|
@ -64,6 +64,7 @@ struct u_upload_mgr;
|
|||
#define ST_NEW_SAMPLER_VIEWS (1 << 11)
|
||||
#define ST_NEW_ATOMIC_BUFFER (1 << 12)
|
||||
#define ST_NEW_STORAGE_BUFFER (1 << 13)
|
||||
#define ST_NEW_COMPUTE_PROGRAM (1 << 14)
|
||||
|
||||
|
||||
struct st_state_flags {
|
||||
|
@ -174,12 +175,14 @@ struct st_context
|
|||
struct st_geometry_program *gp; /**< Currently bound geometry program */
|
||||
struct st_tessctrl_program *tcp; /**< Currently bound tess control program */
|
||||
struct st_tesseval_program *tep; /**< Currently bound tess eval program */
|
||||
struct st_compute_program *cp; /**< Currently bound compute program */
|
||||
|
||||
struct st_vp_variant *vp_variant;
|
||||
struct st_fp_variant *fp_variant;
|
||||
struct st_basic_variant *gp_variant;
|
||||
struct st_basic_variant *tcp_variant;
|
||||
struct st_basic_variant *tep_variant;
|
||||
struct st_basic_variant *cp_variant;
|
||||
|
||||
struct gl_texture_object *default_texture;
|
||||
|
||||
|
|
|
@ -174,9 +174,12 @@ void st_init_limits(struct pipe_screen *screen,
|
|||
pc = &c->Program[MESA_SHADER_TESS_EVAL];
|
||||
options = &c->ShaderCompilerOptions[MESA_SHADER_TESS_EVAL];
|
||||
break;
|
||||
case PIPE_SHADER_COMPUTE:
|
||||
pc = &c->Program[MESA_SHADER_COMPUTE];
|
||||
options = &c->ShaderCompilerOptions[MESA_SHADER_COMPUTE];
|
||||
break;
|
||||
default:
|
||||
/* compute shader, etc. */
|
||||
continue;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
pc->MaxTextureImageUnits =
|
||||
|
|
|
@ -158,6 +158,9 @@ delete_basic_variant(struct st_context *st, struct st_basic_variant *v,
|
|||
case GL_GEOMETRY_PROGRAM_NV:
|
||||
cso_delete_geometry_shader(st->cso_context, v->driver_shader);
|
||||
break;
|
||||
case GL_COMPUTE_PROGRAM_NV:
|
||||
cso_delete_compute_shader(st->cso_context, v->driver_shader);
|
||||
break;
|
||||
default:
|
||||
assert(!"this shouldn't occur");
|
||||
}
|
||||
|
@ -192,6 +195,30 @@ st_release_basic_variants(struct st_context *st, GLenum target,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free all variants of a compute program.
|
||||
*/
|
||||
void
|
||||
st_release_cp_variants(struct st_context *st, struct st_compute_program *stcp)
|
||||
{
|
||||
struct st_basic_variant **variants = &stcp->variants;
|
||||
struct st_basic_variant *v;
|
||||
|
||||
for (v = *variants; v; ) {
|
||||
struct st_basic_variant *next = v->next;
|
||||
delete_basic_variant(st, v, stcp->Base.Base.Target);
|
||||
v = next;
|
||||
}
|
||||
|
||||
*variants = NULL;
|
||||
|
||||
if (stcp->tgsi.prog) {
|
||||
ureg_free_tokens(stcp->tgsi.prog);
|
||||
stcp->tgsi.prog = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translate a vertex program.
|
||||
*/
|
||||
|
@ -1394,6 +1421,57 @@ st_translate_tesseval_program(struct st_context *st,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translate a compute program to create a new variant.
|
||||
*/
|
||||
bool
|
||||
st_translate_compute_program(struct st_context *st,
|
||||
struct st_compute_program *stcp)
|
||||
{
|
||||
return false; /* will be updated in the next commit */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get/create compute program variant.
|
||||
*/
|
||||
struct st_basic_variant *
|
||||
st_get_cp_variant(struct st_context *st,
|
||||
struct pipe_compute_state *tgsi,
|
||||
struct st_basic_variant **variants)
|
||||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
struct st_basic_variant *v;
|
||||
struct st_basic_variant_key key;
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.st = st->has_shareable_shaders ? NULL : st;
|
||||
|
||||
/* Search for existing variant */
|
||||
for (v = *variants; v; v = v->next) {
|
||||
if (memcmp(&v->key, &key, sizeof(key)) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!v) {
|
||||
/* create new */
|
||||
v = CALLOC_STRUCT(st_basic_variant);
|
||||
if (v) {
|
||||
/* fill in new variant */
|
||||
v->driver_shader = pipe->create_compute_state(pipe, tgsi);
|
||||
v->key = key;
|
||||
|
||||
/* insert into list */
|
||||
v->next = *variants;
|
||||
*variants = v;
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Vert/Geom/Frag programs have per-context variants. Free all the
|
||||
* variants attached to the given program which match the given context.
|
||||
|
@ -1449,14 +1527,17 @@ destroy_program_variants(struct st_context *st, struct gl_program *target)
|
|||
case GL_GEOMETRY_PROGRAM_NV:
|
||||
case GL_TESS_CONTROL_PROGRAM_NV:
|
||||
case GL_TESS_EVALUATION_PROGRAM_NV:
|
||||
case GL_COMPUTE_PROGRAM_NV:
|
||||
{
|
||||
struct st_geometry_program *gp = (struct st_geometry_program*)target;
|
||||
struct st_tessctrl_program *tcp = (struct st_tessctrl_program*)target;
|
||||
struct st_tesseval_program *tep = (struct st_tesseval_program*)target;
|
||||
struct st_compute_program *cp = (struct st_compute_program*)target;
|
||||
struct st_basic_variant **variants =
|
||||
target->Target == GL_GEOMETRY_PROGRAM_NV ? &gp->variants :
|
||||
target->Target == GL_TESS_CONTROL_PROGRAM_NV ? &tcp->variants :
|
||||
target->Target == GL_TESS_EVALUATION_PROGRAM_NV ? &tep->variants :
|
||||
target->Target == GL_COMPUTE_PROGRAM_NV ? &cp->variants :
|
||||
NULL;
|
||||
struct st_basic_variant *v, **prevPtr = variants;
|
||||
|
||||
|
@ -1513,6 +1594,7 @@ destroy_shader_program_variants_cb(GLuint key, void *data, void *userData)
|
|||
case GL_GEOMETRY_SHADER:
|
||||
case GL_TESS_CONTROL_SHADER:
|
||||
case GL_TESS_EVALUATION_SHADER:
|
||||
case GL_COMPUTE_SHADER:
|
||||
{
|
||||
destroy_program_variants(st, shader->Program);
|
||||
}
|
||||
|
@ -1629,6 +1711,12 @@ st_precompile_shader_variant(struct st_context *st,
|
|||
break;
|
||||
}
|
||||
|
||||
case GL_COMPUTE_PROGRAM_NV: {
|
||||
struct st_compute_program *p = (struct st_compute_program *)prog;
|
||||
st_get_cp_variant(st, &p->tgsi, &p->variants);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
@ -231,6 +231,18 @@ struct st_tesseval_program
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* Derived from Mesa gl_compute_program:
|
||||
*/
|
||||
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;
|
||||
|
||||
struct st_basic_variant *variants;
|
||||
};
|
||||
|
||||
|
||||
static inline struct st_fragment_program *
|
||||
st_fragment_program( struct gl_fragment_program *fp )
|
||||
|
@ -263,6 +275,12 @@ st_tesseval_program( struct gl_tess_eval_program *tep )
|
|||
return (struct st_tesseval_program *)tep;
|
||||
}
|
||||
|
||||
static inline struct st_compute_program *
|
||||
st_compute_program( struct gl_compute_program *cp )
|
||||
{
|
||||
return (struct st_compute_program *)cp;
|
||||
}
|
||||
|
||||
static inline void
|
||||
st_reference_vertprog(struct st_context *st,
|
||||
struct st_vertex_program **ptr,
|
||||
|
@ -313,6 +331,16 @@ st_reference_tesseprog(struct st_context *st,
|
|||
(struct gl_program *) prog);
|
||||
}
|
||||
|
||||
static inline void
|
||||
st_reference_compprog(struct st_context *st,
|
||||
struct st_compute_program **ptr,
|
||||
struct st_compute_program *prog)
|
||||
{
|
||||
_mesa_reference_program(st->ctx,
|
||||
(struct gl_program **) ptr,
|
||||
(struct gl_program *) prog);
|
||||
}
|
||||
|
||||
/**
|
||||
* This defines mapping from Mesa VARYING_SLOTs to TGSI GENERIC slots.
|
||||
*/
|
||||
|
@ -350,6 +378,11 @@ st_get_fp_variant(struct st_context *st,
|
|||
struct st_fragment_program *stfp,
|
||||
const struct st_fp_variant_key *key);
|
||||
|
||||
extern struct st_basic_variant *
|
||||
st_get_cp_variant(struct st_context *st,
|
||||
struct pipe_compute_state *tgsi,
|
||||
struct st_basic_variant **variants);
|
||||
|
||||
extern struct st_basic_variant *
|
||||
st_get_basic_variant(struct st_context *st,
|
||||
unsigned pipe_shader,
|
||||
|
@ -364,6 +397,10 @@ extern void
|
|||
st_release_fp_variants( struct st_context *st,
|
||||
struct st_fragment_program *stfp );
|
||||
|
||||
extern void
|
||||
st_release_cp_variants(struct st_context *st,
|
||||
struct st_compute_program *stcp);
|
||||
|
||||
extern void
|
||||
st_release_basic_variants(struct st_context *st, GLenum target,
|
||||
struct st_basic_variant **variants,
|
||||
|
@ -392,6 +429,10 @@ extern bool
|
|||
st_translate_tesseval_program(struct st_context *st,
|
||||
struct st_tesseval_program *sttep);
|
||||
|
||||
extern bool
|
||||
st_translate_compute_program(struct st_context *st,
|
||||
struct st_compute_program *stcp);
|
||||
|
||||
extern void
|
||||
st_print_current_vertex_program(void);
|
||||
|
||||
|
|
Loading…
Reference in New Issue