st/mesa: translate fragment shaders into TGSI when we get them

Reviewed-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
Tested-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
Marek Olšák
2015-10-05 03:26:48 +02:00
parent 46021ace51
commit a907b5dd16
4 changed files with 55 additions and 37 deletions

View File

@@ -234,6 +234,8 @@ st_program_string_notify( struct gl_context *ctx,
struct st_fragment_program *stfp = (struct st_fragment_program *) prog; struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
st_release_fp_variants(st, stfp); st_release_fp_variants(st, stfp);
if (!st_translate_fragment_program(st, stfp))
return false;
if (st->fp == stfp) if (st->fp == stfp)
st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM; st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;

View File

@@ -98,7 +98,7 @@ st_print_current(void)
if (st->vp->Base.Base.Parameters) if (st->vp->Base.Base.Parameters)
_mesa_print_parameter_list(st->vp->Base.Base.Parameters); _mesa_print_parameter_list(st->vp->Base.Base.Parameters);
tgsi_dump( st->fp->variants[0].tgsi.tokens, 0 ); tgsi_dump(st->fp->tgsi.tokens, 0);
if (st->fp->Base.Base.Parameters) if (st->fp->Base.Base.Parameters)
_mesa_print_parameter_list(st->fp->Base.Base.Parameters); _mesa_print_parameter_list(st->fp->Base.Base.Parameters);
} }

View File

