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:
@@ -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;
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user