aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/vega/shaders_cache.c
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2010-11-29 19:15:03 +0800
committerChia-I Wu <[email protected]>2010-12-01 11:23:52 +0800
commit213e288e78bf5b0fb0a996cc17dfd959756c2c53 (patch)
treed24ba0185852f83d40d84364855747fe9ba31950 /src/gallium/state_trackers/vega/shaders_cache.c
parent30cab4b6cbf741e1ae727bfaed10cc3772e4dff9 (diff)
st/vega: More flexible shader selection.
Divide bits of VegaShaderType into 6 groups: paint, image, mask, fill, premultiply, and bw. Each group represents a stage. At most one shader from each group will be selected when constructing the final fragment shader.
Diffstat (limited to 'src/gallium/state_trackers/vega/shaders_cache.c')
-rw-r--r--src/gallium/state_trackers/vega/shaders_cache.c153
1 files changed, 70 insertions, 83 deletions
diff --git a/src/gallium/state_trackers/vega/shaders_cache.c b/src/gallium/state_trackers/vega/shaders_cache.c
index e002a7ed428..49b451c1179 100644
--- a/src/gallium/state_trackers/vega/shaders_cache.c
+++ b/src/gallium/state_trackers/vega/shaders_cache.c
@@ -50,8 +50,8 @@
/* Essentially we construct an ubber-shader based on the state
* of the pipeline. The stages are:
- * 1) Fill (mandatory, solid color/gradient/pattern/image draw)
- * 2) Image composition (image mode multiply and stencil)
+ * 1) Paint generation (color/gradient/pattern)
+ * 2) Image composition (normal/multiply/stencil)
* 3) Mask
* 4) Extended blend (multiply/screen/darken/lighten)
* 5) Premultiply/Unpremultiply
@@ -86,13 +86,6 @@ static INLINE struct tgsi_token *tokens_from_assembly(const char *txt, int num_t
return tokens;
}
-#define ALL_FILLS (VEGA_SOLID_FILL_SHADER | \
- VEGA_LINEAR_GRADIENT_SHADER | \
- VEGA_RADIAL_GRADIENT_SHADER | \
- VEGA_PATTERN_SHADER | \
- VEGA_IMAGE_NORMAL_SHADER)
-
-
/*
static const char max_shader_preamble[] =
"FRAG\n"
@@ -257,98 +250,92 @@ create_shader(struct pipe_context *pipe,
int id,
struct pipe_shader_state *shader)
{
- int idx = 0;
+ int idx = 0, sh;
const struct shader_asm_info * shaders[SHADER_STAGES];
- /* the shader has to have a fill */
- debug_assert(id & ALL_FILLS);
-
/* first stage */
- if (id & VEGA_SOLID_FILL_SHADER) {
- debug_assert(idx == 0);
- shaders[idx] = &shaders_asm[0];
- debug_assert(shaders_asm[0].id == VEGA_SOLID_FILL_SHADER);
- ++idx;
- }
- if ((id & VEGA_LINEAR_GRADIENT_SHADER)) {
- debug_assert(idx == 0);
- shaders[idx] = &shaders_asm[1];
- debug_assert(shaders_asm[1].id == VEGA_LINEAR_GRADIENT_SHADER);
- ++idx;
- }
- if ((id & VEGA_RADIAL_GRADIENT_SHADER)) {
- debug_assert(idx == 0);
- shaders[idx] = &shaders_asm[2];
- debug_assert(shaders_asm[2].id == VEGA_RADIAL_GRADIENT_SHADER);
- ++idx;
- }
- if ((id & VEGA_PATTERN_SHADER)) {
- debug_assert(idx == 0);
- debug_assert(shaders_asm[3].id == VEGA_PATTERN_SHADER);
- shaders[idx] = &shaders_asm[3];
- ++idx;
- }
- if ((id & VEGA_IMAGE_NORMAL_SHADER)) {
- debug_assert(idx == 0);
- debug_assert(shaders_asm[4].id == VEGA_IMAGE_NORMAL_SHADER);
- shaders[idx] = &shaders_asm[4];
- ++idx;
+ sh = SHADERS_GET_PAINT_SHADER(id);
+ switch (sh << SHADERS_PAINT_SHIFT) {
+ case VEGA_SOLID_FILL_SHADER:
+ case VEGA_LINEAR_GRADIENT_SHADER:
+ case VEGA_RADIAL_GRADIENT_SHADER:
+ case VEGA_PATTERN_SHADER:
+ shaders[idx] = &shaders_paint_asm[(sh >> SHADERS_PAINT_SHIFT) - 1];
+ assert(shaders[idx]->id == sh);
+ idx++;
+ break;
+ default:
+ break;
}
/* second stage */
- if ((id & VEGA_IMAGE_MULTIPLY_SHADER)) {
- debug_assert(shaders_asm[5].id == VEGA_IMAGE_MULTIPLY_SHADER);
- shaders[idx] = &shaders_asm[5];
- ++idx;
- } else if ((id & VEGA_IMAGE_STENCIL_SHADER)) {
- debug_assert(shaders_asm[6].id == VEGA_IMAGE_STENCIL_SHADER);
- shaders[idx] = &shaders_asm[6];
- ++idx;
+ sh = SHADERS_GET_IMAGE_SHADER(id);
+ switch (sh) {
+ case VEGA_IMAGE_NORMAL_SHADER:
+ case VEGA_IMAGE_MULTIPLY_SHADER:
+ case VEGA_IMAGE_STENCIL_SHADER:
+ shaders[idx] = &shaders_image_asm[(sh >> SHADERS_IMAGE_SHIFT) - 1];
+ assert(shaders[idx]->id == sh);
+ idx++;
+ break;
+ default:
+ break;
}
+ /* sanity check */
+ assert(idx == ((!sh || sh == VEGA_IMAGE_NORMAL_SHADER) ? 1 : 2));
+
/* third stage */
- if ((id & VEGA_MASK_SHADER)) {
- debug_assert(idx == 1);
- debug_assert(shaders_asm[7].id == VEGA_MASK_SHADER);
- shaders[idx] = &shaders_asm[7];
- ++idx;
+ sh = SHADERS_GET_MASK_SHADER(id);
+ switch (sh) {
+ case VEGA_MASK_SHADER:
+ shaders[idx] = &shaders_mask_asm[(sh >> SHADERS_MASK_SHIFT) - 1];
+ assert(shaders[idx]->id == sh);
+ idx++;
+ break;
+ default:
+ break;
}
/* fourth stage */
- if ((id & VEGA_BLEND_MULTIPLY_SHADER)) {
- debug_assert(shaders_asm[8].id == VEGA_BLEND_MULTIPLY_SHADER);
- shaders[idx] = &shaders_asm[8];
- ++idx;
- } else if ((id & VEGA_BLEND_SCREEN_SHADER)) {
- debug_assert(shaders_asm[9].id == VEGA_BLEND_SCREEN_SHADER);
- shaders[idx] = &shaders_asm[9];
- ++idx;
- } else if ((id & VEGA_BLEND_DARKEN_SHADER)) {
- debug_assert(shaders_asm[10].id == VEGA_BLEND_DARKEN_SHADER);
- shaders[idx] = &shaders_asm[10];
- ++idx;
- } else if ((id & VEGA_BLEND_LIGHTEN_SHADER)) {
- debug_assert(shaders_asm[11].id == VEGA_BLEND_LIGHTEN_SHADER);
- shaders[idx] = &shaders_asm[11];
- ++idx;
+ sh = SHADERS_GET_BLEND_SHADER(id);
+ switch (sh) {
+ case VEGA_BLEND_MULTIPLY_SHADER:
+ case VEGA_BLEND_SCREEN_SHADER:
+ case VEGA_BLEND_DARKEN_SHADER:
+ case VEGA_BLEND_LIGHTEN_SHADER:
+ shaders[idx] = &shaders_blend_asm[(sh >> SHADERS_BLEND_SHIFT) - 1];
+ assert(shaders[idx]->id == sh);
+ idx++;
+ break;
+ default:
+ break;
}
/* fifth stage */
- if ((id & VEGA_PREMULTIPLY_SHADER)) {
- debug_assert(shaders_asm[12].id == VEGA_PREMULTIPLY_SHADER);
- shaders[idx] = &shaders_asm[12];
- ++idx;
- } else if ((id & VEGA_UNPREMULTIPLY_SHADER)) {
- debug_assert(shaders_asm[13].id == VEGA_UNPREMULTIPLY_SHADER);
- shaders[idx] = &shaders_asm[13];
- ++idx;
+ sh = SHADERS_GET_PREMULTIPLY_SHADER(id);
+ switch (sh) {
+ case VEGA_PREMULTIPLY_SHADER:
+ case VEGA_UNPREMULTIPLY_SHADER:
+ shaders[idx] = &shaders_premultiply_asm[
+ (sh >> SHADERS_PREMULTIPLY_SHIFT) - 1];
+ assert(shaders[idx]->id == sh);
+ idx++;
+ break;
+ default:
+ break;
}
/* sixth stage */
- if ((id & VEGA_BW_SHADER)) {
- debug_assert(shaders_asm[14].id == VEGA_BW_SHADER);
- shaders[idx] = &shaders_asm[14];
- ++idx;
+ sh = SHADERS_GET_BW_SHADER(id);
+ switch (sh) {
+ case VEGA_BW_SHADER:
+ shaders[idx] = &shaders_bw_asm[(sh >> SHADERS_BW_SHIFT) - 1];
+ assert(shaders[idx]->id == sh);
+ idx++;
+ break;
+ default:
+ break;
}
return combine_shaders(shaders, idx, pipe, shader);