Hello, This is just a report about the work i am doing.
2 days ago i began to study the vega state tracker to understand better and help a bit since there i already fix some bugs. So right now i am implementing the advanced blending extension[1]. This extension include many blending methods supported in authoring tools & file formats like SVG 1.2. I just implemented right now 2 blend operations in next days i am finishing all operation methods. [1]. http://www.khronos.org/registry/vg/extensions/KHR/advanced_blending.txt Igor diff --git a/include/VG/openvg.h b/include/VG/openvg.h index 60167e4..2a6c510 100644 --- a/include/VG/openvg.h +++ b/include/VG/openvg.h @@ -444,6 +444,8 @@ typedef enum { VG_BLEND_DARKEN = 0x2007, VG_BLEND_LIGHTEN = 0x2008, VG_BLEND_ADDITIVE = 0x2009, + VG_BLEND_SUBTRACT_KHR = 0x2017, + VG_BLEND_INVERT_KHR = 0x2018, VG_BLEND_MODE_FORCE_SIZE = VG_MAX_ENUM } VGBlendMode; diff --git a/src/gallium/state_trackers/vega/api_params.c b/src/gallium/state_trackers/vega/api_params.c index db77fd9..0bc5e09 100644 --- a/src/gallium/state_trackers/vega/api_params.c +++ b/src/gallium/state_trackers/vega/api_params.c @@ -160,7 +160,7 @@ void vgSeti (VGParamType type, VGint value) break; case VG_BLEND_MODE: if (value < VG_BLEND_SRC || - value > VG_BLEND_ADDITIVE) + value > VG_BLEND_INVERT_KHR) error = VG_ILLEGAL_ARGUMENT_ERROR; else { ctx->state.dirty |= BLEND_DIRTY; diff --git a/src/gallium/state_trackers/vega/asm_fill.h b/src/gallium/state_trackers/vega/asm_fill.h index 2f394ad..47c8b9d 100644 --- a/src/gallium/state_trackers/vega/asm_fill.h +++ b/src/gallium/state_trackers/vega/asm_fill.h @@ -164,6 +164,30 @@ static const char blend_lighten_asm[] = "SUB TEMP[1].w, TEMP[3], TEMP[2]\n" "MOV %s, TEMP[1]\n"; +static const char blend_subtract_khr_asm[] = + "TEX TEMP[1], IN[0], SAMP[2], 2D\n" + "SUB TEMP[1], TEMP[1], TEMP[0]\n" + "STR TEMP[2]\n" + "NOT TEMP[2]\n" + "MAX TEMP[1], TEMP[1], TEMP[2]\n" + "MUL TEMP[2], TEMP[0].wwww, TEMP[1].wwww\n" + "ADD TEMP[3], TEMP[0].wwww, TEMP[1].wwww\n" + "SUB TEMP[1].w, TEMP[3], TEMP[2]\n" + "MOV %s, TEMP[0]\n"; + +static const char blend_invert_khr_asm[] = + "TEX TEMP[1], IN[0], SAMP[2], 2D\n" + "SUB TEMP[2], CONST[0].yyyy, TEMP[0].wwww\n" + "SUB TEMP[3], CONST[0].yyyy, TEMP[1]\n" + "MUL TEMP[2].xyz, TEMP[1], TEMP[2].wwww\n" + "MUL TEMP[3].xyz, TEMP[0].wwww, TEMP[3]\n" + "ADD TEMP[0], TEMP[2], TEMP[3]\n" + "MUL TEMP[2], TEMP[0].wwww, TEMP[1].wwww\n" + "ADD TEMP[3], TEMP[0].wwww, TEMP[1].wwww\n" + "SUB TEMP[1].w, TEMP[3], TEMP[2]\n" + "MOV %s, TEMP[0]\n"; + + static const char premultiply_asm[] = "MUL TEMP[0].xyz, TEMP[0], TEMP[0].wwww\n"; @@ -224,14 +248,18 @@ static const struct shader_asm_info shaders_asm[] = { VG_TRUE, 0, 0, 1, 1, 0, 2}, /* extra blend modes */ - {VEGA_BLEND_MULTIPLY_SHADER, 200, blend_multiply_asm, + {VEGA_BLEND_MULTIPLY_SHADER, 200, blend_multiply_asm, VG_TRUE, 1, 1, 2, 1, 0, 5}, - {VEGA_BLEND_SCREEN_SHADER, 200, blend_screen_asm, + {VEGA_BLEND_SCREEN_SHADER, 200, blend_screen_asm, VG_TRUE, 0, 0, 2, 1, 0, 4}, - {VEGA_BLEND_DARKEN_SHADER, 200, blend_darken_asm, + {VEGA_BLEND_DARKEN_SHADER, 200, blend_darken_asm, VG_TRUE, 1, 1, 2, 1, 0, 6}, - {VEGA_BLEND_LIGHTEN_SHADER, 200, blend_lighten_asm, + {VEGA_BLEND_LIGHTEN_SHADER, 200, blend_lighten_asm, VG_TRUE, 1, 1, 2, 1, 0, 6}, + {VEGA_BLEND_SUBTRACT_KHR_SHADER, 200, blend_subtract_khr_asm, + VG_TRUE, 0, 0, 2, 1, 0, 4}, + {VEGA_BLEND_INVERT_KHR_SHADER, 200, blend_invert_khr_asm, + VG_TRUE, 1, 1, 2, 1, 0, 4}, /* premultiply */ {VEGA_PREMULTIPLY_SHADER, 100, premultiply_asm, diff --git a/src/gallium/state_trackers/vega/shader.c b/src/gallium/state_trackers/vega/shader.c index 8e59d53..b25cbf2 100644 --- a/src/gallium/state_trackers/vega/shader.c +++ b/src/gallium/state_trackers/vega/shader.c @@ -126,7 +126,9 @@ static VGint blend_bind_samplers(struct vg_context *ctx, if (bmode == VG_BLEND_MULTIPLY || bmode == VG_BLEND_SCREEN || bmode == VG_BLEND_DARKEN || - bmode == VG_BLEND_LIGHTEN) { + bmode == VG_BLEND_LIGHTEN || + bmode == VG_BLEND_SUBTRACT_KHR || + bmode == VG_BLEND_INVERT_KHR) { struct st_framebuffer *stfb = ctx->draw_buffer; vg_prepare_blend_surface(ctx); @@ -261,6 +263,12 @@ static void setup_shader_program(struct shader *shader) case VG_BLEND_LIGHTEN: shader_id |= VEGA_BLEND_LIGHTEN_SHADER; break; + case VG_BLEND_SUBTRACT_KHR: + shader_id |= VEGA_BLEND_SUBTRACT_KHR_SHADER; + break; + case VG_BLEND_INVERT_KHR: + shader_id |= VEGA_BLEND_INVERT_KHR_SHADER; + break; default: /* handled by pipe_blend_state */ break; diff --git a/src/gallium/state_trackers/vega/shaders_cache.c b/src/gallium/state_trackers/vega/shaders_cache.c index f620075..416c095 100644 --- a/src/gallium/state_trackers/vega/shaders_cache.c +++ b/src/gallium/state_trackers/vega/shaders_cache.c @@ -315,7 +315,7 @@ create_shader(struct pipe_context *pipe, ++idx; } - /* fourth stage */ + /* fourth stage */ if ((id & VEGA_BLEND_MULTIPLY_SHADER)) { debug_assert(shaders_asm[8].id == VEGA_BLEND_MULTIPLY_SHADER); shaders[idx] = &shaders_asm[8]; @@ -332,23 +332,31 @@ create_shader(struct pipe_context *pipe, debug_assert(shaders_asm[11].id == VEGA_BLEND_LIGHTEN_SHADER); shaders[idx] = &shaders_asm[11]; ++idx; + } else if ((id & VEGA_BLEND_SUBTRACT_KHR_SHADER)) { + debug_assert(shaders_asm[12].id == VEGA_BLEND_SUBTRACT_KHR_SHADER); + shaders[idx] = &shaders_asm[12]; + ++idx; + } else if ((id & VEGA_BLEND_INVERT_KHR_SHADER)) { + debug_assert(shaders_asm[13].id == VEGA_BLEND_INVERT_KHR_SHADER); + shaders[idx] = &shaders_asm[13]; + ++idx; } /* fifth stage */ if ((id & VEGA_PREMULTIPLY_SHADER)) { - debug_assert(shaders_asm[12].id == VEGA_PREMULTIPLY_SHADER); - shaders[idx] = &shaders_asm[12]; + debug_assert(shaders_asm[14].id == VEGA_PREMULTIPLY_SHADER); + shaders[idx] = &shaders_asm[14]; ++idx; } else if ((id & VEGA_UNPREMULTIPLY_SHADER)) { - debug_assert(shaders_asm[13].id == VEGA_UNPREMULTIPLY_SHADER); - shaders[idx] = &shaders_asm[13]; + debug_assert(shaders_asm[15].id == VEGA_UNPREMULTIPLY_SHADER); + shaders[idx] = &shaders_asm[15]; ++idx; } /* sixth stage */ if ((id & VEGA_BW_SHADER)) { - debug_assert(shaders_asm[14].id == VEGA_BW_SHADER); - shaders[idx] = &shaders_asm[14]; + debug_assert(shaders_asm[16].id == VEGA_BW_SHADER); + shaders[idx] = &shaders_asm[16]; ++idx; } diff --git a/src/gallium/state_trackers/vega/shaders_cache.h b/src/gallium/state_trackers/vega/shaders_cache.h index feca58b..5bbb724 100644 --- a/src/gallium/state_trackers/vega/shaders_cache.h +++ b/src/gallium/state_trackers/vega/shaders_cache.h @@ -48,11 +48,13 @@ enum VegaShaderType { VEGA_BLEND_SCREEN_SHADER = 1 << 9, VEGA_BLEND_DARKEN_SHADER = 1 << 10, VEGA_BLEND_LIGHTEN_SHADER = 1 << 11, + VEGA_BLEND_SUBTRACT_KHR_SHADER = 1 << 12, + VEGA_BLEND_INVERT_KHR_SHADER = 1 << 13, - VEGA_PREMULTIPLY_SHADER = 1 << 12, - VEGA_UNPREMULTIPLY_SHADER = 1 << 13, + VEGA_PREMULTIPLY_SHADER = 1 << 14, + VEGA_UNPREMULTIPLY_SHADER = 1 << 15, - VEGA_BW_SHADER = 1 << 14 + VEGA_BW_SHADER = 1 << 16 }; struct vg_shader { diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c index c16ac03..0a64217 100644 --- a/src/gallium/state_trackers/vega/vg_context.c +++ b/src/gallium/state_trackers/vega/vg_context.c @@ -342,6 +342,8 @@ void vg_validate_state(struct vg_context *ctx) case VG_BLEND_SCREEN: case VG_BLEND_DARKEN: case VG_BLEND_LIGHTEN: + case VG_BLEND_SUBTRACT_KHR: + case VG_BLEND_INVERT_KHR: blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE; blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend->rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; ------------------------------------------------------------------------------ The Planet: dedicated and managed hosting, cloud storage, colocation Stay online with enterprise data centers and the best network in the business Choose flexible plans and management services without long-term contracts Personal 24x7 support from experience hosting pros just a phone call away. http://p.sf.net/sfu/theplanet-com _______________________________________________ Mesa3d-dev mailing list Mesa3d-dev@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mesa3d-dev