@@ -114,8 +114,6 @@ delete_fp_variant(struct st_context *st, struct st_fp_variant *fpv)
cso_delete_fragment_shader(st->cso_context, fpv->driver_shader); cso_delete_fragment_shader(st->cso_context, fpv->driver_shader);
if (fpv->parameters) if (fpv->parameters)
_mesa_free_parameter_list(fpv->parameters); _mesa_free_parameter_list(fpv->parameters);
if (fpv->tgsi.tokens)
ureg_free_tokens(fpv->tgsi.tokens);
free(fpv); free(fpv);
} }
@@ -135,6 +133,11 @@ st_release_fp_variants(struct st_context *st, struct st_fragment_program *stfp)
} }
stfp->variants = NULL; stfp->variants = NULL;
if (stfp->tgsi.tokens) {
ureg_free_tokens(stfp->tgsi.tokens);
stfp->tgsi.tokens = NULL;
}
} }
@@ -531,17 +534,12 @@ st_translate_interp(enum glsl_interp_qualifier glsl_qual, bool is_color)
/** /**
* Translate a Mesa fragment shader into a TGSI shader using extra info in * Translate a Mesa fragment shader into a TGSI shader.
* the key.
* \return new fragment program variant
*/ */
static struct st_fp_variant * bool
st_translate_fragment_program(struct st_context *st, st_translate_fragment_program(struct st_context *st,
struct st_fragment_program *stfp, struct st_fragment_program *stfp)
const struct st_fp_variant_key *key)
{ {
struct pipe_context *pipe = st->pipe;
struct st_fp_variant *variant = CALLOC_STRUCT(st_fp_variant);
GLuint outputMapping[FRAG_RESULT_MAX]; GLuint outputMapping[FRAG_RESULT_MAX];
GLuint inputMapping[VARYING_SLOT_MAX]; GLuint inputMapping[VARYING_SLOT_MAX];
GLuint inputSlotToAttr[VARYING_SLOT_MAX]; GLuint inputSlotToAttr[VARYING_SLOT_MAX];
@@ -561,10 +559,6 @@ st_translate_fragment_program(struct st_context *st,
ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
uint fs_num_outputs = 0; uint fs_num_outputs = 0;
if (!variant)
return NULL;
assert(!(key->bitmap && key->drawpixels));
memset(inputSlotToAttr, ~0, sizeof(inputSlotToAttr)); memset(inputSlotToAttr, ~0, sizeof(inputSlotToAttr));
if (!stfp->glsl_to_tgsi) if (!stfp->glsl_to_tgsi)
@@ -772,10 +766,8 @@ st_translate_fragment_program(struct st_context *st,
} }
ureg = ureg_create_with_screen(TGSI_PROCESSOR_FRAGMENT, st->pipe->screen); ureg = ureg_create_with_screen(TGSI_PROCESSOR_FRAGMENT, st->pipe->screen);
if (ureg == NULL) { if (ureg == NULL)
free(variant); return false;
return NULL;
}
if (ST_DEBUG & DEBUG_MESA) { if (ST_DEBUG & DEBUG_MESA) {
_mesa_print_program(&stfp->Base.Base); _mesa_print_program(&stfp->Base.Base);
@@ -845,8 +837,26 @@ st_translate_fragment_program(struct st_context *st,
fs_output_semantic_name, fs_output_semantic_name,
fs_output_semantic_index); fs_output_semantic_index);
variant->tgsi.tokens = ureg_get_tokens(ureg, NULL); stfp->tgsi.tokens = ureg_get_tokens(ureg, NULL);
ureg_destroy(ureg); ureg_destroy(ureg);
return stfp->tgsi.tokens != NULL;
}
static struct st_fp_variant *
st_create_fp_variant(struct st_context *st,
struct st_fragment_program *stfp,
const struct st_fp_variant_key *key)
{
struct pipe_context *pipe = st->pipe;
struct st_fp_variant *variant = CALLOC_STRUCT(st_fp_variant);
struct pipe_shader_state tgsi = {0};
if (!variant)
return NULL;
tgsi.tokens = stfp->tgsi.tokens;
assert(!(key->bitmap && key->drawpixels));
/* Emulate features. */ /* Emulate features. */
if (key->clamp_color || key->persample_shading) { if (key->clamp_color || key->persample_shading) {
@@ -855,12 +865,11 @@ st_translate_fragment_program(struct st_context *st,
(key->clamp_color ? TGSI_EMU_CLAMP_COLOR_OUTPUTS : 0) | (key->clamp_color ? TGSI_EMU_CLAMP_COLOR_OUTPUTS : 0) |
(key->persample_shading ? TGSI_EMU_FORCE_PERSAMPLE_INTERP : 0); (key->persample_shading ? TGSI_EMU_FORCE_PERSAMPLE_INTERP : 0);
tokens = tgsi_emulate(variant->tgsi.tokens, flags); tokens = tgsi_emulate(tgsi.tokens, flags);
if (tokens) { if (tokens)
tgsi_free_tokens(variant->tgsi.tokens); tgsi.tokens = tokens;
variant->tgsi.tokens = tokens; else
} else
fprintf(stderr, "mesa: cannot emulate deprecated features\n"); fprintf(stderr, "mesa: cannot emulate deprecated features\n");
} }
@@ -870,15 +879,16 @@ st_translate_fragment_program(struct st_context *st,
variant->bitmap_sampler = ffs(~stfp->Base.Base.SamplersUsed) - 1; variant->bitmap_sampler = ffs(~stfp->Base.Base.SamplersUsed) - 1;
tokens = st_get_bitmap_shader(variant->tgsi.tokens, tokens = st_get_bitmap_shader(tgsi.tokens,
variant->bitmap_sampler, variant->bitmap_sampler,
st->needs_texcoord_semantic, st->needs_texcoord_semantic,
st->bitmap.tex_format == st->bitmap.tex_format ==
PIPE_FORMAT_L8_UNORM); PIPE_FORMAT_L8_UNORM);
if (tokens) { if (tokens) {
tgsi_free_tokens(variant->tgsi.tokens); if (tgsi.tokens != stfp->tgsi.tokens)
variant->tgsi.tokens = tokens; tgsi_free_tokens(tgsi.tokens);
tgsi.tokens = tokens;
variant->parameters = variant->parameters =
_mesa_clone_parameter_list(stfp->Base.Base.Parameters); _mesa_clone_parameter_list(stfp->Base.Base.Parameters);
} else } else
@@ -923,7 +933,7 @@ st_translate_fragment_program(struct st_context *st,
state); state);
} }
tokens = st_get_drawpix_shader(variant->tgsi.tokens, tokens = st_get_drawpix_shader(tgsi.tokens,
st->needs_texcoord_semantic, st->needs_texcoord_semantic,
key->scaleAndBias, scale_const, key->scaleAndBias, scale_const,
bias_const, key->pixelMaps, bias_const, key->pixelMaps,
@@ -932,24 +942,27 @@ st_translate_fragment_program(struct st_context *st,
texcoord_const); texcoord_const);
if (tokens) { if (tokens) {
tgsi_free_tokens(variant->tgsi.tokens); if (tgsi.tokens != stfp->tgsi.tokens)
variant->tgsi.tokens = tokens; tgsi_free_tokens(tgsi.tokens);
tgsi.tokens = tokens;
} else } else
fprintf(stderr, "mesa: cannot create a shader for glDrawPixels\n"); fprintf(stderr, "mesa: cannot create a shader for glDrawPixels\n");
} }
if (ST_DEBUG & DEBUG_TGSI) { if (ST_DEBUG & DEBUG_TGSI) {
tgsi_dump(variant->tgsi.tokens, 0/*TGSI_DUMP_VERBOSE*/); tgsi_dump(tgsi.tokens, 0);
debug_printf("\n"); debug_printf("\n");
} }
/* fill in variant */ /* fill in variant */
variant->driver_shader = pipe->create_fs_state(pipe, &variant->tgsi); variant->driver_shader = pipe->create_fs_state(pipe, &tgsi);
variant->key = *key; variant->key = *key;
if (tgsi.tokens != stfp->tgsi.tokens)
tgsi_free_tokens(tgsi.tokens);
return variant; return variant;
} }
/** /**
* Translate fragment program if needed. * Translate fragment program if needed.
*/ */
@@ -969,7 +982,7 @@ st_get_fp_variant(struct st_context *st,
if (!fpv) { if (!fpv) {
/* create new */ /* create new */
fpv = st_translate_fragment_program(st, stfp, key); fpv = st_create_fp_variant(st, stfp, key);
if (fpv) { if (fpv) {
/* insert into list */ /* insert into list */
fpv->next = stfp->variants; fpv->next = stfp->variants;

View File

@@ -76,8 +76,6 @@ struct st_fp_variant
/** Parameters which generated this version of fragment program */ /** Parameters which generated this version of fragment program */
struct st_fp_variant_key key; struct st_fp_variant_key key;
struct pipe_shader_state tgsi;
/** Driver's compiled shader */ /** Driver's compiled shader */
void *driver_shader; void *driver_shader;
@@ -100,6 +98,7 @@ struct st_fp_variant
struct st_fragment_program struct st_fragment_program
{ {
struct gl_fragment_program Base; struct gl_fragment_program Base;
struct pipe_shader_state tgsi;
struct glsl_to_tgsi_visitor* glsl_to_tgsi; struct glsl_to_tgsi_visitor* glsl_to_tgsi;
struct st_fp_variant *variants; struct st_fp_variant *variants;
@@ -439,6 +438,10 @@ extern bool
st_translate_vertex_program(struct st_context *st, st_translate_vertex_program(struct st_context *st,
struct st_vertex_program *stvp); struct st_vertex_program *stvp);
extern bool
st_translate_fragment_program(struct st_context *st,
struct st_fragment_program *stfp);
extern void extern void
st_print_current_vertex_program(void); st_print_current_vertex_program(void);