From 213e288e78bf5b0fb0a996cc17dfd959756c2c53 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 29 Nov 2010 19:15:03 +0800 Subject: [PATCH] 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. --- src/gallium/state_trackers/vega/asm_fill.h | 29 ++-- .../state_trackers/vega/shaders_cache.c | 153 ++++++++---------- .../state_trackers/vega/shaders_cache.h | 55 +++++-- 3 files changed, 130 insertions(+), 107 deletions(-) diff --git a/src/gallium/state_trackers/vega/asm_fill.h b/src/gallium/state_trackers/vega/asm_fill.h index 9a06982c6a6..3f09e73f194 100644 --- a/src/gallium/state_trackers/vega/asm_fill.h +++ b/src/gallium/state_trackers/vega/asm_fill.h @@ -410,8 +410,8 @@ struct shader_asm_info { }; -static const struct shader_asm_info shaders_asm[] = { - /* fills */ +/* paint types */ +static const struct shader_asm_info shaders_paint_asm[] = { {VEGA_SOLID_FILL_SHADER, solid_fill, VG_FALSE, 0, 1, 0, 0, 0, 0}, {VEGA_LINEAR_GRADIENT_SHADER, linear_grad, @@ -419,20 +419,26 @@ static const struct shader_asm_info shaders_asm[] = { {VEGA_RADIAL_GRADIENT_SHADER, radial_grad, VG_TRUE, 0, 5, 0, 1, 0, 6}, {VEGA_PATTERN_SHADER, pattern, - VG_TRUE, 1, 4, 0, 1, 0, 5}, + VG_TRUE, 1, 4, 0, 1, 0, 5} +}; - /* image draw modes */ +/* image draw modes */ +static const struct shader_asm_info shaders_image_asm[] = { {VEGA_IMAGE_NORMAL_SHADER, image_normal, VG_TRUE, 0, 0, 3, 1, 0, 0}, {VEGA_IMAGE_MULTIPLY_SHADER, image_multiply, VG_TRUE, 0, 0, 3, 1, 0, 2}, {VEGA_IMAGE_STENCIL_SHADER, image_stencil, - VG_TRUE, 0, 0, 3, 1, 0, 2}, + VG_TRUE, 0, 0, 3, 1, 0, 2} +}; +static const struct shader_asm_info shaders_mask_asm[] = { {VEGA_MASK_SHADER, mask, - VG_TRUE, 0, 0, 1, 1, 0, 2}, + VG_TRUE, 0, 0, 1, 1, 0, 2} +}; - /* extra blend modes */ +/* extra blend modes */ +static const struct shader_asm_info shaders_blend_asm[] = { {VEGA_BLEND_MULTIPLY_SHADER, blend_multiply, VG_TRUE, 1, 1, 2, 1, 0, 5}, {VEGA_BLEND_SCREEN_SHADER, blend_screen, @@ -441,15 +447,20 @@ static const struct shader_asm_info shaders_asm[] = { VG_TRUE, 1, 1, 2, 1, 0, 6}, {VEGA_BLEND_LIGHTEN_SHADER, blend_lighten, VG_TRUE, 1, 1, 2, 1, 0, 6}, +}; - /* premultiply */ +/* premultiply */ +static const struct shader_asm_info shaders_premultiply_asm[] = { {VEGA_PREMULTIPLY_SHADER, premultiply, VG_FALSE, 0, 0, 0, 0, 0, 1}, {VEGA_UNPREMULTIPLY_SHADER, unpremultiply, VG_FALSE, 0, 0, 0, 0, 0, 1}, +}; - /* color transform to black and white */ +/* color transform to black and white */ +static const struct shader_asm_info shaders_bw_asm[] = { {VEGA_BW_SHADER, color_bw, VG_FALSE, 1, 1, 0, 0, 0, 3}, }; + #endif 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); diff --git a/src/gallium/state_trackers/vega/shaders_cache.h b/src/gallium/state_trackers/vega/shaders_cache.h index feca58b61a9..2d0c2da30ec 100644 --- a/src/gallium/state_trackers/vega/shaders_cache.h +++ b/src/gallium/state_trackers/vega/shaders_cache.h @@ -33,26 +33,51 @@ struct pipe_context; struct tgsi_token; struct shaders_cache; +#define _SHADERS_PAINT_BITS 3 +#define _SHADERS_IMAGE_BITS 2 +#define _SHADERS_MASK_BITS 1 +#define _SHADERS_BLEND_BITS 3 +#define _SHADERS_PREMULTIPLY_BITS 2 +#define _SHADERS_BW_BITS 1 + +#define SHADERS_PAINT_SHIFT (0) +#define SHADERS_IMAGE_SHIFT (SHADERS_PAINT_SHIFT + _SHADERS_PAINT_BITS) +#define SHADERS_MASK_SHIFT (SHADERS_IMAGE_SHIFT + _SHADERS_IMAGE_BITS) +#define SHADERS_BLEND_SHIFT (SHADERS_MASK_SHIFT + _SHADERS_MASK_BITS) +#define SHADERS_PREMULTIPLY_SHIFT (SHADERS_BLEND_SHIFT + _SHADERS_BLEND_BITS) +#define SHADERS_BW_SHIFT (SHADERS_PREMULTIPLY_SHIFT + _SHADERS_PREMULTIPLY_BITS) + +#define _SHADERS_GET_STAGE(stage, id) \ + ((id) & (((1 << _SHADERS_ ## stage ## _BITS) - 1) << SHADERS_ ## stage ## _SHIFT)) + +#define SHADERS_GET_PAINT_SHADER(id) _SHADERS_GET_STAGE(PAINT, id) +#define SHADERS_GET_IMAGE_SHADER(id) _SHADERS_GET_STAGE(IMAGE, id) +#define SHADERS_GET_MASK_SHADER(id) _SHADERS_GET_STAGE(MASK, id) +#define SHADERS_GET_BLEND_SHADER(id) _SHADERS_GET_STAGE(BLEND, id) +#define SHADERS_GET_PREMULTIPLY_SHADER(id) _SHADERS_GET_STAGE(PREMULTIPLY, id) +#define SHADERS_GET_BW_SHADER(id) _SHADERS_GET_STAGE(BW, id) + enum VegaShaderType { - VEGA_SOLID_FILL_SHADER = 1 << 0, - VEGA_LINEAR_GRADIENT_SHADER = 1 << 1, - VEGA_RADIAL_GRADIENT_SHADER = 1 << 2, - VEGA_PATTERN_SHADER = 1 << 3, - VEGA_IMAGE_NORMAL_SHADER = 1 << 4, - VEGA_IMAGE_MULTIPLY_SHADER = 1 << 5, - VEGA_IMAGE_STENCIL_SHADER = 1 << 6, + VEGA_SOLID_FILL_SHADER = 1 << SHADERS_PAINT_SHIFT, + VEGA_LINEAR_GRADIENT_SHADER = 2 << SHADERS_PAINT_SHIFT, + VEGA_RADIAL_GRADIENT_SHADER = 3 << SHADERS_PAINT_SHIFT, + VEGA_PATTERN_SHADER = 4 << SHADERS_PAINT_SHIFT, + + VEGA_IMAGE_NORMAL_SHADER = 1 << SHADERS_IMAGE_SHIFT, + VEGA_IMAGE_MULTIPLY_SHADER = 2 << SHADERS_IMAGE_SHIFT, + VEGA_IMAGE_STENCIL_SHADER = 3 << SHADERS_IMAGE_SHIFT, - VEGA_MASK_SHADER = 1 << 7, + VEGA_MASK_SHADER = 1 << SHADERS_MASK_SHIFT, - VEGA_BLEND_MULTIPLY_SHADER = 1 << 8, - VEGA_BLEND_SCREEN_SHADER = 1 << 9, - VEGA_BLEND_DARKEN_SHADER = 1 << 10, - VEGA_BLEND_LIGHTEN_SHADER = 1 << 11, + VEGA_BLEND_MULTIPLY_SHADER = 1 << SHADERS_BLEND_SHIFT, + VEGA_BLEND_SCREEN_SHADER = 2 << SHADERS_BLEND_SHIFT, + VEGA_BLEND_DARKEN_SHADER = 3 << SHADERS_BLEND_SHIFT, + VEGA_BLEND_LIGHTEN_SHADER = 4 << SHADERS_BLEND_SHIFT, - VEGA_PREMULTIPLY_SHADER = 1 << 12, - VEGA_UNPREMULTIPLY_SHADER = 1 << 13, + VEGA_PREMULTIPLY_SHADER = 1 << SHADERS_PREMULTIPLY_SHIFT, + VEGA_UNPREMULTIPLY_SHADER = 2 << SHADERS_PREMULTIPLY_SHIFT, - VEGA_BW_SHADER = 1 << 14 + VEGA_BW_SHADER = 1 << SHADERS_BW_SHIFT }; struct vg_shader { -- 2.30.2