On 24.06.2010 01:36, Brian Paul wrote: > I'll try to answer a few... > > > Corbin Simpson wrote: >> Yep, it's that time again. These are just things marked in the docs as >> unknown, so I'm not grinding any axes, just cleaning stuff up. >> >> ~ "If a surface includes several layers/slices (XXX: not yet...) then >> all layers will be cleared." From the information on >> pipe_context::clear(). Is this just wishful thinking, or do drivers >> need to implement this? Drivers need to implement this, if they implement array textures (and geometry shaders too actually), otherwise they should never see more than one layer in the surface (that is, first_layer and last_layer should always be the same). For a better understanding you'd probably need to look in the gallium-array-textures branch it should be more obvious once that is merged, the explanation in pipe_context might not make sense without that. Both d3d and OGL allow this, though in OGL it is limited to either all or one layer (one of zslice, cube face, array range), whereas d3d10 allows arbitrary range of layers in the render target / depth stencil views, and those specified in the range need to get cleared.
>> >> ~ An explanation of dual-source blends and how they work would be nice. > > Marek provided a pointer, but I don't think we've done anything with > this in gallium yet. This should work in gallium. Once upon a time I implemented this in softpipe but had nothing to test with at that time (attached, might not cleanly apply). Though this would be using the simpler option of what ARB_blend_func_extended provides (that is, use first color output for first blend color, second for second blend color - impossible with MRT that way). > >> ~ If logicop_enable and independent_blend_enable are set, are lops >> performed for all render targets, or only those that have blend_enable >> set? > > The GL_ARB_drawbuffers2 spec is a bit vague on this but in swrast > logicop had precedence over blending and either applies to all color > buffers or none. I think this is indeed the case, logic op has a global enable and overrides blending (it is OpenGL only hence we need not worry what d3d would like). Roland
diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index d65307b..85fda0b 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -222,7 +222,7 @@ logicop_quad(struct quad_stage *qs, static void blend_quad(struct quad_stage *qs, - float (*quadColor)[4], + float (*quadColors)[4][4], float (*dest)[4], unsigned cbuf) { @@ -230,6 +230,7 @@ blend_quad(struct quad_stage *qs, static const float one[4] = { 1, 1, 1, 1 }; struct softpipe_context *softpipe = qs->softpipe; float source[4][QUAD_SIZE] = { { 0 } }; + float (*quadColor)[4] = quadColors[cbuf]; /* * Compute src/first term RGB @@ -298,11 +299,23 @@ blend_quad(struct quad_stage *qs, } break; case PIPE_BLENDFACTOR_SRC1_COLOR: - assert(0); /* to do */ - break; + { + float (*quadColor1)[4] = quadColors[1]; + assert(cbuf == 0); + VEC4_MUL(source[0], quadColor[0], quadColor1[0]); /* R */ + VEC4_MUL(source[1], quadColor[1], quadColor1[1]); /* G */ + VEC4_MUL(source[2], quadColor[2], quadColor1[2]); /* B */ + } + break; case PIPE_BLENDFACTOR_SRC1_ALPHA: - assert(0); /* to do */ - break; + { + const float *alpha = quadColors[1][3]; + assert(cbuf == 0); + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + } + break; case PIPE_BLENDFACTOR_ZERO: VEC4_COPY(source[0], zero); /* R */ VEC4_COPY(source[1], zero); /* G */ @@ -372,11 +385,29 @@ blend_quad(struct quad_stage *qs, } break; case PIPE_BLENDFACTOR_INV_SRC1_COLOR: - assert(0); /* to do */ - break; + { + float (*quadColor1)[4] = quadColors[1]; + float inv_comp[4]; + assert(cbuf == 0); + VEC4_SUB(inv_comp, one, quadColor1[0]); /* R */ + VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */ + VEC4_SUB(inv_comp, one, quadColor1[1]); /* G */ + VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */ + VEC4_SUB(inv_comp, one, quadColor1[2]); /* B */ + VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ + } + break; case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: - assert(0); /* to do */ - break; + { + const float *alpha = quadColors[1][3]; + float inv_alpha[4]; + assert(cbuf == 0); + VEC4_SUB(inv_alpha, one, alpha); + VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ + } + break; default: assert(0); } @@ -414,6 +445,15 @@ blend_quad(struct quad_stage *qs, VEC4_MUL(source[3], quadColor[3], comp); /* A */ } break; + case PIPE_BLENDFACTOR_SRC1_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_SRC1_ALPHA: + { + const float *alpha = quadColors[1][3]; + assert(cbuf == 0); + VEC4_MUL(source[3], quadColor[3], alpha); /* R */ + } + break; case PIPE_BLENDFACTOR_ZERO: VEC4_COPY(source[3], zero); /* A */ break; @@ -445,6 +485,16 @@ blend_quad(struct quad_stage *qs, VEC4_MUL(source[3], quadColor[3], inv_comp); } break; + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + { + float inv_alpha[4]; + assert(cbuf == 0); + VEC4_SUB(inv_alpha, one, quadColors[1][3]); + VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ + } + break; default: assert(0); } @@ -508,16 +558,29 @@ blend_quad(struct quad_stage *qs, VEC4_MUL(dest[2], dest[2], comp); /* B */ } break; + case PIPE_BLENDFACTOR_SRC1_COLOR: + { + float (*quadColor1)[4] = quadColors[1]; + assert(cbuf == 0); + VEC4_MUL(dest[0], dest[0], quadColor1[0]); /* R */ + VEC4_MUL(dest[1], dest[1], quadColor1[1]); /* G */ + VEC4_MUL(dest[2], dest[2], quadColor1[2]); /* B */ + } + break; + case PIPE_BLENDFACTOR_SRC1_ALPHA: + { + const float *alpha = quadColors[1][3]; + assert(cbuf == 0); + VEC4_MUL(dest[0], dest[0], alpha); /* R */ + VEC4_MUL(dest[1], dest[1], alpha); /* G */ + VEC4_MUL(dest[2], dest[2], alpha); /* B */ + } + break; case PIPE_BLENDFACTOR_ZERO: VEC4_COPY(dest[0], zero); /* R */ VEC4_COPY(dest[1], zero); /* G */ VEC4_COPY(dest[2], zero); /* B */ break; - case PIPE_BLENDFACTOR_SRC1_COLOR: - case PIPE_BLENDFACTOR_SRC1_ALPHA: - /* XXX what are these? */ - assert(0); - break; case PIPE_BLENDFACTOR_INV_SRC_COLOR: { float inv_comp[4]; @@ -582,10 +645,29 @@ blend_quad(struct quad_stage *qs, } break; case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + { + float (*quadColor1)[4] = quadColors[1]; + float inv_comp[4]; + assert(cbuf == 0); + VEC4_SUB(inv_comp, one, quadColor1[0]); /* R */ + VEC4_MUL(dest[0], dest[0], inv_comp); /* R */ + VEC4_SUB(inv_comp, one, quadColor1[1]); /* G */ + VEC4_MUL(dest[1], dest[1], inv_comp); /* G */ + VEC4_SUB(inv_comp, one, quadColor1[2]); /* B */ + VEC4_MUL(dest[2], dest[2], inv_comp); /* B */ + } + break; case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: - /* XXX what are these? */ - assert(0); - break; + { + const float *alpha = quadColors[1][3]; + float inv_alpha[4]; + assert(cbuf == 0); + VEC4_SUB(inv_alpha, one, alpha); + VEC4_MUL(dest[0], dest[0], inv_alpha); /* R */ + VEC4_MUL(dest[1], dest[1], inv_alpha); /* G */ + VEC4_MUL(dest[2], dest[2], inv_alpha); /* B */ + } + break; default: assert(0); } @@ -619,6 +701,15 @@ blend_quad(struct quad_stage *qs, VEC4_MUL(dest[3], dest[3], comp); /* A */ } break; + case PIPE_BLENDFACTOR_SRC1_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_SRC1_ALPHA: + { + const float *alpha = quadColors[1][3]; + assert(cbuf == 0); + VEC4_MUL(dest[3], dest[3], alpha); /* R */ + } + break; case PIPE_BLENDFACTOR_ZERO: VEC4_COPY(dest[3], zero); /* A */ break; @@ -649,6 +740,16 @@ blend_quad(struct quad_stage *qs, VEC4_MUL(dest[3], dest[3], inv_comp); } break; + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + { + float inv_alpha[4]; + assert(cbuf == 0); + VEC4_SUB(inv_alpha, one, quadColors[1][3]); + VEC4_MUL(dest[3], dest[3], inv_alpha); /* A */ + } + break; default: assert(0); } @@ -772,7 +873,7 @@ blend_fallback(struct quad_stage *qs, logicop_quad( qs, quadColor, dest ); } else if (blend->rt[cbuf].blend_enable) { - blend_quad( qs, quadColor, dest, cbuf ); + blend_quad( qs, quad->output.color, dest, cbuf ); } if (blend->rt[cbuf].colormask != 0xf) diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index b2841f4..df30ac4 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -99,6 +99,8 @@ softpipe_get_param(struct pipe_screen *screen, int param) return 1; case PIPE_CAP_INDEP_BLEND_FUNC: return 1; + case PIPE_CAP_DUAL_SOURCE_BLEND: + return 1; default: return 0; }
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev