Simplify ctx->_NumColorDrawBuffers, _ColorDrawBuffers and fix bug 13835.
These fields are no longer indexed by shader output. Now, we just have a simple array of renderbuffer pointers. If the shader writes to gl_FragData[i], send those colors to the N _ColorDrawBuffers. Otherwise, replicate the single gl_FragColor (or the fixed-function color) to the N _ColorDrawBuffers. A few more changes and simplifications can follow from this...
This commit is contained in:
@@ -234,7 +234,7 @@ intelCalcViewport(GLcontext * ctx)
|
||||
if (ctx->DrawBuffer->Name) {
|
||||
/* User created FBO */
|
||||
struct intel_renderbuffer *irb
|
||||
= intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]);
|
||||
= intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
|
||||
if (irb && !irb->RenderToTexture) {
|
||||
/* y=0=top */
|
||||
yScale = -1.0;
|
||||
|
@@ -62,12 +62,9 @@ static GLboolean do_check_fallback(struct brw_context *brw)
|
||||
/* We can only handle a single draw buffer at the moment, and only as the
|
||||
* first color buffer.
|
||||
*/
|
||||
for (i = 0; i < MAX_DRAW_BUFFERS; i++) {
|
||||
if (fb->_NumColorDrawBuffers[i] > (i == 0 ? 1 : 0)) {
|
||||
DBG("FALLBACK: draw buffer %d: 0x%08x\n",
|
||||
i, ctx->DrawBuffer->_ColorDrawBufferMask[i]);
|
||||
return GL_TRUE;
|
||||
}
|
||||
if (fb->_NumColorDrawBuffers > 1) {
|
||||
DBG("FALLBACK: multiple color draw buffers\n");
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* _NEW_RENDERMODE
|
||||
|
@@ -43,7 +43,7 @@ static void upload_sf_vp(struct brw_context *brw)
|
||||
const GLfloat depth_scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
|
||||
struct brw_sf_viewport sfv;
|
||||
struct intel_renderbuffer *irb =
|
||||
intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]);
|
||||
intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
|
||||
GLfloat y_scale, y_bias;
|
||||
|
||||
memset(&sfv, 0, sizeof(sfv));
|
||||
|
@@ -102,7 +102,7 @@ struct intel_region *
|
||||
intel_drawbuf_region(struct intel_context *intel)
|
||||
{
|
||||
struct intel_renderbuffer *irbColor =
|
||||
intel_renderbuffer(intel->ctx.DrawBuffer->_ColorDrawBuffers[0][0]);
|
||||
intel_renderbuffer(intel->ctx.DrawBuffer->_ColorDrawBuffers[0]);
|
||||
if (irbColor)
|
||||
return irbColor->region;
|
||||
else
|
||||
@@ -931,7 +931,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
|
||||
/*
|
||||
* How many color buffers are we drawing into?
|
||||
*/
|
||||
if (fb->_NumColorDrawBuffers[0] != 1) {
|
||||
if (fb->_NumColorDrawBuffers != 1) {
|
||||
/* writing to 0 or 2 or 4 color buffers */
|
||||
/*_mesa_debug(ctx, "Software rendering\n");*/
|
||||
FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE);
|
||||
@@ -967,7 +967,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
|
||||
/* drawing to user-created FBO */
|
||||
struct intel_renderbuffer *irb;
|
||||
intelSetRenderbufferClipRects(intel);
|
||||
irb = intel_renderbuffer(fb->_ColorDrawBuffers[0][0]);
|
||||
irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
|
||||
colorRegion = (irb && irb->region) ? irb->region : NULL;
|
||||
}
|
||||
}
|
||||
|
@@ -186,21 +186,18 @@ intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
|
||||
struct intel_renderbuffer *irb;
|
||||
|
||||
/* color draw buffers */
|
||||
for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
|
||||
for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers[i]; j++) {
|
||||
struct gl_renderbuffer *rb =
|
||||
ctx->DrawBuffer->_ColorDrawBuffers[i][j];
|
||||
irb = intel_renderbuffer(rb);
|
||||
if (irb) {
|
||||
/* this is a user-created intel_renderbuffer */
|
||||
if (irb->region) {
|
||||
if (map)
|
||||
intel_region_map(intel, irb->region);
|
||||
else
|
||||
intel_region_unmap(intel, irb->region);
|
||||
irb->pfMap = irb->region->map;
|
||||
irb->pfPitch = irb->region->pitch;
|
||||
}
|
||||
for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++) {
|
||||
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[j];
|
||||
irb = intel_renderbuffer(rb);
|
||||
if (irb) {
|
||||
/* this is a user-created intel_renderbuffer */
|
||||
if (irb->region) {
|
||||
if (map)
|
||||
intel_region_map(intel, irb->region);
|
||||
else
|
||||
intel_region_unmap(intel, irb->region);
|
||||
irb->pfMap = irb->region->map;
|
||||
irb->pfPitch = irb->region->pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -149,12 +149,12 @@ static void nouveauClear( GLcontext *ctx, GLbitfield mask )
|
||||
clear_value = PACK_COLOR_8888(c[3],c[0],c[1],c[2]);
|
||||
|
||||
if (ctx->DrawBuffer) {
|
||||
/* FIXME: find correct color buffer, instead of [0][0] */
|
||||
if (ctx->DrawBuffer->_ColorDrawBuffers[0][0]) {
|
||||
color_bits = ctx->DrawBuffer->_ColorDrawBuffers[0][0]->RedBits;
|
||||
color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0][0]->GreenBits;
|
||||
color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0][0]->BlueBits;
|
||||
color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0][0]->AlphaBits;
|
||||
/* FIXME: find correct color buffer, instead of [0] */
|
||||
if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
|
||||
color_bits = ctx->DrawBuffer->_ColorDrawBuffers[0]->RedBits;
|
||||
color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0]->GreenBits;
|
||||
color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0]->BlueBits;
|
||||
color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0]->AlphaBits;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -177,8 +177,7 @@ nouveau_window_moved(GLcontext * ctx)
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
nouveau_renderbuffer_t *nrb;
|
||||
|
||||
nrb = (nouveau_renderbuffer_t *)
|
||||
ctx->DrawBuffer->_ColorDrawBuffers[0][0];
|
||||
nrb = (nouveau_renderbuffer_t *) ctx->DrawBuffer->_ColorDrawBuffers[0];
|
||||
if (!nrb)
|
||||
return;
|
||||
|
||||
@@ -204,7 +203,7 @@ nouveau_build_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
|
||||
_mesa_update_framebuffer(ctx);
|
||||
_mesa_update_draw_buffer_bounds(ctx);
|
||||
|
||||
color[0] = (nouveau_renderbuffer_t *) fb->_ColorDrawBuffers[0][0];
|
||||
color[0] = (nouveau_renderbuffer_t *) fb->_ColorDrawBuffers[0];
|
||||
if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped)
|
||||
depth = (nouveau_renderbuffer_t *) fb->_DepthBuffer->Wrapped;
|
||||
else
|
||||
|
@@ -813,7 +813,7 @@ static void r128UpdateWindow( GLcontext *ctx )
|
||||
r128ContextPtr rmesa = R128_CONTEXT(ctx);
|
||||
int x = rmesa->driDrawable->x;
|
||||
int y = rmesa->driDrawable->y;
|
||||
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
|
||||
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
|
||||
driRenderbuffer *drb = (driRenderbuffer *) rb;
|
||||
|
||||
rmesa->setup.window_xy_offset = (((y & 0xFFF) << R128_WINDOW_Y_SHIFT) |
|
||||
|
@@ -294,7 +294,7 @@ static void do_draw_pix( GLcontext *ctx,
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
__DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
|
||||
drm_clip_rect_t *box = dPriv->pClipRects;
|
||||
struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorDrawBuffers[0][0];
|
||||
struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorDrawBuffers[0];
|
||||
driRenderbuffer *drb = (driRenderbuffer *) rb;
|
||||
int nbox = dPriv->numClipRects;
|
||||
int i;
|
||||
@@ -388,7 +388,7 @@ r200TryDrawPixels( GLcontext *ctx,
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
/* check that we're drawing to exactly one color buffer */
|
||||
if (ctx->DrawBuffer->_NumColorDrawBuffers[0] != 1)
|
||||
if (ctx->DrawBuffer->_NumColorDrawBuffers != 1)
|
||||
return GL_FALSE;
|
||||
|
||||
switch (format) {
|
||||
|
@@ -255,7 +255,7 @@ static void r200SpanRenderStart( GLcontext *ctx )
|
||||
{
|
||||
int p;
|
||||
driRenderbuffer *drb =
|
||||
(driRenderbuffer *) ctx->WinSysDrawBuffer->_ColorDrawBuffers[0][0];
|
||||
(driRenderbuffer *) ctx->WinSysDrawBuffer->_ColorDrawBuffers[0];
|
||||
volatile int *buf =
|
||||
(volatile int *)(rmesa->dri.screen->pFB + drb->offset);
|
||||
p = *buf;
|
||||
|
@@ -435,7 +435,7 @@ xmesa_DrawPixels_8R8G8B( GLcontext *ctx,
|
||||
const GLvoid *pixels )
|
||||
{
|
||||
const SWcontext *swrast = SWRAST_CONTEXT( ctx );
|
||||
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
|
||||
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
|
||||
struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb->Wrapped);
|
||||
|
||||
if (swrast->NewState)
|
||||
@@ -544,7 +544,7 @@ xmesa_DrawPixels_5R6G5B( GLcontext *ctx,
|
||||
const GLvoid *pixels )
|
||||
{
|
||||
struct xmesa_renderbuffer *xrb
|
||||
= xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped);
|
||||
= xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped);
|
||||
const XMesaContext xmesa = XMESA_CONTEXT(ctx);
|
||||
const SWcontext *swrast = SWRAST_CONTEXT( ctx );
|
||||
XMesaDisplay *dpy = xmesa->xm_visual->display;
|
||||
@@ -654,7 +654,7 @@ xmesa_CopyPixels( GLcontext *ctx,
|
||||
struct xmesa_renderbuffer *srcXrb
|
||||
= xmesa_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer->Wrapped);
|
||||
struct xmesa_renderbuffer *dstXrb
|
||||
= xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped);
|
||||
= xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped);
|
||||
|
||||
ASSERT(dpy);
|
||||
ASSERT(gc);
|
||||
|
@@ -121,7 +121,7 @@ void xmesa_choose_point( GLcontext *ctx )
|
||||
|
||||
|
||||
#define GET_XRB(XRB) struct xmesa_renderbuffer *XRB = \
|
||||
xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped)
|
||||
xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped)
|
||||
|
||||
|
||||
/*
|
||||
@@ -598,7 +598,7 @@ get_line_func(GLcontext *ctx)
|
||||
if (swrast->_RasterMask & MULTI_DRAW_BIT) return (swrast_line_func) NULL;
|
||||
if (xmbuf->swAlpha) return (swrast_line_func) NULL;
|
||||
|
||||
xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped);
|
||||
xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped);
|
||||
|
||||
if (xrb->ximage
|
||||
&& swrast->_RasterMask==DEPTH_BIT
|
||||
@@ -661,7 +661,7 @@ get_line_func(GLcontext *ctx)
|
||||
}
|
||||
|
||||
#ifndef XFree86Server
|
||||
if (ctx->DrawBuffer->_NumColorDrawBuffers[0] == 1
|
||||
if (ctx->DrawBuffer->_NumColorDrawBuffers == 1
|
||||
&& ctx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT
|
||||
&& swrast->_RasterMask == LOGIC_OP_BIT
|
||||
&& ctx->Color.LogicOp == GL_XOR
|
||||
|
@@ -45,7 +45,7 @@
|
||||
|
||||
|
||||
#define GET_XRB(XRB) struct xmesa_renderbuffer *XRB = \
|
||||
xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped)
|
||||
xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped)
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
@@ -1479,7 +1479,7 @@ get_triangle_func(GLcontext *ctx)
|
||||
if (xmbuf->swAlpha)
|
||||
return (swrast_tri_func) NULL;
|
||||
|
||||
xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped);
|
||||
xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped);
|
||||
|
||||
if (xrb->ximage) {
|
||||
if ( ctx->Light.ShadeModel==GL_SMOOTH
|
||||
|
@@ -508,8 +508,9 @@ set_color_output(GLcontext *ctx, GLuint output, GLenum buffer,
|
||||
/* Set per-FBO state */
|
||||
fb->ColorDrawBuffer[output] = buffer;
|
||||
fb->_ColorDrawBufferMask[output] = destMask;
|
||||
/* not really needed, will be set later */
|
||||
fb->_NumColorDrawBuffers[output] = 0;
|
||||
|
||||
/* this will be computed later, but zero to be safe */
|
||||
fb->_NumColorDrawBuffers = 0;
|
||||
|
||||
if (fb->Name == 0) {
|
||||
/* Only set the per-context DrawBuffer state if we're currently
|
||||
|
@@ -583,6 +583,51 @@ _mesa_update_stencil_buffer(GLcontext *ctx,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Example DrawBuffers scenarios:
|
||||
*
|
||||
* 1. glDrawBuffer(GL_FRONT_AND_BACK), fixed-func or shader writes to
|
||||
* "gl_FragColor" or program writes to the "result.color" register:
|
||||
*
|
||||
* fragment color output renderbuffer
|
||||
* --------------------- ---------------
|
||||
* color[0] Front, Back
|
||||
*
|
||||
*
|
||||
* 2. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]), shader writes to
|
||||
* gl_FragData[i] or program writes to result.color[i] registers:
|
||||
*
|
||||
* fragment color output renderbuffer
|
||||
* --------------------- ---------------
|
||||
* color[0] Front
|
||||
* color[1] Aux0
|
||||
* color[3] Aux1
|
||||
*
|
||||
*
|
||||
* 3. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]) and shader writes to
|
||||
* gl_FragColor, or fixed function:
|
||||
*
|
||||
* fragment color output renderbuffer
|
||||
* --------------------- ---------------
|
||||
* color[0] Front, Aux0, Aux1
|
||||
*
|
||||
*
|
||||
* In either case, the list of renderbuffers is stored in the
|
||||
* framebuffer->_ColorDrawBuffers[] array and
|
||||
* framebuffer->_NumColorDrawBuffers indicates the number of buffers.
|
||||
* The renderer (like swrast) has to look at the current fragment shader
|
||||
* to see if it writes to gl_FragColor vs. gl_FragData[i] to determine
|
||||
* how to map color outputs to renderbuffers.
|
||||
*
|
||||
* Note that these two calls are equivalent (for fixed function fragment
|
||||
* shading anyway):
|
||||
* a) glDrawBuffer(GL_FRONT_AND_BACK); (assuming non-stereo framebuffer)
|
||||
* b) glDrawBuffers(2, [GL_FRONT_LEFT, GL_BACK_LEFT]);
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Update the (derived) list of color drawing renderbuffer pointers.
|
||||
* Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers
|
||||
@@ -591,39 +636,39 @@ _mesa_update_stencil_buffer(GLcontext *ctx,
|
||||
static void
|
||||
update_color_draw_buffers(GLcontext *ctx, struct gl_framebuffer *fb)
|
||||
{
|
||||
GLuint output;
|
||||
GLuint output, count = 0;
|
||||
|
||||
/*
|
||||
* Fragment programs can write to multiple colorbuffers with
|
||||
* the GL_ARB_draw_buffers extension.
|
||||
/* First, interpret _ColorDrawBufferMask[] in the manner that would be
|
||||
* used if the fragment program/shader writes to gl_FragData[]
|
||||
*/
|
||||
for (output = 0; output < ctx->Const.MaxDrawBuffers; output++) {
|
||||
GLbitfield bufferMask = fb->_ColorDrawBufferMask[output];
|
||||
GLuint count = 0;
|
||||
GLuint i;
|
||||
if (!fb->DeletePending) {
|
||||
/* We need the inner loop here because glDrawBuffer(GL_FRONT_AND_BACK)
|
||||
* can specify writing to two or four color buffers (for example).
|
||||
*/
|
||||
for (i = 0; bufferMask && i < BUFFER_COUNT; i++) {
|
||||
const GLuint bufferBit = 1 << i;
|
||||
if (bufferBit & bufferMask) {
|
||||
struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
|
||||
if (rb && rb->Width > 0 && rb->Height > 0) {
|
||||
fb->_ColorDrawBuffers[output][count] = rb;
|
||||
count++;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
_mesa_warning(ctx, "DrawBuffer names a missing buffer!\n");
|
||||
*/
|
||||
}
|
||||
bufferMask &= ~bufferBit;
|
||||
}
|
||||
}
|
||||
GLuint buf = _mesa_ffs(fb->_ColorDrawBufferMask[output]);
|
||||
if (buf) {
|
||||
struct gl_renderbuffer *rb = fb->Attachment[buf - 1].Renderbuffer;
|
||||
fb->_ColorDrawBuffers[output] = rb; /* may be NULL */
|
||||
if (rb)
|
||||
count = output + 1;
|
||||
}
|
||||
fb->_NumColorDrawBuffers[output] = count;
|
||||
}
|
||||
|
||||
/* Second, handle the GL_FRONT_AND_BACK case, overwriting the above
|
||||
* if needed.
|
||||
*/
|
||||
GLbitfield bufferMask = fb->_ColorDrawBufferMask[0];
|
||||
if (_mesa_bitcount(bufferMask) > 1) {
|
||||
GLuint i;
|
||||
count = 0;
|
||||
for (i = 0; bufferMask && i < BUFFER_COUNT; i++) {
|
||||
if (bufferMask & (1 << i)) {
|
||||
struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
|
||||
fb->_ColorDrawBuffers[count] = rb;
|
||||
count++;
|
||||
}
|
||||
bufferMask &= ~(1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
fb->_NumColorDrawBuffers = count;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -2400,8 +2400,8 @@ struct gl_framebuffer
|
||||
GLint _ColorReadBufferIndex; /* -1 = None */
|
||||
|
||||
/* These are computed from _ColorDrawBufferMask and _ColorReadBufferIndex */
|
||||
GLuint _NumColorDrawBuffers[MAX_DRAW_BUFFERS];
|
||||
struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS][4];
|
||||
GLuint _NumColorDrawBuffers;
|
||||
struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS];
|
||||
struct gl_renderbuffer *_ColorReadBuffer;
|
||||
|
||||
/** The Actual depth/stencil buffers to use. May be wrappers around the
|
||||
|
@@ -525,8 +525,8 @@ accum_return(GLcontext *ctx, GLfloat value,
|
||||
}
|
||||
|
||||
/* store colors */
|
||||
for (buffer = 0; buffer < fb->_NumColorDrawBuffers[0]; buffer++) {
|
||||
struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[0][buffer];
|
||||
for (buffer = 0; buffer < fb->_NumColorDrawBuffers; buffer++) {
|
||||
struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buffer];
|
||||
if (masking) {
|
||||
_swrast_mask_rgba_span(ctx, rb, &span);
|
||||
}
|
||||
|
@@ -135,7 +135,7 @@ blit_nearest(GLcontext *ctx,
|
||||
switch (buffer) {
|
||||
case GL_COLOR_BUFFER_BIT:
|
||||
readRb = ctx->ReadBuffer->_ColorReadBuffer;
|
||||
drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
|
||||
drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0];
|
||||
comps = 4;
|
||||
break;
|
||||
case GL_DEPTH_BUFFER_BIT:
|
||||
@@ -319,7 +319,7 @@ blit_linear(GLcontext *ctx,
|
||||
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1)
|
||||
{
|
||||
struct gl_renderbuffer *readRb = ctx->ReadBuffer->_ColorReadBuffer;
|
||||
struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
|
||||
struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0];
|
||||
|
||||
const GLint srcWidth = ABS(srcX1 - srcX0);
|
||||
const GLint dstWidth = ABS(dstX1 - dstX0);
|
||||
@@ -493,7 +493,7 @@ simple_blit(GLcontext *ctx,
|
||||
switch (buffer) {
|
||||
case GL_COLOR_BUFFER_BIT:
|
||||
readRb = ctx->ReadBuffer->_ColorReadBuffer;
|
||||
drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
|
||||
drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0];
|
||||
comps = 4;
|
||||
break;
|
||||
case GL_DEPTH_BUFFER_BIT:
|
||||
|
@@ -251,7 +251,7 @@ static void
|
||||
clear_color_buffers(GLcontext *ctx)
|
||||
{
|
||||
GLboolean masking;
|
||||
GLuint i;
|
||||
GLuint buf;
|
||||
|
||||
if (ctx->Visual.rgbMode) {
|
||||
if (ctx->Color.ColorMask[0] &&
|
||||
@@ -265,7 +265,7 @@ clear_color_buffers(GLcontext *ctx)
|
||||
}
|
||||
}
|
||||
else {
|
||||
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
|
||||
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
|
||||
const GLuint indexBits = (1 << rb->IndexBits) - 1;
|
||||
if ((ctx->Color.IndexMask & indexBits) == indexBits) {
|
||||
masking = GL_FALSE;
|
||||
@@ -275,8 +275,8 @@ clear_color_buffers(GLcontext *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers[0]; i++) {
|
||||
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][i];
|
||||
for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) {
|
||||
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[buf];
|
||||
if (ctx->Visual.rgbMode) {
|
||||
if (masking) {
|
||||
clear_rgba_buffer_with_masking(ctx, rb);
|
||||
@@ -331,7 +331,7 @@ _swrast_Clear(GLcontext *ctx, GLbitfield buffers)
|
||||
|
||||
/* do software clearing here */
|
||||
if (buffers) {
|
||||
if (buffers & ctx->DrawBuffer->_ColorDrawBufferMask[0]) {
|
||||
if (buffers & ctx->DrawBuffer->_NumColorDrawBuffers > 0) {
|
||||
clear_color_buffers(ctx);
|
||||
}
|
||||
if (buffers & BUFFER_BIT_DEPTH) {
|
||||
|
@@ -87,7 +87,7 @@ _swrast_update_rasterflags( GLcontext *ctx )
|
||||
* MULTI_DRAW_BIT flag. Also set it if we're drawing to no
|
||||
* buffers or the RGBA or CI mask disables all writes.
|
||||
*/
|
||||
if (ctx->DrawBuffer->_NumColorDrawBuffers[0] != 1) {
|
||||
if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
|
||||
/* more than one color buffer designated for writing (or zero buffers) */
|
||||
rasterMask |= MULTI_DRAW_BIT;
|
||||
}
|
||||
@@ -596,44 +596,6 @@ _swrast_update_active_attribs(GLcontext *ctx)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the swrast->_ColorOutputsMask which indicates which color
|
||||
* renderbuffers (aka rendertargets) are being written to by the current
|
||||
* fragment program.
|
||||
* We also take glDrawBuffers() into account to skip outputs that are
|
||||
* set to GL_NONE.
|
||||
*/
|
||||
static void
|
||||
_swrast_update_color_outputs(GLcontext *ctx)
|
||||
{
|
||||
SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||
const struct gl_framebuffer *fb = ctx->DrawBuffer;
|
||||
|
||||
swrast->_ColorOutputsMask = 0;
|
||||
swrast->_NumColorOutputs = 0;
|
||||
|
||||
if (ctx->FragmentProgram._Current) {
|
||||
const GLbitfield outputsWritten
|
||||
= ctx->FragmentProgram._Current->Base.OutputsWritten;
|
||||
GLuint output;
|
||||
for (output = 0; output < ctx->Const.MaxDrawBuffers; output++) {
|
||||
if ((outputsWritten & (1 << (FRAG_RESULT_DATA0 + output)))
|
||||
&& (fb->_NumColorDrawBuffers[output] > 0)) {
|
||||
swrast->_ColorOutputsMask |= (1 << output);
|
||||
swrast->_NumColorOutputs = output + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (swrast->_ColorOutputsMask == 0x0) {
|
||||
/* no fragment program, or frag prog didn't write to gl_FragData[] */
|
||||
if (fb->_NumColorDrawBuffers[0] > 0) {
|
||||
swrast->_ColorOutputsMask = 0x1;
|
||||
swrast->_NumColorOutputs = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_swrast_validate_derived( GLcontext *ctx )
|
||||
{
|
||||
@@ -683,9 +645,6 @@ _swrast_validate_derived( GLcontext *ctx )
|
||||
_NEW_TEXTURE))
|
||||
_swrast_update_active_attribs(ctx);
|
||||
|
||||
if (swrast->NewState & (_NEW_PROGRAM | _NEW_BUFFERS))
|
||||
_swrast_update_color_outputs(ctx);
|
||||
|
||||
swrast->NewState = 0;
|
||||
swrast->StateChanges = 0;
|
||||
swrast->InvalidateState = _swrast_invalidate_state;
|
||||
|
@@ -136,10 +136,6 @@ typedef struct
|
||||
GLboolean _DeferredTexture;
|
||||
GLenum _FogMode; /* either GL_FOG_MODE or fragment program's fog mode */
|
||||
|
||||
/** Multiple render targets */
|
||||
GLbitfield _ColorOutputsMask;
|
||||
GLuint _NumColorOutputs;
|
||||
|
||||
/** List/array of the fragment attributes to interpolate */
|
||||
GLuint _ActiveAttribs[FRAG_ATTRIB_MAX];
|
||||
/** Same info, but as a bitmask */
|
||||
|
@@ -830,10 +830,10 @@ fast_copy_pixels(GLcontext *ctx,
|
||||
}
|
||||
|
||||
if (type == GL_COLOR) {
|
||||
if (dstFb->_NumColorDrawBuffers[0] != 1)
|
||||
if (dstFb->_NumColorDrawBuffers != 1)
|
||||
return GL_FALSE;
|
||||
srcRb = srcFb->_ColorReadBuffer;
|
||||
dstRb = dstFb->_ColorDrawBuffers[0][0];
|
||||
dstRb = dstFb->_ColorDrawBuffers[0];
|
||||
}
|
||||
else if (type == GL_STENCIL) {
|
||||
srcRb = srcFb->_StencilBuffer;
|
||||
|
@@ -53,7 +53,7 @@ fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y,
|
||||
const GLvoid *pixels)
|
||||
{
|
||||
const GLint imgX = x, imgY = y;
|
||||
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
|
||||
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
|
||||
const GLenum rbType = rb->DataType;
|
||||
SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||
SWspan span;
|
||||
@@ -608,8 +608,8 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
|
||||
IMAGE_POST_CONVOLUTION_SCALE_BIAS);
|
||||
}
|
||||
|
||||
if (ctx->DrawBuffer->_NumColorDrawBuffers[0] > 0 &&
|
||||
ctx->DrawBuffer->_ColorDrawBuffers[0][0]->DataType != GL_FLOAT &&
|
||||
if (ctx->DrawBuffer->_NumColorDrawBuffers > 0 &&
|
||||
ctx->DrawBuffer->_ColorDrawBuffers[0]->DataType != GL_FLOAT &&
|
||||
ctx->Color.ClampFragmentColor != GL_FALSE) {
|
||||
/* need to clamp colors before applying fragment ops */
|
||||
transferOps |= IMAGE_CLAMP_BIT;
|
||||
|
@@ -167,11 +167,11 @@ run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end)
|
||||
* Note that colors beyond 0 and 1 will overwrite other
|
||||
* attributes, such as FOGC, TEX0, TEX1, etc. That's OK.
|
||||
*/
|
||||
GLuint output;
|
||||
for (output = 0; output < swrast->_NumColorOutputs; output++) {
|
||||
if (outputsWritten & (1 << (FRAG_RESULT_DATA0 + output))) {
|
||||
COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0+output][i],
|
||||
machine->Outputs[FRAG_RESULT_DATA0 + output]);
|
||||
GLuint buf;
|
||||
for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) {
|
||||
if (outputsWritten & (1 << (FRAG_RESULT_DATA0 + buf))) {
|
||||
COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0 + buf][i],
|
||||
machine->Outputs[FRAG_RESULT_DATA0 + buf]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -792,6 +792,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
|
||||
const SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||
const GLbitfield origInterpMask = span->interpMask;
|
||||
const GLbitfield origArrayMask = span->arrayMask;
|
||||
struct gl_framebuffer *fb = ctx->DrawBuffer;
|
||||
|
||||
ASSERT(span->end <= MAX_WIDTH);
|
||||
ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE ||
|
||||
@@ -818,7 +819,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
|
||||
}
|
||||
|
||||
/* Depth bounds test */
|
||||
if (ctx->Depth.BoundsTest && ctx->DrawBuffer->Visual.depthBits > 0) {
|
||||
if (ctx->Depth.BoundsTest && fb->Visual.depthBits > 0) {
|
||||
if (!_swrast_depth_bounds_test(ctx, span)) {
|
||||
return;
|
||||
}
|
||||
@@ -830,10 +831,10 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
|
||||
GLuint i;
|
||||
for (i = 0; i < span->end; i++) {
|
||||
if (span->array->mask[i]) {
|
||||
assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin);
|
||||
assert(span->array->x[i] < ctx->DrawBuffer->_Xmax);
|
||||
assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin);
|
||||
assert(span->array->y[i] < ctx->DrawBuffer->_Ymax);
|
||||
assert(span->array->x[i] >= fb->_Xmin);
|
||||
assert(span->array->x[i] < fb->_Xmax);
|
||||
assert(span->array->y[i] >= fb->_Ymin);
|
||||
assert(span->array->y[i] < fb->_Ymax);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -912,22 +913,21 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
|
||||
* Write to renderbuffers
|
||||
*/
|
||||
{
|
||||
struct gl_framebuffer *fb = ctx->DrawBuffer;
|
||||
const GLuint output = 0; /* only frag progs can write to other outputs */
|
||||
const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output];
|
||||
GLuint indexSave[MAX_WIDTH];
|
||||
const GLuint numBuffers = fb->_NumColorDrawBuffers;
|
||||
GLuint buf;
|
||||
|
||||
if (numDrawBuffers > 1) {
|
||||
/* save indexes for second, third renderbuffer writes */
|
||||
_mesa_memcpy(indexSave, span->array->index,
|
||||
span->end * sizeof(indexSave[0]));
|
||||
}
|
||||
for (buf = 0; buf < numBuffers; buf++) {
|
||||
struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf];
|
||||
GLuint indexSave[MAX_WIDTH];
|
||||
|
||||
for (buf = 0; buf < fb->_NumColorDrawBuffers[output]; buf++) {
|
||||
struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf];
|
||||
ASSERT(rb->_BaseFormat == GL_COLOR_INDEX);
|
||||
|
||||
if (numBuffers > 1) {
|
||||
/* save indexes for second, third renderbuffer writes */
|
||||
_mesa_memcpy(indexSave, span->array->index,
|
||||
span->end * sizeof(indexSave[0]));
|
||||
}
|
||||
|
||||
if (ctx->Color.IndexLogicOpEnabled) {
|
||||
_swrast_logicop_ci_span(ctx, rb, span);
|
||||
}
|
||||
@@ -1002,7 +1002,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
|
||||
}
|
||||
}
|
||||
|
||||
if (buf + 1 < numDrawBuffers) {
|
||||
if (buf + 1 < numBuffers) {
|
||||
/* restore original span values */
|
||||
_mesa_memcpy(span->array->index, indexSave,
|
||||
span->end * sizeof(indexSave[0]));
|
||||
@@ -1119,7 +1119,7 @@ clamp_colors(SWspan *span)
|
||||
|
||||
/**
|
||||
* Convert the span's color arrays to the given type.
|
||||
* The only way 'output' can be greater than one is when we have a fragment
|
||||
* The only way 'output' can be greater than zero is when we have a fragment
|
||||
* program that writes to gl_FragData[1] or higher.
|
||||
* \param output which fragment program color output is being processed
|
||||
*/
|
||||
@@ -1249,7 +1249,6 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
|
||||
|| ctx->ATIFragmentShader._Enabled);
|
||||
const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits;
|
||||
struct gl_framebuffer *fb = ctx->DrawBuffer;
|
||||
GLuint output;
|
||||
|
||||
/*
|
||||
printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__,
|
||||
@@ -1399,67 +1398,69 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
|
||||
/*
|
||||
* Write to renderbuffers
|
||||
*/
|
||||
/* Loop over color outputs (GL_ARB_draw_buffers) written by frag prog */
|
||||
for (output = 0; output < swrast->_NumColorOutputs; output++) {
|
||||
if (swrast->_ColorOutputsMask & (1 << output)) {
|
||||
const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output];
|
||||
GLchan rgbaSave[MAX_WIDTH][4];
|
||||
GLuint buf;
|
||||
{
|
||||
const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
|
||||
const GLboolean multiFragOutputs
|
||||
= fp && fp->Base.InputsRead >= (1 << FRAG_RESULT_DATA0);
|
||||
const GLuint numBuffers = fb->_NumColorDrawBuffers;
|
||||
GLuint buf;
|
||||
|
||||
ASSERT(numDrawBuffers > 0);
|
||||
for (buf = 0; buf < numBuffers; buf++) {
|
||||
struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf];
|
||||
|
||||
if (fb->_ColorDrawBuffers[output][0]->DataType
|
||||
!= span->array->ChanType || output > 0) {
|
||||
convert_color_type(span,
|
||||
fb->_ColorDrawBuffers[output][0]->DataType,
|
||||
output);
|
||||
}
|
||||
/* color[fragOutput] will be written to buffer[buf] */
|
||||
|
||||
if (numDrawBuffers > 1) {
|
||||
/* save colors for second, third renderbuffer writes */
|
||||
_mesa_memcpy(rgbaSave, span->array->rgba,
|
||||
4 * span->end * sizeof(GLchan));
|
||||
}
|
||||
if (rb) {
|
||||
GLchan rgbaSave[MAX_WIDTH][4];
|
||||
const GLuint fragOutput = multiFragOutputs ? buf : 0;
|
||||
|
||||
/* Loop over renderbuffers (i.e. GL_FRONT_AND_BACK) */
|
||||
for (buf = 0; buf < numDrawBuffers; buf++) {
|
||||
struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf];
|
||||
ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB);
|
||||
if (rb->DataType != span->array->ChanType || fragOutput > 0) {
|
||||
convert_color_type(span, rb->DataType, fragOutput);
|
||||
}
|
||||
|
||||
if (ctx->Color._LogicOpEnabled) {
|
||||
_swrast_logicop_rgba_span(ctx, rb, span);
|
||||
}
|
||||
else if (ctx->Color.BlendEnabled) {
|
||||
_swrast_blend_span(ctx, rb, span);
|
||||
}
|
||||
if (!multiFragOutputs && numBuffers > 1) {
|
||||
/* save colors for second, third renderbuffer writes */
|
||||
_mesa_memcpy(rgbaSave, span->array->rgba,
|
||||
4 * span->end * sizeof(GLchan));
|
||||
}
|
||||
|
||||
if (colorMask != 0xffffffff) {
|
||||
_swrast_mask_rgba_span(ctx, rb, span);
|
||||
}
|
||||
ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB);
|
||||
|
||||
if (span->arrayMask & SPAN_XY) {
|
||||
/* array of pixel coords */
|
||||
ASSERT(rb->PutValues);
|
||||
rb->PutValues(ctx, rb, span->end,
|
||||
span->array->x, span->array->y,
|
||||
span->array->rgba, span->array->mask);
|
||||
}
|
||||
else {
|
||||
/* horizontal run of pixels */
|
||||
ASSERT(rb->PutRow);
|
||||
rb->PutRow(ctx, rb, span->end, span->x, span->y,
|
||||
span->array->rgba,
|
||||
span->writeAll ? NULL: span->array->mask);
|
||||
}
|
||||
if (ctx->Color._LogicOpEnabled) {
|
||||
_swrast_logicop_rgba_span(ctx, rb, span);
|
||||
}
|
||||
else if (ctx->Color.BlendEnabled) {
|
||||
_swrast_blend_span(ctx, rb, span);
|
||||
}
|
||||
|
||||
if (buf + 1 < numDrawBuffers) {
|
||||
/* restore original span values */
|
||||
_mesa_memcpy(span->array->rgba, rgbaSave,
|
||||
4 * span->end * sizeof(GLchan));
|
||||
}
|
||||
} /* for buf */
|
||||
} /* if output is written to */
|
||||
} /* for output */
|
||||
if (colorMask != 0xffffffff) {
|
||||
_swrast_mask_rgba_span(ctx, rb, span);
|
||||
}
|
||||
|
||||
if (span->arrayMask & SPAN_XY) {
|
||||
/* array of pixel coords */
|
||||
ASSERT(rb->PutValues);
|
||||
rb->PutValues(ctx, rb, span->end,
|
||||
span->array->x, span->array->y,
|
||||
span->array->rgba, span->array->mask);
|
||||
}
|
||||
else {
|
||||
/* horizontal run of pixels */
|
||||
ASSERT(rb->PutRow);
|
||||
rb->PutRow(ctx, rb, span->end, span->x, span->y,
|
||||
span->array->rgba,
|
||||
span->writeAll ? NULL: span->array->mask);
|
||||
}
|
||||
|
||||
if (!multiFragOutputs && numBuffers > 1) {
|
||||
/* restore original span values */
|
||||
_mesa_memcpy(span->array->rgba, rgbaSave,
|
||||
4 * span->end * sizeof(GLchan));
|
||||
}
|
||||
|
||||
} /* if rb */
|
||||
} /* for buf */
|
||||
}
|
||||
|
||||
end:
|
||||
/* restore these values before returning */
|
||||
|
@@ -130,7 +130,7 @@ _swrast_culltriangle( GLcontext *ctx,
|
||||
#define T_SCALE theight
|
||||
|
||||
#define SETUP_CODE \
|
||||
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];\
|
||||
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];\
|
||||
struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \
|
||||
const GLint b = obj->BaseLevel; \
|
||||
const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width; \
|
||||
@@ -182,7 +182,7 @@ _swrast_culltriangle( GLcontext *ctx,
|
||||
#define T_SCALE theight
|
||||
|
||||
#define SETUP_CODE \
|
||||
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];\
|
||||
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];\
|
||||
struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \
|
||||
const GLint b = obj->BaseLevel; \
|
||||
const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width; \
|
||||
|
Reference in New Issue
Block a user