"`OPTION ARB_draw_buffers' or "
"`OPTION ATI_draw_buffers'");
YYERROR;
- } else if ((yyvsp[(2) - (3)].integer) >= state->MaxDrawBuffers) {
+ } else if ((yyvsp[(2) - (3)].integer) > 0) {
yyerror(& (yylsp[(1) - (3)]), state,
"result.color[] exceeds MAX_DRAW_BUFFERS_ARB");
YYERROR;
state->MaxClipPlanes = ctx->Const.MaxClipPlanes;
state->MaxLights = ctx->Const.MaxLights;
state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices;
- state->MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
+ state->MaxDrawBuffers = 1;
state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB)
? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM;
this->Const.MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents;
- this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
+ this->Const.MaxDrawBuffers = 1;
/* Note: Once the OpenGL 3.0 'forward compatible' context or the OpenGL 3.2
* Core context is supported, this logic will need change. Older versions of
goto done;
}
- if (!assign_attribute_or_color_locations(prog, MESA_SHADER_FRAGMENT, ctx->Const.MaxDrawBuffers)) {
+ if (!assign_attribute_or_color_locations(prog, MESA_SHADER_FRAGMENT, 1)) {
goto done;
}
driver->ColorMaterial = NULL;
driver->CullFace = NULL;
driver->DrawBuffer = NULL;
- driver->DrawBuffers = NULL;
driver->FrontFace = NULL;
driver->DepthFunc = NULL;
driver->DepthMask = NULL;
/* GL_ARB_texture_storage */
driver->AllocTextureStorage = _swrast_AllocTextureStorage;
}
-
-
-/**
- * Call the ctx->Driver.* state functions with current values to initialize
- * driver state.
- * Only the Intel drivers use this so far.
- */
-void
-_mesa_init_driver_state(struct gl_context *ctx)
-{
- ctx->Driver.AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
-
- ctx->Driver.BlendColor(ctx, ctx->Color.BlendColor);
-
- ctx->Driver.BlendEquationSeparate(ctx,
- ctx->Color.Blend[0].EquationRGB,
- ctx->Color.Blend[0].EquationA);
-
- ctx->Driver.BlendFuncSeparate(ctx,
- ctx->Color.Blend[0].SrcRGB,
- ctx->Color.Blend[0].DstRGB,
- ctx->Color.Blend[0].SrcA,
- ctx->Color.Blend[0].DstA);
-
- if (ctx->Driver.ColorMaskIndexed) {
- GLuint i;
- for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
- ctx->Driver.ColorMaskIndexed(ctx, i,
- ctx->Color.ColorMask[i][RCOMP],
- ctx->Color.ColorMask[i][GCOMP],
- ctx->Color.ColorMask[i][BCOMP],
- ctx->Color.ColorMask[i][ACOMP]);
- }
- }
- else {
- ctx->Driver.ColorMask(ctx,
- ctx->Color.ColorMask[0][RCOMP],
- ctx->Color.ColorMask[0][GCOMP],
- ctx->Color.ColorMask[0][BCOMP],
- ctx->Color.ColorMask[0][ACOMP]);
- }
-
- ctx->Driver.CullFace(ctx, ctx->Polygon.CullFaceMode);
- ctx->Driver.DepthFunc(ctx, ctx->Depth.Func);
- ctx->Driver.DepthMask(ctx, ctx->Depth.Mask);
-
- ctx->Driver.Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled);
- ctx->Driver.Enable(ctx, GL_BLEND, ctx->Color.BlendEnabled);
- ctx->Driver.Enable(ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled);
- ctx->Driver.Enable(ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled);
- ctx->Driver.Enable(ctx, GL_CULL_FACE, ctx->Polygon.CullFlag);
- ctx->Driver.Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);
- ctx->Driver.Enable(ctx, GL_DITHER, ctx->Color.DitherFlag);
- ctx->Driver.Enable(ctx, GL_FOG, ctx->Fog.Enabled);
- ctx->Driver.Enable(ctx, GL_LIGHTING, ctx->Light.Enabled);
- ctx->Driver.Enable(ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag);
- ctx->Driver.Enable(ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag);
- ctx->Driver.Enable(ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled);
- ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil._Enabled);
- ctx->Driver.Enable(ctx, GL_TEXTURE_1D, GL_FALSE);
- ctx->Driver.Enable(ctx, GL_TEXTURE_2D, GL_FALSE);
- ctx->Driver.Enable(ctx, GL_TEXTURE_3D, GL_FALSE);
- ctx->Driver.Enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE);
-
- ctx->Driver.Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color);
- {
- GLfloat mode = (GLfloat) ctx->Fog.Mode;
- ctx->Driver.Fogfv(ctx, GL_FOG_MODE, &mode);
- }
- ctx->Driver.Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density);
- ctx->Driver.Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start);
- ctx->Driver.Fogfv(ctx, GL_FOG_END, &ctx->Fog.End);
-
- ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
-
- {
- GLfloat f = (GLfloat) ctx->Light.Model.ColorControl;
- ctx->Driver.LightModelfv(ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f);
- }
-
- ctx->Driver.LineWidth(ctx, ctx->Line.Width);
- ctx->Driver.LogicOpcode(ctx, ctx->Color.LogicOp);
- ctx->Driver.PointSize(ctx, ctx->Point.Size);
- ctx->Driver.PolygonStipple(ctx, (const GLubyte *) ctx->PolygonStipple);
- ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
- ctx->Scissor.Width, ctx->Scissor.Height);
- ctx->Driver.ShadeModel(ctx, ctx->Light.ShadeModel);
- ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT,
- ctx->Stencil.Function[0],
- ctx->Stencil.Ref[0],
- ctx->Stencil.ValueMask[0]);
- ctx->Driver.StencilFuncSeparate(ctx, GL_BACK,
- ctx->Stencil.Function[1],
- ctx->Stencil.Ref[1],
- ctx->Stencil.ValueMask[1]);
- ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT, ctx->Stencil.WriteMask[0]);
- ctx->Driver.StencilMaskSeparate(ctx, GL_BACK, ctx->Stencil.WriteMask[1]);
- ctx->Driver.StencilOpSeparate(ctx, GL_FRONT,
- ctx->Stencil.FailFunc[0],
- ctx->Stencil.ZFailFunc[0],
- ctx->Stencil.ZPassFunc[0]);
- ctx->Driver.StencilOpSeparate(ctx, GL_BACK,
- ctx->Stencil.FailFunc[1],
- ctx->Stencil.ZFailFunc[1],
- ctx->Stencil.ZPassFunc[1]);
-
-
- ctx->Driver.DrawBuffer(ctx, ctx->Color.DrawBuffer[0]);
-}
_mesa_init_driver_functions(struct dd_function_table *driver);
-extern void
-_mesa_init_driver_state(struct gl_context *ctx);
-
-
#endif
GLboolean ColorLogicOpEnabled;
/** MESA_META_COLOR_MASK */
- GLubyte ColorMask[MAX_DRAW_BUFFERS][4];
+ GLubyte ColorMask[4];
/** MESA_META_DEPTH_TEST */
struct gl_depthbuffer_attrib Depth;
};
-/**
- * State for glDrawPixels()
- */
-struct drawpix_state
-{
- GLuint ArrayObj;
-
- GLuint StencilFP; /**< Fragment program for drawing stencil images */
- GLuint DepthFP; /**< Fragment program for drawing depth images */
-};
-
-
-/**
- * State for glBitmap()
- */
-struct bitmap_state
-{
- GLuint ArrayObj;
- GLuint VBO;
- struct temp_texture Tex; /**< separate texture from other meta ops */
-};
-
-
/**
* State for _mesa_meta_generate_mipmap()
*/
GLint Width, Height;
};
-/**
- * State for glDrawTex()
- */
-struct drawtex_state
-{
- GLuint ArrayObj;
- GLuint VBO;
-};
-
#define MAX_META_OPS_DEPTH 8
/**
* All per-context meta state.
struct temp_texture TempTex;
- struct blit_state Blit; /**< For _mesa_meta_BlitFramebuffer() */
- struct clear_state Clear; /**< For _mesa_meta_Clear() */
struct copypix_state CopyPix; /**< For _mesa_meta_CopyPixels() */
- struct drawpix_state DrawPix; /**< For _mesa_meta_DrawPixels() */
- struct bitmap_state Bitmap; /**< For _mesa_meta_Bitmap() */
struct gen_mipmap_state Mipmap; /**< For _mesa_meta_GenerateMipmap() */
struct decompress_state Decompress; /**< For texture decompression */
- struct drawtex_state DrawTex; /**< For _mesa_meta_DrawTex() */
};
-static void meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit);
static void cleanup_temp_texture(struct gl_context *ctx, struct temp_texture *tex);
-static void meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear);
-
-static GLuint
-compile_shader_with_debug(struct gl_context *ctx, GLenum target, const GLcharARB *source)
-{
- GLuint shader;
- GLint ok, size;
- GLchar *info;
-
- shader = _mesa_CreateShaderObjectARB(target);
- _mesa_ShaderSourceARB(shader, 1, &source, NULL);
- _mesa_CompileShaderARB(shader);
-
- _mesa_GetShaderiv(shader, GL_COMPILE_STATUS, &ok);
- if (ok)
- return shader;
-
- _mesa_GetShaderiv(shader, GL_INFO_LOG_LENGTH, &size);
- if (size == 0) {
- _mesa_DeleteObjectARB(shader);
- return 0;
- }
-
- info = malloc(size);
- if (!info) {
- _mesa_DeleteObjectARB(shader);
- return 0;
- }
-
- _mesa_GetProgramInfoLog(shader, size, NULL, info);
- _mesa_problem(ctx,
- "meta program compile failed:\n%s\n"
- "source:\n%s\n",
- info, source);
-
- free(info);
- _mesa_DeleteObjectARB(shader);
-
- return 0;
-}
-
-static GLuint
-link_program_with_debug(struct gl_context *ctx, GLuint program)
-{
- GLint ok, size;
- GLchar *info;
-
- _mesa_LinkProgramARB(program);
-
- _mesa_GetProgramiv(program, GL_LINK_STATUS, &ok);
- if (ok)
- return program;
-
- _mesa_GetProgramiv(program, GL_INFO_LOG_LENGTH, &size);
- if (size == 0)
- return 0;
-
- info = malloc(size);
- if (!info)
- return 0;
-
- _mesa_GetProgramInfoLog(program, size, NULL, info);
- _mesa_problem(ctx, "meta program link failed:\n%s", info);
-
- free(info);
-
- return 0;
-}
/**
* Initialize meta-ops for a context.
{
GET_CURRENT_CONTEXT(old_context);
_mesa_make_current(ctx, NULL, NULL);
- meta_glsl_blit_cleanup(ctx, &ctx->Meta->Blit);
- meta_glsl_clear_cleanup(ctx, &ctx->Meta->Clear);
cleanup_temp_texture(ctx, &ctx->Meta->TempTex);
if (old_context)
_mesa_make_current(old_context, old_context->WinSysDrawBuffer, old_context->WinSysReadBuffer);
if (state & MESA_META_COLOR_MASK) {
memcpy(save->ColorMask, ctx->Color.ColorMask,
sizeof(ctx->Color.ColorMask));
- if (!ctx->Color.ColorMask[0][0] ||
- !ctx->Color.ColorMask[0][1] ||
- !ctx->Color.ColorMask[0][2] ||
- !ctx->Color.ColorMask[0][3])
+ if (!ctx->Color.ColorMask[0] ||
+ !ctx->Color.ColorMask[1] ||
+ !ctx->Color.ColorMask[2] ||
+ !ctx->Color.ColorMask[3])
_mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
}
if (state & MESA_META_COLOR_MASK) {
- GLuint i;
- for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
- if (!TEST_EQ_4V(ctx->Color.ColorMask[i], save->ColorMask[i])) {
- if (i == 0) {
- _mesa_ColorMask(save->ColorMask[i][0], save->ColorMask[i][1],
- save->ColorMask[i][2], save->ColorMask[i][3]);
- }
- else {
- _mesa_ColorMaskIndexed(i,
- save->ColorMask[i][0],
- save->ColorMask[i][1],
- save->ColorMask[i][2],
- save->ColorMask[i][3]);
- }
- }
+ if (!TEST_EQ_4V(ctx->Color.ColorMask, save->ColorMask)) {
+ _mesa_ColorMask(save->ColorMask[0], save->ColorMask[1],
+ save->ColorMask[2], save->ColorMask[3]);
}
}
}
-/**
- * Return pointer to temp_texture info for _mesa_meta_bitmap().
- * We use a separate texture for bitmaps to reduce texture
- * allocation/deallocation.
- */
-static struct temp_texture *
-get_bitmap_temp_texture(struct gl_context *ctx)
-{
- struct temp_texture *tex = &ctx->Meta->Bitmap.Tex;
-
- if (!tex->TexObj) {
- init_temp_texture(ctx, tex);
- }
-
- return tex;
-}
-
-
/**
* Compute the width/height of texture needed to draw an image of the
* given size. Return a flag indicating whether the current texture
}
}
-
-/**
- * Setup/load texture for glDrawPixels.
- */
-static void
-setup_drawpix_texture(struct gl_context *ctx,
- struct temp_texture *tex,
- GLboolean newTex,
- GLenum texIntFormat,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const GLvoid *pixels)
-{
- _mesa_BindTexture(tex->Target, tex->TexObj);
- _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
- /* copy pixel data to texture */
- if (newTex) {
- /* create new tex image */
- if (tex->Width == width && tex->Height == height) {
- /* create new tex and load image data */
- _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
- tex->Width, tex->Height, 0, format, type, pixels);
- }
- else {
- struct gl_buffer_object *save_unpack_obj = NULL;
-
- _mesa_reference_buffer_object(ctx, &save_unpack_obj,
- ctx->Unpack.BufferObj);
- _mesa_BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
- /* create empty texture */
- _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
- tex->Width, tex->Height, 0, format, type, NULL);
- if (save_unpack_obj != NULL)
- _mesa_BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
- save_unpack_obj->Name);
- /* load image */
- _mesa_TexSubImage2D(tex->Target, 0,
- 0, 0, width, height, format, type, pixels);
- }
- }
- else {
- /* replace existing tex image */
- _mesa_TexSubImage2D(tex->Target, 0,
- 0, 0, width, height, format, type, pixels);
- }
-}
-
-
-
-/**
- * One-time init for drawing depth pixels.
- */
-static void
-init_blit_depth_pixels(struct gl_context *ctx)
-{
- static const char *program =
- "!!ARBfp1.0\n"
- "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
- "END \n";
- char program2[200];
- struct blit_state *blit = &ctx->Meta->Blit;
- const char *texTarget;
-
- assert(blit->DepthFP == 0);
-
- /* replace %s with "RECT" or "2D" */
- assert(strlen(program) + 4 < sizeof(program2));
- texTarget = "2D";
- _mesa_snprintf(program2, sizeof(program2), program, texTarget);
-
- _mesa_GenPrograms(1, &blit->DepthFP);
- _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
- _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
- strlen(program2), (const GLubyte *) program2);
-}
-
-
-/**
- * Try to do a glBlitFramebuffer using no-copy texturing.
- * We can do this when the src renderbuffer is actually a texture.
- * But if the src buffer == dst buffer we cannot do this.
- *
- * \return new buffer mask indicating the buffers left to blit using the
- * normal path.
- */
-static GLbitfield
-blitframebuffer_texture(struct gl_context *ctx,
- GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
-{
- if (mask & GL_COLOR_BUFFER_BIT) {
- const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
- const struct gl_framebuffer *readFb = ctx->ReadBuffer;
- const struct gl_renderbuffer_attachment *drawAtt =
- &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]];
- const struct gl_renderbuffer_attachment *readAtt =
- &readFb->Attachment[readFb->_ColorReadBufferIndex];
-
- if (readAtt && readAtt->Texture) {
- const struct gl_texture_object *texObj = readAtt->Texture;
- const GLuint srcLevel = readAtt->TextureLevel;
- const GLenum minFilterSave = texObj->Sampler.MinFilter;
- const GLenum magFilterSave = texObj->Sampler.MagFilter;
- const GLint baseLevelSave = texObj->BaseLevel;
- const GLint maxLevelSave = texObj->MaxLevel;
- const GLenum wrapSSave = texObj->Sampler.WrapS;
- const GLenum wrapTSave = texObj->Sampler.WrapT;
- const GLenum target = texObj->Target;
-
- if (drawAtt->Texture == readAtt->Texture) {
- /* Can't use same texture as both the source and dest. We need
- * to handle overlapping blits and besides, some hw may not
- * support this.
- */
- return mask;
- }
-
- if (target != GL_TEXTURE_2D) {
- /* Can't handle other texture types at this time */
- return mask;
- }
-
- /*
- printf("Blit from texture!\n");
- printf(" srcAtt %p dstAtt %p\n", readAtt, drawAtt);
- printf(" srcTex %p dstText %p\n", texObj, drawAtt->Texture);
- */
-
- /* Prepare src texture state */
- _mesa_BindTexture(target, texObj->Name);
- _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
- _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
- _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, srcLevel);
- _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel);
- _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- _mesa_set_enable(ctx, target, GL_TRUE);
-
- /* Prepare vertex data (the VBO was previously created and bound) */
- {
- struct vertex {
- GLfloat x, y, s, t;
- };
- struct vertex verts[4];
- GLfloat s0, t0, s1, t1;
-
- const struct gl_texture_image *texImage
- = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
- s0 = srcX0 / (float) texImage->Width;
- s1 = srcX1 / (float) texImage->Width;
- t0 = srcY0 / (float) texImage->Height;
- t1 = srcY1 / (float) texImage->Height;
-
- verts[0].x = (GLfloat) dstX0;
- verts[0].y = (GLfloat) dstY0;
- verts[1].x = (GLfloat) dstX1;
- verts[1].y = (GLfloat) dstY0;
- verts[2].x = (GLfloat) dstX1;
- verts[2].y = (GLfloat) dstY1;
- verts[3].x = (GLfloat) dstX0;
- verts[3].y = (GLfloat) dstY1;
-
- verts[0].s = s0;
- verts[0].t = t0;
- verts[1].s = s1;
- verts[1].t = t0;
- verts[2].s = s1;
- verts[2].t = t1;
- verts[3].s = s0;
- verts[3].t = t1;
-
- _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
- }
-
- _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- /* Restore texture object state, the texture binding will
- * be restored by _mesa_meta_end().
- */
- _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilterSave);
- _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilterSave);
- _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave);
- _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave);
- _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, wrapSSave);
- _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, wrapTSave);
-
- /* Done with color buffer */
- mask &= ~GL_COLOR_BUFFER_BIT;
- }
- }
-
- return mask;
-}
-
-
/**
- * Meta implementation of ctx->Driver.BlitFramebuffer() in terms
- * of texture mapping and polygon rendering.
+ * Meta implementation of ctx->Driver.CopyPixels() in terms
+ * of texture mapping and polygon rendering and GLSL shaders.
*/
void
-_mesa_meta_BlitFramebuffer(struct gl_context *ctx,
- GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
+_mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY,
+ GLsizei width, GLsizei height,
+ GLint dstX, GLint dstY, GLenum type)
{
- struct blit_state *blit = &ctx->Meta->Blit;
+ struct copypix_state *copypix = &ctx->Meta->CopyPix;
struct temp_texture *tex = get_temp_texture(ctx);
- const GLsizei maxTexSize = tex->MaxSize;
- const GLint srcX = MIN2(srcX0, srcX1);
- const GLint srcY = MIN2(srcY0, srcY1);
- const GLint srcW = abs(srcX1 - srcX0);
- const GLint srcH = abs(srcY1 - srcY0);
- const GLboolean srcFlipX = srcX1 < srcX0;
- const GLboolean srcFlipY = srcY1 < srcY0;
struct vertex {
- GLfloat x, y, s, t;
+ GLfloat x, y, z, s, t;
};
struct vertex verts[4];
GLboolean newTex;
+ GLenum intFormat = GL_RGBA;
- /* In addition to falling back if the blit size is larger than the maximum
- * texture size, fallback if the source is multisampled. This fallback can
- * be removed once Mesa gets support ARB_texture_multisample.
- */
- if (srcW > maxTexSize || srcH > maxTexSize
- || ctx->ReadBuffer->Visual.samples > 0) {
+ if (type != GL_COLOR ||
+ ctx->_ImageTransferState ||
+ ctx->Fog.Enabled ||
+ width > tex->MaxSize ||
+ height > tex->MaxSize) {
/* XXX avoid this fallback */
- _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1, mask, filter);
+ _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type);
return;
}
- if (srcFlipX) {
- GLint tmp = dstX0;
- dstX0 = dstX1;
- dstX1 = tmp;
- }
-
- if (srcFlipY) {
- GLint tmp = dstY0;
- dstY0 = dstY1;
- dstY1 = tmp;
- }
-
- /* only scissor effects blit so save/clear all other relevant state */
- _mesa_meta_begin(ctx, ~MESA_META_SCISSOR);
+ /* Most GL state applies to glCopyPixels, but a there's a few things
+ * we need to override:
+ */
+ _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION |
+ MESA_META_SHADER |
+ MESA_META_TEXTURE |
+ MESA_META_TRANSFORM |
+ MESA_META_CLIP |
+ MESA_META_VERTEX |
+ MESA_META_VIEWPORT));
- if (blit->ArrayObj == 0) {
+ if (copypix->ArrayObj == 0) {
/* one-time setup */
/* create vertex array object */
- _mesa_GenVertexArrays(1, &blit->ArrayObj);
- _mesa_BindVertexArray(blit->ArrayObj);
+ _mesa_GenVertexArrays(1, ©pix->ArrayObj);
+ _mesa_BindVertexArray(copypix->ArrayObj);
/* create vertex array buffer */
- _mesa_GenBuffersARB(1, &blit->VBO);
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
+ _mesa_GenBuffersARB(1, ©pix->VBO);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
_mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
NULL, GL_DYNAMIC_DRAW_ARB);
/* setup vertex arrays */
- _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
+ _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
_mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
_mesa_EnableClientState(GL_VERTEX_ARRAY);
_mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
}
else {
- _mesa_BindVertexArray(blit->ArrayObj);
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
- }
-
- /* Try faster, direct texture approach first */
- mask = blitframebuffer_texture(ctx, srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1, mask, filter);
- if (mask == 0x0) {
- _mesa_meta_end(ctx);
- return;
+ _mesa_BindVertexArray(copypix->ArrayObj);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
}
- /* Continue with "normal" approach which involves copying the src rect
- * into a temporary texture and is "blitted" by drawing a textured quad.
- */
-
- newTex = alloc_texture(tex, srcW, srcH, GL_RGBA);
+ newTex = alloc_texture(tex, width, height, intFormat);
- /* vertex positions/texcoords (after texture allocation!) */
+ /* vertex positions, texcoords (after texture allocation!) */
{
- verts[0].x = (GLfloat) dstX0;
- verts[0].y = (GLfloat) dstY0;
- verts[1].x = (GLfloat) dstX1;
- verts[1].y = (GLfloat) dstY0;
- verts[2].x = (GLfloat) dstX1;
- verts[2].y = (GLfloat) dstY1;
- verts[3].x = (GLfloat) dstX0;
- verts[3].y = (GLfloat) dstY1;
+ const GLfloat dstX0 = (GLfloat) dstX;
+ const GLfloat dstY0 = (GLfloat) dstY;
+ const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX;
+ const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY;
+ const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
+ verts[0].x = dstX0;
+ verts[0].y = dstY0;
+ verts[0].z = z;
verts[0].s = 0.0F;
verts[0].t = 0.0F;
+ verts[1].x = dstX1;
+ verts[1].y = dstY0;
+ verts[1].z = z;
verts[1].s = tex->Sright;
verts[1].t = 0.0F;
+ verts[2].x = dstX1;
+ verts[2].y = dstY1;
+ verts[2].z = z;
verts[2].s = tex->Sright;
verts[2].t = tex->Ttop;
+ verts[3].x = dstX0;
+ verts[3].y = dstY1;
+ verts[3].z = z;
verts[3].s = 0.0F;
verts[3].t = tex->Ttop;
_mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
}
- _mesa_set_enable(ctx, tex->Target, GL_TRUE);
-
- if (mask & GL_COLOR_BUFFER_BIT) {
- setup_copypix_texture(tex, newTex, srcX, srcY, srcW, srcH,
- GL_RGBA, filter);
- _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
- mask &= ~GL_COLOR_BUFFER_BIT;
- }
-
- if (mask & GL_DEPTH_BUFFER_BIT) {
- GLuint *tmp = (GLuint *) malloc(srcW * srcH * sizeof(GLuint));
- if (tmp) {
- if (!blit->DepthFP)
- init_blit_depth_pixels(ctx);
-
- /* maybe change tex format here */
- newTex = alloc_texture(tex, srcW, srcH, GL_DEPTH_COMPONENT);
-
- _mesa_ReadPixels(srcX, srcY, srcW, srcH,
- GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
-
- setup_drawpix_texture(ctx, tex, newTex, GL_DEPTH_COMPONENT, srcW, srcH,
- GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
-
- _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
- _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
- _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
- _mesa_DepthFunc(GL_ALWAYS);
- _mesa_DepthMask(GL_TRUE);
-
- _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
- mask &= ~GL_DEPTH_BUFFER_BIT;
+ /* Alloc/setup texture */
+ setup_copypix_texture(tex, newTex, srcX, srcY, width, height,
+ GL_RGBA, GL_NEAREST);
- free(tmp);
- }
- }
+ _mesa_set_enable(ctx, tex->Target, GL_TRUE);
- if (mask & GL_STENCIL_BUFFER_BIT) {
- /* XXX can't easily do stencil */
- }
+ /* draw textured quad */
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
_mesa_set_enable(ctx, tex->Target, GL_FALSE);
_mesa_meta_end(ctx);
-
- if (mask) {
- _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1, mask, filter);
- }
-}
-
-static void
-meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit)
-{
- if (blit->ArrayObj) {
- _mesa_DeleteVertexArraysAPPLE(1, &blit->ArrayObj);
- blit->ArrayObj = 0;
- _mesa_DeleteBuffersARB(1, &blit->VBO);
- blit->VBO = 0;
- }
- if (blit->DepthFP) {
- _mesa_DeletePrograms(1, &blit->DepthFP);
- blit->DepthFP = 0;
- }
}
-
-/**
- * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
- */
-void
-_mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers)
-{
- struct clear_state *clear = &ctx->Meta->Clear;
- struct vertex {
- GLfloat x, y, z, r, g, b, a;
- };
- struct vertex verts[4];
- /* save all state but scissor, pixel pack/unpack */
- GLbitfield metaSave = (MESA_META_ALL -
- MESA_META_SCISSOR -
- MESA_META_PIXEL_STORE);
- const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
-
- if (buffers & BUFFER_BITS_COLOR) {
- /* if clearing color buffers, don't save/restore colormask */
- metaSave -= MESA_META_COLOR_MASK;
- }
-
- _mesa_meta_begin(ctx, metaSave);
-
- if (clear->ArrayObj == 0) {
- /* one-time setup */
-
- /* create vertex array object */
- _mesa_GenVertexArrays(1, &clear->ArrayObj);
- _mesa_BindVertexArray(clear->ArrayObj);
-
- /* create vertex array buffer */
- _mesa_GenBuffersARB(1, &clear->VBO);
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
-
- /* setup vertex arrays */
- _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
- _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
- _mesa_EnableClientState(GL_VERTEX_ARRAY);
- _mesa_EnableClientState(GL_COLOR_ARRAY);
- }
- else {
- _mesa_BindVertexArray(clear->ArrayObj);
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
- }
-
- /* GL_COLOR_BUFFER_BIT */
- if (buffers & BUFFER_BITS_COLOR) {
- /* leave colormask, glDrawBuffer state as-is */
-
- /* Clears never have the color clamped. */
- _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
- }
- else {
- ASSERT(metaSave & MESA_META_COLOR_MASK);
- _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- }
-
- /* GL_DEPTH_BUFFER_BIT */
- if (buffers & BUFFER_BIT_DEPTH) {
- _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
- _mesa_DepthFunc(GL_ALWAYS);
- _mesa_DepthMask(GL_TRUE);
- }
- else {
- assert(!ctx->Depth.Test);
- }
-
- /* GL_STENCIL_BUFFER_BIT */
- if (buffers & BUFFER_BIT_STENCIL) {
- _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
- _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
- GL_REPLACE, GL_REPLACE, GL_REPLACE);
- _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
- ctx->Stencil.Clear & stencilMax,
- ctx->Stencil.WriteMask[0]);
- }
- else {
- assert(!ctx->Stencil.Enabled);
- }
-
- /* vertex positions/colors */
- {
- const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin;
- const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin;
- const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax;
- const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax;
- const GLfloat z = invert_z(ctx->Depth.Clear);
- GLuint i;
-
- verts[0].x = x0;
- verts[0].y = y0;
- verts[0].z = z;
- verts[1].x = x1;
- verts[1].y = y0;
- verts[1].z = z;
- verts[2].x = x1;
- verts[2].y = y1;
- verts[2].z = z;
- verts[3].x = x0;
- verts[3].y = y1;
- verts[3].z = z;
-
- /* vertex colors */
- for (i = 0; i < 4; i++) {
- verts[i].r = ctx->Color.ClearColor.f[0];
- verts[i].g = ctx->Color.ClearColor.f[1];
- verts[i].b = ctx->Color.ClearColor.f[2];
- verts[i].a = ctx->Color.ClearColor.f[3];
- }
-
- /* upload new vertex data */
- _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
- GL_DYNAMIC_DRAW_ARB);
- }
-
- /* draw quad */
- _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- _mesa_meta_end(ctx);
-}
-
-static void
-meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
-{
- const char *vs_source =
- "attribute vec4 position;\n"
- "void main()\n"
- "{\n"
- " gl_Position = position;\n"
- "}\n";
- const char *fs_source =
- "uniform vec4 color;\n"
- "void main()\n"
- "{\n"
- " gl_FragColor = color;\n"
- "}\n";
- const char *vs_int_source =
- "#version 130\n"
- "attribute vec4 position;\n"
- "void main()\n"
- "{\n"
- " gl_Position = position;\n"
- "}\n";
- const char *fs_int_source =
- "#version 130\n"
- "uniform ivec4 color;\n"
- "out ivec4 out_color;\n"
- "\n"
- "void main()\n"
- "{\n"
- " out_color = color;\n"
- "}\n";
- GLuint vs, fs;
-
- if (clear->ArrayObj != 0)
- return;
-
- /* create vertex array object */
- _mesa_GenVertexArrays(1, &clear->ArrayObj);
- _mesa_BindVertexArray(clear->ArrayObj);
-
- /* create vertex array buffer */
- _mesa_GenBuffersARB(1, &clear->VBO);
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
-
- /* setup vertex arrays */
- _mesa_VertexAttribPointerARB(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
- _mesa_EnableVertexAttribArrayARB(0);
-
- vs = _mesa_CreateShaderObjectARB(GL_VERTEX_SHADER);
- _mesa_ShaderSourceARB(vs, 1, &vs_source, NULL);
- _mesa_CompileShaderARB(vs);
-
- fs = _mesa_CreateShaderObjectARB(GL_FRAGMENT_SHADER);
- _mesa_ShaderSourceARB(fs, 1, &fs_source, NULL);
- _mesa_CompileShaderARB(fs);
-
- clear->ShaderProg = _mesa_CreateProgramObjectARB();
- _mesa_AttachShader(clear->ShaderProg, fs);
- _mesa_DeleteObjectARB(fs);
- _mesa_AttachShader(clear->ShaderProg, vs);
- _mesa_DeleteObjectARB(vs);
- _mesa_BindAttribLocationARB(clear->ShaderProg, 0, "position");
- _mesa_LinkProgramARB(clear->ShaderProg);
-
- clear->ColorLocation = _mesa_GetUniformLocationARB(clear->ShaderProg,
- "color");
-
- if (ctx->Const.GLSLVersion >= 130) {
- vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_int_source);
- fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_int_source);
-
- clear->IntegerShaderProg = _mesa_CreateProgramObjectARB();
- _mesa_AttachShader(clear->IntegerShaderProg, fs);
- _mesa_DeleteObjectARB(fs);
- _mesa_AttachShader(clear->IntegerShaderProg, vs);
- _mesa_DeleteObjectARB(vs);
- _mesa_BindAttribLocationARB(clear->IntegerShaderProg, 0, "position");
-
- /* Note that user-defined out attributes get automatically assigned
- * locations starting from 0, so we don't need to explicitly
- * BindFragDataLocation to 0.
- */
-
- link_program_with_debug(ctx, clear->IntegerShaderProg);
-
- clear->IntegerColorLocation =
- _mesa_GetUniformLocationARB(clear->IntegerShaderProg, "color");
- }
-}
-
-static void
-meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear)
-{
- if (clear->ArrayObj == 0)
- return;
- _mesa_DeleteVertexArraysAPPLE(1, &clear->ArrayObj);
- clear->ArrayObj = 0;
- _mesa_DeleteBuffersARB(1, &clear->VBO);
- clear->VBO = 0;
- _mesa_DeleteObjectARB(clear->ShaderProg);
- clear->ShaderProg = 0;
-
- if (clear->IntegerShaderProg) {
- _mesa_DeleteObjectARB(clear->IntegerShaderProg);
- clear->IntegerShaderProg = 0;
- }
-}
-
-/**
- * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
- */
-void
-_mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers)
-{
- struct clear_state *clear = &ctx->Meta->Clear;
- GLbitfield metaSave;
- const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
- struct gl_framebuffer *fb = ctx->DrawBuffer;
- const float x0 = ((float)fb->_Xmin / fb->Width) * 2.0f - 1.0f;
- const float y0 = ((float)fb->_Ymin / fb->Height) * 2.0f - 1.0f;
- const float x1 = ((float)fb->_Xmax / fb->Width) * 2.0f - 1.0f;
- const float y1 = ((float)fb->_Ymax / fb->Height) * 2.0f - 1.0f;
- const float z = -invert_z(ctx->Depth.Clear);
- struct vertex {
- GLfloat x, y, z;
- } verts[4];
-
- metaSave = (MESA_META_ALPHA_TEST |
- MESA_META_BLEND |
- MESA_META_DEPTH_TEST |
- MESA_META_RASTERIZATION |
- MESA_META_SHADER |
- MESA_META_STENCIL_TEST |
- MESA_META_VERTEX |
- MESA_META_VIEWPORT |
- MESA_META_CLIP |
- MESA_META_CLAMP_FRAGMENT_COLOR);
-
- if (!(buffers & BUFFER_BITS_COLOR)) {
- /* We'll use colormask to disable color writes. Otherwise,
- * respect color mask
- */
- metaSave |= MESA_META_COLOR_MASK;
- }
-
- _mesa_meta_begin(ctx, metaSave);
-
- meta_glsl_clear_init(ctx, clear);
-
- if (fb->_IntegerColor) {
- _mesa_UseProgramObjectARB(clear->IntegerShaderProg);
- _mesa_Uniform4ivARB(clear->IntegerColorLocation, 1,
- ctx->Color.ClearColor.i);
- } else {
- _mesa_UseProgramObjectARB(clear->ShaderProg);
- _mesa_Uniform4fvARB(clear->ColorLocation, 1,
- ctx->Color.ClearColor.f);
- }
-
- _mesa_BindVertexArray(clear->ArrayObj);
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
-
- /* GL_COLOR_BUFFER_BIT */
- if (buffers & BUFFER_BITS_COLOR) {
- /* leave colormask, glDrawBuffer state as-is */
-
- /* Clears never have the color clamped. */
- _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
- }
- else {
- ASSERT(metaSave & MESA_META_COLOR_MASK);
- _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- }
-
- /* GL_DEPTH_BUFFER_BIT */
- if (buffers & BUFFER_BIT_DEPTH) {
- _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
- _mesa_DepthFunc(GL_ALWAYS);
- _mesa_DepthMask(GL_TRUE);
- }
- else {
- assert(!ctx->Depth.Test);
- }
-
- /* GL_STENCIL_BUFFER_BIT */
- if (buffers & BUFFER_BIT_STENCIL) {
- _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
- _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
- GL_REPLACE, GL_REPLACE, GL_REPLACE);
- _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
- ctx->Stencil.Clear & stencilMax,
- ctx->Stencil.WriteMask[0]);
- }
- else {
- assert(!ctx->Stencil.Enabled);
- }
-
- /* vertex positions */
- verts[0].x = x0;
- verts[0].y = y0;
- verts[0].z = z;
- verts[1].x = x1;
- verts[1].y = y0;
- verts[1].z = z;
- verts[2].x = x1;
- verts[2].y = y1;
- verts[2].z = z;
- verts[3].x = x0;
- verts[3].y = y1;
- verts[3].z = z;
-
- /* upload new vertex data */
- _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
- GL_DYNAMIC_DRAW_ARB);
-
- /* draw quad */
- _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- _mesa_meta_end(ctx);
-}
-
-/**
- * Meta implementation of ctx->Driver.CopyPixels() in terms
- * of texture mapping and polygon rendering and GLSL shaders.
- */
-void
-_mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY,
- GLsizei width, GLsizei height,
- GLint dstX, GLint dstY, GLenum type)
-{
- struct copypix_state *copypix = &ctx->Meta->CopyPix;
- struct temp_texture *tex = get_temp_texture(ctx);
- struct vertex {
- GLfloat x, y, z, s, t;
- };
- struct vertex verts[4];
- GLboolean newTex;
- GLenum intFormat = GL_RGBA;
-
- if (type != GL_COLOR ||
- ctx->_ImageTransferState ||
- ctx->Fog.Enabled ||
- width > tex->MaxSize ||
- height > tex->MaxSize) {
- /* XXX avoid this fallback */
- _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type);
- return;
- }
-
- /* Most GL state applies to glCopyPixels, but a there's a few things
- * we need to override:
- */
- _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION |
- MESA_META_SHADER |
- MESA_META_TEXTURE |
- MESA_META_TRANSFORM |
- MESA_META_CLIP |
- MESA_META_VERTEX |
- MESA_META_VIEWPORT));
-
- if (copypix->ArrayObj == 0) {
- /* one-time setup */
-
- /* create vertex array object */
- _mesa_GenVertexArrays(1, ©pix->ArrayObj);
- _mesa_BindVertexArray(copypix->ArrayObj);
-
- /* create vertex array buffer */
- _mesa_GenBuffersARB(1, ©pix->VBO);
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
- _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
- NULL, GL_DYNAMIC_DRAW_ARB);
-
- /* setup vertex arrays */
- _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
- _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
- _mesa_EnableClientState(GL_VERTEX_ARRAY);
- _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
- }
- else {
- _mesa_BindVertexArray(copypix->ArrayObj);
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
- }
-
- newTex = alloc_texture(tex, width, height, intFormat);
-
- /* vertex positions, texcoords (after texture allocation!) */
- {
- const GLfloat dstX0 = (GLfloat) dstX;
- const GLfloat dstY0 = (GLfloat) dstY;
- const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX;
- const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY;
- const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
-
- verts[0].x = dstX0;
- verts[0].y = dstY0;
- verts[0].z = z;
- verts[0].s = 0.0F;
- verts[0].t = 0.0F;
- verts[1].x = dstX1;
- verts[1].y = dstY0;
- verts[1].z = z;
- verts[1].s = tex->Sright;
- verts[1].t = 0.0F;
- verts[2].x = dstX1;
- verts[2].y = dstY1;
- verts[2].z = z;
- verts[2].s = tex->Sright;
- verts[2].t = tex->Ttop;
- verts[3].x = dstX0;
- verts[3].y = dstY1;
- verts[3].z = z;
- verts[3].s = 0.0F;
- verts[3].t = tex->Ttop;
-
- /* upload new vertex data */
- _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
- }
-
- /* Alloc/setup texture */
- setup_copypix_texture(tex, newTex, srcX, srcY, width, height,
- GL_RGBA, GL_NEAREST);
-
- _mesa_set_enable(ctx, tex->Target, GL_TRUE);
-
- /* draw textured quad */
- _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- _mesa_set_enable(ctx, tex->Target, GL_FALSE);
-
- _mesa_meta_end(ctx);
-}
-
-
-
-/**
- * When the glDrawPixels() image size is greater than the max rectangle
- * texture size we use this function to break the glDrawPixels() image
- * into tiles which fit into the max texture size.
- */
-static void
-tiled_draw_pixels(struct gl_context *ctx,
- GLint tileSize,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const struct gl_pixelstore_attrib *unpack,
- const GLvoid *pixels)
-{
- struct gl_pixelstore_attrib tileUnpack = *unpack;
- GLint i, j;
-
- if (tileUnpack.RowLength == 0)
- tileUnpack.RowLength = width;
-
- for (i = 0; i < width; i += tileSize) {
- const GLint tileWidth = MIN2(tileSize, width - i);
- const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX);
-
- tileUnpack.SkipPixels = unpack->SkipPixels + i;
-
- for (j = 0; j < height; j += tileSize) {
- const GLint tileHeight = MIN2(tileSize, height - j);
- const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY);
-
- tileUnpack.SkipRows = unpack->SkipRows + j;
-
- _mesa_meta_DrawPixels(ctx, tileX, tileY, tileWidth, tileHeight,
- format, type, &tileUnpack, pixels);
- }
- }
-}
-
-
-/**
- * One-time init for drawing stencil pixels.
- */
-static void
-init_draw_stencil_pixels(struct gl_context *ctx)
-{
- /* This program is run eight times, once for each stencil bit.
- * The stencil values to draw are found in an 8-bit alpha texture.
- * We read the texture/stencil value and test if bit 'b' is set.
- * If the bit is not set, use KIL to kill the fragment.
- * Finally, we use the stencil test to update the stencil buffer.
- *
- * The basic algorithm for checking if a bit is set is:
- * if (is_odd(value / (1 << bit)))
- * result is one (or non-zero).
- * else
- * result is zero.
- * The program parameter contains three values:
- * parm.x = 255 / (1 << bit)
- * parm.y = 0.5
- * parm.z = 0.0
- */
- static const char *program =
- "!!ARBfp1.0\n"
- "PARAM parm = program.local[0]; \n"
- "TEMP t; \n"
- "TEX t, fragment.texcoord[0], texture[0], %s; \n" /* NOTE %s here! */
- "# t = t * 255 / bit \n"
- "MUL t.x, t.a, parm.x; \n"
- "# t = (int) t \n"
- "FRC t.y, t.x; \n"
- "SUB t.x, t.x, t.y; \n"
- "# t = t * 0.5 \n"
- "MUL t.x, t.x, parm.y; \n"
- "# t = fract(t.x) \n"
- "FRC t.x, t.x; # if t.x != 0, then the bit is set \n"
- "# t.x = (t.x == 0 ? 1 : 0) \n"
- "SGE t.x, -t.x, parm.z; \n"
- "KIL -t.x; \n"
- "# for debug only \n"
- "#MOV result.color, t.x; \n"
- "END \n";
- char program2[1000];
- struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
- const char *texTarget;
-
- assert(drawpix->StencilFP == 0);
-
- /* replace %s with "RECT" or "2D" */
- assert(strlen(program) + 4 < sizeof(program2));
- texTarget = "2D";
- _mesa_snprintf(program2, sizeof(program2), program, texTarget);
-
- _mesa_GenPrograms(1, &drawpix->StencilFP);
- _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
- _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
- strlen(program2), (const GLubyte *) program2);
-}
-
-
-/**
- * One-time init for drawing depth pixels.
- */
-static void
-init_draw_depth_pixels(struct gl_context *ctx)
-{
- static const char *program =
- "!!ARBfp1.0\n"
- "PARAM color = program.local[0]; \n"
- "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
- "MOV result.color, color; \n"
- "END \n";
- char program2[200];
- struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
- const char *texTarget;
-
- assert(drawpix->DepthFP == 0);
-
- /* replace %s with "RECT" or "2D" */
- assert(strlen(program) + 4 < sizeof(program2));
- texTarget = "2D";
- _mesa_snprintf(program2, sizeof(program2), program, texTarget);
-
- _mesa_GenPrograms(1, &drawpix->DepthFP);
- _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
- _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
- strlen(program2), (const GLubyte *) program2);
-}
-
-
-/**
- * Meta implementation of ctx->Driver.DrawPixels() in terms
- * of texture mapping and polygon rendering.
- */
-void
-_mesa_meta_DrawPixels(struct gl_context *ctx,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const struct gl_pixelstore_attrib *unpack,
- const GLvoid *pixels)
-{
- struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
- struct temp_texture *tex = get_temp_texture(ctx);
- const struct gl_pixelstore_attrib unpackSave = ctx->Unpack;
- const GLuint origStencilMask = ctx->Stencil.WriteMask[0];
- struct vertex {
- GLfloat x, y, z, s, t;
- };
- struct vertex verts[4];
- GLenum texIntFormat;
- GLboolean fallback, newTex;
- GLbitfield metaExtraSave = 0x0;
- GLuint vbo;
-
- /*
- * Determine if we can do the glDrawPixels with texture mapping.
- */
- fallback = GL_FALSE;
- if (ctx->_ImageTransferState ||
- ctx->Fog.Enabled) {
- fallback = GL_TRUE;
- }
-
- if (_mesa_is_color_format(format)) {
- /* use more compact format when possible */
- /* XXX disable special case for GL_LUMINANCE for now to work around
- * apparent i965 driver bug (see bug #23670).
- */
- if (/*format == GL_LUMINANCE ||*/ format == GL_LUMINANCE_ALPHA)
- texIntFormat = format;
- else
- texIntFormat = GL_RGBA;
-
- /* If we're not supposed to clamp the resulting color, then just
- * promote our texture to fully float. We could do better by
- * just going for the matching set of channels, in floating
- * point.
- */
- if (ctx->Color.ClampFragmentColor != GL_TRUE &&
- ctx->Extensions.ARB_texture_float)
- texIntFormat = GL_RGBA32F;
- }
- else if (_mesa_is_stencil_format(format)) {
- if (ctx->Extensions.ARB_fragment_program &&
- ctx->Pixel.IndexShift == 0 &&
- ctx->Pixel.IndexOffset == 0 &&
- type == GL_UNSIGNED_BYTE) {
- /* We'll store stencil as alpha. This only works for GLubyte
- * image data because of how incoming values are mapped to alpha
- * in [0,1].
- */
- texIntFormat = GL_ALPHA;
- metaExtraSave = (MESA_META_COLOR_MASK |
- MESA_META_DEPTH_TEST |
- MESA_META_SHADER |
- MESA_META_STENCIL_TEST);
- }
- else {
- fallback = GL_TRUE;
- }
- }
- else if (_mesa_is_depth_format(format)) {
- fallback = GL_TRUE;
- }
- else {
- fallback = GL_TRUE;
- }
-
- if (fallback) {
- _swrast_DrawPixels(ctx, x, y, width, height,
- format, type, unpack, pixels);
- return;
- }
-
- /*
- * Check image size against max texture size, draw as tiles if needed.
- */
- if (width > tex->MaxSize || height > tex->MaxSize) {
- tiled_draw_pixels(ctx, tex->MaxSize, x, y, width, height,
- format, type, unpack, pixels);
- return;
- }
-
- /* Most GL state applies to glDrawPixels (like blending, stencil, etc),
- * but a there's a few things we need to override:
- */
- _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION |
- MESA_META_SHADER |
- MESA_META_TEXTURE |
- MESA_META_TRANSFORM |
- MESA_META_CLIP |
- MESA_META_VERTEX |
- MESA_META_VIEWPORT |
- MESA_META_CLAMP_FRAGMENT_COLOR |
- metaExtraSave));
-
- newTex = alloc_texture(tex, width, height, texIntFormat);
-
- /* vertex positions, texcoords (after texture allocation!) */
- {
- const GLfloat x0 = (GLfloat) x;
- const GLfloat y0 = (GLfloat) y;
- const GLfloat x1 = x + width * ctx->Pixel.ZoomX;
- const GLfloat y1 = y + height * ctx->Pixel.ZoomY;
- const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
-
- verts[0].x = x0;
- verts[0].y = y0;
- verts[0].z = z;
- verts[0].s = 0.0F;
- verts[0].t = 0.0F;
- verts[1].x = x1;
- verts[1].y = y0;
- verts[1].z = z;
- verts[1].s = tex->Sright;
- verts[1].t = 0.0F;
- verts[2].x = x1;
- verts[2].y = y1;
- verts[2].z = z;
- verts[2].s = tex->Sright;
- verts[2].t = tex->Ttop;
- verts[3].x = x0;
- verts[3].y = y1;
- verts[3].z = z;
- verts[3].s = 0.0F;
- verts[3].t = tex->Ttop;
- }
-
- if (drawpix->ArrayObj == 0) {
- /* one-time setup: create vertex array object */
- _mesa_GenVertexArrays(1, &drawpix->ArrayObj);
- }
- _mesa_BindVertexArray(drawpix->ArrayObj);
-
- /* create vertex array buffer */
- _mesa_GenBuffersARB(1, &vbo);
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
- _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
- verts, GL_DYNAMIC_DRAW_ARB);
-
- /* setup vertex arrays */
- _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
- _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
- _mesa_EnableClientState(GL_VERTEX_ARRAY);
- _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- /* set given unpack params */
- ctx->Unpack = *unpack;
-
- _mesa_set_enable(ctx, tex->Target, GL_TRUE);
-
- if (_mesa_is_stencil_format(format)) {
- /* Drawing stencil */
- GLint bit;
-
- if (!drawpix->StencilFP)
- init_draw_stencil_pixels(ctx);
-
- setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
- GL_ALPHA, type, pixels);
-
- _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
- _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
-
- /* set all stencil bits to 0 */
- _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
- _mesa_StencilFunc(GL_ALWAYS, 0, 255);
- _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- /* set stencil bits to 1 where needed */
- _mesa_StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
-
- _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
- _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
-
- for (bit = 0; bit < ctx->DrawBuffer->Visual.stencilBits; bit++) {
- const GLuint mask = 1 << bit;
- if (mask & origStencilMask) {
- _mesa_StencilFunc(GL_ALWAYS, mask, mask);
- _mesa_StencilMask(mask);
-
- _mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0,
- 255.0 / mask, 0.5, 0.0, 0.0);
-
- _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
- }
- }
- else if (_mesa_is_depth_format(format)) {
- /* Drawing depth */
- if (!drawpix->DepthFP)
- init_draw_depth_pixels(ctx);
-
- _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
- _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
-
- /* polygon color = current raster color */
- _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0,
- ctx->Current.RasterColor);
-
- setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
- format, type, pixels);
-
- _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
- else {
- /* Drawing RGBA */
- setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
- format, type, pixels);
- _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
-
- _mesa_set_enable(ctx, tex->Target, GL_FALSE);
-
- _mesa_DeleteBuffersARB(1, &vbo);
-
- /* restore unpack params */
- ctx->Unpack = unpackSave;
-
- _mesa_meta_end(ctx);
-}
-
-static GLboolean
-alpha_test_raster_color(struct gl_context *ctx)
-{
- GLfloat alpha = ctx->Current.RasterColor[ACOMP];
- GLfloat ref = ctx->Color.AlphaRef;
-
- switch (ctx->Color.AlphaFunc) {
- case GL_NEVER:
- return GL_FALSE;
- case GL_LESS:
- return alpha < ref;
- case GL_EQUAL:
- return alpha == ref;
- case GL_LEQUAL:
- return alpha <= ref;
- case GL_GREATER:
- return alpha > ref;
- case GL_NOTEQUAL:
- return alpha != ref;
- case GL_GEQUAL:
- return alpha >= ref;
- case GL_ALWAYS:
- return GL_TRUE;
- default:
- assert(0);
- return GL_FALSE;
- }
-}
-
-/**
- * Do glBitmap with a alpha texture quad. Use the alpha test to cull
- * the 'off' bits. A bitmap cache as in the gallium/mesa state
- * tracker would improve performance a lot.
- */
-void
-_mesa_meta_Bitmap(struct gl_context *ctx,
- GLint x, GLint y, GLsizei width, GLsizei height,
- const struct gl_pixelstore_attrib *unpack,
- const GLubyte *bitmap1)
-{
- struct bitmap_state *bitmap = &ctx->Meta->Bitmap;
- struct temp_texture *tex = get_bitmap_temp_texture(ctx);
- const GLenum texIntFormat = GL_ALPHA;
- const struct gl_pixelstore_attrib unpackSave = *unpack;
- GLubyte fg, bg;
- struct vertex {
- GLfloat x, y, z, s, t, r, g, b, a;
- };
- struct vertex verts[4];
- GLboolean newTex;
- GLubyte *bitmap8;
-
- /*
- * Check if swrast fallback is needed.
- */
- if (ctx->_ImageTransferState ||
- ctx->FragmentProgram._Enabled ||
- ctx->Fog.Enabled ||
- ctx->Texture._EnabledUnits ||
- width > tex->MaxSize ||
- height > tex->MaxSize) {
- _swrast_Bitmap(ctx, x, y, width, height, unpack, bitmap1);
- return;
- }
-
- if (ctx->Color.AlphaEnabled && !alpha_test_raster_color(ctx))
- return;
-
- /* Most GL state applies to glBitmap (like blending, stencil, etc),
- * but a there's a few things we need to override:
- */
- _mesa_meta_begin(ctx, (MESA_META_ALPHA_TEST |
- MESA_META_PIXEL_STORE |
- MESA_META_RASTERIZATION |
- MESA_META_SHADER |
- MESA_META_TEXTURE |
- MESA_META_TRANSFORM |
- MESA_META_CLIP |
- MESA_META_VERTEX |
- MESA_META_VIEWPORT));
-
- if (bitmap->ArrayObj == 0) {
- /* one-time setup */
-
- /* create vertex array object */
- _mesa_GenVertexArraysAPPLE(1, &bitmap->ArrayObj);
- _mesa_BindVertexArrayAPPLE(bitmap->ArrayObj);
-
- /* create vertex array buffer */
- _mesa_GenBuffersARB(1, &bitmap->VBO);
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
- _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
- NULL, GL_DYNAMIC_DRAW_ARB);
-
- /* setup vertex arrays */
- _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
- _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
- _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
- _mesa_EnableClientState(GL_VERTEX_ARRAY);
- _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
- _mesa_EnableClientState(GL_COLOR_ARRAY);
- }
- else {
- _mesa_BindVertexArray(bitmap->ArrayObj);
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
- }
-
- newTex = alloc_texture(tex, width, height, texIntFormat);
-
- /* vertex positions, texcoords, colors (after texture allocation!) */
- {
- const GLfloat x0 = (GLfloat) x;
- const GLfloat y0 = (GLfloat) y;
- const GLfloat x1 = (GLfloat) (x + width);
- const GLfloat y1 = (GLfloat) (y + height);
- const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
- GLuint i;
-
- verts[0].x = x0;
- verts[0].y = y0;
- verts[0].z = z;
- verts[0].s = 0.0F;
- verts[0].t = 0.0F;
- verts[1].x = x1;
- verts[1].y = y0;
- verts[1].z = z;
- verts[1].s = tex->Sright;
- verts[1].t = 0.0F;
- verts[2].x = x1;
- verts[2].y = y1;
- verts[2].z = z;
- verts[2].s = tex->Sright;
- verts[2].t = tex->Ttop;
- verts[3].x = x0;
- verts[3].y = y1;
- verts[3].z = z;
- verts[3].s = 0.0F;
- verts[3].t = tex->Ttop;
-
- for (i = 0; i < 4; i++) {
- verts[i].r = ctx->Current.RasterColor[0];
- verts[i].g = ctx->Current.RasterColor[1];
- verts[i].b = ctx->Current.RasterColor[2];
- verts[i].a = ctx->Current.RasterColor[3];
- }
-
- /* upload new vertex data */
- _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
- }
-
- /* choose different foreground/background alpha values */
- CLAMPED_FLOAT_TO_UBYTE(fg, ctx->Current.RasterColor[ACOMP]);
- bg = (fg > 127 ? 0 : 255);
-
- bitmap1 = _mesa_map_pbo_source(ctx, &unpackSave, bitmap1);
- if (!bitmap1) {
- _mesa_meta_end(ctx);
- return;
- }
-
- bitmap8 = (GLubyte *) malloc(width * height);
- if (bitmap8) {
- memset(bitmap8, bg, width * height);
- _mesa_expand_bitmap(width, height, &unpackSave, bitmap1,
- bitmap8, width, fg);
-
- _mesa_set_enable(ctx, tex->Target, GL_TRUE);
-
- _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_TRUE);
- _mesa_AlphaFunc(GL_NOTEQUAL, UBYTE_TO_FLOAT(bg));
-
- setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
- GL_ALPHA, GL_UNSIGNED_BYTE, bitmap8);
-
- _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- _mesa_set_enable(ctx, tex->Target, GL_FALSE);
-
- free(bitmap8);
- }
-
- _mesa_unmap_pbo_source(ctx, &unpackSave);
-
- _mesa_meta_end(ctx);
-}
-
-
/**
* Check if the call to _mesa_meta_GenerateMipmap() will require a
* software fallback. The fallback path will require that the texture
extern GLboolean
_mesa_meta_in_progress(struct gl_context *ctx);
-extern void
-_mesa_meta_BlitFramebuffer(struct gl_context *ctx,
- GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter);
-
-extern void
-_mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers);
-
-extern void
-_mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers);
-
extern void
_mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
GLsizei width, GLsizei height,
GLint dstx, GLint dsty, GLenum type);
-extern void
-_mesa_meta_DrawPixels(struct gl_context *ctx,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const struct gl_pixelstore_attrib *unpack,
- const GLvoid *pixels);
-
-extern void
-_mesa_meta_Bitmap(struct gl_context *ctx,
- GLint x, GLint y, GLsizei width, GLsizei height,
- const struct gl_pixelstore_attrib *unpack,
- const GLubyte *bitmap);
-
extern GLboolean
_mesa_meta_check_generate_mipmap_fallback(struct gl_context *ctx, GLenum target,
struct gl_texture_object *texObj);
struct gl_renderbuffer *accRb = fb->Attachment[BUFFER_ACCUM].Renderbuffer;
GLubyte *accMap, *colorMap;
GLint accRowStride, colorRowStride;
- GLuint buffer;
+ struct gl_renderbuffer *colorRb = fb->_ColorDrawBuffer;
+ const GLboolean masking = (!ctx->Color.ColorMask[RCOMP] ||
+ !ctx->Color.ColorMask[GCOMP] ||
+ !ctx->Color.ColorMask[BCOMP] ||
+ !ctx->Color.ColorMask[ACOMP]);
+ GLbitfield mappingFlags = GL_MAP_WRITE_BIT;
/* Map accum buffer */
ctx->Driver.MapRenderbuffer(ctx, accRb, xpos, ypos, width, height,
return;
}
- /* Loop over destination buffers */
- for (buffer = 0; buffer < fb->_NumColorDrawBuffers; buffer++) {
- struct gl_renderbuffer *colorRb = fb->_ColorDrawBuffers[buffer];
- const GLboolean masking = (!ctx->Color.ColorMask[buffer][RCOMP] ||
- !ctx->Color.ColorMask[buffer][GCOMP] ||
- !ctx->Color.ColorMask[buffer][BCOMP] ||
- !ctx->Color.ColorMask[buffer][ACOMP]);
- GLbitfield mappingFlags = GL_MAP_WRITE_BIT;
-
- if (masking)
- mappingFlags |= GL_MAP_READ_BIT;
+ if (masking)
+ mappingFlags |= GL_MAP_READ_BIT;
/* Map color buffer */
- ctx->Driver.MapRenderbuffer(ctx, colorRb, xpos, ypos, width, height,
- mappingFlags, &colorMap, &colorRowStride);
- if (!colorMap) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
- continue;
- }
+ ctx->Driver.MapRenderbuffer(ctx, colorRb, xpos, ypos, width, height,
+ mappingFlags, &colorMap, &colorRowStride);
+ if (!colorMap) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
+ ctx->Driver.UnmapRenderbuffer(ctx, accRb);
+ return;
+ }
- if (accRb->Format == MESA_FORMAT_SIGNED_RGBA_16) {
- const GLfloat scale = value / 32767.0f;
- GLint i, j;
- GLfloat (*rgba)[4], (*dest)[4];
+ if (accRb->Format == MESA_FORMAT_SIGNED_RGBA_16) {
+ const GLfloat scale = value / 32767.0f;
+ GLint i, j;
+ GLfloat (*rgba)[4], (*dest)[4];
- rgba = (GLfloat (*)[4]) malloc(width * 4 * sizeof(GLfloat));
- dest = (GLfloat (*)[4]) malloc(width * 4 * sizeof(GLfloat));
+ rgba = (GLfloat (*)[4]) malloc(width * 4 * sizeof(GLfloat));
+ dest = (GLfloat (*)[4]) malloc(width * 4 * sizeof(GLfloat));
- if (rgba && dest) {
- for (j = 0; j < height; j++) {
- GLshort *acc = (GLshort *) accMap;
+ if (rgba && dest) {
+ for (j = 0; j < height; j++) {
+ GLshort *acc = (GLshort *) accMap;
- for (i = 0; i < width; i++) {
- rgba[i][0] = acc[i * 4 + 0] * scale;
- rgba[i][1] = acc[i * 4 + 1] * scale;
- rgba[i][2] = acc[i * 4 + 2] * scale;
- rgba[i][3] = acc[i * 4 + 3] * scale;
- }
+ for (i = 0; i < width; i++) {
+ rgba[i][0] = acc[i * 4 + 0] * scale;
+ rgba[i][1] = acc[i * 4 + 1] * scale;
+ rgba[i][2] = acc[i * 4 + 2] * scale;
+ rgba[i][3] = acc[i * 4 + 3] * scale;
+ }
- if (masking) {
-
- /* get existing colors from dest buffer */
- _mesa_unpack_rgba_row(colorRb->Format, width, colorMap, dest);
-
- /* use the dest colors where mask[channel] = 0 */
- if (ctx->Color.ColorMask[buffer][RCOMP] == 0) {
- for (i = 0; i < width; i++)
- rgba[i][RCOMP] = dest[i][RCOMP];
- }
- if (ctx->Color.ColorMask[buffer][GCOMP] == 0) {
- for (i = 0; i < width; i++)
- rgba[i][GCOMP] = dest[i][GCOMP];
- }
- if (ctx->Color.ColorMask[buffer][BCOMP] == 0) {
- for (i = 0; i < width; i++)
- rgba[i][BCOMP] = dest[i][BCOMP];
- }
- if (ctx->Color.ColorMask[buffer][ACOMP] == 0) {
- for (i = 0; i < width; i++)
- rgba[i][ACOMP] = dest[i][ACOMP];
- }
- }
+ if (masking) {
- _mesa_pack_float_rgba_row(colorRb->Format, width,
- (const GLfloat (*)[4]) rgba, colorMap);
+ /* get existing colors from dest buffer */
+ _mesa_unpack_rgba_row(colorRb->Format, width, colorMap, dest);
- accMap += accRowStride;
- colorMap += colorRowStride;
+ /* use the dest colors where mask[channel] = 0 */
+ if (ctx->Color.ColorMask[RCOMP] == 0) {
+ for (i = 0; i < width; i++)
+ rgba[i][RCOMP] = dest[i][RCOMP];
+ }
+ if (ctx->Color.ColorMask[GCOMP] == 0) {
+ for (i = 0; i < width; i++)
+ rgba[i][GCOMP] = dest[i][GCOMP];
+ }
+ if (ctx->Color.ColorMask[BCOMP] == 0) {
+ for (i = 0; i < width; i++)
+ rgba[i][BCOMP] = dest[i][BCOMP];
+ }
+ if (ctx->Color.ColorMask[ACOMP] == 0) {
+ for (i = 0; i < width; i++)
+ rgba[i][ACOMP] = dest[i][ACOMP];
+ }
}
+
+ _mesa_pack_float_rgba_row(colorRb->Format, width,
+ (const GLfloat (*)[4]) rgba, colorMap);
+
+ accMap += accRowStride;
+ colorMap += colorRowStride;
}
- else {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
- }
- free(rgba);
- free(dest);
}
else {
- /* other types someday? */
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
}
-
- ctx->Driver.UnmapRenderbuffer(ctx, colorRb);
+ free(rgba);
+ free(dest);
+ }
+ else {
+ /* other types someday? */
}
+ ctx->Driver.UnmapRenderbuffer(ctx, colorRb);
ctx->Driver.UnmapRenderbuffer(ctx, accRb);
}
SET_MapBufferARB(exec, _mesa_MapBufferARB);
SET_UnmapBufferARB(exec, _mesa_UnmapBufferARB);
- /* ARB 37. GL_ARB_draw_buffers */
-#if FEATURE_draw_read_buffer
- SET_DrawBuffersARB(exec, _mesa_DrawBuffersARB);
-#endif
-
/* ARB 104. GL_ARB_robustness */
SET_GetGraphicsResetStatusARB(exec, _mesa_GetGraphicsResetStatusARB);
SET_GetnPolygonStippleARB(exec, _mesa_GetnPolygonStippleARB);
SET_GetStringi(exec, _mesa_GetStringi);
SET_ClampColor(exec, _mesa_ClampColorARB);
- /* GL_ARB_draw_buffer_blend */
- SET_BlendFunciARB(exec, _mesa_BlendFunci);
- SET_BlendFuncSeparateiARB(exec, _mesa_BlendFuncSeparatei);
- SET_BlendEquationiARB(exec, _mesa_BlendEquationi);
- SET_BlendEquationSeparateiARB(exec, _mesa_BlendEquationSeparatei);
-
/* GL_NV_texture_barrier */
SET_TextureBarrierNV(exec, _mesa_TextureBarrierNV);
}
if (mask & GL_COLOR_BUFFER_BIT) {
- GLuint i;
struct gl_colorbuffer_attrib *attr;
attr = MALLOC_STRUCT( gl_colorbuffer_attrib );
memcpy( attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib) );
/* push the Draw FBO's DrawBuffer[] state, not ctx->Color.DrawBuffer[] */
- for (i = 0; i < ctx->Const.MaxDrawBuffers; i ++)
- attr->DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i];
+ attr->DrawBuffer = ctx->DrawBuffer->ColorDrawBuffer;
save_attrib_data(&head, GL_COLOR_BUFFER_BIT, attr);
}
color->ClearColor.f[2],
color->ClearColor.f[3]);
_mesa_IndexMask(color->IndexMask);
- _mesa_ColorMask((GLboolean) (color->ColorMask[0][0] != 0),
- (GLboolean) (color->ColorMask[0][1] != 0),
- (GLboolean) (color->ColorMask[0][2] != 0),
- (GLboolean) (color->ColorMask[0][3] != 0));
- {
- /* Need to determine if more than one color output is
- * specified. If so, call glDrawBuffersARB, else call
- * glDrawBuffer(). This is a subtle, but essential point
- * since GL_FRONT (for example) is illegal for the former
- * function, but legal for the later.
- */
- GLboolean multipleBuffers = GL_FALSE;
- GLuint i;
-
- for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) {
- if (color->DrawBuffer[i] != GL_NONE) {
- multipleBuffers = GL_TRUE;
- break;
- }
- }
- /* Call the API_level functions, not _mesa_drawbuffers()
- * since we need to do error checking on the pop'd
- * GL_DRAW_BUFFER.
- * Ex: if GL_FRONT were pushed, but we're popping with a
- * user FBO bound, GL_FRONT will be illegal and we'll need
- * to record that error. Per OpenGL ARB decision.
- */
- if (multipleBuffers)
- _mesa_DrawBuffersARB(ctx->Const.MaxDrawBuffers,
- color->DrawBuffer);
- else
- _mesa_DrawBuffer(color->DrawBuffer[0]);
- }
+ _mesa_ColorMask((GLboolean) (color->ColorMask[0] != 0),
+ (GLboolean) (color->ColorMask[1] != 0),
+ (GLboolean) (color->ColorMask[2] != 0),
+ (GLboolean) (color->ColorMask[3] != 0));
+ _mesa_DrawBuffer(color->DrawBuffer);
_mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled);
_mesa_AlphaFunc(color->AlphaFunc, color->AlphaRefUnclamped);
if (ctx->Color.BlendEnabled != color->BlendEnabled) {
_mesa_set_enable(ctx, GL_BLEND, (color->BlendEnabled & 1));
}
- if (ctx->Color._BlendFuncPerBuffer ||
- ctx->Color._BlendEquationPerBuffer) {
- /* set blend per buffer */
- GLuint buf;
- for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) {
- _mesa_BlendFuncSeparatei(buf, color->Blend[buf].SrcRGB,
- color->Blend[buf].DstRGB,
- color->Blend[buf].SrcA,
- color->Blend[buf].DstA);
- _mesa_BlendEquationSeparatei(buf,
- color->Blend[buf].EquationRGB,
- color->Blend[buf].EquationA);
- }
+ /* set same blend modes for all buffers */
+ _mesa_BlendFuncSeparateEXT(color->SrcRGB,
+ color->DstRGB,
+ color->SrcA,
+ color->DstA);
+ /* This special case is because glBlendEquationSeparateEXT
+ * cannot take GL_LOGIC_OP as a parameter.
+ */
+ if (color->EquationRGB == color->EquationA) {
+ _mesa_BlendEquation(color->EquationRGB);
}
else {
- /* set same blend modes for all buffers */
- _mesa_BlendFuncSeparateEXT(color->Blend[0].SrcRGB,
- color->Blend[0].DstRGB,
- color->Blend[0].SrcA,
- color->Blend[0].DstA);
- /* This special case is because glBlendEquationSeparateEXT
- * cannot take GL_LOGIC_OP as a parameter.
- */
- if (color->Blend[0].EquationRGB ==
- color->Blend[0].EquationA) {
- _mesa_BlendEquation(color->Blend[0].EquationRGB);
- }
- else {
- _mesa_BlendEquationSeparateEXT(
- color->Blend[0].EquationRGB,
- color->Blend[0].EquationA);
- }
+ _mesa_BlendEquationSeparateEXT(
+ color->EquationRGB,
+ color->EquationA);
}
_mesa_BlendColor(color->BlendColorUnclamped[0],
color->BlendColorUnclamped[1],
_mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
GLenum sfactorA, GLenum dfactorA )
{
- GLuint buf, numBuffers;
- GLboolean changed;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
return;
}
- numBuffers = ctx->Extensions.ARB_draw_buffers_blend
- ? ctx->Const.MaxDrawBuffers : 1;
-
- changed = GL_FALSE;
- for (buf = 0; buf < numBuffers; buf++) {
- if (ctx->Color.Blend[buf].SrcRGB != sfactorRGB ||
- ctx->Color.Blend[buf].DstRGB != dfactorRGB ||
- ctx->Color.Blend[buf].SrcA != sfactorA ||
- ctx->Color.Blend[buf].DstA != dfactorA) {
- changed = GL_TRUE;
- break;
- }
- }
- if (!changed)
+ if (ctx->Color.SrcRGB == sfactorRGB &&
+ ctx->Color.DstRGB == dfactorRGB &&
+ ctx->Color.SrcA == sfactorA &&
+ ctx->Color.DstA == dfactorA) {
return;
+ }
FLUSH_VERTICES(ctx, _NEW_COLOR);
- for (buf = 0; buf < numBuffers; buf++) {
- ctx->Color.Blend[buf].SrcRGB = sfactorRGB;
- ctx->Color.Blend[buf].DstRGB = dfactorRGB;
- ctx->Color.Blend[buf].SrcA = sfactorA;
- ctx->Color.Blend[buf].DstA = dfactorA;
- }
- ctx->Color._BlendFuncPerBuffer = GL_FALSE;
-
+ ctx->Color.SrcRGB = sfactorRGB;
+ ctx->Color.DstRGB = dfactorRGB;
+ ctx->Color.SrcA = sfactorA;
+ ctx->Color.DstA = dfactorA;
if (ctx->Driver.BlendFuncSeparate) {
ctx->Driver.BlendFuncSeparate(ctx, sfactorRGB, dfactorRGB,
sfactorA, dfactorA);
#if _HAVE_FULL_GL
-
-
-/**
- * Set blend source/dest factors for one color buffer/target.
- */
-void GLAPIENTRY
-_mesa_BlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor)
-{
- _mesa_BlendFuncSeparatei(buf, sfactor, dfactor, sfactor, dfactor);
-}
-
-
-/**
- * Set separate blend source/dest factors for one color buffer/target.
- */
-void GLAPIENTRY
-_mesa_BlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB,
- GLenum sfactorA, GLenum dfactorA)
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (!ctx->Extensions.ARB_draw_buffers_blend) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glBlendFunc[Separate]i()");
- return;
- }
-
- if (buf >= ctx->Const.MaxDrawBuffers) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glBlendFuncSeparatei(buffer=%u)",
- buf);
- return;
- }
-
- if (!validate_blend_factors(ctx, "glBlendFuncSeparatei",
- sfactorRGB, dfactorRGB,
- sfactorA, dfactorA)) {
- return;
- }
-
- if (ctx->Color.Blend[buf].SrcRGB == sfactorRGB &&
- ctx->Color.Blend[buf].DstRGB == dfactorRGB &&
- ctx->Color.Blend[buf].SrcA == sfactorA &&
- ctx->Color.Blend[buf].DstA == dfactorA)
- return; /* no change */
-
- FLUSH_VERTICES(ctx, _NEW_COLOR);
-
- ctx->Color.Blend[buf].SrcRGB = sfactorRGB;
- ctx->Color.Blend[buf].DstRGB = dfactorRGB;
- ctx->Color.Blend[buf].SrcA = sfactorA;
- ctx->Color.Blend[buf].DstA = dfactorA;
- ctx->Color._BlendFuncPerBuffer = GL_TRUE;
-
- if (ctx->Driver.BlendFuncSeparatei) {
- ctx->Driver.BlendFuncSeparatei(ctx, buf, sfactorRGB, dfactorRGB,
- sfactorA, dfactorA);
- }
-}
-
-
/**
* Check if given blend equation is legal.
* \return GL_TRUE if legal, GL_FALSE otherwise.
void GLAPIENTRY
_mesa_BlendEquation( GLenum mode )
{
- GLuint buf, numBuffers;
- GLboolean changed;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
return;
}
- numBuffers = ctx->Extensions.ARB_draw_buffers_blend
- ? ctx->Const.MaxDrawBuffers : 1;
-
- changed = GL_FALSE;
- for (buf = 0; buf < numBuffers; buf++) {
- if (ctx->Color.Blend[buf].EquationRGB != mode ||
- ctx->Color.Blend[buf].EquationA != mode) {
- changed = GL_TRUE;
- break;
- }
- }
- if (!changed)
+ if (ctx->Color.EquationRGB == mode && ctx->Color.EquationA == mode) {
return;
+ }
FLUSH_VERTICES(ctx, _NEW_COLOR);
- for (buf = 0; buf < numBuffers; buf++) {
- ctx->Color.Blend[buf].EquationRGB = mode;
- ctx->Color.Blend[buf].EquationA = mode;
- }
- ctx->Color._BlendEquationPerBuffer = GL_FALSE;
+ ctx->Color.EquationRGB = mode;
+ ctx->Color.EquationA = mode;
if (ctx->Driver.BlendEquationSeparate)
(*ctx->Driver.BlendEquationSeparate)( ctx, mode, mode );
}
-
-/**
- * Set blend equation for one color buffer/target.
- */
-void GLAPIENTRY
-_mesa_BlendEquationi(GLuint buf, GLenum mode)
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glBlendEquationi(%u, %s)\n",
- buf, _mesa_lookup_enum_by_nr(mode));
-
- if (buf >= ctx->Const.MaxDrawBuffers) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glBlendFuncSeparatei(buffer=%u)",
- buf);
- return;
- }
-
- if (!legal_blend_equation(ctx, mode)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationi");
- return;
- }
-
- if (ctx->Color.Blend[buf].EquationRGB == mode &&
- ctx->Color.Blend[buf].EquationA == mode)
- return; /* no change */
-
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- ctx->Color.Blend[buf].EquationRGB = mode;
- ctx->Color.Blend[buf].EquationA = mode;
- ctx->Color._BlendEquationPerBuffer = GL_TRUE;
-
- if (ctx->Driver.BlendEquationSeparatei)
- ctx->Driver.BlendEquationSeparatei(ctx, buf, mode, mode);
-}
-
-
void GLAPIENTRY
_mesa_BlendEquationSeparateEXT( GLenum modeRGB, GLenum modeA )
{
- GLuint buf, numBuffers;
- GLboolean changed;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
return;
}
- numBuffers = ctx->Extensions.ARB_draw_buffers_blend
- ? ctx->Const.MaxDrawBuffers : 1;
-
- changed = GL_FALSE;
- for (buf = 0; buf < numBuffers; buf++) {
- if (ctx->Color.Blend[buf].EquationRGB != modeRGB ||
- ctx->Color.Blend[buf].EquationA != modeA) {
- changed = GL_TRUE;
- break;
- }
- }
- if (!changed)
+ if (ctx->Color.EquationRGB == modeRGB && ctx->Color.EquationA == modeA) {
return;
-
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- for (buf = 0; buf < numBuffers; buf++) {
- ctx->Color.Blend[buf].EquationRGB = modeRGB;
- ctx->Color.Blend[buf].EquationA = modeA;
}
- ctx->Color._BlendEquationPerBuffer = GL_FALSE;
+
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ ctx->Color.EquationRGB = modeRGB;
+ ctx->Color.EquationA = modeA;
if (ctx->Driver.BlendEquationSeparate)
ctx->Driver.BlendEquationSeparate(ctx, modeRGB, modeA);
}
-/**
- * Set separate blend equations for one color buffer/target.
- */
-void GLAPIENTRY
-_mesa_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeA)
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glBlendEquationSeparatei(%u, %s %s)\n", buf,
- _mesa_lookup_enum_by_nr(modeRGB),
- _mesa_lookup_enum_by_nr(modeA));
-
- if (buf >= ctx->Const.MaxDrawBuffers) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glBlendEquationSeparatei(buffer=%u)",
- buf);
- return;
- }
-
- if (!legal_blend_equation(ctx, modeRGB)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparatei(modeRGB)");
- return;
- }
-
- if (!legal_blend_equation(ctx, modeA)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparatei(modeA)");
- return;
- }
-
- if (ctx->Color.Blend[buf].EquationRGB == modeRGB &&
- ctx->Color.Blend[buf].EquationA == modeA)
- return; /* no change */
-
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- ctx->Color.Blend[buf].EquationRGB = modeRGB;
- ctx->Color.Blend[buf].EquationA = modeA;
- ctx->Color._BlendEquationPerBuffer = GL_TRUE;
-
- if (ctx->Driver.BlendEquationSeparatei)
- ctx->Driver.BlendEquationSeparatei(ctx, buf, modeRGB, modeA);
-}
-
-
-
#endif /* _HAVE_FULL_GL */
{
GET_CURRENT_CONTEXT(ctx);
GLubyte tmp[4];
- GLuint i;
- GLboolean flushed;
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (MESA_VERBOSE & VERBOSE_API)
tmp[BCOMP] = blue ? 0xff : 0x0;
tmp[ACOMP] = alpha ? 0xff : 0x0;
- flushed = GL_FALSE;
- for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
- if (!TEST_EQ_4V(tmp, ctx->Color.ColorMask[i])) {
- if (!flushed) {
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- }
- flushed = GL_TRUE;
- COPY_4UBV(ctx->Color.ColorMask[i], tmp);
- }
+ if (!TEST_EQ_4V(tmp, ctx->Color.ColorMask)) {
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ COPY_4UBV(ctx->Color.ColorMask, tmp);
}
if (ctx->Driver.ColorMask)
ctx->Driver.ColorMask( ctx, red, green, blue, alpha );
}
-
-/**
- * For GL_EXT_draw_buffers2 and GL3
- */
-void GLAPIENTRY
-_mesa_ColorMaskIndexed( GLuint buf, GLboolean red, GLboolean green,
- GLboolean blue, GLboolean alpha )
-{
- GLubyte tmp[4];
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glColorMaskIndexed %u %d %d %d %d\n",
- buf, red, green, blue, alpha);
-
- if (buf >= ctx->Const.MaxDrawBuffers) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glColorMaskIndexed(buf=%u)", buf);
- return;
- }
-
- /* Shouldn't have any information about channel depth in core mesa
- * -- should probably store these as the native booleans:
- */
- tmp[RCOMP] = red ? 0xff : 0x0;
- tmp[GCOMP] = green ? 0xff : 0x0;
- tmp[BCOMP] = blue ? 0xff : 0x0;
- tmp[ACOMP] = alpha ? 0xff : 0x0;
-
- if (TEST_EQ_4V(tmp, ctx->Color.ColorMask[buf]))
- return;
-
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- COPY_4UBV(ctx->Color.ColorMask[buf], tmp);
-
- if (ctx->Driver.ColorMaskIndexed)
- ctx->Driver.ColorMaskIndexed(ctx, buf, red, green, blue, alpha);
-}
-
-
void GLAPIENTRY
_mesa_ClampColorARB(GLenum target, GLenum clamp)
{
*/
void _mesa_init_color( struct gl_context * ctx )
{
- GLuint i;
-
/* Color buffer group */
ctx->Color.IndexMask = ~0u;
memset(ctx->Color.ColorMask, 0xff, sizeof(ctx->Color.ColorMask));
ctx->Color.AlphaFunc = GL_ALWAYS;
ctx->Color.AlphaRef = 0;
ctx->Color.BlendEnabled = 0x0;
- for (i = 0; i < Elements(ctx->Color.Blend); i++) {
- ctx->Color.Blend[i].SrcRGB = GL_ONE;
- ctx->Color.Blend[i].DstRGB = GL_ZERO;
- ctx->Color.Blend[i].SrcA = GL_ONE;
- ctx->Color.Blend[i].DstA = GL_ZERO;
- ctx->Color.Blend[i].EquationRGB = GL_FUNC_ADD;
- ctx->Color.Blend[i].EquationA = GL_FUNC_ADD;
- }
+ ctx->Color.SrcRGB = GL_ONE;
+ ctx->Color.DstRGB = GL_ZERO;
+ ctx->Color.SrcA = GL_ONE;
+ ctx->Color.DstA = GL_ZERO;
+ ctx->Color.EquationRGB = GL_FUNC_ADD;
+ ctx->Color.EquationA = GL_FUNC_ADD;
ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 );
ASSIGN_4V( ctx->Color.BlendColorUnclamped, 0.0, 0.0, 0.0, 0.0 );
ctx->Color.IndexLogicOpEnabled = GL_FALSE;
ctx->Color.DitherFlag = GL_TRUE;
if (ctx->Visual.doubleBufferMode) {
- ctx->Color.DrawBuffer[0] = GL_BACK;
+ ctx->Color.DrawBuffer = GL_BACK;
}
else {
- ctx->Color.DrawBuffer[0] = GL_FRONT;
+ ctx->Color.DrawBuffer = GL_FRONT;
}
ctx->Color.ClampFragmentColor = GL_FIXED_ONLY_ARB;
GLenum sfactorA, GLenum dfactorA );
-extern void GLAPIENTRY
-_mesa_BlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor);
-
-
-extern void GLAPIENTRY
-_mesa_BlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB,
- GLenum sfactorA, GLenum dfactorA);
-
-
extern void GLAPIENTRY
_mesa_BlendEquation( GLenum mode );
-extern void GLAPIENTRY
-_mesa_BlendEquationi(GLuint buf, GLenum mode);
-
extern void GLAPIENTRY
_mesa_BlendEquationSeparateEXT( GLenum modeRGB, GLenum modeA );
-extern void GLAPIENTRY
-_mesa_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeA);
-
-
extern void GLAPIENTRY
_mesa_BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
_mesa_ColorMask( GLboolean red, GLboolean green,
GLboolean blue, GLboolean alpha );
-extern void GLAPIENTRY
-_mesa_ColorMaskIndexed( GLuint buf, GLboolean red, GLboolean green,
- GLboolean blue, GLboolean alpha );
-
extern void GLAPIENTRY
_mesa_ClampColorARB(GLenum target, GLenum clamp);
}
/* if we get here, there's no error so set new state */
- _mesa_drawbuffers(ctx, 1, &buffer, &destMask);
+ _mesa_drawbuffer(ctx, buffer, destMask);
/*
* Call device driver function.
*/
- if (ctx->Driver.DrawBuffers)
- ctx->Driver.DrawBuffers(ctx, 1, &buffer);
- else if (ctx->Driver.DrawBuffer)
+ if (ctx->Driver.DrawBuffer)
ctx->Driver.DrawBuffer(ctx, buffer);
}
-
-/**
- * Called by glDrawBuffersARB; specifies the destination color renderbuffers
- * for N fragment program color outputs.
- * \sa _mesa_DrawBuffer
- * \param n number of outputs
- * \param buffers array [n] of renderbuffer names. Unlike glDrawBuffer, the
- * names cannot specify more than one buffer. For example,
- * GL_FRONT_AND_BACK is illegal.
- */
-void GLAPIENTRY
-_mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers)
-{
- GLint output;
- GLbitfield usedBufferMask, supportedMask;
- GLbitfield destMask[MAX_DRAW_BUFFERS];
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- /* Turns out n==0 is a valid input that should not produce an error.
- * The remaining code below correctly handles the n==0 case.
- */
- if (n < 0 || n > (GLsizei) ctx->Const.MaxDrawBuffers) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)");
- return;
- }
-
- supportedMask = supported_buffer_bitmask(ctx, ctx->DrawBuffer);
- usedBufferMask = 0x0;
-
- /* complicated error checking... */
- for (output = 0; output < n; output++) {
- if (buffers[output] == GL_NONE) {
- destMask[output] = 0x0;
- }
- else {
- destMask[output] = draw_buffer_enum_to_bitmask(buffers[output]);
- if (destMask[output] == BAD_MASK
- || _mesa_bitcount(destMask[output]) > 1) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)");
- return;
- }
- destMask[output] &= supportedMask;
- if (destMask[output] == 0) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glDrawBuffersARB(unsupported buffer)");
- return;
- }
- if (destMask[output] & usedBufferMask) {
- /* can't specify a dest buffer more than once! */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glDrawBuffersARB(duplicated buffer)");
- return;
- }
-
- /* update bitmask */
- usedBufferMask |= destMask[output];
- }
- }
-
- /* OK, if we get here, there were no errors so set the new state */
- _mesa_drawbuffers(ctx, n, buffers, destMask);
-
- /*
- * Call device driver function. Note that n can be equal to 0,
- * in which case we don't want to reference buffers[0], which
- * may not be valid.
- */
- if (ctx->Driver.DrawBuffers)
- ctx->Driver.DrawBuffers(ctx, n, buffers);
- else if (ctx->Driver.DrawBuffer)
- ctx->Driver.DrawBuffer(ctx, n > 0 ? buffers[0] : GL_NONE);
-}
-
/**
* Performs necessary state updates when _mesa_drawbuffers makes an
* actual change.
* BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT).
*/
void
-_mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
- const GLbitfield *destMask)
+_mesa_drawbuffer(struct gl_context *ctx, const GLenum buffers, GLbitfield destMask)
{
struct gl_framebuffer *fb = ctx->DrawBuffer;
- GLbitfield mask[MAX_DRAW_BUFFERS];
- GLuint buf;
+ GLint bufIndex;
if (!destMask) {
/* compute destMask values now */
const GLbitfield supportedMask = supported_buffer_bitmask(ctx, fb);
- GLuint output;
- for (output = 0; output < n; output++) {
- mask[output] = draw_buffer_enum_to_bitmask(buffers[output]);
- ASSERT(mask[output] != BAD_MASK);
- mask[output] &= supportedMask;
- }
- destMask = mask;
- }
-
- /*
- * If n==1, destMask[0] may have up to four bits set.
- * Otherwise, destMask[x] can only have one bit set.
- */
- if (n == 1) {
- GLuint count = 0, destMask0 = destMask[0];
- while (destMask0) {
- GLint bufIndex = _mesa_ffs(destMask0) - 1;
- if (fb->_ColorDrawBufferIndexes[count] != bufIndex) {
- updated_drawbuffers(ctx);
- fb->_ColorDrawBufferIndexes[count] = bufIndex;
- }
- count++;
- destMask0 &= ~(1 << bufIndex);
- }
- fb->ColorDrawBuffer[0] = buffers[0];
- fb->_NumColorDrawBuffers = count;
- }
- else {
- GLuint count = 0;
- for (buf = 0; buf < n; buf++ ) {
- if (destMask[buf]) {
- GLint bufIndex = _mesa_ffs(destMask[buf]) - 1;
- /* only one bit should be set in the destMask[buf] field */
- ASSERT(_mesa_bitcount(destMask[buf]) == 1);
- if (fb->_ColorDrawBufferIndexes[buf] != bufIndex) {
- updated_drawbuffers(ctx);
- fb->_ColorDrawBufferIndexes[buf] = bufIndex;
- }
- count = buf + 1;
- }
- else {
- if (fb->_ColorDrawBufferIndexes[buf] != -1) {
- updated_drawbuffers(ctx);
- fb->_ColorDrawBufferIndexes[buf] = -1;
- }
- }
- fb->ColorDrawBuffer[buf] = buffers[buf];
- }
- fb->_NumColorDrawBuffers = count;
+ destMask = draw_buffer_enum_to_bitmask(buffers);
+ ASSERT(destmask != BAD_MASK);
+ destMask &= supportedMask;
}
+
+ bufIndex = _mesa_ffs(destMask) - 1;
- /* set remaining outputs to -1 (GL_NONE) */
- for (buf = fb->_NumColorDrawBuffers; buf < ctx->Const.MaxDrawBuffers; buf++) {
- if (fb->_ColorDrawBufferIndexes[buf] != -1) {
- updated_drawbuffers(ctx);
- fb->_ColorDrawBufferIndexes[buf] = -1;
- }
- }
- for (buf = n; buf < ctx->Const.MaxDrawBuffers; buf++) {
- fb->ColorDrawBuffer[buf] = GL_NONE;
+ if (fb->_ColorDrawBufferIndex != bufIndex) {
+ updated_drawbuffers(ctx);
+ fb->_ColorDrawBufferIndex = bufIndex;
}
+ fb->ColorDrawBuffer = buffers;
if (fb->Name == 0) {
- /* also set context drawbuffer state */
- for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) {
- if (ctx->Color.DrawBuffer[buf] != fb->ColorDrawBuffer[buf]) {
- updated_drawbuffers(ctx);
- ctx->Color.DrawBuffer[buf] = fb->ColorDrawBuffer[buf];
- }
+ if (ctx->Color.DrawBuffer != fb->ColorDrawBuffer) {
+ updated_drawbuffers(ctx);
+ ctx->Color.DrawBuffer = fb->ColorDrawBuffer;
}
}
}
* Use when changing contexts.
*/
void
-_mesa_update_draw_buffers(struct gl_context *ctx)
+_mesa_update_draw_buffer(struct gl_context *ctx)
{
- GLenum buffers[MAX_DRAW_BUFFERS];
- GLuint i;
-
/* should be a window system FBO */
assert(ctx->DrawBuffer->Name == 0);
- for (i = 0; i < ctx->Const.MaxDrawBuffers; i++)
- buffers[i] = ctx->Color.DrawBuffer[i];
-
- _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, buffers, NULL);
+ _mesa_drawbuffer(ctx, ctx->Color.DrawBuffer, 0);
}
extern void GLAPIENTRY
_mesa_DrawBuffer( GLenum mode );
-extern void GLAPIENTRY
-_mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers);
-
extern void
-_mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
- const GLbitfield *destMask);
+_mesa_drawbuffer(struct gl_context *ctx, const GLenum buffers, const GLbitfield destMask);
extern void
_mesa_readbuffer(struct gl_context *ctx, GLenum buffer, GLint bufferIndex);
extern void
-_mesa_update_draw_buffers(struct gl_context *ctx);
+_mesa_update_draw_buffer(struct gl_context *ctx);
extern void GLAPIENTRY
*/
bufferMask = 0;
if (mask & GL_COLOR_BUFFER_BIT) {
- GLuint i;
- for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
- bufferMask |= (1 << ctx->DrawBuffer->_ColorDrawBufferIndexes[i]);
- }
+ bufferMask |= (1 << ctx->DrawBuffer->_ColorDrawBufferIndex);
}
if ((mask & GL_DEPTH_BUFFER_BIT)
/*@}*/
-/** For GL_ARB_draw_buffers */
-/*@{*/
-#define MAX_DRAW_BUFFERS 8
-/*@}*/
-
-
/** For GL_EXT_framebuffer_object */
/*@{*/
#define MAX_COLOR_ATTACHMENTS 8
/* CheckArrayBounds is overriden by drivers/x11 for X server */
ctx->Const.CheckArrayBounds = GL_FALSE;
- /* GL_ARB_draw_buffers */
- ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS;
-
#if FEATURE_EXT_framebuffer_object
ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
ctx->Const.MaxRenderbufferSize = MAX_WIDTH;
assert(ctx->Const.MaxViewportWidth <= MAX_WIDTH);
assert(ctx->Const.MaxViewportHeight <= MAX_WIDTH);
- assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS);
-
/* if this fails, add more enum values to gl_buffer_index */
- assert(BUFFER_COLOR0 + MAX_DRAW_BUFFERS <= BUFFER_COUNT);
+ assert(BUFFER_COLOR0 + 1 <= BUFFER_COUNT);
/* XXX probably add more tests */
}
* For winsys FBOs this comes from the GL state (which may have
* changed since the last time this FBO was bound).
*/
- _mesa_update_draw_buffers(newCtx);
+ _mesa_update_draw_buffer(newCtx);
}
if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) {
_mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
/** Enable and disable writing of frame buffer color components */
void (*ColorMask)(struct gl_context *ctx, GLboolean rmask, GLboolean gmask,
GLboolean bmask, GLboolean amask );
- void (*ColorMaskIndexed)(struct gl_context *ctx, GLuint buf, GLboolean rmask,
- GLboolean gmask, GLboolean bmask, GLboolean amask);
/** Cause a material color to track the current color */
void (*ColorMaterial)(struct gl_context *ctx, GLenum face, GLenum mode);
/** Specify whether front- or back-facing facets can be culled */
void (*DepthRange)(struct gl_context *ctx, GLclampd nearval, GLclampd farval);
/** Specify the current buffer for writing */
void (*DrawBuffer)( struct gl_context *ctx, GLenum buffer );
- /** Specify the buffers for writing for fragment programs*/
- void (*DrawBuffers)( struct gl_context *ctx, GLsizei n, const GLenum *buffers );
/** Enable or disable server-side gl capabilities */
void (*Enable)(struct gl_context *ctx, GLenum cap, GLboolean state);
/** Specify fog parameters */
printf("ReadBuffer %p 0x%x DrawBuffer %p 0x%x\n",
(void *) ctx->ReadBuffer->_ColorReadBuffer,
ctx->ReadBuffer->ColorReadBuffer,
- (void *) ctx->DrawBuffer->_ColorDrawBuffers[0],
- ctx->DrawBuffer->ColorDrawBuffer[0]);
+ (void *) ctx->DrawBuffer->_ColorDrawBuffer,
+ ctx->DrawBuffer->ColorDrawBuffer);
printf("Writing %d x %d color buffer to %s\n", w, h, filename);
write_ppm(filename, buf, w, h, 4, 0, 1, 2, GL_TRUE);
#define _gloffset_BindAttribLocationARB 568
#define _gloffset_GetActiveAttribARB 569
#define _gloffset_GetAttribLocationARB 570
-#define _gloffset_DrawBuffersARB 571
#define _gloffset_ClampColorARB 572
#define _gloffset_RenderbufferStorageMultisample 575
#define _gloffset_FlushMappedBufferRange 580
#define _gloffset_MapBufferRange 581
#define _gloffset_BindVertexArray 583
#define _gloffset_GenVertexArrays 584
-#define _gloffset_BlendEquationSeparateiARB 597
-#define _gloffset_BlendEquationiARB 598
-#define _gloffset_BlendFuncSeparateiARB 599
-#define _gloffset_BlendFunciARB 600
#define _gloffset_GetGraphicsResetStatusARB 665
#define _gloffset_GetnColorTableARB 666
#define _gloffset_GetnConvolutionFilterARB 668
#define BindAttribLocationARB_remap_index 160
#define GetActiveAttribARB_remap_index 161
#define GetAttribLocationARB_remap_index 162
-#define DrawBuffersARB_remap_index 163
#define ClampColorARB_remap_index 164
#define RenderbufferStorageMultisample_remap_index 167
#define VertexAttribDivisorARB_remap_index 171
#define MapBufferRange_remap_index 173
#define BindVertexArray_remap_index 175
#define GenVertexArrays_remap_index 176
-#define BlendEquationSeparateiARB_remap_index 189
-#define BlendEquationiARB_remap_index 190
-#define BlendFuncSeparateiARB_remap_index 191
-#define BlendFunciARB_remap_index 192
#define GetGraphicsResetStatusARB_remap_index 257
#define GetnColorTableARB_remap_index 258
#define GetnConvolutionFilterARB_remap_index 260
#define _gloffset_BindAttribLocationARB driDispatchRemapTable[BindAttribLocationARB_remap_index]
#define _gloffset_GetActiveAttribARB driDispatchRemapTable[GetActiveAttribARB_remap_index]
#define _gloffset_GetAttribLocationARB driDispatchRemapTable[GetAttribLocationARB_remap_index]
-#define _gloffset_DrawBuffersARB driDispatchRemapTable[DrawBuffersARB_remap_index]
#define _gloffset_ClampColorARB driDispatchRemapTable[ClampColorARB_remap_index]
#define _gloffset_RenderbufferStorageMultisample driDispatchRemapTable[RenderbufferStorageMultisample_remap_index]
#define _gloffset_FlushMappedBufferRange driDispatchRemapTable[FlushMappedBufferRange_remap_index]
#define _gloffset_MapBufferRange driDispatchRemapTable[MapBufferRange_remap_index]
#define _gloffset_BindVertexArray driDispatchRemapTable[BindVertexArray_remap_index]
#define _gloffset_GenVertexArrays driDispatchRemapTable[GenVertexArrays_remap_index]
-#define _gloffset_BlendEquationSeparateiARB driDispatchRemapTable[BlendEquationSeparateiARB_remap_index]
-#define _gloffset_BlendEquationiARB driDispatchRemapTable[BlendEquationiARB_remap_index]
-#define _gloffset_BlendFuncSeparateiARB driDispatchRemapTable[BlendFuncSeparateiARB_remap_index]
-#define _gloffset_BlendFunciARB driDispatchRemapTable[BlendFunciARB_remap_index]
#define _gloffset_GetGraphicsResetStatusARB driDispatchRemapTable[GetGraphicsResetStatusARB_remap_index]
#define _gloffset_GetnColorTableARB driDispatchRemapTable[GetnColorTableARB_remap_index]
#define _gloffset_GetnConvolutionFilterARB driDispatchRemapTable[GetnConvolutionFilterARB_remap_index]
SET_by_offset(disp, _gloffset_GetAttribLocationARB, fn);
}
-typedef void (GLAPIENTRYP _glptr_DrawBuffersARB)(GLsizei, const GLenum *);
-#define CALL_DrawBuffersARB(disp, parameters) \
- (* GET_DrawBuffersARB(disp)) parameters
-static inline _glptr_DrawBuffersARB GET_DrawBuffersARB(struct _glapi_table *disp) {
- return (_glptr_DrawBuffersARB) (GET_by_offset(disp, _gloffset_DrawBuffersARB));
-}
-
-static inline void SET_DrawBuffersARB(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLsizei, const GLenum *)) {
- SET_by_offset(disp, _gloffset_DrawBuffersARB, fn);
-}
-
typedef void (GLAPIENTRYP _glptr_ClampColorARB)(GLenum, GLenum);
#define CALL_ClampColorARB(disp, parameters) \
(* GET_ClampColorARB(disp)) parameters
SET_by_offset(disp, _gloffset_GenVertexArrays, fn);
}
-typedef void (GLAPIENTRYP _glptr_BlendEquationSeparateiARB)(GLuint, GLenum, GLenum);
-#define CALL_BlendEquationSeparateiARB(disp, parameters) \
- (* GET_BlendEquationSeparateiARB(disp)) parameters
-static inline _glptr_BlendEquationSeparateiARB GET_BlendEquationSeparateiARB(struct _glapi_table *disp) {
- return (_glptr_BlendEquationSeparateiARB) (GET_by_offset(disp, _gloffset_BlendEquationSeparateiARB));
-}
-
-static inline void SET_BlendEquationSeparateiARB(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLuint, GLenum, GLenum)) {
- SET_by_offset(disp, _gloffset_BlendEquationSeparateiARB, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_BlendEquationiARB)(GLuint, GLenum);
-#define CALL_BlendEquationiARB(disp, parameters) \
- (* GET_BlendEquationiARB(disp)) parameters
-static inline _glptr_BlendEquationiARB GET_BlendEquationiARB(struct _glapi_table *disp) {
- return (_glptr_BlendEquationiARB) (GET_by_offset(disp, _gloffset_BlendEquationiARB));
-}
-
-static inline void SET_BlendEquationiARB(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLuint, GLenum)) {
- SET_by_offset(disp, _gloffset_BlendEquationiARB, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_BlendFuncSeparateiARB)(GLuint, GLenum, GLenum, GLenum, GLenum);
-#define CALL_BlendFuncSeparateiARB(disp, parameters) \
- (* GET_BlendFuncSeparateiARB(disp)) parameters
-static inline _glptr_BlendFuncSeparateiARB GET_BlendFuncSeparateiARB(struct _glapi_table *disp) {
- return (_glptr_BlendFuncSeparateiARB) (GET_by_offset(disp, _gloffset_BlendFuncSeparateiARB));
-}
-
-static inline void SET_BlendFuncSeparateiARB(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLuint, GLenum, GLenum, GLenum, GLenum)) {
- SET_by_offset(disp, _gloffset_BlendFuncSeparateiARB, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_BlendFunciARB)(GLuint, GLenum, GLenum);
-#define CALL_BlendFunciARB(disp, parameters) \
- (* GET_BlendFunciARB(disp)) parameters
-static inline _glptr_BlendFunciARB GET_BlendFunciARB(struct _glapi_table *disp) {
- return (_glptr_BlendFunciARB) (GET_by_offset(disp, _gloffset_BlendFunciARB));
-}
-
-static inline void SET_BlendFunciARB(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLuint, GLenum, GLenum)) {
- SET_by_offset(disp, _gloffset_BlendFunciARB, fn);
-}
-
typedef GLenum (GLAPIENTRYP _glptr_GetGraphicsResetStatusARB)(void);
#define CALL_GetGraphicsResetStatusARB(disp, parameters) \
(* GET_GetGraphicsResetStatusARB(disp)) parameters
OPCODE_BLEND_EQUATION_SEPARATE,
OPCODE_BLEND_FUNC_SEPARATE,
- OPCODE_BLEND_EQUATION_I,
- OPCODE_BLEND_EQUATION_SEPARATE_I,
- OPCODE_BLEND_FUNC_I,
- OPCODE_BLEND_FUNC_SEPARATE_I,
-
OPCODE_CALL_LIST,
OPCODE_CALL_LIST_OFFSET,
OPCODE_CLEAR,
/* GL_ARB_vertex/fragment_program */
OPCODE_PROGRAM_STRING_ARB,
OPCODE_PROGRAM_ENV_PARAMETER_ARB,
- /* GL_ARB_draw_buffers */
- OPCODE_DRAW_BUFFERS_ARB,
/* GL_ATI_fragment_shader */
OPCODE_TEX_BUMP_PARAMETER_ATI,
/* OpenGL 2.0 */
}
}
-/* GL_ARB_draw_buffers_blend */
-static void GLAPIENTRY
-save_BlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB,
- GLenum sfactorA, GLenum dfactorA)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_BLEND_FUNC_SEPARATE_I, 5);
- if (n) {
- n[1].ui = buf;
- n[2].e = sfactorRGB;
- n[3].e = dfactorRGB;
- n[4].e = sfactorA;
- n[5].e = dfactorA;
- }
- if (ctx->ExecuteFlag) {
- CALL_BlendFuncSeparateiARB(ctx->Exec, (buf, sfactorRGB, dfactorRGB,
- sfactorA, dfactorA));
- }
-}
-
-/* GL_ARB_draw_buffers_blend */
-static void GLAPIENTRY
-save_BlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_BLEND_FUNC_SEPARATE_I, 3);
- if (n) {
- n[1].ui = buf;
- n[2].e = sfactor;
- n[3].e = dfactor;
- }
- if (ctx->ExecuteFlag) {
- CALL_BlendFunciARB(ctx->Exec, (buf, sfactor, dfactor));
- }
-}
-
-/* GL_ARB_draw_buffers_blend */
-static void GLAPIENTRY
-save_BlendEquationi(GLuint buf, GLenum mode)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION_I, 2);
- if (n) {
- n[1].ui = buf;
- n[2].e = mode;
- }
- if (ctx->ExecuteFlag) {
- CALL_BlendEquationiARB(ctx->Exec, (buf, mode));
- }
-}
-
-/* GL_ARB_draw_buffers_blend */
-static void GLAPIENTRY
-save_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeA)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION_SEPARATE_I, 3);
- if (n) {
- n[1].ui = buf;
- n[2].e = modeRGB;
- n[3].e = modeA;
- }
- if (ctx->ExecuteFlag) {
- CALL_BlendEquationSeparateiARB(ctx->Exec, (buf, modeRGB, modeA));
- }
-}
-
static void invalidate_saved_current_state( struct gl_context *ctx )
{
GLint i;
#endif /* FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program */
-
-static void GLAPIENTRY
-save_DrawBuffersARB(GLsizei count, const GLenum * buffers)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_DRAW_BUFFERS_ARB, 1 + MAX_DRAW_BUFFERS);
- if (n) {
- GLint i;
- n[1].i = count;
- if (count > MAX_DRAW_BUFFERS)
- count = MAX_DRAW_BUFFERS;
- for (i = 0; i < count; i++) {
- n[2 + i].e = buffers[i];
- }
- }
- if (ctx->ExecuteFlag) {
- CALL_DrawBuffersARB(ctx->Exec, (count, buffers));
- }
-}
-
static void GLAPIENTRY
save_TexBumpParameterfvATI(GLenum pname, const GLfloat *param)
{
(n[1].e, n[2].e, n[3].e, n[4].e));
break;
- case OPCODE_BLEND_FUNC_I:
- /* GL_ARB_draw_buffers_blend */
- CALL_BlendFunciARB(ctx->Exec, (n[1].ui, n[2].e, n[3].e));
- break;
- case OPCODE_BLEND_FUNC_SEPARATE_I:
- /* GL_ARB_draw_buffers_blend */
- CALL_BlendFuncSeparateiARB(ctx->Exec, (n[1].ui, n[2].e, n[3].e,
- n[4].e, n[5].e));
- break;
- case OPCODE_BLEND_EQUATION_I:
- /* GL_ARB_draw_buffers_blend */
- CALL_BlendEquationiARB(ctx->Exec, (n[1].ui, n[2].e));
- break;
- case OPCODE_BLEND_EQUATION_SEPARATE_I:
- /* GL_ARB_draw_buffers_blend */
- CALL_BlendEquationSeparateiARB(ctx->Exec,
- (n[1].ui, n[2].e, n[3].e));
- break;
-
case OPCODE_CALL_LIST:
/* Generated by glCallList(), don't add ListBase */
if (ctx->ListState.CallDepth < MAX_LIST_NESTING) {
n[6].f));
break;
#endif
- case OPCODE_DRAW_BUFFERS_ARB:
- {
- GLenum buffers[MAX_DRAW_BUFFERS];
- GLint i, count = MIN2(n[1].i, MAX_DRAW_BUFFERS);
- for (i = 0; i < count; i++)
- buffers[i] = n[2 + i].e;
- CALL_DrawBuffersARB(ctx->Exec, (n[1].i, buffers));
- }
- break;
#if FEATURE_EXT_framebuffer_blit
case OPCODE_BLIT_FRAMEBUFFER:
CALL_BlitFramebufferEXT(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i,
SET_MapBufferARB(table, _mesa_MapBufferARB);
SET_UnmapBufferARB(table, _mesa_UnmapBufferARB);
- SET_DrawBuffersARB(table, save_DrawBuffersARB);
-
#if FEATURE_EXT_framebuffer_blit
SET_BlitFramebufferEXT(table, save_BlitFramebufferEXT);
#endif
/* GL_NV_texture_barrier */
SET_TextureBarrierNV(table, save_TextureBarrierNV);
- /* GL_ARB_draw_buffer_blend */
- SET_BlendFunciARB(table, save_BlendFunci);
- SET_BlendFuncSeparateiARB(table, save_BlendFuncSeparatei);
- SET_BlendEquationiARB(table, save_BlendEquationi);
- SET_BlendEquationSeparateiARB(table, save_BlendEquationSeparatei);
-
/* GL_ARB_texture_storage (no dlist support) */
SET_TexStorage1D(table, _mesa_TexStorage1D);
SET_TexStorage2D(table, _mesa_TexStorage2D);
_mesa_lookup_enum_by_nr(format),
_mesa_lookup_enum_by_nr(type),
pixels,
- _mesa_lookup_enum_by_nr(ctx->DrawBuffer->ColorDrawBuffer[0]),
+ _mesa_lookup_enum_by_nr(ctx->DrawBuffer->ColorDrawBuffer),
IROUND(ctx->Current.RasterPos[0]),
IROUND(ctx->Current.RasterPos[1]));
srcx, srcy, width, height,
_mesa_lookup_enum_by_nr(type),
_mesa_lookup_enum_by_nr(ctx->ReadBuffer->ColorReadBuffer),
- _mesa_lookup_enum_by_nr(ctx->DrawBuffer->ColorDrawBuffer[0]),
+ _mesa_lookup_enum_by_nr(ctx->DrawBuffer->ColorDrawBuffer),
IROUND(ctx->Current.RasterPos[0]),
IROUND(ctx->Current.RasterPos[1]));
break;
case GL_BLEND:
{
- GLbitfield newEnabled =
- state * ((1 << ctx->Const.MaxDrawBuffers) - 1);
- if (newEnabled != ctx->Color.BlendEnabled) {
+ if (state != ctx->Color.BlendEnabled) {
FLUSH_VERTICES(ctx, _NEW_COLOR);
- ctx->Color.BlendEnabled = newEnabled;
+ ctx->Color.BlendEnabled = state;
}
}
break;
/* ARB Extensions */
{ "GL_ARB_color_buffer_float", o(ARB_color_buffer_float), 2004 },
{ "GL_ARB_conservative_depth", o(ARB_conservative_depth), 2011 },
- { "GL_ARB_draw_buffers", o(dummy_true), 2002 },
- { "GL_ARB_draw_buffers_blend", o(ARB_draw_buffers_blend), 2009 },
{ "GL_ARB_fragment_program", o(ARB_fragment_program), 2002 },
{ "GL_ARB_fragment_program_shadow", o(ARB_fragment_program_shadow), 2003 },
{ "GL_ARB_fragment_shader", o(ARB_fragment_shader), 2002 },
/* Vendor extensions */
{ "GL_AMD_conservative_depth", o(ARB_conservative_depth), 2009 },
- { "GL_AMD_draw_buffers_blend", o(ARB_draw_buffers_blend), 2009 },
{ "GL_AMD_shader_stencil_export", o(ARB_shader_stencil_export), 2009 },
{ "GL_APPLE_object_purgeable", o(APPLE_object_purgeable), 2006 },
{ "GL_APPLE_packed_pixels", o(APPLE_packed_pixels), 2002 },
GLuint minWidth = ~0, minHeight = ~0, maxWidth = 0, maxHeight = 0;
GLint numSamples = -1;
GLint i;
- GLuint j;
assert(is_user_fbo(fb));
}
/* Check that all DrawBuffers are present */
- for (j = 0; j < ctx->Const.MaxDrawBuffers; j++) {
- if (fb->ColorDrawBuffer[j] != GL_NONE) {
+ if (fb->ColorDrawBuffer != GL_NONE) {
const struct gl_renderbuffer_attachment *att
- = _mesa_get_attachment(ctx, fb, fb->ColorDrawBuffer[j]);
+ = _mesa_get_attachment(ctx, fb, fb->ColorDrawBuffer);
assert(att);
if (att->Type == GL_NONE) {
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT;
- fbo_incomplete("missing drawbuffer", j);
+ fbo_incomplete("missing drawbuffer", 0);
return;
}
}
- }
/* Check that the ReadBuffer is present */
if (fb->ColorReadBuffer != GL_NONE) {
/* get color read/draw renderbuffers */
if (mask & GL_COLOR_BUFFER_BIT) {
colorReadRb = readFb->_ColorReadBuffer;
- colorDrawRb = drawFb->_ColorDrawBuffers[0];
+ colorDrawRb = drawFb->_ColorDrawBuffer;
/* From the EXT_framebuffer_object spec:
*
/* Init read/draw renderbuffer state */
if (visual->doubleBufferMode) {
- fb->_NumColorDrawBuffers = 1;
- fb->ColorDrawBuffer[0] = GL_BACK;
- fb->_ColorDrawBufferIndexes[0] = BUFFER_BACK_LEFT;
+ fb->ColorDrawBuffer = GL_BACK;
+ fb->_ColorDrawBufferIndex = BUFFER_BACK_LEFT;
fb->ColorReadBuffer = GL_BACK;
fb->_ColorReadBufferIndex = BUFFER_BACK_LEFT;
}
else {
- fb->_NumColorDrawBuffers = 1;
- fb->ColorDrawBuffer[0] = GL_FRONT;
- fb->_ColorDrawBufferIndexes[0] = BUFFER_FRONT_LEFT;
+ fb->ColorDrawBuffer = GL_FRONT;
+ fb->_ColorDrawBufferIndex = BUFFER_FRONT_LEFT;
fb->ColorReadBuffer = GL_FRONT;
fb->_ColorReadBufferIndex = BUFFER_FRONT_LEFT;
}
fb->Name = name;
fb->RefCount = 1;
- fb->_NumColorDrawBuffers = 1;
- fb->ColorDrawBuffer[0] = GL_COLOR_ATTACHMENT0_EXT;
- fb->_ColorDrawBufferIndexes[0] = BUFFER_COLOR0;
+ fb->ColorDrawBuffer = GL_COLOR_ATTACHMENT0_EXT;
+ fb->_ColorDrawBufferIndex = BUFFER_COLOR0;
fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT;
fb->_ColorReadBufferIndex = BUFFER_COLOR0;
fb->Delete = _mesa_destroy_framebuffer;
static void
update_color_draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb)
{
- GLuint output;
-
- /* set 0th buffer to NULL now in case _NumColorDrawBuffers is zero */
- fb->_ColorDrawBuffers[0] = NULL;
-
- for (output = 0; output < fb->_NumColorDrawBuffers; output++) {
- GLint buf = fb->_ColorDrawBufferIndexes[output];
- if (buf >= 0) {
- fb->_ColorDrawBuffers[output] = fb->Attachment[buf].Renderbuffer;
- }
- else {
- fb->_ColorDrawBuffers[output] = NULL;
- }
+ GLint buf = fb->_ColorDrawBufferIndex;
+ if (buf >= 0) {
+ fb->_ColorDrawBuffer = fb->Attachment[buf].Renderbuffer;
+ }
+ else {
+ fb->_ColorDrawBuffer = NULL;
}
}
/* Need to update the FB's GL_DRAW_BUFFER state to match the
* context state (GL_READ_BUFFER too).
*/
- if (fb->ColorDrawBuffer[0] != ctx->Color.DrawBuffer[0]) {
- _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers,
- ctx->Color.DrawBuffer, NULL);
- }
+ _mesa_drawbuffer(ctx, ctx->Color.DrawBuffer, 0);
}
else {
/* This is a user-created framebuffer.
EXTRA_VERSION_32,
EXTRA_NEW_BUFFERS,
EXTRA_NEW_FRAG_CLAMP,
- EXTRA_VALID_DRAW_BUFFER,
EXTRA_VALID_TEXTURE_UNIT,
EXTRA_VALID_CLIP_DISTANCE,
EXTRA_FLUSH_CURRENT,
EXTRA_END
};
-static const int extra_valid_draw_buffer[] = {
- EXTRA_VALID_DRAW_BUFFER,
- EXTRA_END
-};
-
static const int extra_valid_texture_unit[] = {
EXTRA_VALID_TEXTURE_UNIT,
EXTRA_END
static const struct value_desc values[] = {
{ GL_ALPHA_BITS, BUFFER_INT(Visual.alphaBits), extra_new_buffers },
{ GL_BLEND, CONTEXT_BIT0(Color.BlendEnabled), NO_EXTRA },
- { GL_BLEND_SRC, CONTEXT_ENUM(Color.Blend[0].SrcRGB), NO_EXTRA },
+ { GL_BLEND_SRC, CONTEXT_ENUM(Color.SrcRGB), NO_EXTRA },
{ GL_BLUE_BITS, BUFFER_INT(Visual.blueBits), extra_new_buffers },
{ GL_COLOR_CLEAR_VALUE, LOC_CUSTOM, TYPE_FLOATN_4, 0, extra_new_frag_clamp },
{ GL_COLOR_WRITEMASK, LOC_CUSTOM, TYPE_INT_4, 0, NO_EXTRA },
extra_ARB_texture_cube_map }, /* XXX: OES_texture_cube_map */
/* XXX: OES_blend_subtract */
- { GL_BLEND_SRC_RGB_EXT, CONTEXT_ENUM(Color.Blend[0].SrcRGB), NO_EXTRA },
- { GL_BLEND_DST_RGB_EXT, CONTEXT_ENUM(Color.Blend[0].DstRGB), NO_EXTRA },
- { GL_BLEND_SRC_ALPHA_EXT, CONTEXT_ENUM(Color.Blend[0].SrcA), NO_EXTRA },
- { GL_BLEND_DST_ALPHA_EXT, CONTEXT_ENUM(Color.Blend[0].DstA), NO_EXTRA },
+ { GL_BLEND_SRC_RGB_EXT, CONTEXT_ENUM(Color.SrcRGB), NO_EXTRA },
+ { GL_BLEND_DST_RGB_EXT, CONTEXT_ENUM(Color.DstRGB), NO_EXTRA },
+ { GL_BLEND_SRC_ALPHA_EXT, CONTEXT_ENUM(Color.SrcA), NO_EXTRA },
+ { GL_BLEND_DST_ALPHA_EXT, CONTEXT_ENUM(Color.DstA), NO_EXTRA },
/* GL_BLEND_EQUATION_RGB, which is what we're really after, is
* defined identically to GL_BLEND_EQUATION. */
- { GL_BLEND_EQUATION, CONTEXT_ENUM(Color.Blend[0].EquationRGB), NO_EXTRA },
- { GL_BLEND_EQUATION_ALPHA_EXT, CONTEXT_ENUM(Color.Blend[0].EquationA), NO_EXTRA },
+ { GL_BLEND_EQUATION, CONTEXT_ENUM(Color.EquationRGB), NO_EXTRA },
+ { GL_BLEND_EQUATION_ALPHA_EXT, CONTEXT_ENUM(Color.EquationA), NO_EXTRA },
/* GL_ARB_texture_compression */
{ GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
{ GL_ALPHA_TEST, CONTEXT_BOOL(Color.AlphaEnabled), NO_EXTRA },
{ GL_ALPHA_TEST_FUNC, CONTEXT_ENUM(Color.AlphaFunc), NO_EXTRA },
{ GL_ALPHA_TEST_REF, LOC_CUSTOM, TYPE_FLOATN, 0, extra_new_frag_clamp },
- { GL_BLEND_DST, CONTEXT_ENUM(Color.Blend[0].DstRGB), NO_EXTRA },
+ { GL_BLEND_DST, CONTEXT_ENUM(Color.DstRGB), NO_EXTRA },
{ GL_CLIP_DISTANCE0, CONTEXT_BIT0(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
{ GL_CLIP_DISTANCE1, CONTEXT_BIT1(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
{ GL_CLIP_DISTANCE2, CONTEXT_BIT2(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
CONTEXT_INT(Const.MaxTextureCoordUnits),
extra_ARB_fragment_program_NV_fragment_program },
- /* GL_ARB_draw_buffers */
- { GL_MAX_DRAW_BUFFERS_ARB, CONTEXT_INT(Const.MaxDrawBuffers), NO_EXTRA },
-
/* GL_EXT_framebuffer_object / GL_NV_fbo_color_attachments */
{ GL_MAX_COLOR_ATTACHMENTS, CONTEXT_INT(Const.MaxColorAttachments),
extra_EXT_framebuffer_object },
- /* GL_ARB_draw_buffers / GL_NV_draw_buffers (for ES 2.0) */
- { GL_DRAW_BUFFER0_ARB, BUFFER_ENUM(ColorDrawBuffer[0]), NO_EXTRA },
- { GL_DRAW_BUFFER1_ARB, BUFFER_ENUM(ColorDrawBuffer[1]),
- extra_valid_draw_buffer },
- { GL_DRAW_BUFFER2_ARB, BUFFER_ENUM(ColorDrawBuffer[2]),
- extra_valid_draw_buffer },
- { GL_DRAW_BUFFER3_ARB, BUFFER_ENUM(ColorDrawBuffer[3]),
- extra_valid_draw_buffer },
- { GL_DRAW_BUFFER4_ARB, BUFFER_ENUM(ColorDrawBuffer[4]),
- extra_valid_draw_buffer },
- { GL_DRAW_BUFFER5_ARB, BUFFER_ENUM(ColorDrawBuffer[5]),
- extra_valid_draw_buffer },
- { GL_DRAW_BUFFER6_ARB, BUFFER_ENUM(ColorDrawBuffer[6]),
- extra_valid_draw_buffer },
- { GL_DRAW_BUFFER7_ARB, BUFFER_ENUM(ColorDrawBuffer[7]),
- extra_valid_draw_buffer },
-
{ GL_BLEND_COLOR_EXT, LOC_CUSTOM, TYPE_FLOATN_4, 0, extra_new_frag_clamp },
/* GL_ARB_fragment_program */
{ GL_MAX_TEXTURE_IMAGE_UNITS_ARB, /* == GL_MAX_TEXTURE_IMAGE_UNITS_NV */
{ GL_DEPTH_BIAS, CONTEXT_FLOAT(Pixel.DepthBias), NO_EXTRA },
{ GL_DEPTH_SCALE, CONTEXT_FLOAT(Pixel.DepthScale), NO_EXTRA },
{ GL_DOUBLEBUFFER, BUFFER_INT(Visual.doubleBufferMode), NO_EXTRA },
- { GL_DRAW_BUFFER, BUFFER_ENUM(ColorDrawBuffer[0]), NO_EXTRA },
+ { GL_DRAW_BUFFER, BUFFER_ENUM(ColorDrawBuffer), NO_EXTRA },
{ GL_EDGE_FLAG, LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA },
{ GL_FEEDBACK_BUFFER_SIZE, CONTEXT_INT(Feedback.BufferSize), NO_EXTRA },
{ GL_FEEDBACK_BUFFER_TYPE, CONTEXT_ENUM(Feedback.Type), NO_EXTRA },
break;
case GL_COLOR_WRITEMASK:
- v->value_int_4[0] = ctx->Color.ColorMask[0][RCOMP] ? 1 : 0;
- v->value_int_4[1] = ctx->Color.ColorMask[0][GCOMP] ? 1 : 0;
- v->value_int_4[2] = ctx->Color.ColorMask[0][BCOMP] ? 1 : 0;
- v->value_int_4[3] = ctx->Color.ColorMask[0][ACOMP] ? 1 : 0;
+ v->value_int_4[0] = ctx->Color.ColorMask[RCOMP] ? 1 : 0;
+ v->value_int_4[1] = ctx->Color.ColorMask[GCOMP] ? 1 : 0;
+ v->value_int_4[2] = ctx->Color.ColorMask[BCOMP] ? 1 : 0;
+ v->value_int_4[3] = ctx->Color.ColorMask[ACOMP] ? 1 : 0;
break;
case GL_EDGE_FLAG:
case EXTRA_FLUSH_CURRENT:
FLUSH_CURRENT(ctx, 0);
break;
- case EXTRA_VALID_DRAW_BUFFER:
- if (d->pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s(draw buffer %u)",
- func, d->pname - GL_DRAW_BUFFER0_ARB);
- return GL_FALSE;
- }
- break;
case EXTRA_VALID_TEXTURE_UNIT:
if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(texture %u)",
* any are written, FRAG_RESULT_COLOR will not be written.
*/
FRAG_RESULT_DATA0 = 3,
- FRAG_RESULT_MAX = (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS)
+ FRAG_RESULT_MAX = (FRAG_RESULT_DATA0)
} gl_frag_result;
GLuint ClearIndex; /**< Index for glClear */
union gl_color_union ClearColor; /**< Color for glClear, unclamped */
GLuint IndexMask; /**< Color index write mask */
- GLubyte ColorMask[MAX_DRAW_BUFFERS][4]; /**< Each flag is 0xff or 0x0 */
+ GLubyte ColorMask[4]; /**< Each flag is 0xff or 0x0 */
- GLenum DrawBuffer[MAX_DRAW_BUFFERS]; /**< Which buffer to draw into */
+ GLenum DrawBuffer; /**< Which buffer to draw into */
/**
* \name alpha testing
GLfloat BlendColorUnclamped[4]; /**< Blending color */
GLfloat BlendColor[4]; /**< Blending color */
- struct
- {
- GLenum SrcRGB; /**< RGB blend source term */
- GLenum DstRGB; /**< RGB blend dest term */
- GLenum SrcA; /**< Alpha blend source term */
- GLenum DstA; /**< Alpha blend dest term */
- GLenum EquationRGB; /**< GL_ADD, GL_SUBTRACT, etc. */
- GLenum EquationA; /**< GL_ADD, GL_SUBTRACT, etc. */
- } Blend[MAX_DRAW_BUFFERS];
- /** Are the blend func terms currently different for each buffer/target? */
- GLboolean _BlendFuncPerBuffer;
- /** Are the blend equations currently different for each buffer/target? */
- GLboolean _BlendEquationPerBuffer;
+ GLenum SrcRGB; /**< RGB blend source term */
+ GLenum DstRGB; /**< RGB blend dest term */
+ GLenum SrcA; /**< Alpha blend source term */
+ GLenum DstA; /**< Alpha blend dest term */
+ GLenum EquationRGB; /**< GL_ADD, GL_SUBTRACT, etc. */
+ GLenum EquationA; /**< GL_ADD, GL_SUBTRACT, etc. */
/*@}*/
/**
/* In unextended OpenGL these vars are part of the GL_COLOR_BUFFER
* attribute group and GL_PIXEL attribute group, respectively.
*/
- GLenum ColorDrawBuffer[MAX_DRAW_BUFFERS];
+ GLenum ColorDrawBuffer;
GLenum ColorReadBuffer;
/** Computed from ColorDraw/ReadBuffer above */
- GLuint _NumColorDrawBuffers;
- GLint _ColorDrawBufferIndexes[MAX_DRAW_BUFFERS]; /**< BUFFER_x or -1 */
+ GLint _ColorDrawBufferIndex; /**< BUFFER_x or -1 */
GLint _ColorReadBufferIndex; /* -1 = None */
- struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS];
+ struct gl_renderbuffer *_ColorDrawBuffer;
struct gl_renderbuffer *_ColorReadBuffer;
/** Delete this framebuffer */
/** vertex array / buffer object bounds checking */
GLboolean CheckArrayBounds;
- GLuint MaxDrawBuffers; /**< GL_ARB_draw_buffers */
-
GLuint MaxColorAttachments; /**< GL_EXT_framebuffer_object */
GLuint MaxRenderbufferSize; /**< GL_EXT_framebuffer_object */
GLuint MaxSamples; /**< GL_ARB_framebuffer_object */
GLboolean dummy_false; /* Set false by _mesa_init_extensions(). */
GLboolean ARB_color_buffer_float;
GLboolean ARB_conservative_depth;
- GLboolean ARB_depth_clamp;
- GLboolean ARB_draw_buffers_blend;
GLboolean ARB_fragment_program;
GLboolean ARB_fragment_program_shadow;
GLboolean ARB_fragment_shader;
return;
}
- if (colorNumber >= ctx->Const.MaxDrawBuffers) {
+ if (colorNumber > 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glBindFragDataLocation(index)");
return;
}
"result.depth", /* FRAG_RESULT_DEPTH */
"result.(one)", /* FRAG_RESULT_STENCIL */
"result.color", /* FRAG_RESULT_COLOR */
- "result.color[0]", /* FRAG_RESULT_DATA0 (named for GLSL's gl_FragData) */
- "result.color[1]",
- "result.color[2]",
- "result.color[3]",
- "result.color[4]",
- "result.color[5]",
- "result.color[6]",
- "result.color[7]" /* MAX_DRAW_BUFFERS = 8 */
};
/* sanity checks */
case MESA_SHADER_VERTEX:
return index < VERT_RESULT_VAR0 + ctx->Const.MaxVarying;
case MESA_SHADER_FRAGMENT:
- return index < FRAG_RESULT_DATA0 + ctx->Const.MaxDrawBuffers;
+ return index <= FRAG_RESULT_DATA0;
default:
return GL_FALSE;
}
{
GLint bytes;
- ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].SrcRGB == GL_ZERO);
- ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE);
+ ASSERT(ctx->Color.EquationRGB == GL_FUNC_ADD);
+ ASSERT(ctx->Color.EquationA == GL_FUNC_ADD);
+ ASSERT(ctx->Color.SrcRGB == GL_ZERO);
+ ASSERT(ctx->Color.DstRGB == GL_ONE);
(void) ctx;
/* just memcpy */
blend_replace(struct gl_context *ctx, GLuint n, const GLubyte mask[],
GLvoid *src, const GLvoid *dst, GLenum chanType)
{
- ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].SrcRGB == GL_ONE);
- ASSERT(ctx->Color.Blend[0].DstRGB == GL_ZERO);
+ ASSERT(ctx->Color.EquationRGB == GL_FUNC_ADD);
+ ASSERT(ctx->Color.EquationA == GL_FUNC_ADD);
+ ASSERT(ctx->Color.SrcRGB == GL_ONE);
+ ASSERT(ctx->Color.DstRGB == GL_ZERO);
(void) ctx;
(void) n;
(void) mask;
const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
GLuint i;
- ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA);
+ ASSERT(ctx->Color.EquationRGB == GL_FUNC_ADD);
+ ASSERT(ctx->Color.EquationA == GL_FUNC_ADD);
+ ASSERT(ctx->Color.SrcRGB == GL_SRC_ALPHA);
+ ASSERT(ctx->Color.SrcA == GL_SRC_ALPHA);
+ ASSERT(ctx->Color.DstRGB == GL_ONE_MINUS_SRC_ALPHA);
+ ASSERT(ctx->Color.DstA == GL_ONE_MINUS_SRC_ALPHA);
ASSERT(chanType == GL_UNSIGNED_BYTE);
(void) ctx;
const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
GLuint i;
- ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA);
+ ASSERT(ctx->Color.EquationRGB == GL_FUNC_ADD);
+ ASSERT(ctx->Color.EquationA == GL_FUNC_ADD);
+ ASSERT(ctx->Color.SrcRGB == GL_SRC_ALPHA);
+ ASSERT(ctx->Color.SrcA == GL_SRC_ALPHA);
+ ASSERT(ctx->Color.DstRGB == GL_ONE_MINUS_SRC_ALPHA);
+ ASSERT(ctx->Color.DstA == GL_ONE_MINUS_SRC_ALPHA);
ASSERT(chanType == GL_UNSIGNED_SHORT);
(void) ctx;
const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
GLuint i;
- ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA);
+ ASSERT(ctx->Color.EquationRGB == GL_FUNC_ADD);
+ ASSERT(ctx->Color.EquationA == GL_FUNC_ADD);
+ ASSERT(ctx->Color.SrcRGB == GL_SRC_ALPHA);
+ ASSERT(ctx->Color.SrcA == GL_SRC_ALPHA);
+ ASSERT(ctx->Color.DstRGB == GL_ONE_MINUS_SRC_ALPHA);
+ ASSERT(ctx->Color.DstA == GL_ONE_MINUS_SRC_ALPHA);
ASSERT(chanType == GL_FLOAT);
(void) ctx;
{
GLuint i;
- ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].SrcRGB == GL_ONE);
- ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE);
+ ASSERT(ctx->Color.EquationRGB == GL_FUNC_ADD);
+ ASSERT(ctx->Color.EquationA == GL_FUNC_ADD);
+ ASSERT(ctx->Color.SrcRGB == GL_ONE);
+ ASSERT(ctx->Color.DstRGB == GL_ONE);
(void) ctx;
if (chanType == GL_UNSIGNED_BYTE) {
GLvoid *src, const GLvoid *dst, GLenum chanType)
{
GLuint i;
- ASSERT(ctx->Color.Blend[0].EquationRGB == GL_MIN);
- ASSERT(ctx->Color.Blend[0].EquationA == GL_MIN);
+ ASSERT(ctx->Color.EquationRGB == GL_MIN);
+ ASSERT(ctx->Color.EquationA == GL_MIN);
(void) ctx;
if (chanType == GL_UNSIGNED_BYTE) {
GLvoid *src, const GLvoid *dst, GLenum chanType)
{
GLuint i;
- ASSERT(ctx->Color.Blend[0].EquationRGB == GL_MAX);
- ASSERT(ctx->Color.Blend[0].EquationA == GL_MAX);
+ ASSERT(ctx->Color.EquationRGB == GL_MAX);
+ ASSERT(ctx->Color.EquationA == GL_MAX);
(void) ctx;
if (chanType == GL_UNSIGNED_BYTE) {
*/
/* Source RGB factor */
- switch (ctx->Color.Blend[0].SrcRGB) {
+ switch (ctx->Color.SrcRGB) {
case GL_ZERO:
sR = sG = sB = 0.0F;
break;
}
/* Source Alpha factor */
- switch (ctx->Color.Blend[0].SrcA) {
+ switch (ctx->Color.SrcA) {
case GL_ZERO:
sA = 0.0F;
break;
}
/* Dest RGB factor */
- switch (ctx->Color.Blend[0].DstRGB) {
+ switch (ctx->Color.DstRGB) {
case GL_ZERO:
dR = dG = dB = 0.0F;
break;
}
/* Dest Alpha factor */
- switch (ctx->Color.Blend[0].DstA) {
+ switch (ctx->Color.DstA) {
case GL_ZERO:
dA = 0.0F;
break;
}
/* compute the blended RGB */
- switch (ctx->Color.Blend[0].EquationRGB) {
+ switch (ctx->Color.EquationRGB) {
case GL_FUNC_ADD:
r = Rs * sR + Rd * dR;
g = Gs * sG + Gd * dG;
}
/* compute the blended alpha */
- switch (ctx->Color.Blend[0].EquationA) {
+ switch (ctx->Color.EquationA) {
case GL_FUNC_ADD:
a = As * sA + Ad * dA;
break;
_swrast_choose_blend_func(struct gl_context *ctx, GLenum chanType)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- const GLenum eq = ctx->Color.Blend[0].EquationRGB;
- const GLenum srcRGB = ctx->Color.Blend[0].SrcRGB;
- const GLenum dstRGB = ctx->Color.Blend[0].DstRGB;
- const GLenum srcA = ctx->Color.Blend[0].SrcA;
- const GLenum dstA = ctx->Color.Blend[0].DstA;
+ const GLenum eq = ctx->Color.EquationRGB;
+ const GLenum srcRGB = ctx->Color.SrcRGB;
+ const GLenum dstRGB = ctx->Color.DstRGB;
+ const GLenum srcA = ctx->Color.SrcA;
+ const GLenum dstA = ctx->Color.DstA;
- if (ctx->Color.Blend[0].EquationRGB != ctx->Color.Blend[0].EquationA) {
+ if (ctx->Color.EquationRGB != ctx->Color.EquationA) {
swrast->BlendFunc = blend_general;
}
else if (eq == GL_MIN) {
switch (buffer) {
case GL_COLOR_BUFFER_BIT:
readRb = ctx->ReadBuffer->_ColorReadBuffer;
- drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0];
+ drawRb = ctx->DrawBuffer->_ColorDrawBuffer;
if (readRb->Format == drawRb->Format) {
mode = DIRECT;
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1)
{
struct gl_renderbuffer *readRb = ctx->ReadBuffer->_ColorReadBuffer;
- struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0];
+ struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_ColorDrawBuffer;
const GLint srcWidth = ABS(srcX1 - srcX0);
const GLint dstWidth = ABS(dstX1 - dstX0);
static void
clear_color_buffers(struct gl_context *ctx)
{
- GLuint buf;
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffer;
- for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) {
- struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[buf];
-
- /* If this is an ES2 context or GL_ARB_ES2_compatibility is supported,
- * the framebuffer can be complete with some attachments be missing. In
- * this case the _ColorDrawBuffers pointer will be NULL.
- */
- if (rb == NULL)
- continue;
-
- clear_rgba_buffer(ctx, rb, ctx->Color.ColorMask[buf]);
- }
+ clear_rgba_buffer(ctx, rb, ctx->Color.ColorMask);
}
if (SWRAST_CONTEXT(ctx)->NewState)
_swrast_validate_derived(ctx);
- if ((buffers & BUFFER_BITS_COLOR)
- && (ctx->DrawBuffer->_NumColorDrawBuffers > 0)) {
+ if (buffers & BUFFER_BITS_COLOR) {
clear_color_buffers(ctx);
}
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLbitfield rasterMask = 0;
- GLuint i;
if (ctx->Color.AlphaEnabled) rasterMask |= ALPHATEST_BIT;
if (ctx->Color.BlendEnabled) rasterMask |= BLEND_BIT;
if (swrast->_FogEnabled) rasterMask |= FOG_BIT;
if (ctx->Scissor.Enabled) rasterMask |= CLIP_BIT;
if (ctx->Stencil._Enabled) rasterMask |= STENCIL_BIT;
- for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
- if (!ctx->Color.ColorMask[i][0] ||
- !ctx->Color.ColorMask[i][1] ||
- !ctx->Color.ColorMask[i][2] ||
- !ctx->Color.ColorMask[i][3]) {
- rasterMask |= MASKING_BIT;
- break;
- }
+ if (!ctx->Color.ColorMask[0] ||
+ !ctx->Color.ColorMask[1] ||
+ !ctx->Color.ColorMask[2] ||
+ !ctx->Color.ColorMask[3]) {
+ rasterMask |= MASKING_BIT;
}
+
if (ctx->Color.ColorLogicOpEnabled) rasterMask |= LOGIC_OP_BIT;
if (ctx->Texture._EnabledUnits) rasterMask |= TEXTURE_BIT;
if ( ctx->Viewport.X < 0
rasterMask |= CLIP_BIT;
}
-
- /* If we're not drawing to exactly one color buffer set the
- * 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 != 1) {
- /* more than one color buffer designated for writing (or zero buffers) */
- rasterMask |= MULTI_DRAW_BIT;
- }
-
- for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
- if (ctx->Color.ColorMask[i][0] +
- ctx->Color.ColorMask[i][1] +
- ctx->Color.ColorMask[i][2] +
- ctx->Color.ColorMask[i][3] == 0) {
- rasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */
- break;
- }
+ if (ctx->Color.ColorMask[0] +
+ ctx->Color.ColorMask[1] +
+ ctx->Color.ColorMask[2] +
+ ctx->Color.ColorMask[3] == 0) {
+ rasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */
}
#if CHAN_TYPE == GL_FLOAT
GLint srcRowStride, dstRowStride;
if (type == GL_COLOR) {
- if (dstFb->_NumColorDrawBuffers != 1)
- return GL_FALSE;
srcRb = srcFb->_ColorReadBuffer;
- dstRb = dstFb->_ColorDrawBuffers[0];
+ dstRb = dstFb->_ColorDrawBuffer;
}
else if (type == GL_STENCIL) {
srcRb = srcFb->Attachment[BUFFER_STENCIL].Renderbuffer;
const struct gl_pixelstore_attrib *userUnpack,
const GLvoid *pixels)
{
- struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffer;
SWcontext *swrast = SWRAST_CONTEXT(ctx);
struct gl_pixelstore_attrib unpack;
if (!rb)
return GL_TRUE; /* no-op */
- if (ctx->DrawBuffer->_NumColorDrawBuffers > 1 ||
- (swrast->_RasterMask & ~CLIP_BIT) ||
+ if ((swrast->_RasterMask & ~CLIP_BIT) ||
ctx->Texture._EnabledCoordUnits ||
userUnpack->SwapBytes ||
ctx->Pixel.ZoomX != 1.0f ||
span.arrayMask = SPAN_RGBA;
span.arrayAttribs = FRAG_BIT_COL0; /* we're fill in COL0 attrib values */
- if (ctx->DrawBuffer->_NumColorDrawBuffers > 0) {
- GLenum datatype = _mesa_get_format_datatype(
- ctx->DrawBuffer->_ColorDrawBuffers[0]->Format);
- if (datatype != GL_FLOAT &&
- ctx->Color.ClampFragmentColor != GL_FALSE) {
- /* need to clamp colors before applying fragment ops */
- transferOps |= IMAGE_CLAMP_BIT;
- }
+ if (_mesa_get_format_datatype(ctx->DrawBuffer->_ColorDrawBuffer->Format) != GL_FLOAT &&
+ ctx->Color.ClampFragmentColor != GL_FALSE) {
+ /* need to clamp colors before applying fragment ops */
+ transferOps |= IMAGE_CLAMP_BIT;
}
/*
*/
void
_swrast_mask_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb,
- SWspan *span, GLuint buf)
+ SWspan *span)
{
const GLuint n = span->end;
void *rbPixels;
*/
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
/* treat 4xGLubyte as 1xGLuint */
- const GLuint srcMask = *((GLuint *) ctx->Color.ColorMask[buf]);
+ const GLuint srcMask = *((GLuint *) ctx->Color.ColorMask);
const GLuint dstMask = ~srcMask;
const GLuint *dst = (const GLuint *) rbPixels;
GLuint *src = (GLuint *) span->array->rgba8;
else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
/* 2-byte components */
/* XXX try to use 64-bit arithmetic someday */
- const GLushort rMask = ctx->Color.ColorMask[buf][RCOMP] ? 0xffff : 0x0;
- const GLushort gMask = ctx->Color.ColorMask[buf][GCOMP] ? 0xffff : 0x0;
- const GLushort bMask = ctx->Color.ColorMask[buf][BCOMP] ? 0xffff : 0x0;
- const GLushort aMask = ctx->Color.ColorMask[buf][ACOMP] ? 0xffff : 0x0;
+ const GLushort rMask = ctx->Color.ColorMask[RCOMP] ? 0xffff : 0x0;
+ const GLushort gMask = ctx->Color.ColorMask[GCOMP] ? 0xffff : 0x0;
+ const GLushort bMask = ctx->Color.ColorMask[BCOMP] ? 0xffff : 0x0;
+ const GLushort aMask = ctx->Color.ColorMask[ACOMP] ? 0xffff : 0x0;
const GLushort (*dst)[4] = (const GLushort (*)[4]) rbPixels;
GLushort (*src)[4] = span->array->rgba16;
GLuint i;
}
else {
/* 4-byte components */
- const GLuint rMask = ctx->Color.ColorMask[buf][RCOMP] ? ~0x0 : 0x0;
- const GLuint gMask = ctx->Color.ColorMask[buf][GCOMP] ? ~0x0 : 0x0;
- const GLuint bMask = ctx->Color.ColorMask[buf][BCOMP] ? ~0x0 : 0x0;
- const GLuint aMask = ctx->Color.ColorMask[buf][ACOMP] ? ~0x0 : 0x0;
+ const GLuint rMask = ctx->Color.ColorMask[RCOMP] ? ~0x0 : 0x0;
+ const GLuint gMask = ctx->Color.ColorMask[GCOMP] ? ~0x0 : 0x0;
+ const GLuint bMask = ctx->Color.ColorMask[BCOMP] ? ~0x0 : 0x0;
+ const GLuint aMask = ctx->Color.ColorMask[ACOMP] ? ~0x0 : 0x0;
const GLuint (*dst)[4] = (const GLuint (*)[4]) rbPixels;
GLuint (*src)[4] = (GLuint (*)[4]) span->array->attribs[FRAG_ATTRIB_COL0];
GLuint i;
extern void
_swrast_mask_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb,
- SWspan *span, GLuint buf);
+ SWspan *span);
#endif
{
struct gl_framebuffer *fb = ctx->DrawBuffer;
struct gl_renderbuffer *depthRb, *stencilRb;
- GLuint buf;
depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
if (depthRb) {
map_attachment(ctx, fb, BUFFER_STENCIL);
}
- for (buf = 0; buf < fb->_NumColorDrawBuffers; buf++) {
- map_attachment(ctx, fb, fb->_ColorDrawBufferIndexes[buf]);
- find_renderbuffer_colortype(fb->_ColorDrawBuffers[buf]);
- }
+ map_attachment(ctx, fb, fb->_ColorDrawBufferIndex);
+ find_renderbuffer_colortype(fb->_ColorDrawBuffer);
}
{
struct gl_framebuffer *fb = ctx->DrawBuffer;
struct gl_renderbuffer *depthRb, *stencilRb;
- GLuint buf;
depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
if (depthRb) {
unmap_attachment(ctx, fb, BUFFER_STENCIL);
}
- for (buf = 0; buf < fb->_NumColorDrawBuffers; buf++) {
- unmap_attachment(ctx, fb, fb->_ColorDrawBufferIndexes[buf]);
- }
+ unmap_attachment(ctx, fb, fb->_ColorDrawBufferIndex);
}
_swrast_write_rgba_span( struct gl_context *ctx, SWspan *span)
{
const SWcontext *swrast = SWRAST_CONTEXT(ctx);
- const GLuint *colorMask = (GLuint *) ctx->Color.ColorMask;
+ const GLuint colorMask = *((GLuint *)ctx->Color.ColorMask);
const GLbitfield origInterpMask = span->interpMask;
const GLbitfield origArrayMask = span->arrayMask;
const GLbitfield64 origArrayAttribs = span->arrayAttribs;
/* We had to wait until now to check for glColorMask(0,0,0,0) because of
* the occlusion test.
*/
- if (fb->_NumColorDrawBuffers == 1 && colorMask[0] == 0x0) {
+ if (colorMask == 0) {
/* no colors to write */
goto end;
}
* multiFragOutputs=TRUE for the later case.
*/
{
- const GLuint numBuffers = fb->_NumColorDrawBuffers;
- GLuint buf;
+ struct gl_renderbuffer *rb = fb->_ColorDrawBuffer;
- for (buf = 0; buf < numBuffers; buf++) {
- struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf];
+ /* color[fragOutput] will be written to buffer */
- /* color[fragOutput] will be written to buffer[buf] */
+ if (rb) {
+ struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
+ GLenum colorType = srb->ColorType;
- if (rb) {
- GLchan rgbaSave[MAX_WIDTH][4];
- struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
- GLenum colorType = srb->ColorType;
+ assert(colorType == GL_UNSIGNED_BYTE ||
+ colorType == GL_FLOAT);
- assert(colorType == GL_UNSIGNED_BYTE ||
- colorType == GL_FLOAT);
-
- /* set span->array->rgba to colors for renderbuffer's datatype */
- if (span->array->ChanType != colorType) {
- convert_color_type(span, colorType, 0);
+ /* set span->array->rgba to colors for renderbuffer's datatype */
+ if (span->array->ChanType != colorType) {
+ convert_color_type(span, colorType, 0);
+ }
+ else {
+ if (span->array->ChanType == GL_UNSIGNED_BYTE) {
+ span->array->rgba = span->array->rgba8;
}
else {
- if (span->array->ChanType == GL_UNSIGNED_BYTE) {
- span->array->rgba = span->array->rgba8;
- }
- else {
- span->array->rgba = (void *)
- span->array->attribs[FRAG_ATTRIB_COL0];
- }
- }
-
- if (numBuffers > 1) {
- /* save colors for second, third renderbuffer writes */
- memcpy(rgbaSave, span->array->rgba,
- 4 * span->end * sizeof(GLchan));
+ span->array->rgba = (void *)span->array->attribs[FRAG_ATTRIB_COL0];
}
+ }
- ASSERT(rb->_BaseFormat == GL_RGBA ||
- rb->_BaseFormat == GL_RGB ||
- rb->_BaseFormat == GL_RED ||
- rb->_BaseFormat == GL_RG ||
- rb->_BaseFormat == GL_ALPHA);
- if (ctx->Color.ColorLogicOpEnabled) {
- _swrast_logicop_rgba_span(ctx, rb, span);
- }
- else if ((ctx->Color.BlendEnabled >> buf) & 1) {
- _swrast_blend_span(ctx, rb, span);
- }
+ ASSERT(rb->_BaseFormat == GL_RGBA ||
+ rb->_BaseFormat == GL_RGB ||
+ rb->_BaseFormat == GL_RED ||
+ rb->_BaseFormat == GL_RG ||
+ rb->_BaseFormat == GL_ALPHA);
- if (colorMask[buf] != 0xffffffff) {
- _swrast_mask_rgba_span(ctx, rb, span, buf);
- }
+ if (ctx->Color.ColorLogicOpEnabled) {
+ _swrast_logicop_rgba_span(ctx, rb, span);
+ }
+ else if (ctx->Color.BlendEnabled) {
+ _swrast_blend_span(ctx, rb, span);
+ }
- if (span->arrayMask & SPAN_XY) {
- /* array of pixel coords */
- put_values(ctx, rb,
- span->array->ChanType, span->end,
- span->array->x, span->array->y,
- span->array->rgba, span->array->mask);
- }
- else {
- /* horizontal run of pixels */
- _swrast_put_row(ctx, rb,
- span->array->ChanType,
- span->end, span->x, span->y,
- span->array->rgba,
- span->writeAll ? NULL: span->array->mask);
- }
+ if (colorMask != 0xffffffff) {
+ _swrast_mask_rgba_span(ctx, rb, span);
+ }
- if (numBuffers > 1) {
- /* restore original span values */
- memcpy(span->array->rgba, rgbaSave,
- 4 * span->end * sizeof(GLchan));
- }
+ if (span->arrayMask & SPAN_XY) {
+ /* array of pixel coords */
+ put_values(ctx, rb,
+ span->array->ChanType, span->end,
+ span->array->x, span->array->y,
+ span->array->rgba, span->array->mask);
+ }
+ else {
+ /* horizontal run of pixels */
+ _swrast_put_row(ctx, rb,
+ span->array->ChanType,
+ span->end, span->x, span->y,
+ span->array->rgba,
+ span->writeAll ? NULL: span->array->mask);
+ }
- } /* if rb */
- } /* for buf */
+ } /* if rb */
}
end:
#define T_SCALE theight
#define SETUP_CODE \
- struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; \
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffer; \
const struct gl_texture_object *obj = \
ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \
const struct gl_texture_image *texImg = \
#define T_SCALE theight
#define SETUP_CODE \
- struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; \
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffer; \
const struct gl_texture_object *obj = \
ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \
const struct gl_texture_image *texImg = \