void (GLAPIENTRYP BlendEquationSeparateEXT)(GLenum modeRGB, GLenum modeA); /* 879 */
void (GLAPIENTRYP BindFramebufferEXT)(GLenum target, GLuint framebuffer); /* 880 */
void (GLAPIENTRYP BindRenderbufferEXT)(GLenum target, GLuint renderbuffer); /* 881 */
- GLenum (GLAPIENTRYP CheckFramebufferStatusEXT)(GLenum target); /* 882 */
void (GLAPIENTRYP DeleteFramebuffersEXT)(GLsizei n, const GLuint * framebuffers); /* 883 */
void (GLAPIENTRYP DeleteRenderbuffersEXT)(GLsizei n, const GLuint * renderbuffers); /* 884 */
void (GLAPIENTRYP FramebufferRenderbufferEXT)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); /* 885 */
#include "main/arrayobj.h"
#include "main/context.h"
#include "main/framebuffer.h"
-#include "main/mipmap.h"
#include "main/readpix.h"
#include "main/renderbuffer.h"
#include "main/shaderobj.h"
#include "main/texobj.h"
#include "main/texstore.h"
#include "main/bufferobj.h"
-#include "main/fbobject.h"
#include "main/texturebarrier.h"
#include "program/program.h"
driver->CopyTexSubImage1D = _mesa_meta_CopyTexSubImage1D;
driver->CopyTexSubImage2D = _mesa_meta_CopyTexSubImage2D;
driver->CopyTexSubImage3D = _mesa_meta_CopyTexSubImage3D;
- driver->GenerateMipmap = _mesa_meta_GenerateMipmap;
driver->TestProxyTexImage = _mesa_test_proxy_teximage;
driver->BindTexture = NULL;
driver->NewTextureObject = _mesa_new_texture_object;
/* buffer objects */
_mesa_init_buffer_object_functions(driver);
- driver->NewFramebuffer = _mesa_new_framebuffer;
- driver->NewRenderbuffer = _swrast_new_soft_renderbuffer;
driver->MapRenderbuffer = _swrast_map_soft_renderbuffer;
driver->UnmapRenderbuffer = _swrast_unmap_soft_renderbuffer;
- driver->RenderTexture = _swrast_render_texture;
- driver->FinishRenderTexture = _swrast_finish_render_texture;
- driver->FramebufferRenderbuffer = _mesa_framebuffer_renderbuffer;
- driver->ValidateFramebuffer = _mesa_validate_framebuffer;
-
- driver->BlitFramebuffer = _swrast_BlitFramebuffer;
_mesa_init_texture_barrier_functions(driver);
#include "main/context.h"
#include "main/depth.h"
#include "main/enable.h"
-#include "main/fbobject.h"
#include "main/feedback.h"
#include "main/formats.h"
#include "main/image.h"
#include "main/macros.h"
#include "main/matrix.h"
-#include "main/mipmap.h"
#include "main/pixel.h"
#include "main/pbo.h"
#include "main/polygon.h"
GLint ViewportX, ViewportY, ViewportW, ViewportH;
GLclampd DepthNear, DepthFar;
- /** MESA_META_CLAMP_FRAGMENT_COLOR */
- GLenum ClampFragmentColor;
-
- /** MESA_META_CLAMP_VERTEX_COLOR */
- GLenum ClampVertexColor;
-
/** MESA_META_SELECT_FEEDBACK */
GLenum RenderMode;
struct gl_selection Select;
GLuint VBO;
};
-
-/**
- * State for _mesa_meta_generate_mipmap()
- */
-struct gen_mipmap_state
-{
- GLuint ArrayObj;
- GLuint VBO;
- GLuint FBO;
-};
-
-
-/**
- * State for texture decompression
- */
-struct decompress_state
-{
- GLuint ArrayObj;
- GLuint VBO, FBO, RBO;
- GLint Width, Height;
-};
-
#define MAX_META_OPS_DEPTH 8
/**
* All per-context meta state.
struct temp_texture TempTex;
struct copypix_state CopyPix; /**< For _mesa_meta_CopyPixels() */
- struct gen_mipmap_state Mipmap; /**< For _mesa_meta_GenerateMipmap() */
- struct decompress_state Decompress; /**< For texture decompression */
};
static void cleanup_temp_texture(struct gl_context *ctx, struct temp_texture *tex);
_mesa_DepthRange(0.0, 1.0);
}
- if (state & MESA_META_CLAMP_FRAGMENT_COLOR) {
- save->ClampFragmentColor = ctx->Color.ClampFragmentColor;
-
- /* Generally in here we want to do clamping according to whether
- * it's for the pixel path (ClampFragmentColor is GL_TRUE),
- * regardless of the internal implementation of the metaops.
- */
- if (ctx->Color.ClampFragmentColor != GL_TRUE)
- _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
- }
-
- if (state & MESA_META_CLAMP_VERTEX_COLOR) {
- save->ClampVertexColor = ctx->Light.ClampVertexColor;
-
- /* Generally in here we never want vertex color clamping --
- * result clamping is only dependent on fragment clamping.
- */
- _mesa_ClampColorARB(GL_CLAMP_VERTEX_COLOR, GL_FALSE);
- }
-
if (state & MESA_META_SELECT_FEEDBACK) {
save->RenderMode = ctx->RenderMode;
if (ctx->RenderMode == GL_SELECT) {
_mesa_DepthRange(save->DepthNear, save->DepthFar);
}
- if (state & MESA_META_CLAMP_FRAGMENT_COLOR) {
- _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, save->ClampFragmentColor);
- }
-
- if (state & MESA_META_CLAMP_VERTEX_COLOR) {
- _mesa_ClampColorARB(GL_CLAMP_VERTEX_COLOR, save->ClampVertexColor);
- }
-
/* misc */
if (save->Lighting) {
_mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE);
_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
- * images are mapped.
- * \return GL_TRUE if a fallback is needed, GL_FALSE otherwise
- */
-GLboolean
-_mesa_meta_check_generate_mipmap_fallback(struct gl_context *ctx, GLenum target,
- struct gl_texture_object *texObj)
-{
- const GLuint fboSave = ctx->DrawBuffer->Name;
- struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap;
- struct gl_texture_image *baseImage;
- GLuint srcLevel;
- GLenum status;
-
- /* check for fallbacks */
- if (!ctx->Extensions.EXT_framebuffer_object ||
- target == GL_TEXTURE_3D) {
- return GL_TRUE;
- }
-
- srcLevel = texObj->BaseLevel;
- baseImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
- if (!baseImage) {
- return GL_TRUE;
- }
-
- /*
- * Test that we can actually render in the texture's format.
- */
- if (!mipmap->FBO)
- _mesa_GenFramebuffersEXT(1, &mipmap->FBO);
- _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO);
-
- if (target == GL_TEXTURE_1D) {
- _mesa_FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- target, texObj->Name, srcLevel);
- }
-#if 0
- /* other work is needed to enable 3D mipmap generation */
- else if (target == GL_TEXTURE_3D) {
- GLint zoffset = 0;
- _mesa_FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- target, texObj->Name, srcLevel, zoffset);
- }
-#endif
- else {
- /* 2D / cube */
- _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- target, texObj->Name, srcLevel);
- }
-
- status = _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
-
- _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave);
-
- if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- return GL_TRUE;
- }
-
- return GL_FALSE;
-}
-
-
-/**
- * Compute the texture coordinates for the four vertices of a quad for
- * drawing a 2D texture image or slice of a cube/3D texture.
- * \param faceTarget GL_TEXTURE_1D/2D/3D or cube face name
- * \param slice slice of a 1D/2D array texture or 3D texture
- * \param width width of the texture image
- * \param height height of the texture image
- * \param coords0/1/2/3 returns the computed texcoords
- */
-static void
-setup_texture_coords(GLenum faceTarget,
- GLint slice,
- GLint width,
- GLint height,
- GLfloat coords0[3],
- GLfloat coords1[3],
- GLfloat coords2[3],
- GLfloat coords3[3])
-{
- static const GLfloat st[4][2] = {
- {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}
- };
- GLuint i;
- GLfloat r;
-
- switch (faceTarget) {
- case GL_TEXTURE_1D:
- case GL_TEXTURE_2D:
- case GL_TEXTURE_3D:
- if (faceTarget == GL_TEXTURE_3D)
- r = 1.0F / slice;
- else if (faceTarget == GL_TEXTURE_2D_ARRAY)
- r = slice;
- else
- r = 0.0F;
- coords0[0] = 0.0F; /* s */
- coords0[1] = 0.0F; /* t */
- coords0[2] = r; /* r */
- coords1[0] = 1.0F;
- coords1[1] = 0.0F;
- coords1[2] = r;
- coords2[0] = 1.0F;
- coords2[1] = 1.0F;
- coords2[2] = r;
- coords3[0] = 0.0F;
- coords3[1] = 1.0F;
- coords3[2] = r;
- break;
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- /* loop over quad verts */
- for (i = 0; i < 4; i++) {
- /* Compute sc = +/-scale and tc = +/-scale.
- * Not +/-1 to avoid cube face selection ambiguity near the edges,
- * though that can still sometimes happen with this scale factor...
- */
- const GLfloat scale = 0.9999f;
- const GLfloat sc = (2.0f * st[i][0] - 1.0f) * scale;
- const GLfloat tc = (2.0f * st[i][1] - 1.0f) * scale;
- GLfloat *coord;
-
- switch (i) {
- case 0:
- coord = coords0;
- break;
- case 1:
- coord = coords1;
- break;
- case 2:
- coord = coords2;
- break;
- case 3:
- coord = coords3;
- break;
- default:
- assert(0);
- }
-
- switch (faceTarget) {
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- coord[0] = 1.0f;
- coord[1] = -tc;
- coord[2] = -sc;
- break;
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- coord[0] = -1.0f;
- coord[1] = -tc;
- coord[2] = sc;
- break;
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- coord[0] = sc;
- coord[1] = 1.0f;
- coord[2] = tc;
- break;
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- coord[0] = sc;
- coord[1] = -1.0f;
- coord[2] = -tc;
- break;
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- coord[0] = sc;
- coord[1] = -tc;
- coord[2] = 1.0f;
- break;
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- coord[0] = -sc;
- coord[1] = -tc;
- coord[2] = -1.0f;
- break;
- default:
- assert(0);
- }
- }
- break;
- default:
- assert(0 && "unexpected target in meta setup_texture_coords()");
- }
-}
-
-
-/**
- * Called via ctx->Driver.GenerateMipmap()
- * Note: We don't yet support 3D textures, 1D/2D array textures or texture
- * borders.
- */
-void
-_mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
- struct gl_texture_object *texObj)
-{
- struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap;
- struct vertex {
- GLfloat x, y, tex[3];
- };
- struct vertex verts[4];
- const GLuint baseLevel = texObj->BaseLevel;
- const GLuint maxLevel = texObj->MaxLevel;
- const GLenum minFilterSave = texObj->Sampler.MinFilter;
- const GLenum magFilterSave = texObj->Sampler.MagFilter;
- const GLint maxLevelSave = texObj->MaxLevel;
- const GLboolean genMipmapSave = texObj->GenerateMipmap;
- const GLenum wrapSSave = texObj->Sampler.WrapS;
- const GLenum wrapTSave = texObj->Sampler.WrapT;
- const GLenum wrapRSave = texObj->Sampler.WrapR;
- const GLuint fboSave = ctx->DrawBuffer->Name;
- const GLuint original_active_unit = ctx->Texture.CurrentUnit;
- GLenum faceTarget;
- GLuint dstLevel;
- const GLuint border = 0;
- const GLint slice = 0;
-
- if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) {
- _mesa_generate_mipmap(ctx, target, texObj);
- return;
- }
-
- if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
- target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) {
- faceTarget = target;
- target = GL_TEXTURE_CUBE_MAP;
- }
- else {
- faceTarget = target;
- }
-
- _mesa_meta_begin(ctx, MESA_META_ALL);
-
- if (original_active_unit != 0)
- _mesa_BindTexture(target, texObj->Name);
-
- if (mipmap->ArrayObj == 0) {
- /* one-time setup */
-
- /* create vertex array object */
- _mesa_GenVertexArraysAPPLE(1, &mipmap->ArrayObj);
- _mesa_BindVertexArrayAPPLE(mipmap->ArrayObj);
-
- /* create vertex array buffer */
- _mesa_GenBuffersARB(1, &mipmap->VBO);
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->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_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(tex));
- _mesa_EnableClientState(GL_VERTEX_ARRAY);
- _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
- }
- else {
- _mesa_BindVertexArray(mipmap->ArrayObj);
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
- }
-
- if (!mipmap->FBO) {
- _mesa_GenFramebuffersEXT(1, &mipmap->FBO);
- }
- _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO);
-
- _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, GL_FALSE);
- _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
-
- _mesa_set_enable(ctx, target, GL_TRUE);
-
- /* setup texcoords (XXX what about border?) */
- setup_texture_coords(faceTarget,
- slice,
- 0, 0, /* width, height never used here */
- verts[0].tex,
- verts[1].tex,
- verts[2].tex,
- verts[3].tex);
-
- /* setup vertex positions */
- verts[0].x = 0.0F;
- verts[0].y = 0.0F;
- verts[1].x = 1.0F;
- verts[1].y = 0.0F;
- verts[2].x = 1.0F;
- verts[2].y = 1.0F;
- verts[3].x = 0.0F;
- verts[3].y = 1.0F;
-
- /* upload new vertex data */
- _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
-
- /* setup projection matrix */
- _mesa_MatrixMode(GL_PROJECTION);
- _mesa_LoadIdentity();
- _mesa_Ortho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
-
- /* texture is already locked, unlock now */
- _mesa_unlock_texture(ctx, texObj);
-
- for (dstLevel = baseLevel + 1; dstLevel <= maxLevel; dstLevel++) {
- const struct gl_texture_image *srcImage;
- const GLuint srcLevel = dstLevel - 1;
- GLsizei srcWidth, srcHeight, srcDepth;
- GLsizei dstWidth, dstHeight, dstDepth;
- GLenum status;
-
- srcImage = _mesa_select_tex_image(ctx, texObj, faceTarget, srcLevel);
- assert(srcImage->Border == 0); /* XXX we can fix this */
-
- /* src size w/out border */
- srcWidth = srcImage->Width - 2 * border;
- srcHeight = srcImage->Height - 2 * border;
- srcDepth = srcImage->Depth - 2 * border;
-
- /* new dst size w/ border */
- dstWidth = MAX2(1, srcWidth / 2) + 2 * border;
- dstHeight = MAX2(1, srcHeight / 2) + 2 * border;
- dstDepth = MAX2(1, srcDepth / 2) + 2 * border;
-
- if (dstWidth == srcImage->Width &&
- dstHeight == srcImage->Height &&
- dstDepth == srcImage->Depth) {
- /* all done */
- break;
- }
-
- /* Allocate storage for the destination mipmap image(s) */
-
- /* Set MaxLevel large enough to hold the new level when we allocate it */
- _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, dstLevel);
-
- if (!_mesa_prepare_mipmap_level(ctx, texObj, dstLevel,
- dstWidth, dstHeight, dstDepth,
- srcImage->Border,
- srcImage->InternalFormat,
- srcImage->TexFormat)) {
- /* All done. We either ran out of memory or we would go beyond the
- * last valid level of an immutable texture if we continued.
- */
- break;
- }
-
- /* limit minification to src level */
- _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel);
-
- /* Set to draw into the current dstLevel */
- if (target == GL_TEXTURE_1D) {
- _mesa_FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- target,
- texObj->Name,
- dstLevel);
- }
- else if (target == GL_TEXTURE_3D) {
- GLint zoffset = 0; /* XXX unfinished */
- _mesa_FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- target,
- texObj->Name,
- dstLevel, zoffset);
- }
- else {
- /* 2D / cube */
- _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- faceTarget,
- texObj->Name,
- dstLevel);
- }
-
- _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
-
- /* sanity check */
- status = _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
- if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- abort();
- break;
- }
-
- assert(dstWidth == ctx->DrawBuffer->Width);
- assert(dstHeight == ctx->DrawBuffer->Height);
-
- /* setup viewport */
- _mesa_set_viewport(ctx, 0, 0, dstWidth, dstHeight);
-
- _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
-
- _mesa_lock_texture(ctx, texObj); /* relock */
-
- _mesa_meta_end(ctx);
-
- _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilterSave);
- _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilterSave);
- _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave);
- _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, genMipmapSave);
- _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, wrapSSave);
- _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, wrapTSave);
- _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, wrapRSave);
-
- _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave);
-}
-
/**
* Determine the GL data type to use for the temporary image read with
#define MESA_META_TEXTURE 0x1000
#define MESA_META_VERTEX 0x2000
#define MESA_META_VIEWPORT 0x4000
-#define MESA_META_CLAMP_FRAGMENT_COLOR 0x8000
-#define MESA_META_CLAMP_VERTEX_COLOR 0x10000
-#define MESA_META_CLIP 0x40000
-#define MESA_META_SELECT_FEEDBACK 0x80000
+#define MESA_META_CLIP 0x8000
+#define MESA_META_SELECT_FEEDBACK 0x10000
/**\}*/
extern void
GLsizei width, GLsizei height,
GLint dstx, GLint dsty, GLenum type);
-extern GLboolean
-_mesa_meta_check_generate_mipmap_fallback(struct gl_context *ctx, GLenum target,
- struct gl_texture_object *texObj);
-
-extern void
-_mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
- struct gl_texture_object *texObj);
-
extern void
_mesa_meta_CopyTexSubImage1D(struct gl_context *ctx,
struct gl_texture_image *texImage,
context.c
convolve.c
cpuinfo.c
- debug.c
depth.c
dlist.c
dlopen.c
eval.c
execmem.c
extensions.c
- fbobject.c
feedback.c
fog.c
formats.c
light.c
lines.c
matrix.c
- mipmap.c
mm.c
multisample.c
pack.c
if (ctx->NewState)
_mesa_update_state(ctx);
- if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glAccum(incomplete framebuffer)");
- return;
- }
-
if (ctx->RasterDiscard)
return;
#include "get.h"
#include "feedback.h"
#include "fog.h"
-#if FEATURE_EXT_framebuffer_object
-#include "fbobject.h"
-#endif
#include "framebuffer.h"
#include "hint.h"
#include "histogram.h"
SET_BlendFuncSeparateEXT(exec, _mesa_BlendFuncSeparateEXT);
#endif
- /* 196. GL_MESA_resize_buffers */
-#if _HAVE_FULL_GL
- SET_ResizeBuffersMESA(exec, _mesa_ResizeBuffersMESA);
-#endif
-
/* 197. GL_MESA_window_pos */
/* part of _mesa_init_rastpos_dispatch(exec); */
SET_TexBumpParameterivATI(exec, _mesa_TexBumpParameterivATI);
SET_TexBumpParameterfvATI(exec, _mesa_TexBumpParameterfvATI);
-#if FEATURE_EXT_framebuffer_object
- SET_IsRenderbufferEXT(exec, _mesa_IsRenderbufferEXT);
- SET_BindRenderbufferEXT(exec, _mesa_BindRenderbufferEXT);
- SET_DeleteRenderbuffersEXT(exec, _mesa_DeleteRenderbuffersEXT);
- SET_GenRenderbuffersEXT(exec, _mesa_GenRenderbuffersEXT);
- SET_RenderbufferStorageEXT(exec, _mesa_RenderbufferStorageEXT);
- SET_GetRenderbufferParameterivEXT(exec, _mesa_GetRenderbufferParameterivEXT);
- SET_IsFramebufferEXT(exec, _mesa_IsFramebufferEXT);
- SET_BindFramebufferEXT(exec, _mesa_BindFramebufferEXT);
- SET_DeleteFramebuffersEXT(exec, _mesa_DeleteFramebuffersEXT);
- SET_GenFramebuffersEXT(exec, _mesa_GenFramebuffersEXT);
- SET_CheckFramebufferStatusEXT(exec, _mesa_CheckFramebufferStatusEXT);
- SET_FramebufferTexture1DEXT(exec, _mesa_FramebufferTexture1DEXT);
- SET_FramebufferTexture2DEXT(exec, _mesa_FramebufferTexture2DEXT);
- SET_FramebufferTexture3DEXT(exec, _mesa_FramebufferTexture3DEXT);
- SET_FramebufferRenderbufferEXT(exec, _mesa_FramebufferRenderbufferEXT);
- SET_GetFramebufferAttachmentParameterivEXT(exec, _mesa_GetFramebufferAttachmentParameterivEXT);
- SET_GenerateMipmapEXT(exec, _mesa_GenerateMipmapEXT);
-#endif
-
-#if FEATURE_EXT_framebuffer_blit
- SET_BlitFramebufferEXT(exec, _mesa_BlitFramebufferEXT);
-#endif
-
/* GL_EXT_gpu_program_parameters */
#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
SET_ProgramEnvParameters4fvEXT(exec, _mesa_ProgramEnvParameters4fvEXT);
/* GL_ATI_separate_stencil */
SET_StencilFuncSeparateATI(exec, _mesa_StencilFuncSeparateATI);
-#if FEATURE_ARB_framebuffer_object
- /* The ARB_fbo functions are the union of
- * GL_EXT_fbo, GL_EXT_framebuffer_blit, GL_EXT_texture_array
- */
- SET_RenderbufferStorageMultisample(exec, _mesa_RenderbufferStorageMultisample);
-#endif
-
#if FEATURE_ARB_map_buffer_range
SET_MapBufferRange(exec, _mesa_MapBufferRange);
SET_FlushMappedBufferRange(exec, _mesa_FlushMappedBufferRange);
SET_GetObjectParameterivAPPLE(exec, _mesa_GetObjectParameterivAPPLE);
#endif
- SET_ClampColorARB(exec, _mesa_ClampColorARB);
-
/* GL_EXT_texture_integer */
SET_ClearColorIiEXT(exec, _mesa_ClearColorIiEXT);
SET_ClearColorIuiEXT(exec, _mesa_ClearColorIuiEXT);
/* GL 3.0 (functions not covered by other extensions) */
SET_GetStringi(exec, _mesa_GetStringi);
- SET_ClampColor(exec, _mesa_ClampColorARB);
/* GL_NV_texture_barrier */
SET_TextureBarrierNV(exec, _mesa_TextureBarrierNV);
_mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, samp->WrapR);
_mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, samp->MinFilter);
_mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, samp->MagFilter);
- _mesa_TexParameterf(target, GL_TEXTURE_MIN_LOD, samp->MinLod);
- _mesa_TexParameterf(target, GL_TEXTURE_MAX_LOD, samp->MaxLod);
- _mesa_TexParameterf(target, GL_TEXTURE_LOD_BIAS, samp->LodBias);
_mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority);
- _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, obj->BaseLevel);
- _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, obj->MaxLevel);
if (ctx->Extensions.EXT_texture_filter_anisotropic) {
_mesa_TexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
samp->MaxAnisotropy);
(GLboolean) (color->ColorMask[3] != 0));
_mesa_DrawBuffer(color->DrawBuffer);
_mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled);
- _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRefUnclamped);
+ _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRef);
if (ctx->Color.BlendEnabled != color->BlendEnabled) {
_mesa_set_enable(ctx, GL_BLEND, (color->BlendEnabled & 1));
}
color->EquationRGB,
color->EquationA);
}
- _mesa_BlendColor(color->BlendColorUnclamped[0],
- color->BlendColorUnclamped[1],
- color->BlendColorUnclamped[2],
- color->BlendColorUnclamped[3]);
+ _mesa_BlendColor(color->BlendColor[0],
+ color->BlendColor[1],
+ color->BlendColor[2],
+ color->BlendColor[3]);
_mesa_LogicOp(color->LogicOp);
_mesa_set_enable(ctx, GL_COLOR_LOGIC_OP,
color->ColorLogicOpEnabled);
_mesa_set_enable(ctx, GL_INDEX_LOGIC_OP,
color->IndexLogicOpEnabled);
_mesa_set_enable(ctx, GL_DITHER, color->DitherFlag);
- _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, color->ClampFragmentColor);
- _mesa_ClampColorARB(GL_CLAMP_READ_COLOR_ARB, color->ClampReadColor);
}
break;
case GL_CURRENT_BIT:
_mesa_Hint(GL_FOG_HINT, hint->Fog);
_mesa_Hint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT,
hint->ClipVolumeClipping);
- _mesa_Hint(GL_TEXTURE_COMPRESSION_HINT_ARB,
- hint->TextureCompression);
}
break;
case GL_LIGHTING_BIT:
/* materials */
memcpy(&ctx->Light.Material, &light->Material,
sizeof(struct gl_material));
- _mesa_ClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, light->ClampVertexColor);
}
break;
case GL_LINE_BIT:
tmp[2] = blue;
tmp[3] = alpha;
- if (TEST_EQ_4V(tmp, ctx->Color.BlendColorUnclamped))
+ if (TEST_EQ_4V(tmp, ctx->Color.BlendColor))
return;
FLUSH_VERTICES(ctx, _NEW_COLOR);
- COPY_4FV( ctx->Color.BlendColorUnclamped, tmp );
-
- ctx->Color.BlendColor[0] = CLAMP(tmp[0], 0.0F, 1.0F);
- ctx->Color.BlendColor[1] = CLAMP(tmp[1], 0.0F, 1.0F);
- ctx->Color.BlendColor[2] = CLAMP(tmp[2], 0.0F, 1.0F);
- ctx->Color.BlendColor[3] = CLAMP(tmp[3], 0.0F, 1.0F);
+ COPY_4FV( ctx->Color.BlendColor, tmp );
if (ctx->Driver.BlendColor)
(*ctx->Driver.BlendColor)(ctx, ctx->Color.BlendColor);
case GL_NOTEQUAL:
case GL_GEQUAL:
case GL_ALWAYS:
- if (ctx->Color.AlphaFunc == func && ctx->Color.AlphaRefUnclamped == ref)
+ if (ctx->Color.AlphaFunc == func && ctx->Color.AlphaRef == ref)
return; /* no change */
FLUSH_VERTICES(ctx, _NEW_COLOR);
ctx->Color.AlphaFunc = func;
- ctx->Color.AlphaRefUnclamped = ref;
- ctx->Color.AlphaRef = CLAMP(ref, 0.0F, 1.0F);
+ ctx->Color.AlphaRef = ref;
if (ctx->Driver.AlphaFunc)
ctx->Driver.AlphaFunc(ctx, func, ctx->Color.AlphaRef);
ctx->Driver.ColorMask( ctx, red, green, blue, alpha );
}
-void GLAPIENTRY
-_mesa_ClampColorARB(GLenum target, GLenum clamp)
-{
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (clamp != GL_TRUE && clamp != GL_FALSE && clamp != GL_FIXED_ONLY_ARB) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(clamp)");
- return;
- }
-
- switch (target) {
- case GL_CLAMP_VERTEX_COLOR_ARB:
- FLUSH_VERTICES(ctx, _NEW_LIGHT);
- ctx->Light.ClampVertexColor = clamp;
- break;
- case GL_CLAMP_FRAGMENT_COLOR_ARB:
- FLUSH_VERTICES(ctx, _NEW_FRAG_CLAMP);
- ctx->Color.ClampFragmentColor = clamp;
- break;
- case GL_CLAMP_READ_COLOR_ARB:
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- ctx->Color.ClampReadColor = clamp;
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(target)");
- return;
- }
-}
-
-
-
/**********************************************************************/
/** \name Initialization */
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.ColorLogicOpEnabled = GL_FALSE;
ctx->Color.LogicOp = GL_COPY;
else {
ctx->Color.DrawBuffer = GL_FRONT;
}
-
- ctx->Color.ClampFragmentColor = GL_FIXED_ONLY_ARB;
- ctx->Color._ClampFragmentColor = GL_TRUE;
- ctx->Color.ClampReadColor = GL_FIXED_ONLY_ARB;
- ctx->Color._ClampReadColor = GL_TRUE;
}
/*@}*/
GLboolean blue, GLboolean alpha );
-extern void GLAPIENTRY
-_mesa_ClampColorARB(GLenum target, GLenum clamp);
-
-
extern void
_mesa_init_color( struct gl_context * ctx );
#include "image.h"
#include "context.h"
#include "bufferobj.h"
-#include "fbobject.h"
#include "mfeatures.h"
#include "mtypes.h"
#include "texobj.h"
return retval;
}
-
-static GLenum
-renderbuffer_purgeable(struct gl_context *ctx, GLuint name, GLenum option)
-{
- struct gl_renderbuffer *bufObj;
- GLenum retval;
-
- bufObj = _mesa_lookup_renderbuffer(ctx, name);
- if (!bufObj) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glObjectUnpurgeable(name = 0x%x)", name);
- return 0;
- }
-
- if (bufObj->Purgeable) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glObjectPurgeable(name = 0x%x) is already purgeable", name);
- return GL_VOLATILE_APPLE;
- }
-
- bufObj->Purgeable = GL_TRUE;
-
- retval = GL_VOLATILE_APPLE;
- if (ctx->Driver.RenderObjectPurgeable)
- retval = ctx->Driver.RenderObjectPurgeable(ctx, bufObj, option);
-
- return retval;
-}
-
-
static GLenum
texture_object_purgeable(struct gl_context *ctx, GLuint name, GLenum option)
{
case GL_TEXTURE:
retval = texture_object_purgeable(ctx, name, option);
break;
- case GL_RENDERBUFFER_EXT:
- retval = renderbuffer_purgeable(ctx, name, option);
- break;
case GL_BUFFER_OBJECT_APPLE:
retval = buffer_object_purgeable(ctx, name, option);
break;
return retval;
}
-
-static GLenum
-renderbuffer_unpurgeable(struct gl_context *ctx, GLuint name, GLenum option)
-{
- struct gl_renderbuffer *bufObj;
- GLenum retval;
-
- bufObj = _mesa_lookup_renderbuffer(ctx, name);
- if (!bufObj) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glObjectUnpurgeable(name = 0x%x)", name);
- return 0;
- }
-
- if (! bufObj->Purgeable) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glObjectUnpurgeable(name = 0x%x) object is "
- " already \"unpurged\"", name);
- return 0;
- }
-
- bufObj->Purgeable = GL_FALSE;
-
- retval = option;
- if (ctx->Driver.RenderObjectUnpurgeable)
- retval = ctx->Driver.RenderObjectUnpurgeable(ctx, bufObj, option);
-
- return retval;
-}
-
-
static GLenum
texture_object_unpurgeable(struct gl_context *ctx, GLuint name, GLenum option)
{
return buffer_object_unpurgeable(ctx, name, option);
case GL_TEXTURE:
return texture_object_unpurgeable(ctx, name, option);
- case GL_RENDERBUFFER_EXT:
- return renderbuffer_unpurgeable(ctx, name, option);
default:
_mesa_error(ctx, GL_INVALID_ENUM,
"glObjectUnpurgeable(name = 0x%x) invalid type: %d",
}
}
-
-static void
-get_renderbuffer_parameteriv(struct gl_context *ctx, GLuint name,
- GLenum pname, GLint *params)
-{
- struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, name);
- if (!rb) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glObjectUnpurgeable(name = 0x%x)", name);
- return;
- }
-
- switch (pname) {
- case GL_PURGEABLE_APPLE:
- *params = rb->Purgeable;
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetObjectParameteriv(name = 0x%x) invalid enum: %d",
- name, pname);
- break;
- }
-}
-
-
static void
get_texture_object_parameteriv(struct gl_context *ctx, GLuint name,
GLenum pname, GLint *params)
case GL_BUFFER_OBJECT_APPLE:
get_buffer_object_parameteriv(ctx, name, pname, params);
break;
- case GL_RENDERBUFFER_EXT:
- get_renderbuffer_parameteriv(ctx, name, pname, params);
- break;
default:
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetObjectParameteriv(name = 0x%x) invalid type: %d",
{
GLbitfield mask = 0x0;
- if (fb->Name > 0) {
- /* A user-created renderbuffer */
- GLuint i;
- ASSERT(ctx->Extensions.EXT_framebuffer_object);
- for (i = 0; i < ctx->Const.MaxColorAttachments; i++) {
- mask |= (BUFFER_BIT_COLOR0 << i);
+ /* A window system framebuffer */
+ GLint i;
+ mask = BUFFER_BIT_FRONT_LEFT; /* always have this */
+ if (fb->Visual.stereoMode) {
+ mask |= BUFFER_BIT_FRONT_RIGHT;
+ if (fb->Visual.doubleBufferMode) {
+ mask |= BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT;
}
}
- else {
- /* A window system framebuffer */
- GLint i;
- mask = BUFFER_BIT_FRONT_LEFT; /* always have this */
- if (fb->Visual.stereoMode) {
- mask |= BUFFER_BIT_FRONT_RIGHT;
- if (fb->Visual.doubleBufferMode) {
- mask |= BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT;
- }
- }
- else if (fb->Visual.doubleBufferMode) {
- mask |= BUFFER_BIT_BACK_LEFT;
- }
+ else if (fb->Visual.doubleBufferMode) {
+ mask |= BUFFER_BIT_BACK_LEFT;
+ }
- for (i = 0; i < fb->Visual.numAuxBuffers; i++) {
- mask |= (BUFFER_BIT_AUX0 << i);
- }
+ for (i = 0; i < fb->Visual.numAuxBuffers; i++) {
+ mask |= (BUFFER_BIT_AUX0 << i);
}
return mask;
case GL_AUX2:
case GL_AUX3:
return 1 << BUFFER_COUNT; /* invalid, but not BAD_MASK */
- case GL_COLOR_ATTACHMENT0_EXT:
- return BUFFER_BIT_COLOR0;
- case GL_COLOR_ATTACHMENT1_EXT:
- return BUFFER_BIT_COLOR1;
- case GL_COLOR_ATTACHMENT2_EXT:
- return BUFFER_BIT_COLOR2;
- case GL_COLOR_ATTACHMENT3_EXT:
- return BUFFER_BIT_COLOR3;
- case GL_COLOR_ATTACHMENT4_EXT:
- return BUFFER_BIT_COLOR4;
- case GL_COLOR_ATTACHMENT5_EXT:
- return BUFFER_BIT_COLOR5;
- case GL_COLOR_ATTACHMENT6_EXT:
- return BUFFER_BIT_COLOR6;
- case GL_COLOR_ATTACHMENT7_EXT:
- return BUFFER_BIT_COLOR7;
default:
/* error */
return BAD_MASK;
case GL_AUX2:
case GL_AUX3:
return BUFFER_COUNT; /* invalid, but not -1 */
- case GL_COLOR_ATTACHMENT0_EXT:
- return BUFFER_COLOR0;
- case GL_COLOR_ATTACHMENT1_EXT:
- return BUFFER_COLOR1;
- case GL_COLOR_ATTACHMENT2_EXT:
- return BUFFER_COLOR2;
- case GL_COLOR_ATTACHMENT3_EXT:
- return BUFFER_COLOR3;
- case GL_COLOR_ATTACHMENT4_EXT:
- return BUFFER_COLOR4;
- case GL_COLOR_ATTACHMENT5_EXT:
- return BUFFER_COLOR5;
- case GL_COLOR_ATTACHMENT6_EXT:
- return BUFFER_COLOR6;
- case GL_COLOR_ATTACHMENT7_EXT:
- return BUFFER_COLOR7;
default:
/* error */
return -1;
static void
updated_drawbuffers(struct gl_context *ctx)
{
- struct gl_framebuffer *fb = ctx->DrawBuffer;
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- /* Flag the FBO as requiring validation. */
- if (fb->Name != 0) {
- fb->_Status = 0;
- }
}
/**
}
fb->ColorDrawBuffer = buffers;
- if (fb->Name == 0) {
- if (ctx->Color.DrawBuffer != fb->ColorDrawBuffer) {
- updated_drawbuffers(ctx);
- ctx->Color.DrawBuffer = fb->ColorDrawBuffer;
- }
+ if (ctx->Color.DrawBuffer != fb->ColorDrawBuffer) {
+ updated_drawbuffers(ctx);
+ ctx->Color.DrawBuffer = fb->ColorDrawBuffer;
}
}
void
_mesa_update_draw_buffer(struct gl_context *ctx)
{
- /* should be a window system FBO */
- assert(ctx->DrawBuffer->Name == 0);
-
_mesa_drawbuffer(ctx, ctx->Color.DrawBuffer, 0);
}
{
struct gl_framebuffer *fb = ctx->ReadBuffer;
- if (fb->Name == 0) {
- /* Only update the per-context READ_BUFFER state if we're bound to
- * a window-system framebuffer.
- */
- ctx->Pixel.ReadBuffer = buffer;
- }
+ ctx->Pixel.ReadBuffer = buffer;
fb->ColorReadBuffer = buffer;
fb->_ColorReadBufferIndex = bufferIndex;
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
- if (fb->Name > 0 && buffer == GL_NONE) {
- /* This is legal for user-created framebuffer objects */
- srcBuffer = -1;
+ /* general case / window-system framebuffer */
+ srcBuffer = read_buffer_enum_to_index(buffer);
+ if (srcBuffer == -1) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glReadBuffer(buffer=0x%x)", buffer);
+ return;
}
- else {
- /* general case / window-system framebuffer */
- srcBuffer = read_buffer_enum_to_index(buffer);
- if (srcBuffer == -1) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glReadBuffer(buffer=0x%x)", buffer);
- return;
- }
- supportedMask = supported_buffer_bitmask(ctx, fb);
- if (((1 << srcBuffer) & supportedMask) == 0) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glReadBuffer(buffer=0x%x)", buffer);
- return;
- }
+ supportedMask = supported_buffer_bitmask(ctx, fb);
+ if (((1 << srcBuffer) & supportedMask) == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glReadBuffer(buffer=0x%x)", buffer);
+ return;
}
/* OK, all error checking has been completed now */
_mesa_update_state( ctx ); /* update _Xmin, etc */
}
- if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glClear(incomplete framebuffer)");
- return;
- }
-
if (ctx->DrawBuffer->Width == 0 || ctx->DrawBuffer->Height == 0 ||
ctx->DrawBuffer->_Xmin >= ctx->DrawBuffer->_Xmax ||
ctx->DrawBuffer->_Ymin >= ctx->DrawBuffer->_Ymax)
/** For GL_EXT_texture_filter_anisotropic */
#define MAX_TEXTURE_MAX_ANISOTROPY 16.0
-/** For GL_EXT_texture_lod_bias (typically MAX_TEXTURE_LEVELS - 1) */
-#define MAX_TEXTURE_LOD_BIAS 14.0
-
/** For any program target/extension */
/*@{*/
#define MAX_PROGRAM_INSTRUCTIONS (16 * 1024)
#include "dlist.h"
#include "eval.h"
#include "extensions.h"
-#include "fbobject.h"
#include "feedback.h"
#include "fog.h"
#include "formats.h"
* \param greenBits same as above.
* \param blueBits same as above.
* \param alphaBits same as above.
- * \param numSamples not really used.
*
* \return pointer to new struct gl_config or NULL if requested parameters
* can't be met.
GLint accumRedBits,
GLint accumGreenBits,
GLint accumBlueBits,
- GLint accumAlphaBits,
- GLint numSamples )
+ GLint accumAlphaBits)
{
struct gl_config *vis = CALLOC_STRUCT(gl_config);
if (vis) {
redBits, greenBits, blueBits, alphaBits,
depthBits, stencilBits,
accumRedBits, accumGreenBits,
- accumBlueBits, accumAlphaBits,
- numSamples)) {
+ accumBlueBits, accumAlphaBits)) {
free(vis);
return NULL;
}
GLint accumRedBits,
GLint accumGreenBits,
GLint accumBlueBits,
- GLint accumAlphaBits,
- GLint numSamples )
+ GLint accumAlphaBits)
{
assert(vis);
vis->numAuxBuffers = 0;
vis->level = 0;
- vis->sampleBuffers = numSamples > 0 ? 1 : 0;
- vis->samples = numSamples;
return GL_TRUE;
}
ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits,
ctx->Const.MaxTextureImageUnits);
ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
- ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
ctx->Const.MinPointSize = MIN_POINT_SIZE;
/* CheckArrayBounds is overriden by drivers/x11 for X server */
ctx->Const.CheckArrayBounds = GL_FALSE;
-#if FEATURE_EXT_framebuffer_object
- ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
- ctx->Const.MaxRenderbufferSize = MAX_WIDTH;
-#endif
-
#if FEATURE_ARB_vertex_shader
ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
ctx->Const.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
ctx->Const.GLSLVersion = 120;
_mesa_override_glsl_version(ctx);
- /* GL_ARB_framebuffer_object */
- ctx->Const.MaxSamples = 0;
-
/* GL_ATI_envmap_bumpmap */
ctx->Const.SupportedBumpUnits = SUPPORTED_ATI_BUMP_UNITS;
assert(ctx->Const.MaxViewportWidth <= MAX_WIDTH);
assert(ctx->Const.MaxViewportHeight <= MAX_WIDTH);
-
- /* if this fails, add more enum values to gl_buffer_index */
- assert(BUFFER_COLOR0 + 1 <= BUFFER_COUNT);
-
- /* XXX probably add more tests */
}
_mesa_init_debug( ctx );
_mesa_init_display_list( ctx );
_mesa_init_eval( ctx );
- _mesa_init_fbobjects( ctx );
_mesa_init_feedback( ctx );
_mesa_init_fog( ctx );
_mesa_init_hint( ctx );
const struct gl_config *ctxvis = &ctx->Visual;
const struct gl_config *bufvis = &buffer->Visual;
- if (buffer == _mesa_get_incomplete_framebuffer())
- return GL_TRUE;
-
#if 0
/* disabling this fixes the fgl_glxgears pbuffer demo */
if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)
* Only set the context's Draw/ReadBuffer fields if they're NULL
* or not bound to a user-created FBO.
*/
- if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {
- _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);
- /* Update the FBO's list of drawbuffers/renderbuffers.
- * For winsys FBOs this comes from the GL state (which may have
- * changed since the last time this FBO was bound).
- */
- _mesa_update_draw_buffer(newCtx);
- }
- if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) {
- _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
- }
+ _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);
+ /* Update the FBO's list of drawbuffers/renderbuffers.
+ * For winsys FBOs this comes from the GL state (which may have
+ * changed since the last time this FBO was bound).
+ */
+ _mesa_update_draw_buffer(newCtx);
+
+ _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
/* XXX only set this flag if we're really changing the draw/read
* framebuffer bindings.
}
}
- if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "%s(incomplete framebuffer)", where);
- return GL_FALSE;
- }
-
#ifdef DEBUG
if (ctx->Shader.Flags & GLSL_LOG) {
struct gl_shader_program *shProg[MESA_SHADER_TYPES];
GLint accumRedBits,
GLint accumGreenBits,
GLint accumBlueBits,
- GLint accumAlphaBits,
- GLint numSamples );
+ GLint accumAlphaBits);
extern GLboolean
_mesa_initialize_visual( struct gl_config *v,
GLint accumRedBits,
GLint accumGreenBits,
GLint accumBlueBits,
- GLint accumAlphaBits,
- GLint numSamples );
+ GLint accumAlphaBits);
extern void
_mesa_destroy_visual( struct gl_config *vis );
GLint x, GLint y,
GLsizei width, GLsizei height);
- /**
- * Called by glGenerateMipmap() or when GL_GENERATE_MIPMAP_SGIS is enabled.
- */
- void (*GenerateMipmap)(struct gl_context *ctx, GLenum target,
- struct gl_texture_object *texObj);
-
/**
* Called by glTexImage[123]D when user specifies a proxy texture
* target.
GLenum (*TextureObjectUnpurgeable)( struct gl_context *ctx, struct gl_texture_object *obj, GLenum option );
/*@}*/
- /**
- * \name Functions for GL_EXT_framebuffer_{object,blit}.
- */
- /*@{*/
- struct gl_framebuffer * (*NewFramebuffer)(struct gl_context *ctx, GLuint name);
- struct gl_renderbuffer * (*NewRenderbuffer)(struct gl_context *ctx, GLuint name);
- void (*BindFramebuffer)(struct gl_context *ctx, GLenum target,
- struct gl_framebuffer *drawFb,
- struct gl_framebuffer *readFb);
- void (*FramebufferRenderbuffer)(struct gl_context *ctx,
- struct gl_framebuffer *fb,
- GLenum attachment,
- struct gl_renderbuffer *rb);
- void (*RenderTexture)(struct gl_context *ctx,
- struct gl_framebuffer *fb,
- struct gl_renderbuffer_attachment *att);
- void (*FinishRenderTexture)(struct gl_context *ctx,
- struct gl_renderbuffer_attachment *att);
- void (*ValidateFramebuffer)(struct gl_context *ctx,
- struct gl_framebuffer *fb);
- /*@}*/
- void (*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);
-
- /**
- * \name Query objects
- */
- /*@{*/
- struct gl_query_object * (*NewQueryObject)(struct gl_context *ctx, GLuint id);
- void (*DeleteQuery)(struct gl_context *ctx, struct gl_query_object *q);
- void (*BeginQuery)(struct gl_context *ctx, struct gl_query_object *q);
- void (*EndQuery)(struct gl_context *ctx, struct gl_query_object *q);
- void (*CheckQuery)(struct gl_context *ctx, struct gl_query_object *q);
- void (*WaitQuery)(struct gl_context *ctx, struct gl_query_object *q);
- /*@}*/
-
/**
* \name Vertex Array objects
format, type, &ctx->DefaultPacking, buffer);
/* make filename */
- _mesa_snprintf(s, sizeof(s), "/tmp/renderbuffer%u.ppm", rb->Name);
- _mesa_snprintf(s, sizeof(s), "C:\\renderbuffer%u.ppm", rb->Name);
+ _mesa_snprintf(s, sizeof(s), "/tmp/renderbuffer.ppm");
+ _mesa_snprintf(s, sizeof(s), "C:\\renderbuffer.ppm");
printf(" Writing renderbuffer image to %s\n", s);
static void
dump_renderbuffer(const struct gl_renderbuffer *rb, GLboolean writeImage)
{
- printf("Renderbuffer %u: %u x %u IntFormat = %s\n",
- rb->Name, rb->Width, rb->Height,
+ printf("Renderbuffer: %u x %u IntFormat = %s\n",
+ rb->Width, rb->Height,
_mesa_lookup_enum_by_nr(rb->InternalFormat));
if (writeImage) {
_mesa_write_renderbuffer_image(rb);
#define _gloffset_UniformMatrix3x4fv 427
#define _gloffset_UniformMatrix4x2fv 428
#define _gloffset_UniformMatrix4x3fv 429
-#define _gloffset_ClampColor 430
#define _gloffset_GetStringi 435
#define _gloffset_GetBufferParameteri64v 438
#define _gloffset_GetInteger64i_v 439
#define _gloffset_BindAttribLocationARB 568
#define _gloffset_GetActiveAttribARB 569
#define _gloffset_GetAttribLocationARB 570
-#define _gloffset_ClampColorARB 572
-#define _gloffset_RenderbufferStorageMultisample 575
#define _gloffset_FlushMappedBufferRange 580
#define _gloffset_MapBufferRange 581
#define _gloffset_BindVertexArray 583
#define _gloffset_GetCombinerOutputParameterivNV 748
#define _gloffset_GetFinalCombinerInputParameterfvNV 749
#define _gloffset_GetFinalCombinerInputParameterivNV 750
-#define _gloffset_ResizeBuffersMESA 751
#define _gloffset_WindowPos2dMESA 752
#define _gloffset_WindowPos2dvMESA 753
#define _gloffset_WindowPos2fMESA 754
#define _gloffset_ProgramNamedParameter4fvNV 875
#define _gloffset_DepthBoundsEXT 878
#define _gloffset_BlendEquationSeparateEXT 879
-#define _gloffset_BindFramebufferEXT 880
-#define _gloffset_BindRenderbufferEXT 881
-#define _gloffset_CheckFramebufferStatusEXT 882
-#define _gloffset_DeleteFramebuffersEXT 883
-#define _gloffset_DeleteRenderbuffersEXT 884
-#define _gloffset_FramebufferRenderbufferEXT 885
-#define _gloffset_FramebufferTexture1DEXT 886
-#define _gloffset_FramebufferTexture2DEXT 887
-#define _gloffset_FramebufferTexture3DEXT 888
-#define _gloffset_GenFramebuffersEXT 889
-#define _gloffset_GenRenderbuffersEXT 890
-#define _gloffset_GenerateMipmapEXT 891
-#define _gloffset_GetFramebufferAttachmentParameterivEXT 892
-#define _gloffset_GetRenderbufferParameterivEXT 893
-#define _gloffset_IsFramebufferEXT 894
-#define _gloffset_IsRenderbufferEXT 895
-#define _gloffset_RenderbufferStorageEXT 896
-#define _gloffset_BlitFramebufferEXT 897
#define _gloffset_BufferParameteriAPPLE 898
#define _gloffset_FlushMappedBufferRangeAPPLE 899
#define _gloffset_BindFragDataLocationEXT 900
#define UniformMatrix3x4fv_remap_index 19
#define UniformMatrix4x2fv_remap_index 20
#define UniformMatrix4x3fv_remap_index 21
-#define ClampColor_remap_index 22
#define GetStringi_remap_index 27
#define TexBuffer_remap_index 28
#define GetBufferParameteri64v_remap_index 30
#define BindAttribLocationARB_remap_index 160
#define GetActiveAttribARB_remap_index 161
#define GetAttribLocationARB_remap_index 162
-#define ClampColorARB_remap_index 164
-#define RenderbufferStorageMultisample_remap_index 167
#define VertexAttribDivisorARB_remap_index 171
#define FlushMappedBufferRange_remap_index 172
#define MapBufferRange_remap_index 173
#define GetCombinerOutputParameterivNV_remap_index 340
#define GetFinalCombinerInputParameterfvNV_remap_index 341
#define GetFinalCombinerInputParameterivNV_remap_index 342
-#define ResizeBuffersMESA_remap_index 343
#define WindowPos2dMESA_remap_index 344
#define WindowPos2dvMESA_remap_index 345
#define WindowPos2fMESA_remap_index 346
#define ProgramNamedParameter4fvNV_remap_index 467
#define DepthBoundsEXT_remap_index 470
#define BlendEquationSeparateEXT_remap_index 471
-#define BindFramebufferEXT_remap_index 472
-#define BindRenderbufferEXT_remap_index 473
-#define CheckFramebufferStatusEXT_remap_index 474
-#define DeleteFramebuffersEXT_remap_index 475
-#define DeleteRenderbuffersEXT_remap_index 476
-#define FramebufferRenderbufferEXT_remap_index 477
-#define FramebufferTexture1DEXT_remap_index 478
-#define FramebufferTexture2DEXT_remap_index 479
-#define FramebufferTexture3DEXT_remap_index 480
-#define GenFramebuffersEXT_remap_index 481
-#define GenRenderbuffersEXT_remap_index 482
-#define GenerateMipmapEXT_remap_index 483
-#define GetFramebufferAttachmentParameterivEXT_remap_index 484
-#define GetRenderbufferParameterivEXT_remap_index 485
-#define IsFramebufferEXT_remap_index 486
-#define IsRenderbufferEXT_remap_index 487
-#define RenderbufferStorageEXT_remap_index 488
-#define BlitFramebufferEXT_remap_index 489
#define BufferParameteriAPPLE_remap_index 490
#define FlushMappedBufferRangeAPPLE_remap_index 491
#define BindFragDataLocationEXT_remap_index 492
#define _gloffset_UniformMatrix3x4fv driDispatchRemapTable[UniformMatrix3x4fv_remap_index]
#define _gloffset_UniformMatrix4x2fv driDispatchRemapTable[UniformMatrix4x2fv_remap_index]
#define _gloffset_UniformMatrix4x3fv driDispatchRemapTable[UniformMatrix4x3fv_remap_index]
-#define _gloffset_ClampColor driDispatchRemapTable[ClampColor_remap_index]
#define _gloffset_GetStringi driDispatchRemapTable[GetStringi_remap_index]
-#define _gloffset_FramebufferTexture driDispatchRemapTable[FramebufferTexture_remap_index]
#define _gloffset_GetBufferParameteri64v driDispatchRemapTable[GetBufferParameteri64v_remap_index]
#define _gloffset_GetInteger64i_v driDispatchRemapTable[GetInteger64i_v_remap_index]
#define _gloffset_LoadTransposeMatrixdARB driDispatchRemapTable[LoadTransposeMatrixdARB_remap_index]
#define _gloffset_BindAttribLocationARB driDispatchRemapTable[BindAttribLocationARB_remap_index]
#define _gloffset_GetActiveAttribARB driDispatchRemapTable[GetActiveAttribARB_remap_index]
#define _gloffset_GetAttribLocationARB driDispatchRemapTable[GetAttribLocationARB_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_GetCombinerOutputParameterivNV driDispatchRemapTable[GetCombinerOutputParameterivNV_remap_index]
#define _gloffset_GetFinalCombinerInputParameterfvNV driDispatchRemapTable[GetFinalCombinerInputParameterfvNV_remap_index]
#define _gloffset_GetFinalCombinerInputParameterivNV driDispatchRemapTable[GetFinalCombinerInputParameterivNV_remap_index]
-#define _gloffset_ResizeBuffersMESA driDispatchRemapTable[ResizeBuffersMESA_remap_index]
#define _gloffset_WindowPos2dMESA driDispatchRemapTable[WindowPos2dMESA_remap_index]
#define _gloffset_WindowPos2dvMESA driDispatchRemapTable[WindowPos2dvMESA_remap_index]
#define _gloffset_WindowPos2fMESA driDispatchRemapTable[WindowPos2fMESA_remap_index]
#define _gloffset_ProgramNamedParameter4fvNV driDispatchRemapTable[ProgramNamedParameter4fvNV_remap_index]
#define _gloffset_DepthBoundsEXT driDispatchRemapTable[DepthBoundsEXT_remap_index]
#define _gloffset_BlendEquationSeparateEXT driDispatchRemapTable[BlendEquationSeparateEXT_remap_index]
-#define _gloffset_BindFramebufferEXT driDispatchRemapTable[BindFramebufferEXT_remap_index]
-#define _gloffset_BindRenderbufferEXT driDispatchRemapTable[BindRenderbufferEXT_remap_index]
-#define _gloffset_CheckFramebufferStatusEXT driDispatchRemapTable[CheckFramebufferStatusEXT_remap_index]
-#define _gloffset_DeleteFramebuffersEXT driDispatchRemapTable[DeleteFramebuffersEXT_remap_index]
-#define _gloffset_DeleteRenderbuffersEXT driDispatchRemapTable[DeleteRenderbuffersEXT_remap_index]
-#define _gloffset_FramebufferRenderbufferEXT driDispatchRemapTable[FramebufferRenderbufferEXT_remap_index]
-#define _gloffset_FramebufferTexture1DEXT driDispatchRemapTable[FramebufferTexture1DEXT_remap_index]
-#define _gloffset_FramebufferTexture2DEXT driDispatchRemapTable[FramebufferTexture2DEXT_remap_index]
-#define _gloffset_FramebufferTexture3DEXT driDispatchRemapTable[FramebufferTexture3DEXT_remap_index]
-#define _gloffset_GenFramebuffersEXT driDispatchRemapTable[GenFramebuffersEXT_remap_index]
-#define _gloffset_GenRenderbuffersEXT driDispatchRemapTable[GenRenderbuffersEXT_remap_index]
-#define _gloffset_GenerateMipmapEXT driDispatchRemapTable[GenerateMipmapEXT_remap_index]
-#define _gloffset_GetFramebufferAttachmentParameterivEXT driDispatchRemapTable[GetFramebufferAttachmentParameterivEXT_remap_index]
-#define _gloffset_GetRenderbufferParameterivEXT driDispatchRemapTable[GetRenderbufferParameterivEXT_remap_index]
-#define _gloffset_IsFramebufferEXT driDispatchRemapTable[IsFramebufferEXT_remap_index]
-#define _gloffset_IsRenderbufferEXT driDispatchRemapTable[IsRenderbufferEXT_remap_index]
-#define _gloffset_RenderbufferStorageEXT driDispatchRemapTable[RenderbufferStorageEXT_remap_index]
-#define _gloffset_BlitFramebufferEXT driDispatchRemapTable[BlitFramebufferEXT_remap_index]
#define _gloffset_BufferParameteriAPPLE driDispatchRemapTable[BufferParameteriAPPLE_remap_index]
#define _gloffset_FlushMappedBufferRangeAPPLE driDispatchRemapTable[FlushMappedBufferRangeAPPLE_remap_index]
#define _gloffset_BindFragDataLocationEXT driDispatchRemapTable[BindFragDataLocationEXT_remap_index]
SET_by_offset(disp, _gloffset_UniformMatrix4x3fv, fn);
}
-typedef void (GLAPIENTRYP _glptr_ClampColor)(GLenum, GLenum);
-#define CALL_ClampColor(disp, parameters) \
- (* GET_ClampColor(disp)) parameters
-static inline _glptr_ClampColor GET_ClampColor(struct _glapi_table *disp) {
- return (_glptr_ClampColor) (GET_by_offset(disp, _gloffset_ClampColor));
-}
-
-static inline void SET_ClampColor(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLenum, GLenum)) {
- SET_by_offset(disp, _gloffset_ClampColor, fn);
-}
-
typedef const GLubyte * (GLAPIENTRYP _glptr_GetStringi)(GLenum, GLuint);
#define CALL_GetStringi(disp, parameters) \
(* GET_GetStringi(disp)) parameters
SET_by_offset(disp, _gloffset_GetAttribLocationARB, fn);
}
-typedef void (GLAPIENTRYP _glptr_ClampColorARB)(GLenum, GLenum);
-#define CALL_ClampColorARB(disp, parameters) \
- (* GET_ClampColorARB(disp)) parameters
-static inline _glptr_ClampColorARB GET_ClampColorARB(struct _glapi_table *disp) {
- return (_glptr_ClampColorARB) (GET_by_offset(disp, _gloffset_ClampColorARB));
-}
-
-static inline void SET_ClampColorARB(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLenum, GLenum)) {
- SET_by_offset(disp, _gloffset_ClampColorARB, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_RenderbufferStorageMultisample)(GLenum, GLsizei, GLenum, GLsizei, GLsizei);
-#define CALL_RenderbufferStorageMultisample(disp, parameters) \
- (* GET_RenderbufferStorageMultisample(disp)) parameters
-static inline _glptr_RenderbufferStorageMultisample GET_RenderbufferStorageMultisample(struct _glapi_table *disp) {
- return (_glptr_RenderbufferStorageMultisample) (GET_by_offset(disp, _gloffset_RenderbufferStorageMultisample));
-}
-
-static inline void SET_RenderbufferStorageMultisample(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)) {
- SET_by_offset(disp, _gloffset_RenderbufferStorageMultisample, fn);
-}
-
typedef void (GLAPIENTRYP _glptr_FlushMappedBufferRange)(GLenum, GLintptr, GLsizeiptr);
#define CALL_FlushMappedBufferRange(disp, parameters) \
(* GET_FlushMappedBufferRange(disp)) parameters
SET_by_offset(disp, _gloffset_GetFinalCombinerInputParameterivNV, fn);
}
-typedef void (GLAPIENTRYP _glptr_ResizeBuffersMESA)(void);
-#define CALL_ResizeBuffersMESA(disp, parameters) \
- (* GET_ResizeBuffersMESA(disp)) parameters
-static inline _glptr_ResizeBuffersMESA GET_ResizeBuffersMESA(struct _glapi_table *disp) {
- return (_glptr_ResizeBuffersMESA) (GET_by_offset(disp, _gloffset_ResizeBuffersMESA));
-}
-
-static inline void SET_ResizeBuffersMESA(struct _glapi_table *disp, void (GLAPIENTRYP fn)(void)) {
- SET_by_offset(disp, _gloffset_ResizeBuffersMESA, fn);
-}
-
typedef void (GLAPIENTRYP _glptr_WindowPos2dMESA)(GLdouble, GLdouble);
#define CALL_WindowPos2dMESA(disp, parameters) \
(* GET_WindowPos2dMESA(disp)) parameters
SET_by_offset(disp, _gloffset_BlendEquationSeparateEXT, fn);
}
-typedef void (GLAPIENTRYP _glptr_BindFramebufferEXT)(GLenum, GLuint);
-#define CALL_BindFramebufferEXT(disp, parameters) \
- (* GET_BindFramebufferEXT(disp)) parameters
-static inline _glptr_BindFramebufferEXT GET_BindFramebufferEXT(struct _glapi_table *disp) {
- return (_glptr_BindFramebufferEXT) (GET_by_offset(disp, _gloffset_BindFramebufferEXT));
-}
-
-static inline void SET_BindFramebufferEXT(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLenum, GLuint)) {
- SET_by_offset(disp, _gloffset_BindFramebufferEXT, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_BindRenderbufferEXT)(GLenum, GLuint);
-#define CALL_BindRenderbufferEXT(disp, parameters) \
- (* GET_BindRenderbufferEXT(disp)) parameters
-static inline _glptr_BindRenderbufferEXT GET_BindRenderbufferEXT(struct _glapi_table *disp) {
- return (_glptr_BindRenderbufferEXT) (GET_by_offset(disp, _gloffset_BindRenderbufferEXT));
-}
-
-static inline void SET_BindRenderbufferEXT(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLenum, GLuint)) {
- SET_by_offset(disp, _gloffset_BindRenderbufferEXT, fn);
-}
-
-typedef GLenum (GLAPIENTRYP _glptr_CheckFramebufferStatusEXT)(GLenum);
-#define CALL_CheckFramebufferStatusEXT(disp, parameters) \
- (* GET_CheckFramebufferStatusEXT(disp)) parameters
-static inline _glptr_CheckFramebufferStatusEXT GET_CheckFramebufferStatusEXT(struct _glapi_table *disp) {
- return (_glptr_CheckFramebufferStatusEXT) (GET_by_offset(disp, _gloffset_CheckFramebufferStatusEXT));
-}
-
-static inline void SET_CheckFramebufferStatusEXT(struct _glapi_table *disp, GLenum (GLAPIENTRYP fn)(GLenum)) {
- SET_by_offset(disp, _gloffset_CheckFramebufferStatusEXT, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_DeleteFramebuffersEXT)(GLsizei, const GLuint *);
-#define CALL_DeleteFramebuffersEXT(disp, parameters) \
- (* GET_DeleteFramebuffersEXT(disp)) parameters
-static inline _glptr_DeleteFramebuffersEXT GET_DeleteFramebuffersEXT(struct _glapi_table *disp) {
- return (_glptr_DeleteFramebuffersEXT) (GET_by_offset(disp, _gloffset_DeleteFramebuffersEXT));
-}
-
-static inline void SET_DeleteFramebuffersEXT(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLsizei, const GLuint *)) {
- SET_by_offset(disp, _gloffset_DeleteFramebuffersEXT, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_DeleteRenderbuffersEXT)(GLsizei, const GLuint *);
-#define CALL_DeleteRenderbuffersEXT(disp, parameters) \
- (* GET_DeleteRenderbuffersEXT(disp)) parameters
-static inline _glptr_DeleteRenderbuffersEXT GET_DeleteRenderbuffersEXT(struct _glapi_table *disp) {
- return (_glptr_DeleteRenderbuffersEXT) (GET_by_offset(disp, _gloffset_DeleteRenderbuffersEXT));
-}
-
-static inline void SET_DeleteRenderbuffersEXT(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLsizei, const GLuint *)) {
- SET_by_offset(disp, _gloffset_DeleteRenderbuffersEXT, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_FramebufferRenderbufferEXT)(GLenum, GLenum, GLenum, GLuint);
-#define CALL_FramebufferRenderbufferEXT(disp, parameters) \
- (* GET_FramebufferRenderbufferEXT(disp)) parameters
-static inline _glptr_FramebufferRenderbufferEXT GET_FramebufferRenderbufferEXT(struct _glapi_table *disp) {
- return (_glptr_FramebufferRenderbufferEXT) (GET_by_offset(disp, _gloffset_FramebufferRenderbufferEXT));
-}
-
-static inline void SET_FramebufferRenderbufferEXT(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLenum, GLenum, GLenum, GLuint)) {
- SET_by_offset(disp, _gloffset_FramebufferRenderbufferEXT, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_FramebufferTexture1DEXT)(GLenum, GLenum, GLenum, GLuint, GLint);
-#define CALL_FramebufferTexture1DEXT(disp, parameters) \
- (* GET_FramebufferTexture1DEXT(disp)) parameters
-static inline _glptr_FramebufferTexture1DEXT GET_FramebufferTexture1DEXT(struct _glapi_table *disp) {
- return (_glptr_FramebufferTexture1DEXT) (GET_by_offset(disp, _gloffset_FramebufferTexture1DEXT));
-}
-
-static inline void SET_FramebufferTexture1DEXT(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLenum, GLenum, GLenum, GLuint, GLint)) {
- SET_by_offset(disp, _gloffset_FramebufferTexture1DEXT, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_FramebufferTexture2DEXT)(GLenum, GLenum, GLenum, GLuint, GLint);
-#define CALL_FramebufferTexture2DEXT(disp, parameters) \
- (* GET_FramebufferTexture2DEXT(disp)) parameters
-static inline _glptr_FramebufferTexture2DEXT GET_FramebufferTexture2DEXT(struct _glapi_table *disp) {
- return (_glptr_FramebufferTexture2DEXT) (GET_by_offset(disp, _gloffset_FramebufferTexture2DEXT));
-}
-
-static inline void SET_FramebufferTexture2DEXT(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLenum, GLenum, GLenum, GLuint, GLint)) {
- SET_by_offset(disp, _gloffset_FramebufferTexture2DEXT, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_FramebufferTexture3DEXT)(GLenum, GLenum, GLenum, GLuint, GLint, GLint);
-#define CALL_FramebufferTexture3DEXT(disp, parameters) \
- (* GET_FramebufferTexture3DEXT(disp)) parameters
-static inline _glptr_FramebufferTexture3DEXT GET_FramebufferTexture3DEXT(struct _glapi_table *disp) {
- return (_glptr_FramebufferTexture3DEXT) (GET_by_offset(disp, _gloffset_FramebufferTexture3DEXT));
-}
-
-static inline void SET_FramebufferTexture3DEXT(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLenum, GLenum, GLenum, GLuint, GLint, GLint)) {
- SET_by_offset(disp, _gloffset_FramebufferTexture3DEXT, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_GenFramebuffersEXT)(GLsizei, GLuint *);
-#define CALL_GenFramebuffersEXT(disp, parameters) \
- (* GET_GenFramebuffersEXT(disp)) parameters
-static inline _glptr_GenFramebuffersEXT GET_GenFramebuffersEXT(struct _glapi_table *disp) {
- return (_glptr_GenFramebuffersEXT) (GET_by_offset(disp, _gloffset_GenFramebuffersEXT));
-}
-
-static inline void SET_GenFramebuffersEXT(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLsizei, GLuint *)) {
- SET_by_offset(disp, _gloffset_GenFramebuffersEXT, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_GenRenderbuffersEXT)(GLsizei, GLuint *);
-#define CALL_GenRenderbuffersEXT(disp, parameters) \
- (* GET_GenRenderbuffersEXT(disp)) parameters
-static inline _glptr_GenRenderbuffersEXT GET_GenRenderbuffersEXT(struct _glapi_table *disp) {
- return (_glptr_GenRenderbuffersEXT) (GET_by_offset(disp, _gloffset_GenRenderbuffersEXT));
-}
-
-static inline void SET_GenRenderbuffersEXT(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLsizei, GLuint *)) {
- SET_by_offset(disp, _gloffset_GenRenderbuffersEXT, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_GenerateMipmapEXT)(GLenum);
-#define CALL_GenerateMipmapEXT(disp, parameters) \
- (* GET_GenerateMipmapEXT(disp)) parameters
-static inline _glptr_GenerateMipmapEXT GET_GenerateMipmapEXT(struct _glapi_table *disp) {
- return (_glptr_GenerateMipmapEXT) (GET_by_offset(disp, _gloffset_GenerateMipmapEXT));
-}
-
-static inline void SET_GenerateMipmapEXT(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLenum)) {
- SET_by_offset(disp, _gloffset_GenerateMipmapEXT, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_GetFramebufferAttachmentParameterivEXT)(GLenum, GLenum, GLenum, GLint *);
-#define CALL_GetFramebufferAttachmentParameterivEXT(disp, parameters) \
- (* GET_GetFramebufferAttachmentParameterivEXT(disp)) parameters
-static inline _glptr_GetFramebufferAttachmentParameterivEXT GET_GetFramebufferAttachmentParameterivEXT(struct _glapi_table *disp) {
- return (_glptr_GetFramebufferAttachmentParameterivEXT) (GET_by_offset(disp, _gloffset_GetFramebufferAttachmentParameterivEXT));
-}
-
-static inline void SET_GetFramebufferAttachmentParameterivEXT(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLenum, GLenum, GLenum, GLint *)) {
- SET_by_offset(disp, _gloffset_GetFramebufferAttachmentParameterivEXT, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_GetRenderbufferParameterivEXT)(GLenum, GLenum, GLint *);
-#define CALL_GetRenderbufferParameterivEXT(disp, parameters) \
- (* GET_GetRenderbufferParameterivEXT(disp)) parameters
-static inline _glptr_GetRenderbufferParameterivEXT GET_GetRenderbufferParameterivEXT(struct _glapi_table *disp) {
- return (_glptr_GetRenderbufferParameterivEXT) (GET_by_offset(disp, _gloffset_GetRenderbufferParameterivEXT));
-}
-
-static inline void SET_GetRenderbufferParameterivEXT(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLenum, GLenum, GLint *)) {
- SET_by_offset(disp, _gloffset_GetRenderbufferParameterivEXT, fn);
-}
-
-typedef GLboolean (GLAPIENTRYP _glptr_IsFramebufferEXT)(GLuint);
-#define CALL_IsFramebufferEXT(disp, parameters) \
- (* GET_IsFramebufferEXT(disp)) parameters
-static inline _glptr_IsFramebufferEXT GET_IsFramebufferEXT(struct _glapi_table *disp) {
- return (_glptr_IsFramebufferEXT) (GET_by_offset(disp, _gloffset_IsFramebufferEXT));
-}
-
-static inline void SET_IsFramebufferEXT(struct _glapi_table *disp, GLboolean (GLAPIENTRYP fn)(GLuint)) {
- SET_by_offset(disp, _gloffset_IsFramebufferEXT, fn);
-}
-
-typedef GLboolean (GLAPIENTRYP _glptr_IsRenderbufferEXT)(GLuint);
-#define CALL_IsRenderbufferEXT(disp, parameters) \
- (* GET_IsRenderbufferEXT(disp)) parameters
-static inline _glptr_IsRenderbufferEXT GET_IsRenderbufferEXT(struct _glapi_table *disp) {
- return (_glptr_IsRenderbufferEXT) (GET_by_offset(disp, _gloffset_IsRenderbufferEXT));
-}
-
-static inline void SET_IsRenderbufferEXT(struct _glapi_table *disp, GLboolean (GLAPIENTRYP fn)(GLuint)) {
- SET_by_offset(disp, _gloffset_IsRenderbufferEXT, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_RenderbufferStorageEXT)(GLenum, GLenum, GLsizei, GLsizei);
-#define CALL_RenderbufferStorageEXT(disp, parameters) \
- (* GET_RenderbufferStorageEXT(disp)) parameters
-static inline _glptr_RenderbufferStorageEXT GET_RenderbufferStorageEXT(struct _glapi_table *disp) {
- return (_glptr_RenderbufferStorageEXT) (GET_by_offset(disp, _gloffset_RenderbufferStorageEXT));
-}
-
-static inline void SET_RenderbufferStorageEXT(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLenum, GLenum, GLsizei, GLsizei)) {
- SET_by_offset(disp, _gloffset_RenderbufferStorageEXT, fn);
-}
-
-typedef void (GLAPIENTRYP _glptr_BlitFramebufferEXT)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum);
-#define CALL_BlitFramebufferEXT(disp, parameters) \
- (* GET_BlitFramebufferEXT(disp)) parameters
-static inline _glptr_BlitFramebufferEXT GET_BlitFramebufferEXT(struct _glapi_table *disp) {
- return (_glptr_BlitFramebufferEXT) (GET_by_offset(disp, _gloffset_BlitFramebufferEXT));
-}
-
-static inline void SET_BlitFramebufferEXT(struct _glapi_table *disp, void (GLAPIENTRYP fn)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) {
- SET_by_offset(disp, _gloffset_BlitFramebufferEXT, fn);
-}
-
typedef void (GLAPIENTRYP _glptr_BufferParameteriAPPLE)(GLenum, GLenum, GLint);
#define CALL_BufferParameteriAPPLE(disp, parameters) \
(* GET_BufferParameteriAPPLE(disp)) parameters
#include "dlist.h"
#include "enums.h"
#include "eval.h"
-#if FEATURE_EXT_framebuffer_object
-#include "fbobject.h"
-#endif
#include "framebuffer.h"
#include "glapi/glapi.h"
#include "hash.h"
OPCODE_UNIFORM_3UIV,
OPCODE_UNIFORM_4UIV,
- /* GL_ARB_color_buffer_float */
- OPCODE_CLAMP_COLOR,
-
- /* GL_EXT_framebuffer_blit */
- OPCODE_BLIT_FRAMEBUFFER,
-
/* Vertex attributes -- fallback for when optimized display
* list build isn't active.
*/
/* XXX more shader functions needed here */
-#if FEATURE_EXT_framebuffer_blit
-static void GLAPIENTRY
-save_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_BLIT_FRAMEBUFFER, 10);
- if (n) {
- n[1].i = srcX0;
- n[2].i = srcY0;
- n[3].i = srcX1;
- n[4].i = srcY1;
- n[5].i = dstX0;
- n[6].i = dstY0;
- n[7].i = dstX1;
- n[8].i = dstY1;
- n[9].i = mask;
- n[10].e = filter;
- }
- if (ctx->ExecuteFlag) {
- CALL_BlitFramebufferEXT(ctx->Exec, (srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1,
- mask, filter));
- }
-}
-#endif
-
-
/* aka UseProgram() */
static void GLAPIENTRY
save_UseProgramObjectARB(GLhandleARB program)
}
}
-static void GLAPIENTRY
-save_ClampColorARB(GLenum target, GLenum clamp)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_CLAMP_COLOR, 2);
- if (n) {
- n[1].e = target;
- n[2].e = clamp;
- }
- if (ctx->ExecuteFlag) {
- CALL_ClampColorARB(ctx->Exec, (target, clamp));
- }
-}
-
static void GLAPIENTRY
save_UseShaderProgramEXT(GLenum type, GLuint program)
{
n[6].f));
break;
#endif
-#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,
- n[5].i, n[6].i, n[7].i, n[8].i,
- n[9].i, n[10].e));
- break;
-#endif
case OPCODE_USE_PROGRAM:
CALL_UseProgramObjectARB(ctx->Exec, (n[1].ui));
(n[1].i, n[2].i, n[3].b, n[4].data));
break;
- case OPCODE_CLAMP_COLOR:
- CALL_ClampColorARB(ctx->Exec, (n[1].e, n[2].e));
- break;
-
case OPCODE_TEX_BUMP_PARAMETER_ATI:
{
GLfloat values[4];
/* 173. GL_EXT_blend_func_separate */
SET_BlendFuncSeparateEXT(table, save_BlendFuncSeparateEXT);
- /* 196. GL_MESA_resize_buffers */
- SET_ResizeBuffersMESA(table, _mesa_ResizeBuffersMESA);
-
/* 197. GL_MESA_window_pos */
SET_WindowPos2dMESA(table, save_WindowPos2dMESA);
SET_WindowPos2dvMESA(table, save_WindowPos2dvMESA);
SET_GenVertexArraysAPPLE(table, _mesa_GenVertexArraysAPPLE);
SET_IsVertexArrayAPPLE(table, _mesa_IsVertexArrayAPPLE);
- /* 310. GL_EXT_framebuffer_object */
- SET_GenFramebuffersEXT(table, _mesa_GenFramebuffersEXT);
- SET_BindFramebufferEXT(table, _mesa_BindFramebufferEXT);
- SET_DeleteFramebuffersEXT(table, _mesa_DeleteFramebuffersEXT);
- SET_CheckFramebufferStatusEXT(table, _mesa_CheckFramebufferStatusEXT);
- SET_GenRenderbuffersEXT(table, _mesa_GenRenderbuffersEXT);
- SET_BindRenderbufferEXT(table, _mesa_BindRenderbufferEXT);
- SET_DeleteRenderbuffersEXT(table, _mesa_DeleteRenderbuffersEXT);
- SET_RenderbufferStorageEXT(table, _mesa_RenderbufferStorageEXT);
- SET_FramebufferTexture1DEXT(table, _mesa_FramebufferTexture1DEXT);
- SET_FramebufferTexture2DEXT(table, _mesa_FramebufferTexture2DEXT);
- SET_FramebufferTexture3DEXT(table, _mesa_FramebufferTexture3DEXT);
- SET_FramebufferRenderbufferEXT(table, _mesa_FramebufferRenderbufferEXT);
- SET_GenerateMipmapEXT(table, _mesa_GenerateMipmapEXT);
-
- /* 317. GL_EXT_framebuffer_multisample */
- SET_RenderbufferStorageMultisample(table, _mesa_RenderbufferStorageMultisample);
-
/* GL_ARB_vertex_array_object */
SET_BindVertexArray(table, _mesa_BindVertexArray);
SET_GenVertexArrays(table, _mesa_GenVertexArrays);
SET_MapBufferARB(table, _mesa_MapBufferARB);
SET_UnmapBufferARB(table, _mesa_UnmapBufferARB);
-#if FEATURE_EXT_framebuffer_blit
- SET_BlitFramebufferEXT(table, save_BlitFramebufferEXT);
-#endif
-
/* GL_ARB_shader_objects */
_mesa_init_shader_dispatch(table); /* Plug in glCreate/Delete/Get, etc */
SET_UseProgramObjectARB(table, save_UseProgramObjectARB);
SET_UseShaderProgramEXT(table, save_UseShaderProgramEXT);
SET_ActiveProgramEXT(table, save_ActiveProgramEXT);
- /* GL_ARB_color_buffer_float */
- SET_ClampColorARB(table, save_ClampColorARB);
- SET_ClampColor(table, save_ClampColorARB);
-
#if 0
SET_Uniform1ui(table, save_Uniform1ui);
SET_Uniform2ui(table, save_Uniform2ui);
goto end; /* the error code was recorded */
}
- /* Check read buffer's status (draw buffer was already checked) */
- if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glCopyPixels(incomplete framebuffer)" );
- goto end;
- }
-
- if (ctx->ReadBuffer->Name != 0 && ctx->ReadBuffer->Visual.samples > 0) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION,
- "glCopyPixels(multisample FBO)");
- goto end;
- }
-
if (!_mesa_source_buffer_exists(ctx, type) ||
!_mesa_dest_buffer_exists(ctx, type)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
*/
static const struct extension extension_table[] = {
/* ARB Extensions */
- { "GL_ARB_color_buffer_float", o(ARB_color_buffer_float), 2004 },
{ "GL_ARB_conservative_depth", o(ARB_conservative_depth), 2011 },
{ "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 },
- { "GL_ARB_framebuffer_object", o(ARB_framebuffer_object), 2005 },
{ "GL_ARB_half_float_pixel", o(ARB_half_float_pixel), 2003 },
{ "GL_ARB_half_float_vertex", o(ARB_half_float_vertex), 2008 },
{ "GL_ARB_map_buffer_range", o(ARB_map_buffer_range), 2008 },
{ "GL_EXT_depth_bounds_test", o(EXT_depth_bounds_test), 2002 },
{ "GL_EXT_draw_range_elements", o(EXT_draw_range_elements), 1997 },
{ "GL_EXT_fog_coord", o(EXT_fog_coord), 1999 },
- { "GL_EXT_framebuffer_blit", o(EXT_framebuffer_blit), 2005 },
- { "GL_EXT_framebuffer_multisample", o(EXT_framebuffer_multisample), 2005 },
- { "GL_EXT_framebuffer_object", o(EXT_framebuffer_object), 2000 },
{ "GL_EXT_gpu_program_parameters", o(EXT_gpu_program_parameters), 2006 },
{ "GL_EXT_gpu_shader4", o(EXT_gpu_shader4), 2006 },
{ "GL_EXT_multi_draw_arrays", o(dummy_true), 1999 },
{ "GL_EXT_texture_env_dot3", o(EXT_texture_env_dot3), 2000 },
{ "GL_EXT_texture_filter_anisotropic", o(EXT_texture_filter_anisotropic), 1999 },
{ "GL_EXT_texture_integer", o(EXT_texture_integer), 2006 },
- { "GL_EXT_texture_lod_bias", o(dummy_true), 1999 },
{ "GL_EXT_texture_mirror_clamp", o(EXT_texture_mirror_clamp), 2004 },
{ "GL_EXT_texture_object", o(dummy_true), 1995 },
{ "GL_EXT_texture", o(dummy_true), 1996 },
{ "GL_APPLE_packed_pixels", o(APPLE_packed_pixels), 2002 },
{ "GL_APPLE_vertex_array_object", o(APPLE_vertex_array_object), 2002 },
{ "GL_ATI_blend_equation_separate", o(EXT_blend_equation_separate), 2003 },
- { "GL_ATI_draw_buffers", o(dummy_true), 2002 },
{ "GL_ATI_envmap_bumpmap", o(ATI_envmap_bumpmap), 2001 },
{ "GL_ATI_separate_stencil", o(ATI_separate_stencil), 2006 },
{ "GL_ATI_texture_env_combine3", o(ATI_texture_env_combine3), 2002 },
{ "GL_NV_texture_env_combine4", o(NV_texture_env_combine4), 1999 },
{ "GL_NV_vertex_program1_1", o(NV_vertex_program1_1), 2001 },
{ "GL_NV_vertex_program", o(NV_vertex_program), 2000 },
- { "GL_SGIS_generate_mipmap", o(dummy_true), 1997 },
{ "GL_SGIS_texture_border_clamp", o(ARB_texture_border_clamp), 1997 },
{ "GL_SGIS_texture_edge_clamp", o(dummy_true), 1997 },
- { "GL_SGIS_texture_lod", o(SGIS_texture_lod), 1997 },
{ "GL_SUN_multi_draw_arrays", o(dummy_true), 1999 },
{ 0, 0, 0},
o(IBM_rasterpos_clip),
o(NV_light_max_exponent),
o(NV_texgen_reflection),
- o(SGIS_texture_lod),
0,
};
#endif
#if FEATURE_ARB_fragment_shader
ctx->Extensions.ARB_fragment_shader = GL_TRUE;
-#endif
-#if FEATURE_ARB_framebuffer_object
- ctx->Extensions.ARB_framebuffer_object = GL_TRUE;
#endif
ctx->Extensions.ARB_half_float_pixel = GL_TRUE;
ctx->Extensions.ARB_half_float_vertex = GL_TRUE;
ctx->Extensions.EXT_blend_minmax = GL_TRUE;
ctx->Extensions.EXT_depth_bounds_test = GL_TRUE;
ctx->Extensions.EXT_fog_coord = GL_TRUE;
-#if FEATURE_EXT_framebuffer_object
- ctx->Extensions.EXT_framebuffer_object = GL_TRUE;
-#endif
-#if FEATURE_EXT_framebuffer_blit
- ctx->Extensions.EXT_framebuffer_blit = GL_TRUE;
-#endif
-#if FEATURE_ARB_framebuffer_object
- ctx->Extensions.EXT_framebuffer_multisample = GL_TRUE;
-#endif
#if FEATURE_EXT_pixel_buffer_object
ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE;
#endif
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 1999-2009 VMware, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-/*
- * GL_EXT/ARB_framebuffer_object extensions
- *
- * Authors:
- * Brian Paul
- */
-
-
-#include "buffers.h"
-#include "context.h"
-#include "enums.h"
-#include "fbobject.h"
-#include "formats.h"
-#include "framebuffer.h"
-#include "hash.h"
-#include "image.h"
-#include "macros.h"
-#include "mfeatures.h"
-#include "mtypes.h"
-#include "renderbuffer.h"
-#include "state.h"
-#include "teximage.h"
-#include "texobj.h"
-
-
-/** Set this to 1 to help debug FBO incompleteness problems */
-#define DEBUG_FBO 0
-
-/** Set this to 1 to debug/log glBlitFramebuffer() calls */
-#define DEBUG_BLIT 0
-
-
-/**
- * Notes:
- *
- * None of the GL_EXT_framebuffer_object functions are compiled into
- * display lists.
- */
-
-
-
-/*
- * When glGenRender/FramebuffersEXT() is called we insert pointers to
- * these placeholder objects into the hash table.
- * Later, when the object ID is first bound, we replace the placeholder
- * with the real frame/renderbuffer.
- */
-static struct gl_framebuffer DummyFramebuffer;
-static struct gl_renderbuffer DummyRenderbuffer;
-
-/* We bind this framebuffer when applications pass a NULL
- * drawable/surface in make current. */
-static struct gl_framebuffer IncompleteFramebuffer;
-
-
-/**
- * Is the given FBO a user-created FBO?
- */
-static inline GLboolean
-is_user_fbo(const struct gl_framebuffer *fb)
-{
- return fb->Name != 0;
-}
-
-
-/**
- * Is the given FBO a window system FBO (like an X window)?
- */
-static inline GLboolean
-is_winsys_fbo(const struct gl_framebuffer *fb)
-{
- return fb->Name == 0;
-}
-
-
-static void
-delete_dummy_renderbuffer(struct gl_renderbuffer *rb)
-{
- /* no op */
-}
-
-static void
-delete_dummy_framebuffer(struct gl_framebuffer *fb)
-{
- /* no op */
-}
-
-
-void
-_mesa_init_fbobjects(struct gl_context *ctx)
-{
- _glthread_INIT_MUTEX(DummyFramebuffer.Mutex);
- _glthread_INIT_MUTEX(DummyRenderbuffer.Mutex);
- _glthread_INIT_MUTEX(IncompleteFramebuffer.Mutex);
- DummyFramebuffer.Delete = delete_dummy_framebuffer;
- DummyRenderbuffer.Delete = delete_dummy_renderbuffer;
- IncompleteFramebuffer.Delete = delete_dummy_framebuffer;
-}
-
-struct gl_framebuffer *
-_mesa_get_incomplete_framebuffer(void)
-{
- return &IncompleteFramebuffer;
-}
-
-/**
- * Helper routine for getting a gl_renderbuffer.
- */
-struct gl_renderbuffer *
-_mesa_lookup_renderbuffer(struct gl_context *ctx, GLuint id)
-{
- struct gl_renderbuffer *rb;
-
- if (id == 0)
- return NULL;
-
- rb = (struct gl_renderbuffer *)
- _mesa_HashLookup(ctx->Shared->RenderBuffers, id);
- return rb;
-}
-
-
-/**
- * Helper routine for getting a gl_framebuffer.
- */
-struct gl_framebuffer *
-_mesa_lookup_framebuffer(struct gl_context *ctx, GLuint id)
-{
- struct gl_framebuffer *fb;
-
- if (id == 0)
- return NULL;
-
- fb = (struct gl_framebuffer *)
- _mesa_HashLookup(ctx->Shared->FrameBuffers, id);
- return fb;
-}
-
-
-/**
- * Mark the given framebuffer as invalid. This will force the
- * test for framebuffer completeness to be done before the framebuffer
- * is used.
- */
-static void
-invalidate_framebuffer(struct gl_framebuffer *fb)
-{
- fb->_Status = 0; /* "indeterminate" */
-}
-
-
-/**
- * Return the gl_framebuffer object which corresponds to the given
- * framebuffer target, such as GL_DRAW_FRAMEBUFFER.
- * Check support for GL_EXT_framebuffer_blit to determine if certain
- * targets are legal.
- * \return gl_framebuffer pointer or NULL if target is illegal
- */
-static struct gl_framebuffer *
-get_framebuffer_target(struct gl_context *ctx, GLenum target)
-{
- switch (target) {
- case GL_DRAW_FRAMEBUFFER:
- return ctx->Extensions.EXT_framebuffer_blit
- ? ctx->DrawBuffer : NULL;
- case GL_READ_FRAMEBUFFER:
- return ctx->Extensions.EXT_framebuffer_blit
- ? ctx->ReadBuffer : NULL;
- case GL_FRAMEBUFFER_EXT:
- return ctx->DrawBuffer;
- default:
- return NULL;
- }
-}
-
-
-/**
- * Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding
- * gl_renderbuffer_attachment object.
- * This function is only used for user-created FB objects, not the
- * default / window-system FB object.
- * If \p attachment is GL_DEPTH_STENCIL_ATTACHMENT, return a pointer to
- * the depth buffer attachment point.
- */
-struct gl_renderbuffer_attachment *
-_mesa_get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
- GLenum attachment)
-{
- GLuint i;
-
- assert(is_user_fbo(fb));
-
- switch (attachment) {
- case GL_COLOR_ATTACHMENT0_EXT:
- case GL_COLOR_ATTACHMENT1_EXT:
- case GL_COLOR_ATTACHMENT2_EXT:
- case GL_COLOR_ATTACHMENT3_EXT:
- case GL_COLOR_ATTACHMENT4_EXT:
- case GL_COLOR_ATTACHMENT5_EXT:
- case GL_COLOR_ATTACHMENT6_EXT:
- case GL_COLOR_ATTACHMENT7_EXT:
- case GL_COLOR_ATTACHMENT8_EXT:
- case GL_COLOR_ATTACHMENT9_EXT:
- case GL_COLOR_ATTACHMENT10_EXT:
- case GL_COLOR_ATTACHMENT11_EXT:
- case GL_COLOR_ATTACHMENT12_EXT:
- case GL_COLOR_ATTACHMENT13_EXT:
- case GL_COLOR_ATTACHMENT14_EXT:
- case GL_COLOR_ATTACHMENT15_EXT:
- /* Only OpenGL ES 1.x forbids color attachments other than
- * GL_COLOR_ATTACHMENT0. For all other APIs the limit set by the
- * hardware is used.
- */
- i = attachment - GL_COLOR_ATTACHMENT0_EXT;
- if (i >= ctx->Const.MaxColorAttachments) {
- return NULL;
- }
- return &fb->Attachment[BUFFER_COLOR0 + i];
- case GL_DEPTH_ATTACHMENT_EXT:
- return &fb->Attachment[BUFFER_DEPTH];
- case GL_STENCIL_ATTACHMENT_EXT:
- return &fb->Attachment[BUFFER_STENCIL];
- default:
- return NULL;
- }
-}
-
-
-/**
- * As above, but only used for getting attachments of the default /
- * window-system framebuffer (not user-created framebuffer objects).
- */
-static struct gl_renderbuffer_attachment *
-_mesa_get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
- GLenum attachment)
-{
- assert(is_winsys_fbo(fb));
-
- switch (attachment) {
- case GL_FRONT_LEFT:
- return &fb->Attachment[BUFFER_FRONT_LEFT];
- case GL_FRONT_RIGHT:
- return &fb->Attachment[BUFFER_FRONT_RIGHT];
- case GL_BACK_LEFT:
- return &fb->Attachment[BUFFER_BACK_LEFT];
- case GL_BACK_RIGHT:
- return &fb->Attachment[BUFFER_BACK_RIGHT];
- case GL_AUX0:
- if (fb->Visual.numAuxBuffers == 1) {
- return &fb->Attachment[BUFFER_AUX0];
- }
- return NULL;
-
- /* Page 336 (page 352 of the PDF) of the OpenGL 3.0 spec says:
- *
- * "If the default framebuffer is bound to target, then attachment must
- * be one of FRONT LEFT, FRONT RIGHT, BACK LEFT, BACK RIGHT, or AUXi,
- * identifying a color buffer; DEPTH, identifying the depth buffer; or
- * STENCIL, identifying the stencil buffer."
- *
- * Revision #34 of the ARB_framebuffer_object spec has essentially the same
- * language. However, revision #33 of the ARB_framebuffer_object spec
- * says:
- *
- * "If the default framebuffer is bound to <target>, then <attachment>
- * must be one of FRONT_LEFT, FRONT_RIGHT, BACK_LEFT, BACK_RIGHT, AUXi,
- * DEPTH_BUFFER, or STENCIL_BUFFER, identifying a color buffer, the
- * depth buffer, or the stencil buffer, and <pname> may be
- * FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE or
- * FRAMEBUFFER_ATTACHMENT_OBJECT_NAME."
- *
- * The enum values for DEPTH_BUFFER and STENCIL_BUFFER have been removed
- * from glext.h, so shipping apps should not use those values.
- *
- * Note that neither EXT_framebuffer_object nor OES_framebuffer_object
- * support queries of the window system FBO.
- */
- case GL_DEPTH:
- return &fb->Attachment[BUFFER_DEPTH];
- case GL_STENCIL:
- return &fb->Attachment[BUFFER_STENCIL];
- default:
- return NULL;
- }
-}
-
-
-
-/**
- * Remove any texture or renderbuffer attached to the given attachment
- * point. Update reference counts, etc.
- */
-void
-_mesa_remove_attachment(struct gl_context *ctx,
- struct gl_renderbuffer_attachment *att)
-{
- if (att->Type == GL_TEXTURE) {
- ASSERT(att->Texture);
- if (ctx->Driver.FinishRenderTexture) {
- /* tell driver that we're done rendering to this texture. */
- ctx->Driver.FinishRenderTexture(ctx, att);
- }
- _mesa_reference_texobj(&att->Texture, NULL); /* unbind */
- ASSERT(!att->Texture);
- }
- if (att->Type == GL_TEXTURE || att->Type == GL_RENDERBUFFER_EXT) {
- ASSERT(!att->Texture);
- _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); /* unbind */
- ASSERT(!att->Renderbuffer);
- }
- att->Type = GL_NONE;
- att->Complete = GL_TRUE;
-}
-
-
-/**
- * Bind a texture object to an attachment point.
- * The previous binding, if any, will be removed first.
- */
-void
-_mesa_set_texture_attachment(struct gl_context *ctx,
- struct gl_framebuffer *fb,
- struct gl_renderbuffer_attachment *att,
- struct gl_texture_object *texObj,
- GLenum texTarget, GLuint level, GLuint zoffset)
-{
- if (att->Texture == texObj) {
- /* re-attaching same texture */
- ASSERT(att->Type == GL_TEXTURE);
- if (ctx->Driver.FinishRenderTexture)
- ctx->Driver.FinishRenderTexture(ctx, att);
- }
- else {
- /* new attachment */
- if (ctx->Driver.FinishRenderTexture && att->Texture)
- ctx->Driver.FinishRenderTexture(ctx, att);
- _mesa_remove_attachment(ctx, att);
- att->Type = GL_TEXTURE;
- assert(!att->Texture);
- _mesa_reference_texobj(&att->Texture, texObj);
- }
-
- /* always update these fields */
- att->TextureLevel = level;
- att->CubeMapFace = _mesa_tex_target_to_face(texTarget);
- att->Zoffset = zoffset;
- att->Complete = GL_FALSE;
-
- if (_mesa_get_attachment_teximage(att)) {
- ctx->Driver.RenderTexture(ctx, fb, att);
- }
-
- invalidate_framebuffer(fb);
-}
-
-
-/**
- * Bind a renderbuffer to an attachment point.
- * The previous binding, if any, will be removed first.
- */
-void
-_mesa_set_renderbuffer_attachment(struct gl_context *ctx,
- struct gl_renderbuffer_attachment *att,
- struct gl_renderbuffer *rb)
-{
- /* XXX check if re-doing same attachment, exit early */
- _mesa_remove_attachment(ctx, att);
- att->Type = GL_RENDERBUFFER_EXT;
- att->Texture = NULL; /* just to be safe */
- att->Complete = GL_FALSE;
- _mesa_reference_renderbuffer(&att->Renderbuffer, rb);
-}
-
-
-/**
- * Fallback for ctx->Driver.FramebufferRenderbuffer()
- * Attach a renderbuffer object to a framebuffer object.
- */
-void
-_mesa_framebuffer_renderbuffer(struct gl_context *ctx,
- struct gl_framebuffer *fb,
- GLenum attachment, struct gl_renderbuffer *rb)
-{
- struct gl_renderbuffer_attachment *att;
-
- _glthread_LOCK_MUTEX(fb->Mutex);
-
- att = _mesa_get_attachment(ctx, fb, attachment);
- ASSERT(att);
- if (rb) {
- _mesa_set_renderbuffer_attachment(ctx, att, rb);
- rb->AttachedAnytime = GL_TRUE;
- }
- else {
- _mesa_remove_attachment(ctx, att);
- }
-
- invalidate_framebuffer(fb);
-
- _glthread_UNLOCK_MUTEX(fb->Mutex);
-}
-
-
-/**
- * Fallback for ctx->Driver.ValidateFramebuffer()
- * Check if the renderbuffer's formats are supported by the software
- * renderer.
- * Drivers should probably override this.
- */
-void
-_mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
-{
- gl_buffer_index buf;
- for (buf = 0; buf < BUFFER_COUNT; buf++) {
- const struct gl_renderbuffer *rb = fb->Attachment[buf].Renderbuffer;
- if (rb) {
- switch (rb->_BaseFormat) {
- case GL_ALPHA:
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE:
- case GL_INTENSITY:
- case GL_RED:
- case GL_RG:
- fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
- return;
-
- default:;
- /* render buffer format is supported by software rendering */
- }
- }
- }
-}
-
-
-/**
- * For debug only.
- */
-static void
-att_incomplete(const char *msg)
-{
-#if DEBUG_FBO
- _mesa_debug(NULL, "attachment incomplete: %s\n", msg);
-#else
- (void) msg;
-#endif
-}
-
-
-/**
- * For debug only.
- */
-static void
-fbo_incomplete(const char *msg, int index)
-{
-#if DEBUG_FBO
- _mesa_debug(NULL, "FBO Incomplete: %s [%d]\n", msg, index);
-#else
- (void) msg;
- (void) index;
-#endif
-}
-
-
-/**
- * Is the given base format a legal format for a color renderbuffer?
- */
-GLboolean
-_mesa_is_legal_color_format(const struct gl_context *ctx, GLenum baseFormat)
-{
- switch (baseFormat) {
- case GL_RGB:
- case GL_RGBA:
- return GL_TRUE;
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- case GL_INTENSITY:
- case GL_ALPHA:
- return ctx->Extensions.ARB_framebuffer_object;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Test if an attachment point is complete and update its Complete field.
- * \param format if GL_COLOR, this is a color attachment point,
- * if GL_DEPTH, this is a depth component attachment point,
- * if GL_STENCIL, this is a stencil component attachment point.
- */
-static void
-test_attachment_completeness(const struct gl_context *ctx, GLenum format,
- struct gl_renderbuffer_attachment *att)
-{
- assert(format == GL_COLOR || format == GL_DEPTH || format == GL_STENCIL);
-
- /* assume complete */
- att->Complete = GL_TRUE;
-
- /* Look for reasons why the attachment might be incomplete */
- if (att->Type == GL_TEXTURE) {
- const struct gl_texture_object *texObj = att->Texture;
- struct gl_texture_image *texImage;
- GLenum baseFormat;
-
- if (!texObj) {
- att_incomplete("no texobj");
- att->Complete = GL_FALSE;
- return;
- }
-
- texImage = texObj->Image[att->CubeMapFace][att->TextureLevel];
- if (!texImage) {
- att_incomplete("no teximage");
- att->Complete = GL_FALSE;
- return;
- }
- if (texImage->Width < 1 || texImage->Height < 1) {
- att_incomplete("teximage width/height=0");
- printf("texobj = %u\n", texObj->Name);
- printf("level = %d\n", att->TextureLevel);
- att->Complete = GL_FALSE;
- return;
- }
- if (texObj->Target == GL_TEXTURE_3D && att->Zoffset >= texImage->Depth) {
- att_incomplete("bad z offset");
- att->Complete = GL_FALSE;
- return;
- }
-
- baseFormat = _mesa_get_format_base_format(texImage->TexFormat);
-
- if (format == GL_COLOR) {
- if (!_mesa_is_legal_color_format(ctx, baseFormat)) {
- att_incomplete("bad format");
- att->Complete = GL_FALSE;
- return;
- }
- }
- else if (format == GL_DEPTH) {
- if (baseFormat == GL_DEPTH_COMPONENT) {
- /* OK */
- }
- else {
- att->Complete = GL_FALSE;
- att_incomplete("bad depth format");
- return;
- }
- }
- else {
- {
- /* no such thing as stencil-only textures */
- att_incomplete("illegal stencil texture");
- att->Complete = GL_FALSE;
- return;
- }
- }
- }
- else if (att->Type == GL_RENDERBUFFER_EXT) {
- const GLenum baseFormat =
- _mesa_get_format_base_format(att->Renderbuffer->Format);
-
- ASSERT(att->Renderbuffer);
- if (!att->Renderbuffer->InternalFormat ||
- att->Renderbuffer->Width < 1 ||
- att->Renderbuffer->Height < 1) {
- att_incomplete("0x0 renderbuffer");
- att->Complete = GL_FALSE;
- return;
- }
- if (format == GL_COLOR) {
- if (!_mesa_is_legal_color_format(ctx, baseFormat)) {
- att_incomplete("bad renderbuffer color format");
- att->Complete = GL_FALSE;
- return;
- }
- }
- else if (format == GL_DEPTH) {
- if (baseFormat == GL_DEPTH_COMPONENT) {
- /* OK */
- }
- else {
- att_incomplete("bad renderbuffer depth format");
- att->Complete = GL_FALSE;
- return;
- }
- }
- else {
- assert(format == GL_STENCIL);
- if (baseFormat == GL_STENCIL_INDEX) {
- /* OK */
- }
- else {
- att->Complete = GL_FALSE;
- att_incomplete("bad renderbuffer stencil format");
- return;
- }
- }
- }
- else {
- ASSERT(att->Type == GL_NONE);
- /* complete */
- return;
- }
-}
-
-
-/**
- * Test if the given framebuffer object is complete and update its
- * Status field with the results.
- * Calls the ctx->Driver.ValidateFramebuffer() function to allow the
- * driver to make hardware-specific validation/completeness checks.
- * Also update the framebuffer's Width and Height fields if the
- * framebuffer is complete.
- */
-void
-_mesa_test_framebuffer_completeness(struct gl_context *ctx,
- struct gl_framebuffer *fb)
-{
- GLuint numImages;
- GLenum intFormat = GL_NONE; /* color buffers' internal format */
- GLuint minWidth = ~0, minHeight = ~0, maxWidth = 0, maxHeight = 0;
- GLint numSamples = -1;
- GLint i;
-
- assert(is_user_fbo(fb));
-
- numImages = 0;
- fb->Width = 0;
- fb->Height = 0;
-
- /* Start at -2 to more easily loop over all attachment points.
- * -2: depth buffer
- * -1: stencil buffer
- * >=0: color buffer
- */
- for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) {
- struct gl_renderbuffer_attachment *att;
- GLenum f;
- gl_format attFormat;
-
- /*
- * XXX for ARB_fbo, only check color buffers that are named by
- * GL_READ_BUFFER and GL_DRAW_BUFFERi.
- */
-
- /* check for attachment completeness
- */
- if (i == -2) {
- att = &fb->Attachment[BUFFER_DEPTH];
- test_attachment_completeness(ctx, GL_DEPTH, att);
- if (!att->Complete) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
- fbo_incomplete("depth attachment incomplete", -1);
- return;
- }
- }
- else if (i == -1) {
- att = &fb->Attachment[BUFFER_STENCIL];
- test_attachment_completeness(ctx, GL_STENCIL, att);
- if (!att->Complete) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
- fbo_incomplete("stencil attachment incomplete", -1);
- return;
- }
- }
- else {
- att = &fb->Attachment[BUFFER_COLOR0 + i];
- test_attachment_completeness(ctx, GL_COLOR, att);
- if (!att->Complete) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
- fbo_incomplete("color attachment incomplete", i);
- return;
- }
- }
-
- /* get width, height, format of the renderbuffer/texture
- */
- if (att->Type == GL_TEXTURE) {
- const struct gl_texture_image *texImg =
- _mesa_get_attachment_teximage(att);
- minWidth = MIN2(minWidth, texImg->Width);
- maxWidth = MAX2(maxWidth, texImg->Width);
- minHeight = MIN2(minHeight, texImg->Height);
- maxHeight = MAX2(maxHeight, texImg->Height);
- f = texImg->_BaseFormat;
- attFormat = texImg->TexFormat;
- numImages++;
- if (!_mesa_is_legal_color_format(ctx, f) &&
- f != GL_DEPTH_COMPONENT) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
- fbo_incomplete("texture attachment incomplete", -1);
- return;
- }
- }
- else if (att->Type == GL_RENDERBUFFER_EXT) {
- minWidth = MIN2(minWidth, att->Renderbuffer->Width);
- maxWidth = MAX2(minWidth, att->Renderbuffer->Width);
- minHeight = MIN2(minHeight, att->Renderbuffer->Height);
- maxHeight = MAX2(minHeight, att->Renderbuffer->Height);
- f = att->Renderbuffer->InternalFormat;
- attFormat = att->Renderbuffer->Format;
- numImages++;
- }
- else {
- assert(att->Type == GL_NONE);
- continue;
- }
-
- if (att->Renderbuffer && numSamples < 0) {
- /* first buffer */
- numSamples = att->Renderbuffer->NumSamples;
- }
-
- /* check if integer color */
- fb->_IntegerColor = _mesa_is_format_integer_color(attFormat);
-
- /* Error-check width, height, format, samples
- */
- if (numImages == 1) {
- /* save format, num samples */
- if (i >= 0) {
- intFormat = f;
- }
- }
- else {
- if (!ctx->Extensions.ARB_framebuffer_object) {
- /* check that width, height, format are same */
- if (minWidth != maxWidth || minHeight != maxHeight) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT;
- fbo_incomplete("width or height mismatch", -1);
- return;
- }
- /* check that all color buffers are the same format */
- if (intFormat != GL_NONE && f != intFormat) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
- fbo_incomplete("format mismatch", -1);
- return;
- }
- }
- if (att->Renderbuffer &&
- att->Renderbuffer->NumSamples != numSamples) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
- fbo_incomplete("inconsistant number of samples", i);
- return;
- }
- }
- }
-
- /* Check that all DrawBuffers are present */
- if (fb->ColorDrawBuffer != GL_NONE) {
- const struct gl_renderbuffer_attachment *att
- = _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", 0);
- return;
- }
- }
-
- /* Check that the ReadBuffer is present */
- if (fb->ColorReadBuffer != GL_NONE) {
- const struct gl_renderbuffer_attachment *att
- = _mesa_get_attachment(ctx, fb, fb->ColorReadBuffer);
- assert(att);
- if (att->Type == GL_NONE) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT;
- fbo_incomplete("missing readbuffer", -1);
- return;
- }
- }
-
- if (numImages == 0) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT;
- fbo_incomplete("no attachments", -1);
- return;
- }
-
- /* Provisionally set status = COMPLETE ... */
- fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
-
- /* ... but the driver may say the FB is incomplete.
- * Drivers will most likely set the status to GL_FRAMEBUFFER_UNSUPPORTED
- * if anything.
- */
- if (ctx->Driver.ValidateFramebuffer) {
- ctx->Driver.ValidateFramebuffer(ctx, fb);
- if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- fbo_incomplete("driver marked FBO as incomplete", -1);
- }
- }
-
- if (fb->_Status == GL_FRAMEBUFFER_COMPLETE_EXT) {
- /*
- * Note that if ARB_framebuffer_object is supported and the attached
- * renderbuffers/textures are different sizes, the framebuffer
- * width/height will be set to the smallest width/height.
- */
- fb->Width = minWidth;
- fb->Height = minHeight;
-
- /* finally, update the visual info for the framebuffer */
- _mesa_update_framebuffer_visual(ctx, fb);
- }
-}
-
-
-GLboolean GLAPIENTRY
-_mesa_IsRenderbufferEXT(GLuint renderbuffer)
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
- if (renderbuffer) {
- struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
- if (rb != NULL && rb != &DummyRenderbuffer)
- return GL_TRUE;
- }
- return GL_FALSE;
-}
-
-
-void GLAPIENTRY
-_mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
-{
- struct gl_renderbuffer *newRb;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (target != GL_RENDERBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBindRenderbufferEXT(target)");
- return;
- }
-
- /* No need to flush here since the render buffer binding has no
- * effect on rendering state.
- */
-
- if (renderbuffer) {
- newRb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
- if (newRb == &DummyRenderbuffer) {
- /* ID was reserved, but no real renderbuffer object made yet */
- newRb = NULL;
- }
- else if (!newRb && ctx->Extensions.ARB_framebuffer_object) {
- /* All RB IDs must be Gen'd */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glBindRenderbuffer(buffer)");
- return;
- }
-
- if (!newRb) {
- /* create new renderbuffer object */
- newRb = ctx->Driver.NewRenderbuffer(ctx, renderbuffer);
- if (!newRb) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindRenderbufferEXT");
- return;
- }
- ASSERT(newRb->AllocStorage);
- _mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb);
- newRb->RefCount = 1; /* referenced by hash table */
- }
- }
- else {
- newRb = NULL;
- }
-
- ASSERT(newRb != &DummyRenderbuffer);
-
- _mesa_reference_renderbuffer(&ctx->CurrentRenderbuffer, newRb);
-}
-
-
-/**
- * If the given renderbuffer is anywhere attached to the framebuffer, detach
- * the renderbuffer.
- * This is used when a renderbuffer object is deleted.
- * The spec calls for unbinding.
- */
-static void
-detach_renderbuffer(struct gl_context *ctx,
- struct gl_framebuffer *fb,
- struct gl_renderbuffer *rb)
-{
- GLuint i;
- for (i = 0; i < BUFFER_COUNT; i++) {
- if (fb->Attachment[i].Renderbuffer == rb) {
- _mesa_remove_attachment(ctx, &fb->Attachment[i]);
- }
- }
- invalidate_framebuffer(fb);
-}
-
-
-void GLAPIENTRY
-_mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
-{
- GLint i;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- for (i = 0; i < n; i++) {
- if (renderbuffers[i] > 0) {
- struct gl_renderbuffer *rb;
- rb = _mesa_lookup_renderbuffer(ctx, renderbuffers[i]);
- if (rb) {
- /* check if deleting currently bound renderbuffer object */
- if (rb == ctx->CurrentRenderbuffer) {
- /* bind default */
- ASSERT(rb->RefCount >= 2);
- _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
- }
-
- if (is_user_fbo(ctx->DrawBuffer)) {
- detach_renderbuffer(ctx, ctx->DrawBuffer, rb);
- }
- if (is_user_fbo(ctx->ReadBuffer)
- && ctx->ReadBuffer != ctx->DrawBuffer) {
- detach_renderbuffer(ctx, ctx->ReadBuffer, rb);
- }
-
- /* Remove from hash table immediately, to free the ID.
- * But the object will not be freed until it's no longer
- * referenced anywhere else.
- */
- _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]);
-
- if (rb != &DummyRenderbuffer) {
- /* no longer referenced by hash table */
- _mesa_reference_renderbuffer(&rb, NULL);
- }
- }
- }
- }
-}
-
-
-void GLAPIENTRY
-_mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLuint first;
- GLint i;
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (n < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGenRenderbuffersEXT(n)");
- return;
- }
-
- if (!renderbuffers)
- return;
-
- first = _mesa_HashFindFreeKeyBlock(ctx->Shared->RenderBuffers, n);
-
- for (i = 0; i < n; i++) {
- GLuint name = first + i;
- renderbuffers[i] = name;
- /* insert dummy placeholder into hash table */
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
- _mesa_HashInsert(ctx->Shared->RenderBuffers, name, &DummyRenderbuffer);
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
- }
-}
-
-
-/**
- * Given an internal format token for a render buffer, return the
- * corresponding base format (one of GL_RGB, GL_RGBA, GL_STENCIL_INDEX,
- * GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL_EXT, GL_ALPHA, GL_LUMINANCE,
- * GL_LUMINANCE_ALPHA, GL_INTENSITY, etc).
- *
- * This is similar to _mesa_base_tex_format() but the set of valid
- * internal formats is different.
- *
- * Note that even if a format is determined to be legal here, validation
- * of the FBO may fail if the format is not supported by the driver/GPU.
- *
- * \param internalFormat as passed to glRenderbufferStorage()
- * \return the base internal format, or 0 if internalFormat is illegal
- */
-GLenum
-_mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
-{
- /*
- * Notes: some formats such as alpha, luminance, etc. were added
- * with GL_ARB_framebuffer_object.
- */
- switch (internalFormat) {
- case GL_ALPHA:
- case GL_ALPHA4:
- case GL_ALPHA8:
- case GL_ALPHA12:
- case GL_ALPHA16:
- return ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0;
- case GL_LUMINANCE:
- case GL_LUMINANCE4:
- case GL_LUMINANCE8:
- case GL_LUMINANCE12:
- case GL_LUMINANCE16:
- return ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE : 0;
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE4_ALPHA4:
- case GL_LUMINANCE6_ALPHA2:
- case GL_LUMINANCE8_ALPHA8:
- case GL_LUMINANCE12_ALPHA4:
- case GL_LUMINANCE12_ALPHA12:
- case GL_LUMINANCE16_ALPHA16:
- return ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE_ALPHA : 0;
- case GL_INTENSITY:
- case GL_INTENSITY4:
- case GL_INTENSITY8:
- case GL_INTENSITY12:
- case GL_INTENSITY16:
- return ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0;
- case GL_RGB:
- case GL_R3_G3_B2:
- case GL_RGB4:
- case GL_RGB5:
- case GL_RGB8:
- case GL_RGB10:
- case GL_RGB12:
- case GL_RGB16:
- return GL_RGB;
- case GL_RGBA:
- case GL_RGBA2:
- case GL_RGBA4:
- case GL_RGB5_A1:
- case GL_RGBA8:
- case GL_RGB10_A2:
- case GL_RGBA12:
- case GL_RGBA16:
- return GL_RGBA;
- case GL_STENCIL_INDEX:
- case GL_STENCIL_INDEX1_EXT:
- case GL_STENCIL_INDEX4_EXT:
- case GL_STENCIL_INDEX8_EXT:
- case GL_STENCIL_INDEX16_EXT:
- return GL_STENCIL_INDEX;
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT24:
- case GL_DEPTH_COMPONENT32:
- return GL_DEPTH_COMPONENT;
- case GL_RGB16F:
- case GL_RGB32F:
- return ctx->Extensions.ARB_texture_float ? GL_RGB : 0;
- case GL_RGBA16F:
- case GL_RGBA32F:
- return ctx->Extensions.ARB_texture_float ? GL_RGBA : 0;
- case GL_ALPHA16F_ARB:
- case GL_ALPHA32F_ARB:
- return ctx->Extensions.ARB_texture_float &&
- ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0;
- case GL_LUMINANCE16F_ARB:
- case GL_LUMINANCE32F_ARB:
- return ctx->Extensions.ARB_texture_float &&
- ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE : 0;
- case GL_LUMINANCE_ALPHA16F_ARB:
- case GL_LUMINANCE_ALPHA32F_ARB:
- return ctx->Extensions.ARB_texture_float &&
- ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE_ALPHA : 0;
- case GL_INTENSITY16F_ARB:
- case GL_INTENSITY32F_ARB:
- return ctx->Extensions.ARB_texture_float &&
- ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0;
-
- case GL_RGBA8UI_EXT:
- case GL_RGBA16UI_EXT:
- case GL_RGBA32UI_EXT:
- case GL_RGBA8I_EXT:
- case GL_RGBA16I_EXT:
- case GL_RGBA32I_EXT:
- return ctx->VersionMajor >= 3 ||
- ctx->Extensions.EXT_texture_integer ? GL_RGBA : 0;
-
- case GL_RGB8UI_EXT:
- case GL_RGB16UI_EXT:
- case GL_RGB32UI_EXT:
- case GL_RGB8I_EXT:
- case GL_RGB16I_EXT:
- case GL_RGB32I_EXT:
- return ctx->VersionMajor >= 3 ||
- ctx->Extensions.EXT_texture_integer ? GL_RGB : 0;
-
- case GL_INTENSITY8I_EXT:
- case GL_INTENSITY8UI_EXT:
- case GL_INTENSITY16I_EXT:
- case GL_INTENSITY16UI_EXT:
- case GL_INTENSITY32I_EXT:
- case GL_INTENSITY32UI_EXT:
- return ctx->Extensions.EXT_texture_integer &&
- ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0;
-
- case GL_LUMINANCE8I_EXT:
- case GL_LUMINANCE8UI_EXT:
- case GL_LUMINANCE16I_EXT:
- case GL_LUMINANCE16UI_EXT:
- case GL_LUMINANCE32I_EXT:
- case GL_LUMINANCE32UI_EXT:
- return ctx->Extensions.EXT_texture_integer &&
- ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE : 0;
-
- case GL_LUMINANCE_ALPHA8I_EXT:
- case GL_LUMINANCE_ALPHA8UI_EXT:
- case GL_LUMINANCE_ALPHA16I_EXT:
- case GL_LUMINANCE_ALPHA16UI_EXT:
- case GL_LUMINANCE_ALPHA32I_EXT:
- case GL_LUMINANCE_ALPHA32UI_EXT:
- return ctx->Extensions.EXT_texture_integer &&
- ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE_ALPHA : 0;
-
- default:
- return 0;
- }
-}
-
-
-/**
- * Invalidate a renderbuffer attachment. Called from _mesa_HashWalk().
- */
-static void
-invalidate_rb(GLuint key, void *data, void *userData)
-{
- struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
- struct gl_renderbuffer *rb = (struct gl_renderbuffer *) userData;
-
- /* If this is a user-created FBO */
- if (is_user_fbo(fb)) {
- GLuint i;
- for (i = 0; i < BUFFER_COUNT; i++) {
- struct gl_renderbuffer_attachment *att = fb->Attachment + i;
- if (att->Type == GL_RENDERBUFFER &&
- att->Renderbuffer == rb) {
- /* Mark fb status as indeterminate to force re-validation */
- fb->_Status = 0;
- return;
- }
- }
- }
-}
-
-
-/** sentinal value, see below */
-#define NO_SAMPLES 1000
-
-
-/**
- * Helper function used by _mesa_RenderbufferStorageEXT() and
- * _mesa_RenderbufferStorageMultisample().
- * samples will be NO_SAMPLES if called by _mesa_RenderbufferStorageEXT().
- */
-static void
-renderbuffer_storage(GLenum target, GLenum internalFormat,
- GLsizei width, GLsizei height, GLsizei samples)
-{
- const char *func = samples == NO_SAMPLES ?
- "glRenderbufferStorage" : "RenderbufferStorageMultisample";
- struct gl_renderbuffer *rb;
- GLenum baseFormat;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (target != GL_RENDERBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func);
- return;
- }
-
- baseFormat = _mesa_base_fbo_format(ctx, internalFormat);
- if (baseFormat == 0) {
- _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat)", func);
- return;
- }
-
- if (width < 0 || width > (GLsizei) ctx->Const.MaxRenderbufferSize) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s(width)", func);
- return;
- }
-
- if (height < 0 || height > (GLsizei) ctx->Const.MaxRenderbufferSize) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s(height)", func);
- return;
- }
-
- if (samples == NO_SAMPLES) {
- /* NumSamples == 0 indicates non-multisampling */
- samples = 0;
- }
- else if (samples > (GLsizei) ctx->Const.MaxSamples) {
- /* note: driver may choose to use more samples than what's requested */
- _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples)", func);
- return;
- }
-
- rb = ctx->CurrentRenderbuffer;
- if (!rb) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s", func);
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- if (rb->InternalFormat == internalFormat &&
- rb->Width == (GLuint) width &&
- rb->Height == (GLuint) height &&
- rb->NumSamples == samples) {
- /* no change in allocation needed */
- return;
- }
-
- /* These MUST get set by the AllocStorage func */
- rb->Format = MESA_FORMAT_NONE;
- rb->NumSamples = samples;
-
- /* Now allocate the storage */
- ASSERT(rb->AllocStorage);
- if (rb->AllocStorage(ctx, rb, internalFormat, width, height)) {
- /* No error - check/set fields now */
- assert(rb->Format != MESA_FORMAT_NONE);
- assert(rb->Width == (GLuint) width);
- assert(rb->Height == (GLuint) height);
- rb->InternalFormat = internalFormat;
- rb->_BaseFormat = baseFormat;
- assert(rb->_BaseFormat != 0);
- }
- else {
- /* Probably ran out of memory - clear the fields */
- rb->Width = 0;
- rb->Height = 0;
- rb->Format = MESA_FORMAT_NONE;
- rb->InternalFormat = GL_NONE;
- rb->_BaseFormat = GL_NONE;
- rb->NumSamples = 0;
- }
-
- /* Invalidate the framebuffers the renderbuffer is attached in. */
- if (rb->AttachedAnytime) {
- _mesa_HashWalk(ctx->Shared->FrameBuffers, invalidate_rb, rb);
- }
-}
-
-/**
- * Helper function for _mesa_GetRenderbufferParameterivEXT() and
- * _mesa_GetFramebufferAttachmentParameterivEXT()
- * We have to be careful to respect the base format. For example, if a
- * renderbuffer/texture was created with internalFormat=GL_RGB but the
- * driver actually chose a GL_RGBA format, when the user queries ALPHA_SIZE
- * we need to return zero.
- */
-static GLint
-get_component_bits(GLenum pname, GLenum baseFormat, gl_format format)
-{
- if (_mesa_base_format_has_channel(baseFormat, pname))
- return _mesa_get_format_bits(format, pname);
- else
- return 0;
-}
-
-
-
-void GLAPIENTRY
-_mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
- GLsizei width, GLsizei height)
-{
- /* GL_ARB_fbo says calling this function is equivalent to calling
- * glRenderbufferStorageMultisample() with samples=0. We pass in
- * a token value here just for error reporting purposes.
- */
- renderbuffer_storage(target, internalFormat, width, height, NO_SAMPLES);
-}
-
-
-void GLAPIENTRY
-_mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples,
- GLenum internalFormat,
- GLsizei width, GLsizei height)
-{
- renderbuffer_storage(target, internalFormat, width, height, samples);
-}
-
-
-/**
- * OpenGL ES version of glRenderBufferStorage.
- */
-void GLAPIENTRY
-_es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
- GLsizei width, GLsizei height)
-{
- switch (internalFormat) {
- case GL_RGB565:
- /* XXX this confuses GL_RENDERBUFFER_INTERNAL_FORMAT_OES */
- /* choose a closest format */
- internalFormat = GL_RGB5;
- break;
- default:
- break;
- }
-
- renderbuffer_storage(target, internalFormat, width, height, 0);
-}
-
-
-void GLAPIENTRY
-_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params)
-{
- struct gl_renderbuffer *rb;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (target != GL_RENDERBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetRenderbufferParameterivEXT(target)");
- return;
- }
-
- rb = ctx->CurrentRenderbuffer;
- if (!rb) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetRenderbufferParameterivEXT");
- return;
- }
-
- /* No need to flush here since we're just quering state which is
- * not effected by rendering.
- */
-
- switch (pname) {
- case GL_RENDERBUFFER_WIDTH_EXT:
- *params = rb->Width;
- return;
- case GL_RENDERBUFFER_HEIGHT_EXT:
- *params = rb->Height;
- return;
- case GL_RENDERBUFFER_INTERNAL_FORMAT_EXT:
- *params = rb->InternalFormat;
- return;
- case GL_RENDERBUFFER_RED_SIZE_EXT:
- case GL_RENDERBUFFER_GREEN_SIZE_EXT:
- case GL_RENDERBUFFER_BLUE_SIZE_EXT:
- case GL_RENDERBUFFER_ALPHA_SIZE_EXT:
- case GL_RENDERBUFFER_DEPTH_SIZE_EXT:
- case GL_RENDERBUFFER_STENCIL_SIZE_EXT:
- *params = get_component_bits(pname, rb->_BaseFormat, rb->Format);
- break;
- case GL_RENDERBUFFER_SAMPLES:
- if (ctx->Extensions.ARB_framebuffer_object) {
- *params = rb->NumSamples;
- break;
- }
- /* fallthrough */
- default:
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetRenderbufferParameterivEXT(target)");
- return;
- }
-}
-
-
-GLboolean GLAPIENTRY
-_mesa_IsFramebufferEXT(GLuint framebuffer)
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
- if (framebuffer) {
- struct gl_framebuffer *rb = _mesa_lookup_framebuffer(ctx, framebuffer);
- if (rb != NULL && rb != &DummyFramebuffer)
- return GL_TRUE;
- }
- return GL_FALSE;
-}
-
-
-/**
- * Check if any of the attachments of the given framebuffer are textures
- * (render to texture). Call ctx->Driver.RenderTexture() for such
- * attachments.
- */
-static void
-check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
-{
- GLuint i;
- ASSERT(ctx->Driver.RenderTexture);
-
- if (is_winsys_fbo(fb))
- return; /* can't render to texture with winsys framebuffers */
-
- for (i = 0; i < BUFFER_COUNT; i++) {
- struct gl_renderbuffer_attachment *att = fb->Attachment + i;
- if (att->Texture && _mesa_get_attachment_teximage(att)) {
- ctx->Driver.RenderTexture(ctx, fb, att);
- }
- }
-}
-
-
-/**
- * Examine all the framebuffer's attachments to see if any are textures.
- * If so, call ctx->Driver.FinishRenderTexture() for each texture to
- * notify the device driver that the texture image may have changed.
- */
-static void
-check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
-{
- if (is_winsys_fbo(fb))
- return; /* can't render to texture with winsys framebuffers */
-
- if (ctx->Driver.FinishRenderTexture) {
- GLuint i;
- for (i = 0; i < BUFFER_COUNT; i++) {
- struct gl_renderbuffer_attachment *att = fb->Attachment + i;
- if (att->Texture && att->Renderbuffer) {
- ctx->Driver.FinishRenderTexture(ctx, att);
- }
- }
- }
-}
-
-
-void GLAPIENTRY
-_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
-{
- struct gl_framebuffer *newDrawFb, *newReadFb;
- struct gl_framebuffer *oldDrawFb, *oldReadFb;
- GLboolean bindReadBuf, bindDrawBuf;
- GET_CURRENT_CONTEXT(ctx);
-
-#ifdef DEBUG
- if (ctx->Extensions.ARB_framebuffer_object) {
- ASSERT(ctx->Extensions.EXT_framebuffer_object);
- ASSERT(ctx->Extensions.EXT_framebuffer_blit);
- }
-#endif
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (!ctx->Extensions.EXT_framebuffer_object) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBindFramebufferEXT(unsupported)");
- return;
- }
-
- switch (target) {
-#if FEATURE_EXT_framebuffer_blit
- case GL_DRAW_FRAMEBUFFER_EXT:
- if (!ctx->Extensions.EXT_framebuffer_blit) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)");
- return;
- }
- bindDrawBuf = GL_TRUE;
- bindReadBuf = GL_FALSE;
- break;
- case GL_READ_FRAMEBUFFER_EXT:
- if (!ctx->Extensions.EXT_framebuffer_blit) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)");
- return;
- }
- bindDrawBuf = GL_FALSE;
- bindReadBuf = GL_TRUE;
- break;
-#endif
- case GL_FRAMEBUFFER_EXT:
- bindDrawBuf = GL_TRUE;
- bindReadBuf = GL_TRUE;
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)");
- return;
- }
-
- if (framebuffer) {
- /* Binding a user-created framebuffer object */
- newDrawFb = _mesa_lookup_framebuffer(ctx, framebuffer);
- if (newDrawFb == &DummyFramebuffer) {
- /* ID was reserved, but no real framebuffer object made yet */
- newDrawFb = NULL;
- }
- else if (!newDrawFb && ctx->Extensions.ARB_framebuffer_object) {
- /* All FBO IDs must be Gen'd */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFramebuffer(buffer)");
- return;
- }
-
- if (!newDrawFb) {
- /* create new framebuffer object */
- newDrawFb = ctx->Driver.NewFramebuffer(ctx, framebuffer);
- if (!newDrawFb) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT");
- return;
- }
- _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newDrawFb);
- }
- newReadFb = newDrawFb;
- }
- else {
- /* Binding the window system framebuffer (which was originally set
- * with MakeCurrent).
- */
- newDrawFb = ctx->WinSysDrawBuffer;
- newReadFb = ctx->WinSysReadBuffer;
- }
-
- ASSERT(newDrawFb);
- ASSERT(newDrawFb != &DummyFramebuffer);
-
- /* save pointers to current/old framebuffers */
- oldDrawFb = ctx->DrawBuffer;
- oldReadFb = ctx->ReadBuffer;
-
- /* check if really changing bindings */
- if (oldDrawFb == newDrawFb)
- bindDrawBuf = GL_FALSE;
- if (oldReadFb == newReadFb)
- bindReadBuf = GL_FALSE;
-
- /*
- * OK, now bind the new Draw/Read framebuffers, if they're changing.
- *
- * We also check if we're beginning and/or ending render-to-texture.
- * When a framebuffer with texture attachments is unbound, call
- * ctx->Driver.FinishRenderTexture().
- * When a framebuffer with texture attachments is bound, call
- * ctx->Driver.RenderTexture().
- *
- * Note that if the ReadBuffer has texture attachments we don't consider
- * that a render-to-texture case.
- */
- if (bindReadBuf) {
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- /* check if old readbuffer was render-to-texture */
- check_end_texture_render(ctx, oldReadFb);
-
- _mesa_reference_framebuffer(&ctx->ReadBuffer, newReadFb);
- }
-
- if (bindDrawBuf) {
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- /* check if old read/draw buffers were render-to-texture */
- if (!bindReadBuf)
- check_end_texture_render(ctx, oldReadFb);
-
- if (oldDrawFb != oldReadFb)
- check_end_texture_render(ctx, oldDrawFb);
-
- /* check if newly bound framebuffer has any texture attachments */
- check_begin_texture_render(ctx, newDrawFb);
-
- _mesa_reference_framebuffer(&ctx->DrawBuffer, newDrawFb);
- }
-
- if ((bindDrawBuf || bindReadBuf) && ctx->Driver.BindFramebuffer) {
- ctx->Driver.BindFramebuffer(ctx, target, newDrawFb, newReadFb);
- }
-}
-
-
-void GLAPIENTRY
-_mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
-{
- GLint i;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- for (i = 0; i < n; i++) {
- if (framebuffers[i] > 0) {
- struct gl_framebuffer *fb;
- fb = _mesa_lookup_framebuffer(ctx, framebuffers[i]);
- if (fb) {
- ASSERT(fb == &DummyFramebuffer || fb->Name == framebuffers[i]);
-
- /* check if deleting currently bound framebuffer object */
- if (ctx->Extensions.EXT_framebuffer_blit) {
- /* separate draw/read binding points */
- if (fb == ctx->DrawBuffer) {
- /* bind default */
- ASSERT(fb->RefCount >= 2);
- _mesa_BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
- }
- if (fb == ctx->ReadBuffer) {
- /* bind default */
- ASSERT(fb->RefCount >= 2);
- _mesa_BindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
- }
- }
- else {
- /* only one binding point for read/draw buffers */
- if (fb == ctx->DrawBuffer || fb == ctx->ReadBuffer) {
- /* bind default */
- ASSERT(fb->RefCount >= 2);
- _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- }
- }
-
- /* remove from hash table immediately, to free the ID */
- _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]);
-
- if (fb != &DummyFramebuffer) {
- /* But the object will not be freed until it's no longer
- * bound in any context.
- */
- _mesa_reference_framebuffer(&fb, NULL);
- }
- }
- }
- }
-}
-
-
-void GLAPIENTRY
-_mesa_GenFramebuffersEXT(GLsizei n, GLuint *framebuffers)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLuint first;
- GLint i;
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (n < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGenFramebuffersEXT(n)");
- return;
- }
-
- if (!framebuffers)
- return;
-
- first = _mesa_HashFindFreeKeyBlock(ctx->Shared->FrameBuffers, n);
-
- for (i = 0; i < n; i++) {
- GLuint name = first + i;
- framebuffers[i] = name;
- /* insert dummy placeholder into hash table */
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
- _mesa_HashInsert(ctx->Shared->FrameBuffers, name, &DummyFramebuffer);
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
- }
-}
-
-
-
-GLenum GLAPIENTRY
-_mesa_CheckFramebufferStatusEXT(GLenum target)
-{
- struct gl_framebuffer *buffer;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
-
- buffer = get_framebuffer_target(ctx, target);
- if (!buffer) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)");
- return 0;
- }
-
- if (is_winsys_fbo(buffer)) {
- /* The window system / default framebuffer is always complete */
- return GL_FRAMEBUFFER_COMPLETE_EXT;
- }
-
- /* No need to flush here */
-
- if (buffer->_Status != GL_FRAMEBUFFER_COMPLETE) {
- _mesa_test_framebuffer_completeness(ctx, buffer);
- }
-
- return buffer->_Status;
-}
-
-
-/**
- * Common code called by glFramebufferTexture1D/2D/3DEXT().
- */
-static void
-framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
- GLenum attachment, GLenum textarget, GLuint texture,
- GLint level, GLint zoffset)
-{
- struct gl_renderbuffer_attachment *att;
- struct gl_texture_object *texObj = NULL;
- struct gl_framebuffer *fb;
- GLenum maxLevelsTarget;
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- fb = get_framebuffer_target(ctx, target);
- if (!fb) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferTexture%sEXT(target=0x%x)", caller, target);
- return;
- }
-
- /* check framebuffer binding */
- if (is_winsys_fbo(fb)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture%sEXT", caller);
- return;
- }
-
- /* The textarget, level, and zoffset parameters are only validated if
- * texture is non-zero.
- */
- if (texture) {
- GLboolean err = GL_TRUE;
-
- texObj = _mesa_lookup_texture(ctx, texture);
- if (texObj != NULL) {
- if (textarget == 0) {
- /* XXX what's the purpose of this? */
- err = (texObj->Target != GL_TEXTURE_3D);
- }
- else {
- err = (texObj->Target == GL_TEXTURE_CUBE_MAP)
- ? !_mesa_is_cube_face(textarget)
- : (texObj->Target != textarget);
- }
- }
- else {
- /* can't render to a non-existant texture */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture%sEXT(non existant texture)",
- caller);
- return;
- }
-
- if (err) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture%sEXT(texture target mismatch)",
- caller);
- return;
- }
-
- if (texObj->Target == GL_TEXTURE_3D) {
- const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
- if (zoffset < 0 || zoffset >= maxSize) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferTexture%sEXT(zoffset)", caller);
- return;
- }
- }
-
- maxLevelsTarget = textarget ? textarget : texObj->Target;
- if ((level < 0) ||
- (level >= _mesa_max_texture_levels(ctx, maxLevelsTarget))) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferTexture%sEXT(level)", caller);
- return;
- }
- }
-
- att = _mesa_get_attachment(ctx, fb, attachment);
- if (att == NULL) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferTexture%sEXT(attachment)", caller);
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- _glthread_LOCK_MUTEX(fb->Mutex);
- if (texObj) {
- _mesa_set_texture_attachment(ctx, fb, att, texObj, textarget,
- level, zoffset);
-
- /* Set the render-to-texture flag. We'll check this flag in
- * glTexImage() and friends to determine if we need to revalidate
- * any FBOs that might be rendering into this texture.
- * This flag never gets cleared since it's non-trivial to determine
- * when all FBOs might be done rendering to this texture. That's OK
- * though since it's uncommon to render to a texture then repeatedly
- * call glTexImage() to change images in the texture.
- */
- texObj->_RenderToTexture = GL_TRUE;
- }
- else {
- _mesa_remove_attachment(ctx, att);
- }
-
- invalidate_framebuffer(fb);
-
- _glthread_UNLOCK_MUTEX(fb->Mutex);
-}
-
-
-
-void GLAPIENTRY
-_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
- GLenum textarget, GLuint texture, GLint level)
-{
- GET_CURRENT_CONTEXT(ctx);
-
- if (texture != 0) {
- GLboolean error;
-
- switch (textarget) {
- case GL_TEXTURE_1D:
- error = GL_FALSE;
- break;
- default:
- error = GL_TRUE;
- }
-
- if (error) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture1DEXT(textarget=%s)",
- _mesa_lookup_enum_by_nr(textarget));
- return;
- }
- }
-
- framebuffer_texture(ctx, "1D", target, attachment, textarget, texture,
- level, 0);
-}
-
-
-void GLAPIENTRY
-_mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
- GLenum textarget, GLuint texture, GLint level)
-{
- GET_CURRENT_CONTEXT(ctx);
-
- if (texture != 0) {
- GLboolean error;
-
- switch (textarget) {
- case GL_TEXTURE_2D:
- error = GL_FALSE;
- break;
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- error = !ctx->Extensions.ARB_texture_cube_map;
- break;
- default:
- error = GL_TRUE;
- }
-
- if (error) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture2DEXT(textarget=%s)",
- _mesa_lookup_enum_by_nr(textarget));
- return;
- }
- }
-
- framebuffer_texture(ctx, "2D", target, attachment, textarget, texture,
- level, 0);
-}
-
-
-void GLAPIENTRY
-_mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
- GLenum textarget, GLuint texture,
- GLint level, GLint zoffset)
-{
- GET_CURRENT_CONTEXT(ctx);
-
- if ((texture != 0) && (textarget != GL_TEXTURE_3D)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture3DEXT(textarget)");
- return;
- }
-
- framebuffer_texture(ctx, "3D", target, attachment, textarget, texture,
- level, zoffset);
-}
-
-
-void GLAPIENTRY
-_mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
- GLenum renderbufferTarget,
- GLuint renderbuffer)
-{
- struct gl_renderbuffer_attachment *att;
- struct gl_framebuffer *fb;
- struct gl_renderbuffer *rb;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- fb = get_framebuffer_target(ctx, target);
- if (!fb) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glFramebufferRenderbufferEXT(target)");
- return;
- }
-
- if (renderbufferTarget != GL_RENDERBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferRenderbufferEXT(renderbufferTarget)");
- return;
- }
-
- if (is_winsys_fbo(fb)) {
- /* Can't attach new renderbuffers to a window system framebuffer */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT");
- return;
- }
-
- att = _mesa_get_attachment(ctx, fb, attachment);
- if (att == NULL) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferRenderbufferEXT(invalid attachment %s)",
- _mesa_lookup_enum_by_nr(attachment));
- return;
- }
-
- if (renderbuffer) {
- rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
- if (!rb) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferRenderbufferEXT(non-existant"
- " renderbuffer %u)", renderbuffer);
- return;
- }
- else if (rb == &DummyRenderbuffer) {
- /* This is what NVIDIA does */
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferRenderbufferEXT(renderbuffer %u)",
- renderbuffer);
- return;
- }
- }
- else {
- /* remove renderbuffer attachment */
- rb = NULL;
- }
-
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- assert(ctx->Driver.FramebufferRenderbuffer);
- ctx->Driver.FramebufferRenderbuffer(ctx, fb, attachment, rb);
-
- /* Some subsequent GL commands may depend on the framebuffer's visual
- * after the binding is updated. Update visual info now.
- */
- _mesa_update_framebuffer_visual(ctx, fb);
-}
-
-
-void GLAPIENTRY
-_mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
- GLenum pname, GLint *params)
-{
- const struct gl_renderbuffer_attachment *att;
- struct gl_framebuffer *buffer;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- buffer = get_framebuffer_target(ctx, target);
- if (!buffer) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(target)");
- return;
- }
-
- if (is_winsys_fbo(buffer)) {
- /* Page 126 (page 136 of the PDF) of the OpenGL ES 2.0.25 spec
- * says:
- *
- * "If the framebuffer currently bound to target is zero, then
- * INVALID_OPERATION is generated."
- *
- * The EXT_framebuffer_object spec has the same wording, and the
- * OES_framebuffer_object spec refers to the EXT_framebuffer_object
- * spec.
- */
- if (!ctx->Extensions.ARB_framebuffer_object) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetFramebufferAttachmentParameteriv(bound FBO = 0)");
- return;
- }
- /* the default / window-system FBO */
- att = _mesa_get_fb0_attachment(ctx, buffer, attachment);
- }
- else {
- /* user-created framebuffer FBO */
- att = _mesa_get_attachment(ctx, buffer, attachment);
- }
-
- if (att == NULL) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(attachment)");
- return;
- }
-
- /* No need to flush here */
-
- switch (pname) {
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
- *params = is_winsys_fbo(buffer) ? GL_FRAMEBUFFER_DEFAULT : att->Type;
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
- if (att->Type == GL_RENDERBUFFER_EXT) {
- *params = att->Renderbuffer->Name;
- }
- else if (att->Type == GL_TEXTURE) {
- *params = att->Texture->Name;
- }
- else {
- assert(att->Type == GL_NONE);
- *params = 0;
- }
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT:
- if (att->Type == GL_TEXTURE) {
- *params = att->TextureLevel;
- }
- else if (att->Type == GL_NONE) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT:
- if (att->Type == GL_TEXTURE) {
- if (att->Texture && att->Texture->Target == GL_TEXTURE_CUBE_MAP) {
- *params = GL_TEXTURE_CUBE_MAP_POSITIVE_X + att->CubeMapFace;
- }
- else {
- *params = 0;
- }
- }
- else if (att->Type == GL_NONE) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT:
- if (att->Type == GL_TEXTURE) {
- if (att->Texture && att->Texture->Target == GL_TEXTURE_3D) {
- *params = att->Zoffset;
- }
- else {
- *params = 0;
- }
- }
- else if (att->Type == GL_NONE) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
- if (!ctx->Extensions.ARB_framebuffer_object) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- else if (att->Type == GL_NONE) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- else {
- /* According to ARB_framebuffer_sRGB, we should return LINEAR
- * if the sRGB conversion is unsupported. */
- *params = GL_LINEAR;
- }
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
- if (!ctx->Extensions.ARB_framebuffer_object) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- return;
- }
- else if (att->Type == GL_NONE) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- else {
- gl_format format = att->Renderbuffer->Format;
- if (format == MESA_FORMAT_S8) {
- /* special cases */
- *params = GL_INDEX;
- }
- else {
- *params = _mesa_get_format_datatype(format);
- }
- }
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
- if (!ctx->Extensions.ARB_framebuffer_object) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- else if (att->Type == GL_NONE) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- else if (att->Texture) {
- const struct gl_texture_image *texImage =
- _mesa_select_tex_image(ctx, att->Texture, att->Texture->Target,
- att->TextureLevel);
- if (texImage) {
- *params = get_component_bits(pname, texImage->_BaseFormat,
- texImage->TexFormat);
- }
- else {
- *params = 0;
- }
- }
- else if (att->Renderbuffer) {
- *params = get_component_bits(pname, att->Renderbuffer->_BaseFormat,
- att->Renderbuffer->Format);
- }
- else {
- _mesa_problem(ctx, "glGetFramebufferAttachmentParameterivEXT:"
- " invalid FBO attachment structure");
- }
- return;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- return;
- }
-}
-
-
-void GLAPIENTRY
-_mesa_GenerateMipmapEXT(GLenum target)
-{
- struct gl_texture_image *srcImage;
- struct gl_texture_object *texObj;
- GLboolean error;
-
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- switch (target) {
- case GL_TEXTURE_1D:
- case GL_TEXTURE_2D:
- case GL_TEXTURE_3D:
- error = GL_FALSE;
- break;
- case GL_TEXTURE_CUBE_MAP:
- error = !ctx->Extensions.ARB_texture_cube_map;
- break;
- default:
- error = GL_TRUE;
- }
-
- if (error) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target=%s)",
- _mesa_lookup_enum_by_nr(target));
- return;
- }
-
- texObj = _mesa_get_current_tex_object(ctx, target);
-
- if (texObj->BaseLevel >= texObj->MaxLevel) {
- /* nothing to do */
- return;
- }
-
- if (texObj->Target == GL_TEXTURE_CUBE_MAP &&
- !_mesa_cube_complete(texObj)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGenerateMipmap(incomplete cube map)");
- return;
- }
-
- _mesa_lock_texture(ctx, texObj);
-
- srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel);
- if (!srcImage) {
- _mesa_unlock_texture(ctx, texObj);
- return;
- }
-
- if (target == GL_TEXTURE_CUBE_MAP) {
- GLuint face;
- for (face = 0; face < 6; face++)
- ctx->Driver.GenerateMipmap(ctx,
- GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + face,
- texObj);
- }
- else {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
- _mesa_unlock_texture(ctx, texObj);
-}
-
-
-#if FEATURE_EXT_framebuffer_blit
-
-static const struct gl_renderbuffer_attachment *
-find_attachment(const struct gl_framebuffer *fb,
- const struct gl_renderbuffer *rb)
-{
- GLuint i;
- for (i = 0; i < Elements(fb->Attachment); i++) {
- if (fb->Attachment[i].Renderbuffer == rb)
- return &fb->Attachment[i];
- }
- return NULL;
-}
-
-
-/**
- * Helper function for checking if the datatypes of color buffers are
- * compatible for glBlitFramebuffer. From the 3.1 spec, page 198:
- *
- * "GL_INVALID_OPERATION is generated if mask contains GL_COLOR_BUFFER_BIT
- * and any of the following conditions hold:
- * - The read buffer contains fixed-point or floating-point values and any
- * draw buffer contains neither fixed-point nor floating-point values.
- * - The read buffer contains unsigned integer values and any draw buffer
- * does not contain unsigned integer values.
- * - The read buffer contains signed integer values and any draw buffer
- * does not contain signed integer values."
- */
-static GLboolean
-compatible_color_datatypes(gl_format srcFormat, gl_format dstFormat)
-{
- GLenum srcType = _mesa_get_format_datatype(srcFormat);
- GLenum dstType = _mesa_get_format_datatype(dstFormat);
-
- if (srcType != GL_INT && srcType != GL_UNSIGNED_INT) {
- assert(srcType == GL_UNSIGNED_NORMALIZED ||
- srcType == GL_SIGNED_NORMALIZED ||
- srcType == GL_FLOAT);
- /* Boil any of those types down to GL_FLOAT */
- srcType = GL_FLOAT;
- }
-
- if (dstType != GL_INT && dstType != GL_UNSIGNED_INT) {
- assert(dstType == GL_UNSIGNED_NORMALIZED ||
- dstType == GL_SIGNED_NORMALIZED ||
- dstType == GL_FLOAT);
- /* Boil any of those types down to GL_FLOAT */
- dstType = GL_FLOAT;
- }
-
- return srcType == dstType;
-}
-
-
-/**
- * Blit rectangular region, optionally from one framebuffer to another.
- *
- * Note, if the src buffer is multisampled and the dest is not, this is
- * when the samples must be resolved to a single color.
- */
-void GLAPIENTRY
-_mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
-{
- const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
- GL_DEPTH_BUFFER_BIT |
- GL_STENCIL_BUFFER_BIT);
- const struct gl_framebuffer *readFb, *drawFb;
- const struct gl_renderbuffer *colorReadRb, *colorDrawRb;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx,
- "glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d, 0x%x, %s)\n",
- srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1,
- mask, _mesa_lookup_enum_by_nr(filter));
-
- if (ctx->NewState) {
- _mesa_update_state(ctx);
- }
-
- readFb = ctx->ReadBuffer;
- drawFb = ctx->DrawBuffer;
-
- if (!readFb || !drawFb) {
- /* This will normally never happen but someday we may want to
- * support MakeCurrent() with no drawables.
- */
- return;
- }
-
- /* check for complete framebuffers */
- if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
- readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glBlitFramebufferEXT(incomplete draw/read buffers)");
- return;
- }
-
- if (filter != GL_NEAREST && filter != GL_LINEAR) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlitFramebufferEXT(filter)");
- return;
- }
-
- if (mask & ~legalMaskBits) {
- _mesa_error( ctx, GL_INVALID_VALUE, "glBlitFramebufferEXT(mask)");
- return;
- }
-
- /* depth/stencil must be blitted with nearest filtering */
- if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
- && filter != GL_NEAREST) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(depth/stencil requires GL_NEAREST filter)");
- return;
- }
-
- /* get color read/draw renderbuffers */
- if (mask & GL_COLOR_BUFFER_BIT) {
- colorReadRb = readFb->_ColorReadBuffer;
- colorDrawRb = drawFb->_ColorDrawBuffer;
-
- /* From the EXT_framebuffer_object spec:
- *
- * "If a buffer is specified in <mask> and does not exist in both
- * the read and draw framebuffers, the corresponding bit is silently
- * ignored."
- */
- if ((colorReadRb == NULL) || (colorDrawRb == NULL)) {
- colorReadRb = colorDrawRb = NULL;
- mask &= ~GL_COLOR_BUFFER_BIT;
- }
- else if (!compatible_color_datatypes(colorReadRb->Format,
- colorDrawRb->Format)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(color buffer datatypes mismatch)");
- return;
- }
- }
- else {
- colorReadRb = colorDrawRb = NULL;
- }
-
- if (mask & GL_STENCIL_BUFFER_BIT) {
- struct gl_renderbuffer *readRb =
- readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
- struct gl_renderbuffer *drawRb =
- drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;
-
- /* From the EXT_framebuffer_object spec:
- *
- * "If a buffer is specified in <mask> and does not exist in both
- * the read and draw framebuffers, the corresponding bit is silently
- * ignored."
- */
- if ((readRb == NULL) || (drawRb == NULL)) {
- mask &= ~GL_STENCIL_BUFFER_BIT;
- }
- else if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
- _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
- /* There is no need to check the stencil datatype here, because
- * there is only one: GL_UNSIGNED_INT.
- */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(stencil buffer size mismatch)");
- return;
- }
- }
-
- if (mask & GL_DEPTH_BUFFER_BIT) {
- struct gl_renderbuffer *readRb =
- readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
- struct gl_renderbuffer *drawRb =
- drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
-
- /* From the EXT_framebuffer_object spec:
- *
- * "If a buffer is specified in <mask> and does not exist in both
- * the read and draw framebuffers, the corresponding bit is silently
- * ignored."
- */
- if ((readRb == NULL) || (drawRb == NULL)) {
- mask &= ~GL_DEPTH_BUFFER_BIT;
- }
- else if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
- _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) ||
- (_mesa_get_format_datatype(readRb->Format) !=
- _mesa_get_format_datatype(drawRb->Format))) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(depth buffer format mismatch)");
- return;
- }
- }
-
- if (readFb->Visual.samples > 0 &&
- drawFb->Visual.samples > 0 &&
- readFb->Visual.samples != drawFb->Visual.samples) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(mismatched samples)");
- return;
- }
-
- /* extra checks for multisample copies... */
- if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) {
- /* src and dest region sizes must be the same */
- if (srcX1 - srcX0 != dstX1 - dstX0 ||
- srcY1 - srcY0 != dstY1 - dstY0) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(bad src/dst multisample region sizes)");
- return;
- }
-
- /* color formats must match */
- if (colorReadRb &&
- colorDrawRb &&
- colorReadRb->Format != colorDrawRb->Format) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(bad src/dst multisample pixel formats)");
- return;
- }
- }
-
- if (filter == GL_LINEAR && (mask & GL_COLOR_BUFFER_BIT)) {
- /* 3.1 spec, page 199:
- * "Calling BlitFramebuffer will result in an INVALID_OPERATION error
- * if filter is LINEAR and read buffer contains integer data."
- */
- GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
- if (type == GL_INT || type == GL_UNSIGNED_INT) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(integer color type)");
- return;
- }
- }
-
- if (!ctx->Extensions.EXT_framebuffer_blit) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT");
- return;
- }
-
- /* Debug code */
- if (DEBUG_BLIT) {
- printf("glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d,"
- " 0x%x, 0x%x)\n",
- srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1,
- mask, filter);
- if (colorReadRb) {
- const struct gl_renderbuffer_attachment *att;
-
- att = find_attachment(readFb, colorReadRb);
- printf(" Src FBO %u RB %u (%dx%d) ",
- readFb->Name, colorReadRb->Name,
- colorReadRb->Width, colorReadRb->Height);
- if (att && att->Texture) {
- printf("Tex %u tgt 0x%x level %u face %u",
- att->Texture->Name,
- att->Texture->Target,
- att->TextureLevel,
- att->CubeMapFace);
- }
- printf("\n");
-
- att = find_attachment(drawFb, colorDrawRb);
- printf(" Dst FBO %u RB %u (%dx%d) ",
- drawFb->Name, colorDrawRb->Name,
- colorDrawRb->Width, colorDrawRb->Height);
- if (att && att->Texture) {
- printf("Tex %u tgt 0x%x level %u face %u",
- att->Texture->Name,
- att->Texture->Target,
- att->TextureLevel,
- att->CubeMapFace);
- }
- printf("\n");
- }
- }
-
- if (!mask) {
- return;
- }
-
- ASSERT(ctx->Driver.BlitFramebuffer);
- ctx->Driver.BlitFramebuffer(ctx,
- srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1,
- mask, filter);
-}
-#endif /* FEATURE_EXT_framebuffer_blit */
-
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#ifndef FBOBJECT_H
-#define FBOBJECT_H
-
-#include "compiler.h"
-#include "glheader.h"
-
-struct gl_context;
-struct gl_texture_object;
-
-extern void
-_mesa_init_fbobjects(struct gl_context *ctx);
-
-extern struct gl_framebuffer *
-_mesa_get_incomplete_framebuffer(void);
-
-extern struct gl_renderbuffer *
-_mesa_lookup_renderbuffer(struct gl_context *ctx, GLuint id);
-
-extern struct gl_framebuffer *
-_mesa_lookup_framebuffer(struct gl_context *ctx, GLuint id);
-
-extern struct gl_renderbuffer_attachment *
-_mesa_get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
- GLenum attachment);
-
-
-/** Return the texture image for a renderbuffer attachment */
-static inline struct gl_texture_image *
-_mesa_get_attachment_teximage(struct gl_renderbuffer_attachment *att)
-{
- assert(att->Type == GL_TEXTURE);
- return att->Texture->Image[att->CubeMapFace][att->TextureLevel];
-}
-
-
-/** Return the (const) texture image for a renderbuffer attachment */
-static inline const struct gl_texture_image *
-_mesa_get_attachment_teximage_const(const struct gl_renderbuffer_attachment *att)
-{
- assert(att->Type == GL_TEXTURE);
- return att->Texture->Image[att->CubeMapFace][att->TextureLevel];
-}
-
-
-extern void
-_mesa_remove_attachment(struct gl_context *ctx,
- struct gl_renderbuffer_attachment *att);
-
-extern void
-_mesa_set_texture_attachment(struct gl_context *ctx,
- struct gl_framebuffer *fb,
- struct gl_renderbuffer_attachment *att,
- struct gl_texture_object *texObj,
- GLenum texTarget, GLuint level, GLuint zoffset);
-
-extern void
-_mesa_set_renderbuffer_attachment(struct gl_context *ctx,
- struct gl_renderbuffer_attachment *att,
- struct gl_renderbuffer *rb);
-
-extern void
-_mesa_framebuffer_renderbuffer(struct gl_context *ctx,
- struct gl_framebuffer *fb,
- GLenum attachment, struct gl_renderbuffer *rb);
-
-extern void
-_mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb);
-
-extern void
-_mesa_test_framebuffer_completeness(struct gl_context *ctx,
- struct gl_framebuffer *fb);
-
-extern GLboolean
-_mesa_is_legal_color_format(const struct gl_context *ctx, GLenum baseFormat);
-
-extern GLenum
-_mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat);
-
-extern GLboolean GLAPIENTRY
-_mesa_IsRenderbufferEXT(GLuint renderbuffer);
-
-extern void GLAPIENTRY
-_mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer);
-
-extern void GLAPIENTRY
-_mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers);
-
-extern void GLAPIENTRY
-_mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers);
-
-extern void GLAPIENTRY
-_mesa_RenderbufferStorageEXT(GLenum target, GLenum internalformat,
- GLsizei width, GLsizei height);
-
-extern void GLAPIENTRY
-_mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples,
- GLenum internalformat,
- GLsizei width, GLsizei height);
-
-extern void GLAPIENTRY
-_es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
- GLsizei width, GLsizei height);
-
-extern void GLAPIENTRY
-_mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);
-
-extern void GLAPIENTRY
-_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname,
- GLint *params);
-
-extern GLboolean GLAPIENTRY
-_mesa_IsFramebufferEXT(GLuint framebuffer);
-
-extern void GLAPIENTRY
-_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer);
-
-extern void GLAPIENTRY
-_mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers);
-
-extern void GLAPIENTRY
-_mesa_GenFramebuffersEXT(GLsizei n, GLuint *framebuffers);
-
-extern GLenum GLAPIENTRY
-_mesa_CheckFramebufferStatusEXT(GLenum target);
-
-extern void GLAPIENTRY
-_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
- GLenum textarget, GLuint texture, GLint level);
-
-extern void GLAPIENTRY
-_mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
- GLenum textarget, GLuint texture, GLint level);
-
-extern void GLAPIENTRY
-_mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
- GLenum textarget, GLuint texture,
- GLint level, GLint zoffset);
-
-extern void GLAPIENTRY
-_mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
- GLenum renderbuffertarget,
- GLuint renderbuffer);
-
-extern void GLAPIENTRY
-_mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
- GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GenerateMipmapEXT(GLenum target);
-
-
-extern void GLAPIENTRY
-_mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter);
-
-
-#endif /* FBOBJECT_H */
if (TEST_EQ_4V(ctx->Fog.Color, params))
return;
FLUSH_VERTICES(ctx, _NEW_FOG);
- ctx->Fog.ColorUnclamped[0] = params[0];
- ctx->Fog.ColorUnclamped[1] = params[1];
- ctx->Fog.ColorUnclamped[2] = params[2];
- ctx->Fog.ColorUnclamped[3] = params[3];
- ctx->Fog.Color[0] = CLAMP(params[0], 0.0F, 1.0F);
- ctx->Fog.Color[1] = CLAMP(params[1], 0.0F, 1.0F);
- ctx->Fog.Color[2] = CLAMP(params[2], 0.0F, 1.0F);
- ctx->Fog.Color[3] = CLAMP(params[3], 0.0F, 1.0F);
+ ctx->Fog.Color[0] = params[0];
+ ctx->Fog.Color[1] = params[1];
+ ctx->Fog.Color[2] = params[2];
+ ctx->Fog.Color[3] = params[3];
break;
case GL_FOG_COORDINATE_SOURCE_EXT: {
GLenum p = (GLenum) (GLint) *params;
ctx->Fog.Enabled = GL_FALSE;
ctx->Fog.Mode = GL_EXP;
ASSIGN_4V( ctx->Fog.Color, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( ctx->Fog.ColorUnclamped, 0.0, 0.0, 0.0, 0.0 );
ctx->Fog.Index = 0.0;
ctx->Fog.Density = 1.0;
ctx->Fog.Start = 0.0;
#include "formats.h"
#include "macros.h"
#include "mtypes.h"
-#include "fbobject.h"
#include "framebuffer.h"
#include "renderbuffer.h"
#include "texobj.h"
}
-/**
- * Allocate a new gl_framebuffer object.
- * This is the default function for ctx->Driver.NewFramebuffer().
- * This is for allocating user-created framebuffers, not window-system
- * framebuffers!
- * \sa _mesa_create_framebuffer
- */
-struct gl_framebuffer *
-_mesa_new_framebuffer(struct gl_context *ctx, GLuint name)
-{
- struct gl_framebuffer *fb;
- (void) ctx;
- assert(name != 0);
- fb = CALLOC_STRUCT(gl_framebuffer);
- if (fb) {
- _mesa_initialize_user_framebuffer(fb, name);
- }
- return fb;
-}
-
-
/**
* Initialize a gl_framebuffer object. Typically used to initialize
* window system-created framebuffers, not user-created framebuffers.
}
fb->Delete = _mesa_destroy_framebuffer;
- fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
compute_depth_max(fb);
}
-/**
- * Initialize a user-created gl_framebuffer object.
- * \sa _mesa_initialize_window_framebuffer
- */
-void
-_mesa_initialize_user_framebuffer(struct gl_framebuffer *fb, GLuint name)
-{
- assert(fb);
- assert(name);
-
- memset(fb, 0, sizeof(struct gl_framebuffer));
-
- fb->Name = name;
- fb->RefCount = 1;
- 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;
- _glthread_INIT_MUTEX(fb->Mutex);
-}
-
-
/**
* Deallocate buffer and everything attached to it.
* Typically called via the gl_framebuffer->Delete() method.
if (att->Renderbuffer) {
_mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
}
- if (att->Texture) {
- _mesa_reference_texobj(&att->Texture, NULL);
- }
- ASSERT(!att->Renderbuffer);
- ASSERT(!att->Texture);
- att->Type = GL_NONE;
}
}
GLuint width, GLuint height)
{
GLuint i;
-
- /* XXX I think we could check if the size is not changing
- * and return early.
- */
-
- /* For window system framebuffers, Name is zero */
- assert(fb->Name == 0);
-
for (i = 0; i < BUFFER_COUNT; i++) {
struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
- if (att->Type == GL_RENDERBUFFER_EXT && att->Renderbuffer) {
+ if (att->Renderbuffer) {
struct gl_renderbuffer *rb = att->Renderbuffer;
/* only resize if size is changing */
if (rb->Width != width || rb->Height != height) {
GLuint newWidth, newHeight;
struct gl_framebuffer *buffer = ctx->WinSysDrawBuffer;
- assert(buffer->Name == 0);
-
/* ask device driver for size of output buffer */
ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight );
GLuint newWidth, newHeight;
struct gl_framebuffer *buffer = ctx->WinSysReadBuffer;
- assert(buffer->Name == 0);
-
/* ask device driver for size of read buffer */
ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight );
ctx->NewState |= _NEW_BUFFERS; /* to update scissor / window bounds */
}
-
-/*
- * XXX THIS IS OBSOLETE
- */
-void GLAPIENTRY
-_mesa_ResizeBuffersMESA( void )
-{
- GET_CURRENT_CONTEXT(ctx);
-
- if (ctx->Extensions.MESA_resize_buffers)
- _mesa_resizebuffers( ctx );
-}
-
-
-
-/**
- * Examine all the framebuffer's renderbuffers to update the Width/Height
- * fields of the framebuffer. If we have renderbuffers with different
- * sizes, set the framebuffer's width and height to the min size.
- * Note: this is only intended for user-created framebuffers, not
- * window-system framebuffes.
- */
-static void
-update_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb)
-{
- GLuint minWidth = ~0, minHeight = ~0;
- GLuint i;
-
- /* user-created framebuffers only */
- assert(fb->Name);
-
- for (i = 0; i < BUFFER_COUNT; i++) {
- struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
- const struct gl_renderbuffer *rb = att->Renderbuffer;
- if (rb) {
- minWidth = MIN2(minWidth, rb->Width);
- minHeight = MIN2(minHeight, rb->Height);
- }
- }
-
- if (minWidth != ~0) {
- fb->Width = minWidth;
- fb->Height = minHeight;
- }
- else {
- fb->Width = 0;
- fb->Height = 0;
- }
-}
-
-
/**
* Update the context's current drawing buffer's Xmin, Xmax, Ymin, Ymax fields.
* These values are computed from the buffer's width and height and
if (!buffer)
return;
- if (buffer->Name) {
- /* user-created framebuffer size depends on the renderbuffers */
- update_framebuffer_size(ctx, buffer);
- }
-
buffer->_Xmin = 0;
buffer->_Ymin = 0;
buffer->_Xmax = buffer->Width;
ASSERT(buffer->_Ymin <= buffer->_Ymax);
}
-
-/**
- * The glGet queries of the framebuffer red/green/blue size, stencil size,
- * etc. are satisfied by the fields of ctx->DrawBuffer->Visual. These can
- * change depending on the renderbuffer bindings. This function updates
- * the given framebuffer's Visual from the current renderbuffer bindings.
- *
- * This may apply to user-created framebuffers or window system framebuffers.
- *
- * Also note: ctx->DrawBuffer->Visual.depthBits might not equal
- * ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer.DepthBits.
- * The former one is used to convert floating point depth values into
- * integer Z values.
- */
-void
-_mesa_update_framebuffer_visual(struct gl_context *ctx,
- struct gl_framebuffer *fb)
-{
- GLuint i;
-
- memset(&fb->Visual, 0, sizeof(fb->Visual));
- fb->Visual.rgbMode = GL_TRUE; /* assume this */
-
-#if 0 /* this _might_ be needed */
- if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- /* leave visual fields zero'd */
- return;
- }
-#endif
-
- /* find first RGB renderbuffer */
- for (i = 0; i < BUFFER_COUNT; i++) {
- if (fb->Attachment[i].Renderbuffer) {
- const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
- const GLenum baseFormat = _mesa_get_format_base_format(rb->Format);
- const gl_format fmt = rb->Format;
-
- if (_mesa_is_legal_color_format(ctx, baseFormat)) {
- fb->Visual.redBits = _mesa_get_format_bits(fmt, GL_RED_BITS);
- fb->Visual.greenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS);
- fb->Visual.blueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS);
- fb->Visual.alphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS);
- fb->Visual.rgbBits = fb->Visual.redBits
- + fb->Visual.greenBits + fb->Visual.blueBits;
- fb->Visual.samples = rb->NumSamples;
- fb->Visual.sampleBuffers = rb->NumSamples > 0 ? 1 : 0;
- break;
- }
- }
- }
-
- fb->Visual.floatMode = GL_FALSE;
- for (i = 0; i < BUFFER_COUNT; i++) {
- if (fb->Attachment[i].Renderbuffer) {
- const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
- const gl_format fmt = rb->Format;
-
- if (_mesa_get_format_datatype(fmt) == GL_FLOAT) {
- fb->Visual.floatMode = GL_TRUE;
- break;
- }
- }
- }
-
- if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) {
- const struct gl_renderbuffer *rb =
- fb->Attachment[BUFFER_DEPTH].Renderbuffer;
- const gl_format fmt = rb->Format;
- fb->Visual.haveDepthBuffer = GL_TRUE;
- fb->Visual.depthBits = _mesa_get_format_bits(fmt, GL_DEPTH_BITS);
- }
-
- if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) {
- const struct gl_renderbuffer *rb =
- fb->Attachment[BUFFER_STENCIL].Renderbuffer;
- const gl_format fmt = rb->Format;
- fb->Visual.haveStencilBuffer = GL_TRUE;
- fb->Visual.stencilBits = _mesa_get_format_bits(fmt, GL_STENCIL_BITS);
- }
-
- if (fb->Attachment[BUFFER_ACCUM].Renderbuffer) {
- const struct gl_renderbuffer *rb =
- fb->Attachment[BUFFER_ACCUM].Renderbuffer;
- const gl_format fmt = rb->Format;
- fb->Visual.haveAccumBuffer = GL_TRUE;
- fb->Visual.accumRedBits = _mesa_get_format_bits(fmt, GL_RED_BITS);
- fb->Visual.accumGreenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS);
- fb->Visual.accumBlueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS);
- fb->Visual.accumAlphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS);
- }
-
- compute_depth_max(fb);
-}
-
-
/*
* Example DrawBuffers scenarios:
*
static void
update_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
{
- if (fb->Name == 0) {
- /* This is a window-system framebuffer */
- /* Need to update the FB's GL_DRAW_BUFFER state to match the
- * context state (GL_READ_BUFFER too).
- */
- _mesa_drawbuffer(ctx, ctx->Color.DrawBuffer, 0);
- }
- else {
- /* This is a user-created framebuffer.
- * Completeness only matters for user-created framebuffers.
- */
- if (fb->_Status != GL_FRAMEBUFFER_COMPLETE) {
- _mesa_test_framebuffer_completeness(ctx, fb);
- }
- }
+ _mesa_drawbuffer(ctx, ctx->Color.DrawBuffer, 0);
/* Strictly speaking, we don't need to update the draw-state
* if this FB is bound as ctx->ReadBuffer (and conversely, the
{
const struct gl_renderbuffer_attachment *att = fb->Attachment;
- /* If we don't know the framebuffer status, update it now */
- if (fb->_Status == 0) {
- _mesa_test_framebuffer_completeness(ctx, fb);
- }
-
- if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- return GL_FALSE;
- }
-
switch (format) {
case GL_COLOR:
case GL_RED:
break;
case GL_DEPTH:
case GL_DEPTH_COMPONENT:
- if (att[BUFFER_DEPTH].Type == GL_NONE) {
+ if (att[BUFFER_DEPTH].Renderbuffer == NULL) {
return GL_FALSE;
}
break;
case GL_STENCIL:
case GL_STENCIL_INDEX:
- if (att[BUFFER_STENCIL].Type == GL_NONE) {
+ if (att[BUFFER_STENCIL].Renderbuffer == NULL) {
return GL_FALSE;
}
break;
}
-/**
- * Print framebuffer info to stderr, for debugging.
- */
-void
-_mesa_print_framebuffer(const struct gl_framebuffer *fb)
-{
- GLuint i;
-
- fprintf(stderr, "Mesa Framebuffer %u at %p\n", fb->Name, (void *) fb);
- fprintf(stderr, " Size: %u x %u Status: %s\n", fb->Width, fb->Height,
- _mesa_lookup_enum_by_nr(fb->_Status));
- fprintf(stderr, " Attachments:\n");
-
- for (i = 0; i < BUFFER_COUNT; i++) {
- const struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
- if (att->Type == GL_TEXTURE) {
- const struct gl_texture_image *texImage =
- _mesa_get_attachment_teximage_const(att);
- fprintf(stderr,
- " %2d: Texture %u, level %u, face %u, slice %u, complete %d\n",
- i, att->Texture->Name, att->TextureLevel, att->CubeMapFace,
- att->Zoffset, att->Complete);
- fprintf(stderr, " Size: %u x %u x %u Format %s\n",
- texImage->Width, texImage->Height, texImage->Depth,
- _mesa_get_format_name(texImage->TexFormat));
- }
- else if (att->Type == GL_RENDERBUFFER) {
- fprintf(stderr, " %2d: Renderbuffer %u, complete %d\n",
- i, att->Renderbuffer->Name, att->Complete);
- fprintf(stderr, " Size: %u x %u Format %s\n",
- att->Renderbuffer->Width, att->Renderbuffer->Height,
- _mesa_get_format_name(att->Renderbuffer->Format));
- }
- else {
- fprintf(stderr, " %2d: none\n", i);
- }
- }
-}
extern struct gl_framebuffer *
_mesa_create_framebuffer(const struct gl_config *visual);
-extern struct gl_framebuffer *
-_mesa_new_framebuffer(struct gl_context *ctx, GLuint name);
-
extern void
_mesa_initialize_window_framebuffer(struct gl_framebuffer *fb,
const struct gl_config *visual);
-extern void
-_mesa_initialize_user_framebuffer(struct gl_framebuffer *fb, GLuint name);
-
extern void
_mesa_destroy_framebuffer(struct gl_framebuffer *buffer);
extern void
_mesa_resizebuffers( struct gl_context *ctx );
-extern void GLAPIENTRY
-_mesa_ResizeBuffersMESA( void );
-
extern void
_mesa_update_draw_buffer_bounds(struct gl_context *ctx);
-extern void
-_mesa_update_framebuffer_visual(struct gl_context *ctx,
- struct gl_framebuffer *fb);
-
extern void
_mesa_update_framebuffer(struct gl_context *ctx);
extern GLenum
_mesa_get_color_read_format(struct gl_context *ctx);
-extern void
-_mesa_print_framebuffer(const struct gl_framebuffer *fb);
-
#endif /* FRAMEBUFFER_H */
EXTRA_VERSION_30,
EXTRA_VERSION_31,
EXTRA_VERSION_32,
- EXTRA_NEW_BUFFERS,
- EXTRA_NEW_FRAG_CLAMP,
+ EXTRA_NEW_BUFFERS,
EXTRA_VALID_TEXTURE_UNIT,
EXTRA_VALID_CLIP_DISTANCE,
EXTRA_FLUSH_CURRENT,
EXTRA_END
};
-static const int extra_new_frag_clamp[] = {
- EXTRA_NEW_FRAG_CLAMP,
- EXTRA_END
-};
-
static const int extra_valid_texture_unit[] = {
EXTRA_VALID_TEXTURE_UNIT,
EXTRA_END
EXTRA_EXT(EXT_stencil_two_side);
EXTRA_EXT(NV_light_max_exponent);
EXTRA_EXT(EXT_depth_bounds_test);
-EXTRA_EXT(EXT_framebuffer_blit);
EXTRA_EXT(ARB_shader_objects);
EXTRA_EXT(ARB_fragment_shader);
EXTRA_EXT(ARB_fragment_program);
-EXTRA_EXT2(ARB_framebuffer_object, EXT_framebuffer_multisample);
-EXTRA_EXT(EXT_framebuffer_object);
EXTRA_EXT(APPLE_vertex_array_object);
EXTRA_EXT(EXT_compiled_vertex_array);
EXTRA_EXT(ARB_vertex_shader);
EXTRA_EXT2(ARB_fragment_program, NV_fragment_program);
EXTRA_EXT2(ARB_vertex_program, NV_vertex_program);
EXTRA_EXT2(ARB_vertex_program, ARB_fragment_program);
-EXTRA_EXT(ARB_color_buffer_float);
static const int
extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program[] = {
{ GL_BLEND, CONTEXT_BIT0(Color.BlendEnabled), 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_CLEAR_VALUE, LOC_CUSTOM, TYPE_FLOATN_4, 0, NO_EXTRA },
{ GL_COLOR_WRITEMASK, LOC_CUSTOM, TYPE_INT_4, 0, NO_EXTRA },
{ GL_CULL_FACE, CONTEXT_BOOL(Polygon.CullFlag), NO_EXTRA },
{ GL_CULL_FACE_MODE, CONTEXT_ENUM(Polygon.CullFaceMode), NO_EXTRA },
CONTEXT_FLOAT(Multisample.SampleCoverageValue), NO_EXTRA },
{ GL_SAMPLE_COVERAGE_INVERT_ARB,
CONTEXT_BOOL(Multisample.SampleCoverageInvert), NO_EXTRA },
- { GL_SAMPLE_BUFFERS_ARB, BUFFER_INT(Visual.sampleBuffers), NO_EXTRA },
- { GL_SAMPLES_ARB, BUFFER_INT(Visual.samples), NO_EXTRA },
-
- /* GL_SGIS_generate_mipmap */
- { GL_GENERATE_MIPMAP_HINT_SGIS, CONTEXT_ENUM(Hint.GenerateMipmap), NO_EXTRA },
/* GL_ARB_vertex_buffer_object */
{ GL_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
/* GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB - not supported */
{ GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
- /* GL_ARB_color_buffer_float */
- { GL_CLAMP_VERTEX_COLOR, CONTEXT_ENUM(Light.ClampVertexColor), extra_ARB_color_buffer_float },
- { GL_CLAMP_FRAGMENT_COLOR, CONTEXT_ENUM(Color.ClampFragmentColor), extra_ARB_color_buffer_float },
- { GL_CLAMP_READ_COLOR, CONTEXT_ENUM(Color.ClampReadColor), extra_ARB_color_buffer_float },
-
/* GL_OES_read_format */
{ GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, LOC_CUSTOM, TYPE_INT, 0,
extra_new_buffers },
{ GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, LOC_CUSTOM, TYPE_INT, 0,
extra_new_buffers },
- /* GL_EXT_framebuffer_object */
- { GL_FRAMEBUFFER_BINDING_EXT, BUFFER_INT(Name),
- extra_EXT_framebuffer_object },
- { GL_RENDERBUFFER_BINDING_EXT, LOC_CUSTOM, TYPE_INT, 0,
- extra_EXT_framebuffer_object },
- { GL_MAX_RENDERBUFFER_SIZE_EXT, CONTEXT_INT(Const.MaxRenderbufferSize),
- extra_EXT_framebuffer_object },
-
/* This entry isn't spec'ed for GLES 2, but is needed for Mesa's
* GLSL: */
{ GL_MAX_CLIP_PLANES, CONTEXT_INT(Const.MaxClipPlanes), NO_EXTRA },
{ GL_LIGHT_MODEL_TWO_SIDE, CONTEXT_BOOL(Light.Model.TwoSide), 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_ALPHA_TEST_REF, LOC_CUSTOM, TYPE_FLOATN, 0, 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 },
extra_flush_current_valid_texture_unit },
{ GL_DISTANCE_ATTENUATION_EXT, CONTEXT_FLOAT3(Point.Params[0]), NO_EXTRA },
{ GL_FOG, CONTEXT_BOOL(Fog.Enabled), NO_EXTRA },
- { GL_FOG_COLOR, LOC_CUSTOM, TYPE_FLOATN_4, 0, extra_new_frag_clamp },
+ { GL_FOG_COLOR, LOC_CUSTOM, TYPE_FLOATN_4, 0, NO_EXTRA },
{ GL_FOG_DENSITY, CONTEXT_FLOAT(Fog.Density), NO_EXTRA },
{ GL_FOG_END, CONTEXT_FLOAT(Fog.End), NO_EXTRA },
{ GL_FOG_HINT, CONTEXT_ENUM(Hint.Fog), NO_EXTRA },
{ GL_MAX_VARYING_FLOATS_ARB, LOC_CUSTOM, TYPE_INT, 0,
extra_ARB_vertex_shader },
- /* GL_EXT_texture_lod_bias */
- { GL_MAX_TEXTURE_LOD_BIAS_EXT, CONTEXT_FLOAT(Const.MaxTextureLodBias),
- NO_EXTRA },
-
/* GL_EXT_texture_filter_anisotropic */
{ GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,
CONTEXT_FLOAT(Const.MaxTextureMaxAnisotropy),
CONTEXT_INT(Const.MaxTextureCoordUnits),
extra_ARB_fragment_program_NV_fragment_program },
- /* GL_EXT_framebuffer_object / GL_NV_fbo_color_attachments */
- { GL_MAX_COLOR_ATTACHMENTS, CONTEXT_INT(Const.MaxColorAttachments),
- extra_EXT_framebuffer_object },
-
- { GL_BLEND_COLOR_EXT, LOC_CUSTOM, TYPE_FLOATN_4, 0, extra_new_frag_clamp },
+ { GL_BLEND_COLOR_EXT, LOC_CUSTOM, TYPE_FLOATN_4, 0, NO_EXTRA },
/* GL_ARB_fragment_program */
{ GL_MAX_TEXTURE_IMAGE_UNITS_ARB, /* == GL_MAX_TEXTURE_IMAGE_UNITS_NV */
CONTEXT_INT(Const.MaxTextureImageUnits),
{ GL_EDGE_FLAG_ARRAY_STRIDE, ARRAY_INT(VertexAttrib[VERT_ATTRIB_EDGEFLAG].Stride), NO_EXTRA },
{ GL_EDGE_FLAG_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA },
- /* GL_ARB_texture_compression */
- { GL_TEXTURE_COMPRESSION_HINT_ARB, CONTEXT_INT(Hint.TextureCompression), NO_EXTRA },
-
/* GL_EXT_compiled_vertex_array */
{ GL_ARRAY_ELEMENT_LOCK_FIRST_EXT, CONTEXT_INT(Array.LockFirst),
extra_EXT_compiled_vertex_array },
{ GL_DEPTH_BOUNDS_EXT, CONTEXT_FLOAT2(Depth.BoundsMin),
extra_EXT_depth_bounds_test },
- /* GL_EXT_framebuffer_blit
- * NOTE: GL_DRAW_FRAMEBUFFER_BINDING_EXT == GL_FRAMEBUFFER_BINDING_EXT */
- { GL_READ_FRAMEBUFFER_BINDING_EXT, LOC_CUSTOM, TYPE_INT, 0,
- extra_EXT_framebuffer_blit },
-
- /* GL_ARB_framebuffer_object */
- { GL_MAX_SAMPLES, CONTEXT_INT(Const.MaxSamples),
- extra_ARB_framebuffer_object_EXT_framebuffer_multisample },
-
/* GL_APPLE_vertex_array_object */
{ GL_VERTEX_ARRAY_BINDING_APPLE, ARRAY_INT(Name),
extra_APPLE_vertex_array_object },
{ GL_RGBA_INTEGER_MODE_EXT, BUFFER_BOOL(_IntegerColor),
extra_EXT_texture_integer },
- /* GL_ARB_color_buffer_float */
- { GL_RGBA_FLOAT_MODE_ARB, BUFFER_FIELD(Visual.floatMode, TYPE_BOOLEAN), 0 },
-
/* GL_EXT_gpu_shader4 / GLSL 1.30 */
{ GL_MIN_PROGRAM_TEXEL_OFFSET,
CONTEXT_INT(Const.MinProgramTexelOffset),
v->value_int =
ctx->Shader.ActiveProgram ? ctx->Shader.ActiveProgram->Name : 0;
break;
- case GL_READ_FRAMEBUFFER_BINDING_EXT:
- v->value_int = ctx->ReadBuffer->Name;
- break;
- case GL_RENDERBUFFER_BINDING_EXT:
- v->value_int =
- ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0;
- break;
case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
v->value_int = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POINT_SIZE].BufferObj->Name;
break;
case GL_FOG_COLOR:
- if(ctx->Color._ClampFragmentColor)
- COPY_4FV(v->value_float_4, ctx->Fog.Color);
- else
- COPY_4FV(v->value_float_4, ctx->Fog.ColorUnclamped);
+ COPY_4FV(v->value_float_4, ctx->Fog.Color);
break;
case GL_COLOR_CLEAR_VALUE:
- if(ctx->Color._ClampFragmentColor) {
- v->value_float_4[0] = CLAMP(ctx->Color.ClearColor.f[0], 0.0F, 1.0F);
- v->value_float_4[1] = CLAMP(ctx->Color.ClearColor.f[1], 0.0F, 1.0F);
- v->value_float_4[2] = CLAMP(ctx->Color.ClearColor.f[2], 0.0F, 1.0F);
- v->value_float_4[3] = CLAMP(ctx->Color.ClearColor.f[3], 0.0F, 1.0F);
- } else
- COPY_4FV(v->value_float_4, ctx->Color.ClearColor.f);
+ v->value_float_4[0] = CLAMP(ctx->Color.ClearColor.f[0], 0.0F, 1.0F);
+ v->value_float_4[1] = CLAMP(ctx->Color.ClearColor.f[1], 0.0F, 1.0F);
+ v->value_float_4[2] = CLAMP(ctx->Color.ClearColor.f[2], 0.0F, 1.0F);
+ v->value_float_4[3] = CLAMP(ctx->Color.ClearColor.f[3], 0.0F, 1.0F);
break;
case GL_BLEND_COLOR_EXT:
- if(ctx->Color._ClampFragmentColor)
- COPY_4FV(v->value_float_4, ctx->Color.BlendColor);
- else
- COPY_4FV(v->value_float_4, ctx->Color.BlendColorUnclamped);
+ COPY_4FV(v->value_float_4, ctx->Color.BlendColor);
break;
case GL_ALPHA_TEST_REF:
- if(ctx->Color._ClampFragmentColor)
v->value_float = ctx->Color.AlphaRef;
- else
- v->value_float = ctx->Color.AlphaRefUnclamped;
- break;
+ break;
case GL_MAX_VERTEX_UNIFORM_VECTORS:
v->value_int = ctx->Const.VertexProgram.MaxUniformComponents / 4;
break;
enabled++;
}
break;
- case EXTRA_NEW_FRAG_CLAMP:
- if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
- _mesa_update_state(ctx);
- break;
- break;
case EXTRA_NEW_BUFFERS:
if (ctx->NewState & _NEW_BUFFERS)
_mesa_update_state(ctx);
ctx->Hint.ClipVolumeClipping = mode;
break;
- /* GL_ARB_texture_compression */
- case GL_TEXTURE_COMPRESSION_HINT_ARB:
- if (ctx->Hint.TextureCompression == mode)
- return;
- FLUSH_VERTICES(ctx, _NEW_HINT);
- ctx->Hint.TextureCompression = mode;
- break;
-
- /* GL_SGIS_generate_mipmap */
- case GL_GENERATE_MIPMAP_HINT_SGIS:
- if (ctx->Hint.GenerateMipmap == mode)
- return;
- FLUSH_VERTICES(ctx, _NEW_HINT);
- ctx->Hint.GenerateMipmap = mode;
- break;
-
/* GL_ARB_fragment_shader */
case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB:
if (!ctx->Extensions.ARB_fragment_shader) {
ctx->Hint.PolygonSmooth = GL_DONT_CARE;
ctx->Hint.Fog = GL_DONT_CARE;
ctx->Hint.ClipVolumeClipping = GL_DONT_CARE;
- ctx->Hint.TextureCompression = GL_DONT_CARE;
- ctx->Hint.GenerateMipmap = GL_DONT_CARE;
ctx->Hint.FragmentShaderDerivative = GL_DONT_CARE;
}
NULL );
ctx->Light.ColorMaterialEnabled = GL_FALSE;
- ctx->Light.ClampVertexColor = GL_TRUE;
/* Lighting miscellaneous */
ctx->_ShineTabList = MALLOC_STRUCT( gl_shine_tab );
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-/**
- * \file mipmap.c mipmap generation and teximage resizing functions.
- */
-
-#include "imports.h"
-#include "formats.h"
-#include "mipmap.h"
-#include "mtypes.h"
-#include "teximage.h"
-#include "texstore.h"
-#include "image.h"
-#include "macros.h"
-
-
-static GLint
-bytes_per_pixel(GLenum datatype, GLuint comps)
-{
- GLint b;
-
- b = _mesa_sizeof_packed_type(datatype);
- assert(b >= 0);
-
- if (_mesa_type_is_packed(datatype))
- return b;
- else
- return b * comps;
-}
-
-
-/**
- * \name Support macros for do_row and do_row_3d
- *
- * The macro madness is here for two reasons. First, it compacts the code
- * slightly. Second, it makes it much easier to adjust the specifics of the
- * filter to tune the rounding characteristics.
- */
-/*@{*/
-#define DECLARE_ROW_POINTERS(t, e) \
- const t(*rowA)[e] = (const t(*)[e]) srcRowA; \
- const t(*rowB)[e] = (const t(*)[e]) srcRowB; \
- const t(*rowC)[e] = (const t(*)[e]) srcRowC; \
- const t(*rowD)[e] = (const t(*)[e]) srcRowD; \
- t(*dst)[e] = (t(*)[e]) dstRow
-
-#define DECLARE_ROW_POINTERS0(t) \
- const t *rowA = (const t *) srcRowA; \
- const t *rowB = (const t *) srcRowB; \
- const t *rowC = (const t *) srcRowC; \
- const t *rowD = (const t *) srcRowD; \
- t *dst = (t *) dstRow
-
-#define FILTER_SUM_3D(Aj, Ak, Bj, Bk, Cj, Ck, Dj, Dk) \
- ((unsigned) Aj + (unsigned) Ak \
- + (unsigned) Bj + (unsigned) Bk \
- + (unsigned) Cj + (unsigned) Ck \
- + (unsigned) Dj + (unsigned) Dk \
- + 4) >> 3
-
-#define FILTER_3D(e) \
- do { \
- dst[i][e] = FILTER_SUM_3D(rowA[j][e], rowA[k][e], \
- rowB[j][e], rowB[k][e], \
- rowC[j][e], rowC[k][e], \
- rowD[j][e], rowD[k][e]); \
- } while(0)
-
-#define FILTER_SUM_3D_SIGNED(Aj, Ak, Bj, Bk, Cj, Ck, Dj, Dk) \
- (Aj + Ak \
- + Bj + Bk \
- + Cj + Ck \
- + Dj + Dk \
- + 4) / 8
-
-#define FILTER_3D_SIGNED(e) \
- do { \
- dst[i][e] = FILTER_SUM_3D_SIGNED(rowA[j][e], rowA[k][e], \
- rowB[j][e], rowB[k][e], \
- rowC[j][e], rowC[k][e], \
- rowD[j][e], rowD[k][e]); \
- } while(0)
-
-#define FILTER_F_3D(e) \
- do { \
- dst[i][e] = (rowA[j][e] + rowA[k][e] \
- + rowB[j][e] + rowB[k][e] \
- + rowC[j][e] + rowC[k][e] \
- + rowD[j][e] + rowD[k][e]) * 0.125F; \
- } while(0)
-
-#define FILTER_HF_3D(e) \
- do { \
- const GLfloat aj = _mesa_half_to_float(rowA[j][e]); \
- const GLfloat ak = _mesa_half_to_float(rowA[k][e]); \
- const GLfloat bj = _mesa_half_to_float(rowB[j][e]); \
- const GLfloat bk = _mesa_half_to_float(rowB[k][e]); \
- const GLfloat cj = _mesa_half_to_float(rowC[j][e]); \
- const GLfloat ck = _mesa_half_to_float(rowC[k][e]); \
- const GLfloat dj = _mesa_half_to_float(rowD[j][e]); \
- const GLfloat dk = _mesa_half_to_float(rowD[k][e]); \
- dst[i][e] = _mesa_float_to_half((aj + ak + bj + bk + cj + ck + dj + dk) \
- * 0.125F); \
- } while(0)
-/*@}*/
-
-
-/**
- * Average together two rows of a source image to produce a single new
- * row in the dest image. It's legal for the two source rows to point
- * to the same data. The source width must be equal to either the
- * dest width or two times the dest width.
- * \param datatype GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_FLOAT, etc.
- * \param comps number of components per pixel (1..4)
- */
-static void
-do_row(GLenum datatype, GLuint comps, GLint srcWidth,
- const GLvoid *srcRowA, const GLvoid *srcRowB,
- GLint dstWidth, GLvoid *dstRow)
-{
- const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1;
- const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2;
-
- ASSERT(comps >= 1);
- ASSERT(comps <= 4);
-
- /* This assertion is no longer valid with non-power-of-2 textures
- assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth);
- */
-
- if (datatype == GL_UNSIGNED_BYTE && comps == 4) {
- GLuint i, j, k;
- const GLubyte(*rowA)[4] = (const GLubyte(*)[4]) srcRowA;
- const GLubyte(*rowB)[4] = (const GLubyte(*)[4]) srcRowB;
- GLubyte(*dst)[4] = (GLubyte(*)[4]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
- dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
- dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
- dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4;
- }
- }
- else if (datatype == GL_UNSIGNED_BYTE && comps == 3) {
- GLuint i, j, k;
- const GLubyte(*rowA)[3] = (const GLubyte(*)[3]) srcRowA;
- const GLubyte(*rowB)[3] = (const GLubyte(*)[3]) srcRowB;
- GLubyte(*dst)[3] = (GLubyte(*)[3]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
- dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
- dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
- }
- }
- else if (datatype == GL_UNSIGNED_BYTE && comps == 2) {
- GLuint i, j, k;
- const GLubyte(*rowA)[2] = (const GLubyte(*)[2]) srcRowA;
- const GLubyte(*rowB)[2] = (const GLubyte(*)[2]) srcRowB;
- GLubyte(*dst)[2] = (GLubyte(*)[2]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) >> 2;
- dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) >> 2;
- }
- }
- else if (datatype == GL_UNSIGNED_BYTE && comps == 1) {
- GLuint i, j, k;
- const GLubyte *rowA = (const GLubyte *) srcRowA;
- const GLubyte *rowB = (const GLubyte *) srcRowB;
- GLubyte *dst = (GLubyte *) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2;
- }
- }
-
- else if (datatype == GL_BYTE && comps == 4) {
- GLuint i, j, k;
- const GLbyte(*rowA)[4] = (const GLbyte(*)[4]) srcRowA;
- const GLbyte(*rowB)[4] = (const GLbyte(*)[4]) srcRowB;
- GLbyte(*dst)[4] = (GLbyte(*)[4]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
- dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
- dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
- dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4;
- }
- }
- else if (datatype == GL_BYTE && comps == 3) {
- GLuint i, j, k;
- const GLbyte(*rowA)[3] = (const GLbyte(*)[3]) srcRowA;
- const GLbyte(*rowB)[3] = (const GLbyte(*)[3]) srcRowB;
- GLbyte(*dst)[3] = (GLbyte(*)[3]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
- dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
- dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
- }
- }
- else if (datatype == GL_BYTE && comps == 2) {
- GLuint i, j, k;
- const GLbyte(*rowA)[2] = (const GLbyte(*)[2]) srcRowA;
- const GLbyte(*rowB)[2] = (const GLbyte(*)[2]) srcRowB;
- GLbyte(*dst)[2] = (GLbyte(*)[2]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
- dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
- }
- }
- else if (datatype == GL_BYTE && comps == 1) {
- GLuint i, j, k;
- const GLbyte *rowA = (const GLbyte *) srcRowA;
- const GLbyte *rowB = (const GLbyte *) srcRowB;
- GLbyte *dst = (GLbyte *) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
- }
- }
-
- else if (datatype == GL_UNSIGNED_SHORT && comps == 4) {
- GLuint i, j, k;
- const GLushort(*rowA)[4] = (const GLushort(*)[4]) srcRowA;
- const GLushort(*rowB)[4] = (const GLushort(*)[4]) srcRowB;
- GLushort(*dst)[4] = (GLushort(*)[4]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
- dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
- dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
- dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4;
- }
- }
- else if (datatype == GL_UNSIGNED_SHORT && comps == 3) {
- GLuint i, j, k;
- const GLushort(*rowA)[3] = (const GLushort(*)[3]) srcRowA;
- const GLushort(*rowB)[3] = (const GLushort(*)[3]) srcRowB;
- GLushort(*dst)[3] = (GLushort(*)[3]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
- dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
- dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
- }
- }
- else if (datatype == GL_UNSIGNED_SHORT && comps == 2) {
- GLuint i, j, k;
- const GLushort(*rowA)[2] = (const GLushort(*)[2]) srcRowA;
- const GLushort(*rowB)[2] = (const GLushort(*)[2]) srcRowB;
- GLushort(*dst)[2] = (GLushort(*)[2]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
- dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
- }
- }
- else if (datatype == GL_UNSIGNED_SHORT && comps == 1) {
- GLuint i, j, k;
- const GLushort *rowA = (const GLushort *) srcRowA;
- const GLushort *rowB = (const GLushort *) srcRowB;
- GLushort *dst = (GLushort *) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
- }
- }
-
- else if (datatype == GL_SHORT && comps == 4) {
- GLuint i, j, k;
- const GLshort(*rowA)[4] = (const GLshort(*)[4]) srcRowA;
- const GLshort(*rowB)[4] = (const GLshort(*)[4]) srcRowB;
- GLshort(*dst)[4] = (GLshort(*)[4]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
- dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
- dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
- dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4;
- }
- }
- else if (datatype == GL_SHORT && comps == 3) {
- GLuint i, j, k;
- const GLshort(*rowA)[3] = (const GLshort(*)[3]) srcRowA;
- const GLshort(*rowB)[3] = (const GLshort(*)[3]) srcRowB;
- GLshort(*dst)[3] = (GLshort(*)[3]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
- dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
- dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
- }
- }
- else if (datatype == GL_SHORT && comps == 2) {
- GLuint i, j, k;
- const GLshort(*rowA)[2] = (const GLshort(*)[2]) srcRowA;
- const GLshort(*rowB)[2] = (const GLshort(*)[2]) srcRowB;
- GLshort(*dst)[2] = (GLshort(*)[2]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
- dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
- }
- }
- else if (datatype == GL_SHORT && comps == 1) {
- GLuint i, j, k;
- const GLshort *rowA = (const GLshort *) srcRowA;
- const GLshort *rowB = (const GLshort *) srcRowB;
- GLshort *dst = (GLshort *) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
- }
- }
-
- else if (datatype == GL_FLOAT && comps == 4) {
- GLuint i, j, k;
- const GLfloat(*rowA)[4] = (const GLfloat(*)[4]) srcRowA;
- const GLfloat(*rowB)[4] = (const GLfloat(*)[4]) srcRowB;
- GLfloat(*dst)[4] = (GLfloat(*)[4]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i][0] = (rowA[j][0] + rowA[k][0] +
- rowB[j][0] + rowB[k][0]) * 0.25F;
- dst[i][1] = (rowA[j][1] + rowA[k][1] +
- rowB[j][1] + rowB[k][1]) * 0.25F;
- dst[i][2] = (rowA[j][2] + rowA[k][2] +
- rowB[j][2] + rowB[k][2]) * 0.25F;
- dst[i][3] = (rowA[j][3] + rowA[k][3] +
- rowB[j][3] + rowB[k][3]) * 0.25F;
- }
- }
- else if (datatype == GL_FLOAT && comps == 3) {
- GLuint i, j, k;
- const GLfloat(*rowA)[3] = (const GLfloat(*)[3]) srcRowA;
- const GLfloat(*rowB)[3] = (const GLfloat(*)[3]) srcRowB;
- GLfloat(*dst)[3] = (GLfloat(*)[3]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i][0] = (rowA[j][0] + rowA[k][0] +
- rowB[j][0] + rowB[k][0]) * 0.25F;
- dst[i][1] = (rowA[j][1] + rowA[k][1] +
- rowB[j][1] + rowB[k][1]) * 0.25F;
- dst[i][2] = (rowA[j][2] + rowA[k][2] +
- rowB[j][2] + rowB[k][2]) * 0.25F;
- }
- }
- else if (datatype == GL_FLOAT && comps == 2) {
- GLuint i, j, k;
- const GLfloat(*rowA)[2] = (const GLfloat(*)[2]) srcRowA;
- const GLfloat(*rowB)[2] = (const GLfloat(*)[2]) srcRowB;
- GLfloat(*dst)[2] = (GLfloat(*)[2]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i][0] = (rowA[j][0] + rowA[k][0] +
- rowB[j][0] + rowB[k][0]) * 0.25F;
- dst[i][1] = (rowA[j][1] + rowA[k][1] +
- rowB[j][1] + rowB[k][1]) * 0.25F;
- }
- }
- else if (datatype == GL_FLOAT && comps == 1) {
- GLuint i, j, k;
- const GLfloat *rowA = (const GLfloat *) srcRowA;
- const GLfloat *rowB = (const GLfloat *) srcRowB;
- GLfloat *dst = (GLfloat *) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
- }
- }
-
- else if (datatype == GL_HALF_FLOAT_ARB && comps == 4) {
- GLuint i, j, k, comp;
- const GLhalfARB(*rowA)[4] = (const GLhalfARB(*)[4]) srcRowA;
- const GLhalfARB(*rowB)[4] = (const GLhalfARB(*)[4]) srcRowB;
- GLhalfARB(*dst)[4] = (GLhalfARB(*)[4]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- for (comp = 0; comp < 4; comp++) {
- GLfloat aj, ak, bj, bk;
- aj = _mesa_half_to_float(rowA[j][comp]);
- ak = _mesa_half_to_float(rowA[k][comp]);
- bj = _mesa_half_to_float(rowB[j][comp]);
- bk = _mesa_half_to_float(rowB[k][comp]);
- dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
- }
- }
- }
- else if (datatype == GL_HALF_FLOAT_ARB && comps == 3) {
- GLuint i, j, k, comp;
- const GLhalfARB(*rowA)[3] = (const GLhalfARB(*)[3]) srcRowA;
- const GLhalfARB(*rowB)[3] = (const GLhalfARB(*)[3]) srcRowB;
- GLhalfARB(*dst)[3] = (GLhalfARB(*)[3]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- for (comp = 0; comp < 3; comp++) {
- GLfloat aj, ak, bj, bk;
- aj = _mesa_half_to_float(rowA[j][comp]);
- ak = _mesa_half_to_float(rowA[k][comp]);
- bj = _mesa_half_to_float(rowB[j][comp]);
- bk = _mesa_half_to_float(rowB[k][comp]);
- dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
- }
- }
- }
- else if (datatype == GL_HALF_FLOAT_ARB && comps == 2) {
- GLuint i, j, k, comp;
- const GLhalfARB(*rowA)[2] = (const GLhalfARB(*)[2]) srcRowA;
- const GLhalfARB(*rowB)[2] = (const GLhalfARB(*)[2]) srcRowB;
- GLhalfARB(*dst)[2] = (GLhalfARB(*)[2]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- for (comp = 0; comp < 2; comp++) {
- GLfloat aj, ak, bj, bk;
- aj = _mesa_half_to_float(rowA[j][comp]);
- ak = _mesa_half_to_float(rowA[k][comp]);
- bj = _mesa_half_to_float(rowB[j][comp]);
- bk = _mesa_half_to_float(rowB[k][comp]);
- dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
- }
- }
- }
- else if (datatype == GL_HALF_FLOAT_ARB && comps == 1) {
- GLuint i, j, k;
- const GLhalfARB *rowA = (const GLhalfARB *) srcRowA;
- const GLhalfARB *rowB = (const GLhalfARB *) srcRowB;
- GLhalfARB *dst = (GLhalfARB *) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- GLfloat aj, ak, bj, bk;
- aj = _mesa_half_to_float(rowA[j]);
- ak = _mesa_half_to_float(rowA[k]);
- bj = _mesa_half_to_float(rowB[j]);
- bk = _mesa_half_to_float(rowB[k]);
- dst[i] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
- }
- }
-
- else if (datatype == GL_UNSIGNED_INT && comps == 1) {
- GLuint i, j, k;
- const GLuint *rowA = (const GLuint *) srcRowA;
- const GLuint *rowB = (const GLuint *) srcRowB;
- GLuint *dst = (GLuint *) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4;
- }
- }
-
- else if (datatype == GL_UNSIGNED_SHORT_5_6_5 && comps == 3) {
- GLuint i, j, k;
- const GLushort *rowA = (const GLushort *) srcRowA;
- const GLushort *rowB = (const GLushort *) srcRowB;
- GLushort *dst = (GLushort *) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- const GLint rowAr0 = rowA[j] & 0x1f;
- const GLint rowAr1 = rowA[k] & 0x1f;
- const GLint rowBr0 = rowB[j] & 0x1f;
- const GLint rowBr1 = rowB[k] & 0x1f;
- const GLint rowAg0 = (rowA[j] >> 5) & 0x3f;
- const GLint rowAg1 = (rowA[k] >> 5) & 0x3f;
- const GLint rowBg0 = (rowB[j] >> 5) & 0x3f;
- const GLint rowBg1 = (rowB[k] >> 5) & 0x3f;
- const GLint rowAb0 = (rowA[j] >> 11) & 0x1f;
- const GLint rowAb1 = (rowA[k] >> 11) & 0x1f;
- const GLint rowBb0 = (rowB[j] >> 11) & 0x1f;
- const GLint rowBb1 = (rowB[k] >> 11) & 0x1f;
- const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
- const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
- const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
- dst[i] = (blue << 11) | (green << 5) | red;
- }
- }
- else if (datatype == GL_UNSIGNED_SHORT_4_4_4_4 && comps == 4) {
- GLuint i, j, k;
- const GLushort *rowA = (const GLushort *) srcRowA;
- const GLushort *rowB = (const GLushort *) srcRowB;
- GLushort *dst = (GLushort *) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- const GLint rowAr0 = rowA[j] & 0xf;
- const GLint rowAr1 = rowA[k] & 0xf;
- const GLint rowBr0 = rowB[j] & 0xf;
- const GLint rowBr1 = rowB[k] & 0xf;
- const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
- const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
- const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
- const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
- const GLint rowAb0 = (rowA[j] >> 8) & 0xf;
- const GLint rowAb1 = (rowA[k] >> 8) & 0xf;
- const GLint rowBb0 = (rowB[j] >> 8) & 0xf;
- const GLint rowBb1 = (rowB[k] >> 8) & 0xf;
- const GLint rowAa0 = (rowA[j] >> 12) & 0xf;
- const GLint rowAa1 = (rowA[k] >> 12) & 0xf;
- const GLint rowBa0 = (rowB[j] >> 12) & 0xf;
- const GLint rowBa1 = (rowB[k] >> 12) & 0xf;
- const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
- const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
- const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
- const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
- dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
- }
- }
- else if (datatype == GL_UNSIGNED_SHORT_1_5_5_5_REV && comps == 4) {
- GLuint i, j, k;
- const GLushort *rowA = (const GLushort *) srcRowA;
- const GLushort *rowB = (const GLushort *) srcRowB;
- GLushort *dst = (GLushort *) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- const GLint rowAr0 = rowA[j] & 0x1f;
- const GLint rowAr1 = rowA[k] & 0x1f;
- const GLint rowBr0 = rowB[j] & 0x1f;
- const GLint rowBr1 = rowB[k] & 0x1f;
- const GLint rowAg0 = (rowA[j] >> 5) & 0x1f;
- const GLint rowAg1 = (rowA[k] >> 5) & 0x1f;
- const GLint rowBg0 = (rowB[j] >> 5) & 0x1f;
- const GLint rowBg1 = (rowB[k] >> 5) & 0x1f;
- const GLint rowAb0 = (rowA[j] >> 10) & 0x1f;
- const GLint rowAb1 = (rowA[k] >> 10) & 0x1f;
- const GLint rowBb0 = (rowB[j] >> 10) & 0x1f;
- const GLint rowBb1 = (rowB[k] >> 10) & 0x1f;
- const GLint rowAa0 = (rowA[j] >> 15) & 0x1;
- const GLint rowAa1 = (rowA[k] >> 15) & 0x1;
- const GLint rowBa0 = (rowB[j] >> 15) & 0x1;
- const GLint rowBa1 = (rowB[k] >> 15) & 0x1;
- const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
- const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
- const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
- const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
- dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
- }
- }
- else if (datatype == GL_UNSIGNED_SHORT_5_5_5_1 && comps == 4) {
- GLuint i, j, k;
- const GLushort *rowA = (const GLushort *) srcRowA;
- const GLushort *rowB = (const GLushort *) srcRowB;
- GLushort *dst = (GLushort *) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- const GLint rowAr0 = (rowA[j] >> 11) & 0x1f;
- const GLint rowAr1 = (rowA[k] >> 11) & 0x1f;
- const GLint rowBr0 = (rowB[j] >> 11) & 0x1f;
- const GLint rowBr1 = (rowB[k] >> 11) & 0x1f;
- const GLint rowAg0 = (rowA[j] >> 6) & 0x1f;
- const GLint rowAg1 = (rowA[k] >> 6) & 0x1f;
- const GLint rowBg0 = (rowB[j] >> 6) & 0x1f;
- const GLint rowBg1 = (rowB[k] >> 6) & 0x1f;
- const GLint rowAb0 = (rowA[j] >> 1) & 0x1f;
- const GLint rowAb1 = (rowA[k] >> 1) & 0x1f;
- const GLint rowBb0 = (rowB[j] >> 1) & 0x1f;
- const GLint rowBb1 = (rowB[k] >> 1) & 0x1f;
- const GLint rowAa0 = (rowA[j] & 0x1);
- const GLint rowAa1 = (rowA[k] & 0x1);
- const GLint rowBa0 = (rowB[j] & 0x1);
- const GLint rowBa1 = (rowB[k] & 0x1);
- const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
- const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
- const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
- const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
- dst[i] = (red << 11) | (green << 6) | (blue << 1) | alpha;
- }
- }
-
- else if (datatype == GL_UNSIGNED_BYTE_3_3_2 && comps == 3) {
- GLuint i, j, k;
- const GLubyte *rowA = (const GLubyte *) srcRowA;
- const GLubyte *rowB = (const GLubyte *) srcRowB;
- GLubyte *dst = (GLubyte *) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- const GLint rowAr0 = rowA[j] & 0x3;
- const GLint rowAr1 = rowA[k] & 0x3;
- const GLint rowBr0 = rowB[j] & 0x3;
- const GLint rowBr1 = rowB[k] & 0x3;
- const GLint rowAg0 = (rowA[j] >> 2) & 0x7;
- const GLint rowAg1 = (rowA[k] >> 2) & 0x7;
- const GLint rowBg0 = (rowB[j] >> 2) & 0x7;
- const GLint rowBg1 = (rowB[k] >> 2) & 0x7;
- const GLint rowAb0 = (rowA[j] >> 5) & 0x7;
- const GLint rowAb1 = (rowA[k] >> 5) & 0x7;
- const GLint rowBb0 = (rowB[j] >> 5) & 0x7;
- const GLint rowBb1 = (rowB[k] >> 5) & 0x7;
- const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
- const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
- const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
- dst[i] = (blue << 5) | (green << 2) | red;
- }
- }
-
- else if (datatype == MESA_UNSIGNED_BYTE_4_4 && comps == 2) {
- GLuint i, j, k;
- const GLubyte *rowA = (const GLubyte *) srcRowA;
- const GLubyte *rowB = (const GLubyte *) srcRowB;
- GLubyte *dst = (GLubyte *) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- const GLint rowAr0 = rowA[j] & 0xf;
- const GLint rowAr1 = rowA[k] & 0xf;
- const GLint rowBr0 = rowB[j] & 0xf;
- const GLint rowBr1 = rowB[k] & 0xf;
- const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
- const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
- const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
- const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
- const GLint r = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
- const GLint g = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
- dst[i] = (g << 4) | r;
- }
- }
-
- else {
- _mesa_problem(NULL, "bad format in do_row()");
- }
-}
-
-
-/**
- * Average together four rows of a source image to produce a single new
- * row in the dest image. It's legal for the two source rows to point
- * to the same data. The source width must be equal to either the
- * dest width or two times the dest width.
- *
- * \param datatype GL pixel type \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT,
- * \c GL_FLOAT, etc.
- * \param comps number of components per pixel (1..4)
- * \param srcWidth Width of a row in the source data
- * \param srcRowA Pointer to one of the rows of source data
- * \param srcRowB Pointer to one of the rows of source data
- * \param srcRowC Pointer to one of the rows of source data
- * \param srcRowD Pointer to one of the rows of source data
- * \param dstWidth Width of a row in the destination data
- * \param srcRowA Pointer to the row of destination data
- */
-static void
-do_row_3D(GLenum datatype, GLuint comps, GLint srcWidth,
- const GLvoid *srcRowA, const GLvoid *srcRowB,
- const GLvoid *srcRowC, const GLvoid *srcRowD,
- GLint dstWidth, GLvoid *dstRow)
-{
- const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1;
- const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2;
- GLuint i, j, k;
-
- ASSERT(comps >= 1);
- ASSERT(comps <= 4);
-
- if ((datatype == GL_UNSIGNED_BYTE) && (comps == 4)) {
- DECLARE_ROW_POINTERS(GLubyte, 4);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_3D(0);
- FILTER_3D(1);
- FILTER_3D(2);
- FILTER_3D(3);
- }
- }
- else if ((datatype == GL_UNSIGNED_BYTE) && (comps == 3)) {
- DECLARE_ROW_POINTERS(GLubyte, 3);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_3D(0);
- FILTER_3D(1);
- FILTER_3D(2);
- }
- }
- else if ((datatype == GL_UNSIGNED_BYTE) && (comps == 2)) {
- DECLARE_ROW_POINTERS(GLubyte, 2);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_3D(0);
- FILTER_3D(1);
- }
- }
- else if ((datatype == GL_UNSIGNED_BYTE) && (comps == 1)) {
- DECLARE_ROW_POINTERS(GLubyte, 1);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_3D(0);
- }
- }
- else if ((datatype == GL_BYTE) && (comps == 4)) {
- DECLARE_ROW_POINTERS(GLbyte, 4);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_3D_SIGNED(0);
- FILTER_3D_SIGNED(1);
- FILTER_3D_SIGNED(2);
- FILTER_3D_SIGNED(3);
- }
- }
- else if ((datatype == GL_BYTE) && (comps == 3)) {
- DECLARE_ROW_POINTERS(GLbyte, 3);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_3D_SIGNED(0);
- FILTER_3D_SIGNED(1);
- FILTER_3D_SIGNED(2);
- }
- }
- else if ((datatype == GL_BYTE) && (comps == 2)) {
- DECLARE_ROW_POINTERS(GLbyte, 2);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_3D_SIGNED(0);
- FILTER_3D_SIGNED(1);
- }
- }
- else if ((datatype == GL_BYTE) && (comps == 1)) {
- DECLARE_ROW_POINTERS(GLbyte, 1);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_3D_SIGNED(0);
- }
- }
- else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 4)) {
- DECLARE_ROW_POINTERS(GLushort, 4);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_3D(0);
- FILTER_3D(1);
- FILTER_3D(2);
- FILTER_3D(3);
- }
- }
- else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 3)) {
- DECLARE_ROW_POINTERS(GLushort, 3);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_3D(0);
- FILTER_3D(1);
- FILTER_3D(2);
- }
- }
- else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 2)) {
- DECLARE_ROW_POINTERS(GLushort, 2);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_3D(0);
- FILTER_3D(1);
- }
- }
- else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 1)) {
- DECLARE_ROW_POINTERS(GLushort, 1);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_3D(0);
- }
- }
- else if ((datatype == GL_SHORT) && (comps == 4)) {
- DECLARE_ROW_POINTERS(GLshort, 4);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_3D(0);
- FILTER_3D(1);
- FILTER_3D(2);
- FILTER_3D(3);
- }
- }
- else if ((datatype == GL_SHORT) && (comps == 3)) {
- DECLARE_ROW_POINTERS(GLshort, 3);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_3D(0);
- FILTER_3D(1);
- FILTER_3D(2);
- }
- }
- else if ((datatype == GL_SHORT) && (comps == 2)) {
- DECLARE_ROW_POINTERS(GLshort, 2);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_3D(0);
- FILTER_3D(1);
- }
- }
- else if ((datatype == GL_SHORT) && (comps == 1)) {
- DECLARE_ROW_POINTERS(GLshort, 1);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_3D(0);
- }
- }
- else if ((datatype == GL_FLOAT) && (comps == 4)) {
- DECLARE_ROW_POINTERS(GLfloat, 4);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_F_3D(0);
- FILTER_F_3D(1);
- FILTER_F_3D(2);
- FILTER_F_3D(3);
- }
- }
- else if ((datatype == GL_FLOAT) && (comps == 3)) {
- DECLARE_ROW_POINTERS(GLfloat, 3);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_F_3D(0);
- FILTER_F_3D(1);
- FILTER_F_3D(2);
- }
- }
- else if ((datatype == GL_FLOAT) && (comps == 2)) {
- DECLARE_ROW_POINTERS(GLfloat, 2);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_F_3D(0);
- FILTER_F_3D(1);
- }
- }
- else if ((datatype == GL_FLOAT) && (comps == 1)) {
- DECLARE_ROW_POINTERS(GLfloat, 1);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_F_3D(0);
- }
- }
- else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 4)) {
- DECLARE_ROW_POINTERS(GLhalfARB, 4);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_HF_3D(0);
- FILTER_HF_3D(1);
- FILTER_HF_3D(2);
- FILTER_HF_3D(3);
- }
- }
- else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 3)) {
- DECLARE_ROW_POINTERS(GLhalfARB, 3);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_HF_3D(0);
- FILTER_HF_3D(1);
- FILTER_HF_3D(2);
- }
- }
- else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 2)) {
- DECLARE_ROW_POINTERS(GLhalfARB, 2);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_HF_3D(0);
- FILTER_HF_3D(1);
- }
- }
- else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 1)) {
- DECLARE_ROW_POINTERS(GLhalfARB, 1);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- FILTER_HF_3D(0);
- }
- }
- else if ((datatype == GL_UNSIGNED_INT) && (comps == 1)) {
- const GLuint *rowA = (const GLuint *) srcRowA;
- const GLuint *rowB = (const GLuint *) srcRowB;
- const GLuint *rowC = (const GLuint *) srcRowC;
- const GLuint *rowD = (const GLuint *) srcRowD;
- GLfloat *dst = (GLfloat *) dstRow;
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- const uint64_t tmp = (((uint64_t) rowA[j] + (uint64_t) rowA[k])
- + ((uint64_t) rowB[j] + (uint64_t) rowB[k])
- + ((uint64_t) rowC[j] + (uint64_t) rowC[k])
- + ((uint64_t) rowD[j] + (uint64_t) rowD[k]));
- dst[i] = (GLfloat)((double) tmp * 0.125);
- }
- }
- else if ((datatype == GL_UNSIGNED_SHORT_5_6_5) && (comps == 3)) {
- DECLARE_ROW_POINTERS0(GLushort);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- const GLint rowAr0 = rowA[j] & 0x1f;
- const GLint rowAr1 = rowA[k] & 0x1f;
- const GLint rowBr0 = rowB[j] & 0x1f;
- const GLint rowBr1 = rowB[k] & 0x1f;
- const GLint rowCr0 = rowC[j] & 0x1f;
- const GLint rowCr1 = rowC[k] & 0x1f;
- const GLint rowDr0 = rowD[j] & 0x1f;
- const GLint rowDr1 = rowD[k] & 0x1f;
- const GLint rowAg0 = (rowA[j] >> 5) & 0x3f;
- const GLint rowAg1 = (rowA[k] >> 5) & 0x3f;
- const GLint rowBg0 = (rowB[j] >> 5) & 0x3f;
- const GLint rowBg1 = (rowB[k] >> 5) & 0x3f;
- const GLint rowCg0 = (rowC[j] >> 5) & 0x3f;
- const GLint rowCg1 = (rowC[k] >> 5) & 0x3f;
- const GLint rowDg0 = (rowD[j] >> 5) & 0x3f;
- const GLint rowDg1 = (rowD[k] >> 5) & 0x3f;
- const GLint rowAb0 = (rowA[j] >> 11) & 0x1f;
- const GLint rowAb1 = (rowA[k] >> 11) & 0x1f;
- const GLint rowBb0 = (rowB[j] >> 11) & 0x1f;
- const GLint rowBb1 = (rowB[k] >> 11) & 0x1f;
- const GLint rowCb0 = (rowC[j] >> 11) & 0x1f;
- const GLint rowCb1 = (rowC[k] >> 11) & 0x1f;
- const GLint rowDb0 = (rowD[j] >> 11) & 0x1f;
- const GLint rowDb1 = (rowD[k] >> 11) & 0x1f;
- const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
- rowCr0, rowCr1, rowDr0, rowDr1);
- const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
- rowCg0, rowCg1, rowDg0, rowDg1);
- const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1,
- rowCb0, rowCb1, rowDb0, rowDb1);
- dst[i] = (b << 11) | (g << 5) | r;
- }
- }
- else if ((datatype == GL_UNSIGNED_SHORT_4_4_4_4) && (comps == 4)) {
- DECLARE_ROW_POINTERS0(GLushort);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- const GLint rowAr0 = rowA[j] & 0xf;
- const GLint rowAr1 = rowA[k] & 0xf;
- const GLint rowBr0 = rowB[j] & 0xf;
- const GLint rowBr1 = rowB[k] & 0xf;
- const GLint rowCr0 = rowC[j] & 0xf;
- const GLint rowCr1 = rowC[k] & 0xf;
- const GLint rowDr0 = rowD[j] & 0xf;
- const GLint rowDr1 = rowD[k] & 0xf;
- const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
- const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
- const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
- const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
- const GLint rowCg0 = (rowC[j] >> 4) & 0xf;
- const GLint rowCg1 = (rowC[k] >> 4) & 0xf;
- const GLint rowDg0 = (rowD[j] >> 4) & 0xf;
- const GLint rowDg1 = (rowD[k] >> 4) & 0xf;
- const GLint rowAb0 = (rowA[j] >> 8) & 0xf;
- const GLint rowAb1 = (rowA[k] >> 8) & 0xf;
- const GLint rowBb0 = (rowB[j] >> 8) & 0xf;
- const GLint rowBb1 = (rowB[k] >> 8) & 0xf;
- const GLint rowCb0 = (rowC[j] >> 8) & 0xf;
- const GLint rowCb1 = (rowC[k] >> 8) & 0xf;
- const GLint rowDb0 = (rowD[j] >> 8) & 0xf;
- const GLint rowDb1 = (rowD[k] >> 8) & 0xf;
- const GLint rowAa0 = (rowA[j] >> 12) & 0xf;
- const GLint rowAa1 = (rowA[k] >> 12) & 0xf;
- const GLint rowBa0 = (rowB[j] >> 12) & 0xf;
- const GLint rowBa1 = (rowB[k] >> 12) & 0xf;
- const GLint rowCa0 = (rowC[j] >> 12) & 0xf;
- const GLint rowCa1 = (rowC[k] >> 12) & 0xf;
- const GLint rowDa0 = (rowD[j] >> 12) & 0xf;
- const GLint rowDa1 = (rowD[k] >> 12) & 0xf;
- const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
- rowCr0, rowCr1, rowDr0, rowDr1);
- const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
- rowCg0, rowCg1, rowDg0, rowDg1);
- const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1,
- rowCb0, rowCb1, rowDb0, rowDb1);
- const GLint a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1,
- rowCa0, rowCa1, rowDa0, rowDa1);
-
- dst[i] = (a << 12) | (b << 8) | (g << 4) | r;
- }
- }
- else if ((datatype == GL_UNSIGNED_SHORT_1_5_5_5_REV) && (comps == 4)) {
- DECLARE_ROW_POINTERS0(GLushort);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- const GLint rowAr0 = rowA[j] & 0x1f;
- const GLint rowAr1 = rowA[k] & 0x1f;
- const GLint rowBr0 = rowB[j] & 0x1f;
- const GLint rowBr1 = rowB[k] & 0x1f;
- const GLint rowCr0 = rowC[j] & 0x1f;
- const GLint rowCr1 = rowC[k] & 0x1f;
- const GLint rowDr0 = rowD[j] & 0x1f;
- const GLint rowDr1 = rowD[k] & 0x1f;
- const GLint rowAg0 = (rowA[j] >> 5) & 0x1f;
- const GLint rowAg1 = (rowA[k] >> 5) & 0x1f;
- const GLint rowBg0 = (rowB[j] >> 5) & 0x1f;
- const GLint rowBg1 = (rowB[k] >> 5) & 0x1f;
- const GLint rowCg0 = (rowC[j] >> 5) & 0x1f;
- const GLint rowCg1 = (rowC[k] >> 5) & 0x1f;
- const GLint rowDg0 = (rowD[j] >> 5) & 0x1f;
- const GLint rowDg1 = (rowD[k] >> 5) & 0x1f;
- const GLint rowAb0 = (rowA[j] >> 10) & 0x1f;
- const GLint rowAb1 = (rowA[k] >> 10) & 0x1f;
- const GLint rowBb0 = (rowB[j] >> 10) & 0x1f;
- const GLint rowBb1 = (rowB[k] >> 10) & 0x1f;
- const GLint rowCb0 = (rowC[j] >> 10) & 0x1f;
- const GLint rowCb1 = (rowC[k] >> 10) & 0x1f;
- const GLint rowDb0 = (rowD[j] >> 10) & 0x1f;
- const GLint rowDb1 = (rowD[k] >> 10) & 0x1f;
- const GLint rowAa0 = (rowA[j] >> 15) & 0x1;
- const GLint rowAa1 = (rowA[k] >> 15) & 0x1;
- const GLint rowBa0 = (rowB[j] >> 15) & 0x1;
- const GLint rowBa1 = (rowB[k] >> 15) & 0x1;
- const GLint rowCa0 = (rowC[j] >> 15) & 0x1;
- const GLint rowCa1 = (rowC[k] >> 15) & 0x1;
- const GLint rowDa0 = (rowD[j] >> 15) & 0x1;
- const GLint rowDa1 = (rowD[k] >> 15) & 0x1;
- const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
- rowCr0, rowCr1, rowDr0, rowDr1);
- const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
- rowCg0, rowCg1, rowDg0, rowDg1);
- const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1,
- rowCb0, rowCb1, rowDb0, rowDb1);
- const GLint a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1,
- rowCa0, rowCa1, rowDa0, rowDa1);
-
- dst[i] = (a << 15) | (b << 10) | (g << 5) | r;
- }
- }
- else if ((datatype == GL_UNSIGNED_SHORT_5_5_5_1) && (comps == 4)) {
- DECLARE_ROW_POINTERS0(GLushort);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- const GLint rowAr0 = (rowA[j] >> 11) & 0x1f;
- const GLint rowAr1 = (rowA[k] >> 11) & 0x1f;
- const GLint rowBr0 = (rowB[j] >> 11) & 0x1f;
- const GLint rowBr1 = (rowB[k] >> 11) & 0x1f;
- const GLint rowCr0 = (rowC[j] >> 11) & 0x1f;
- const GLint rowCr1 = (rowC[k] >> 11) & 0x1f;
- const GLint rowDr0 = (rowD[j] >> 11) & 0x1f;
- const GLint rowDr1 = (rowD[k] >> 11) & 0x1f;
- const GLint rowAg0 = (rowA[j] >> 6) & 0x1f;
- const GLint rowAg1 = (rowA[k] >> 6) & 0x1f;
- const GLint rowBg0 = (rowB[j] >> 6) & 0x1f;
- const GLint rowBg1 = (rowB[k] >> 6) & 0x1f;
- const GLint rowCg0 = (rowC[j] >> 6) & 0x1f;
- const GLint rowCg1 = (rowC[k] >> 6) & 0x1f;
- const GLint rowDg0 = (rowD[j] >> 6) & 0x1f;
- const GLint rowDg1 = (rowD[k] >> 6) & 0x1f;
- const GLint rowAb0 = (rowA[j] >> 1) & 0x1f;
- const GLint rowAb1 = (rowA[k] >> 1) & 0x1f;
- const GLint rowBb0 = (rowB[j] >> 1) & 0x1f;
- const GLint rowBb1 = (rowB[k] >> 1) & 0x1f;
- const GLint rowCb0 = (rowC[j] >> 1) & 0x1f;
- const GLint rowCb1 = (rowC[k] >> 1) & 0x1f;
- const GLint rowDb0 = (rowD[j] >> 1) & 0x1f;
- const GLint rowDb1 = (rowD[k] >> 1) & 0x1f;
- const GLint rowAa0 = (rowA[j] & 0x1);
- const GLint rowAa1 = (rowA[k] & 0x1);
- const GLint rowBa0 = (rowB[j] & 0x1);
- const GLint rowBa1 = (rowB[k] & 0x1);
- const GLint rowCa0 = (rowC[j] & 0x1);
- const GLint rowCa1 = (rowC[k] & 0x1);
- const GLint rowDa0 = (rowD[j] & 0x1);
- const GLint rowDa1 = (rowD[k] & 0x1);
- const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
- rowCr0, rowCr1, rowDr0, rowDr1);
- const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
- rowCg0, rowCg1, rowDg0, rowDg1);
- const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1,
- rowCb0, rowCb1, rowDb0, rowDb1);
- const GLint a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1,
- rowCa0, rowCa1, rowDa0, rowDa1);
-
- dst[i] = (r << 11) | (g << 6) | (b << 1) | a;
- }
- }
- else if ((datatype == GL_UNSIGNED_BYTE_3_3_2) && (comps == 3)) {
- DECLARE_ROW_POINTERS0(GLubyte);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- const GLint rowAr0 = rowA[j] & 0x3;
- const GLint rowAr1 = rowA[k] & 0x3;
- const GLint rowBr0 = rowB[j] & 0x3;
- const GLint rowBr1 = rowB[k] & 0x3;
- const GLint rowCr0 = rowC[j] & 0x3;
- const GLint rowCr1 = rowC[k] & 0x3;
- const GLint rowDr0 = rowD[j] & 0x3;
- const GLint rowDr1 = rowD[k] & 0x3;
- const GLint rowAg0 = (rowA[j] >> 2) & 0x7;
- const GLint rowAg1 = (rowA[k] >> 2) & 0x7;
- const GLint rowBg0 = (rowB[j] >> 2) & 0x7;
- const GLint rowBg1 = (rowB[k] >> 2) & 0x7;
- const GLint rowCg0 = (rowC[j] >> 2) & 0x7;
- const GLint rowCg1 = (rowC[k] >> 2) & 0x7;
- const GLint rowDg0 = (rowD[j] >> 2) & 0x7;
- const GLint rowDg1 = (rowD[k] >> 2) & 0x7;
- const GLint rowAb0 = (rowA[j] >> 5) & 0x7;
- const GLint rowAb1 = (rowA[k] >> 5) & 0x7;
- const GLint rowBb0 = (rowB[j] >> 5) & 0x7;
- const GLint rowBb1 = (rowB[k] >> 5) & 0x7;
- const GLint rowCb0 = (rowC[j] >> 5) & 0x7;
- const GLint rowCb1 = (rowC[k] >> 5) & 0x7;
- const GLint rowDb0 = (rowD[j] >> 5) & 0x7;
- const GLint rowDb1 = (rowD[k] >> 5) & 0x7;
- const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
- rowCr0, rowCr1, rowDr0, rowDr1);
- const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
- rowCg0, rowCg1, rowDg0, rowDg1);
- const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1,
- rowCb0, rowCb1, rowDb0, rowDb1);
- dst[i] = (b << 5) | (g << 2) | r;
- }
- }
- else if (datatype == MESA_UNSIGNED_BYTE_4_4 && comps == 2) {
- DECLARE_ROW_POINTERS0(GLubyte);
-
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- const GLint rowAr0 = rowA[j] & 0xf;
- const GLint rowAr1 = rowA[k] & 0xf;
- const GLint rowBr0 = rowB[j] & 0xf;
- const GLint rowBr1 = rowB[k] & 0xf;
- const GLint rowCr0 = rowC[j] & 0xf;
- const GLint rowCr1 = rowC[k] & 0xf;
- const GLint rowDr0 = rowD[j] & 0xf;
- const GLint rowDr1 = rowD[k] & 0xf;
- const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
- const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
- const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
- const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
- const GLint rowCg0 = (rowC[j] >> 4) & 0xf;
- const GLint rowCg1 = (rowC[k] >> 4) & 0xf;
- const GLint rowDg0 = (rowD[j] >> 4) & 0xf;
- const GLint rowDg1 = (rowD[k] >> 4) & 0xf;
- const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
- rowCr0, rowCr1, rowDr0, rowDr1);
- const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
- rowCg0, rowCg1, rowDg0, rowDg1);
- dst[i] = (g << 4) | r;
- }
- }
-
- else {
- _mesa_problem(NULL, "bad format in do_row()");
- }
-}
-
-
-/*
- * These functions generate a 1/2-size mipmap image from a source image.
- * Texture borders are handled by copying or averaging the source image's
- * border texels, depending on the scale-down factor.
- */
-
-static void
-make_1d_mipmap(GLenum datatype, GLuint comps, GLint border,
- GLint srcWidth, const GLubyte *srcPtr,
- GLint dstWidth, GLubyte *dstPtr)
-{
- const GLint bpt = bytes_per_pixel(datatype, comps);
- const GLubyte *src;
- GLubyte *dst;
-
- /* skip the border pixel, if any */
- src = srcPtr + border * bpt;
- dst = dstPtr + border * bpt;
-
- /* we just duplicate the input row, kind of hack, saves code */
- do_row(datatype, comps, srcWidth - 2 * border, src, src,
- dstWidth - 2 * border, dst);
-
- if (border) {
- /* copy left-most pixel from source */
- assert(dstPtr);
- assert(srcPtr);
- memcpy(dstPtr, srcPtr, bpt);
- /* copy right-most pixel from source */
- memcpy(dstPtr + (dstWidth - 1) * bpt,
- srcPtr + (srcWidth - 1) * bpt,
- bpt);
- }
-}
-
-
-static void
-make_2d_mipmap(GLenum datatype, GLuint comps, GLint border,
- GLint srcWidth, GLint srcHeight,
- const GLubyte *srcPtr, GLint srcRowStride,
- GLint dstWidth, GLint dstHeight,
- GLubyte *dstPtr, GLint dstRowStride)
-{
- const GLint bpt = bytes_per_pixel(datatype, comps);
- const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */
- const GLint dstWidthNB = dstWidth - 2 * border;
- const GLint dstHeightNB = dstHeight - 2 * border;
- const GLubyte *srcA, *srcB;
- GLubyte *dst;
- GLint row, srcRowStep;
-
- /* Compute src and dst pointers, skipping any border */
- srcA = srcPtr + border * ((srcWidth + 1) * bpt);
- if (srcHeight > 1 && srcHeight > dstHeight) {
- /* sample from two source rows */
- srcB = srcA + srcRowStride;
- srcRowStep = 2;
- }
- else {
- /* sample from one source row */
- srcB = srcA;
- srcRowStep = 1;
- }
-
- dst = dstPtr + border * ((dstWidth + 1) * bpt);
-
- for (row = 0; row < dstHeightNB; row++) {
- do_row(datatype, comps, srcWidthNB, srcA, srcB,
- dstWidthNB, dst);
- srcA += srcRowStep * srcRowStride;
- srcB += srcRowStep * srcRowStride;
- dst += dstRowStride;
- }
-
- /* This is ugly but probably won't be used much */
- if (border > 0) {
- /* fill in dest border */
- /* lower-left border pixel */
- assert(dstPtr);
- assert(srcPtr);
- memcpy(dstPtr, srcPtr, bpt);
- /* lower-right border pixel */
- memcpy(dstPtr + (dstWidth - 1) * bpt,
- srcPtr + (srcWidth - 1) * bpt, bpt);
- /* upper-left border pixel */
- memcpy(dstPtr + dstWidth * (dstHeight - 1) * bpt,
- srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
- /* upper-right border pixel */
- memcpy(dstPtr + (dstWidth * dstHeight - 1) * bpt,
- srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
- /* lower border */
- do_row(datatype, comps, srcWidthNB,
- srcPtr + bpt,
- srcPtr + bpt,
- dstWidthNB, dstPtr + bpt);
- /* upper border */
- do_row(datatype, comps, srcWidthNB,
- srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
- srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
- dstWidthNB,
- dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
- /* left and right borders */
- if (srcHeight == dstHeight) {
- /* copy border pixel from src to dst */
- for (row = 1; row < srcHeight; row++) {
- memcpy(dstPtr + dstWidth * row * bpt,
- srcPtr + srcWidth * row * bpt, bpt);
- memcpy(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
- srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);
- }
- }
- else {
- /* average two src pixels each dest pixel */
- for (row = 0; row < dstHeightNB; row += 2) {
- do_row(datatype, comps, 1,
- srcPtr + (srcWidth * (row * 2 + 1)) * bpt,
- srcPtr + (srcWidth * (row * 2 + 2)) * bpt,
- 1, dstPtr + (dstWidth * row + 1) * bpt);
- do_row(datatype, comps, 1,
- srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt,
- srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt,
- 1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt);
- }
- }
- }
-}
-
-
-static void
-make_3d_mipmap(GLenum datatype, GLuint comps, GLint border,
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- const GLubyte **srcPtr, GLint srcRowStride,
- GLint dstWidth, GLint dstHeight, GLint dstDepth,
- GLubyte **dstPtr, GLint dstRowStride)
-{
- const GLint bpt = bytes_per_pixel(datatype, comps);
- const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */
- const GLint srcDepthNB = srcDepth - 2 * border;
- const GLint dstWidthNB = dstWidth - 2 * border;
- const GLint dstHeightNB = dstHeight - 2 * border;
- const GLint dstDepthNB = dstDepth - 2 * border;
- GLint img, row;
- GLint bytesPerSrcImage, bytesPerDstImage;
- GLint bytesPerSrcRow, bytesPerDstRow;
- GLint srcImageOffset, srcRowOffset;
-
- (void) srcDepthNB; /* silence warnings */
-
-
- bytesPerSrcImage = srcWidth * srcHeight * bpt;
- bytesPerDstImage = dstWidth * dstHeight * bpt;
-
- bytesPerSrcRow = srcWidth * bpt;
- bytesPerDstRow = dstWidth * bpt;
-
- /* Offset between adjacent src images to be averaged together */
- srcImageOffset = (srcDepth == dstDepth) ? 0 : 1;
-
- /* Offset between adjacent src rows to be averaged together */
- srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt;
-
- /*
- * Need to average together up to 8 src pixels for each dest pixel.
- * Break that down into 3 operations:
- * 1. take two rows from source image and average them together.
- * 2. take two rows from next source image and average them together.
- * 3. take the two averaged rows and average them for the final dst row.
- */
-
- /*
- printf("mip3d %d x %d x %d -> %d x %d x %d\n",
- srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth);
- */
-
- for (img = 0; img < dstDepthNB; img++) {
- /* first source image pointer, skipping border */
- const GLubyte *imgSrcA = srcPtr[img * 2 + border]
- + bytesPerSrcRow * border + bpt * border;
- /* second source image pointer, skipping border */
- const GLubyte *imgSrcB = srcPtr[img * 2 + srcImageOffset + border]
- + bytesPerSrcRow * border + bpt * border;
-
- /* address of the dest image, skipping border */
- GLubyte *imgDst = dstPtr[img + border]
- + bytesPerDstRow * border + bpt * border;
-
- /* setup the four source row pointers and the dest row pointer */
- const GLubyte *srcImgARowA = imgSrcA;
- const GLubyte *srcImgARowB = imgSrcA + srcRowOffset;
- const GLubyte *srcImgBRowA = imgSrcB;
- const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset;
- GLubyte *dstImgRow = imgDst;
-
- for (row = 0; row < dstHeightNB; row++) {
- do_row_3D(datatype, comps, srcWidthNB,
- srcImgARowA, srcImgARowB,
- srcImgBRowA, srcImgBRowB,
- dstWidthNB, dstImgRow);
-
- /* advance to next rows */
- srcImgARowA += bytesPerSrcRow + srcRowOffset;
- srcImgARowB += bytesPerSrcRow + srcRowOffset;
- srcImgBRowA += bytesPerSrcRow + srcRowOffset;
- srcImgBRowB += bytesPerSrcRow + srcRowOffset;
- dstImgRow += bytesPerDstRow;
- }
- }
-
-
- /* Luckily we can leverage the make_2d_mipmap() function here! */
- if (border > 0) {
- /* do front border image */
- make_2d_mipmap(datatype, comps, 1,
- srcWidth, srcHeight, srcPtr[0], srcRowStride,
- dstWidth, dstHeight, dstPtr[0], dstRowStride);
- /* do back border image */
- make_2d_mipmap(datatype, comps, 1,
- srcWidth, srcHeight, srcPtr[srcDepth - 1], srcRowStride,
- dstWidth, dstHeight, dstPtr[dstDepth - 1], dstRowStride);
-
- /* do four remaining border edges that span the image slices */
- if (srcDepth == dstDepth) {
- /* just copy border pixels from src to dst */
- for (img = 0; img < dstDepthNB; img++) {
- const GLubyte *src;
- GLubyte *dst;
-
- /* do border along [img][row=0][col=0] */
- src = srcPtr[img * 2];
- dst = dstPtr[img];
- memcpy(dst, src, bpt);
-
- /* do border along [img][row=dstHeight-1][col=0] */
- src = srcPtr[img * 2] + (srcHeight - 1) * bytesPerSrcRow;
- dst = dstPtr[img] + (dstHeight - 1) * bytesPerDstRow;
- memcpy(dst, src, bpt);
-
- /* do border along [img][row=0][col=dstWidth-1] */
- src = srcPtr[img * 2] + (srcWidth - 1) * bpt;
- dst = dstPtr[img] + (dstWidth - 1) * bpt;
- memcpy(dst, src, bpt);
-
- /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
- src = srcPtr[img * 2] + (bytesPerSrcImage - bpt);
- dst = dstPtr[img] + (bytesPerDstImage - bpt);
- memcpy(dst, src, bpt);
- }
- }
- else {
- /* average border pixels from adjacent src image pairs */
- ASSERT(srcDepthNB == 2 * dstDepthNB);
- for (img = 0; img < dstDepthNB; img++) {
- const GLubyte *srcA, *srcB;
- GLubyte *dst;
-
- /* do border along [img][row=0][col=0] */
- srcA = srcPtr[img * 2 + 0];
- srcB = srcPtr[img * 2 + srcImageOffset];
- dst = dstPtr[img];
- do_row(datatype, comps, 1, srcA, srcB, 1, dst);
-
- /* do border along [img][row=dstHeight-1][col=0] */
- srcA = srcPtr[img * 2 + 0]
- + (srcHeight - 1) * bytesPerSrcRow;
- srcB = srcPtr[img * 2 + srcImageOffset]
- + (srcHeight - 1) * bytesPerSrcRow;
- dst = dstPtr[img] + (dstHeight - 1) * bytesPerDstRow;
- do_row(datatype, comps, 1, srcA, srcB, 1, dst);
-
- /* do border along [img][row=0][col=dstWidth-1] */
- srcA = srcPtr[img * 2 + 0] + (srcWidth - 1) * bpt;
- srcB = srcPtr[img * 2 + srcImageOffset] + (srcWidth - 1) * bpt;
- dst = dstPtr[img] + (dstWidth - 1) * bpt;
- do_row(datatype, comps, 1, srcA, srcB, 1, dst);
-
- /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
- srcA = srcPtr[img * 2 + 0] + (bytesPerSrcImage - bpt);
- srcB = srcPtr[img * 2 + srcImageOffset] + (bytesPerSrcImage - bpt);
- dst = dstPtr[img] + (bytesPerDstImage - bpt);
- do_row(datatype, comps, 1, srcA, srcB, 1, dst);
- }
- }
- }
-}
-
-
-/**
- * Down-sample a texture image to produce the next lower mipmap level.
- * \param comps components per texel (1, 2, 3 or 4)
- * \param srcData array[slice] of pointers to source image slices
- * \param dstData array[slice] of pointers to dest image slices
- * \param srcRowStride stride between source rows, in bytes
- * \param dstRowStride stride between destination rows, in bytes
- */
-void
-_mesa_generate_mipmap_level(GLenum target,
- GLenum datatype, GLuint comps,
- GLint border,
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- const GLubyte **srcData,
- GLint srcRowStride,
- GLint dstWidth, GLint dstHeight, GLint dstDepth,
- GLubyte **dstData,
- GLint dstRowStride)
-{
- switch (target) {
- case GL_TEXTURE_1D:
- make_1d_mipmap(datatype, comps, border,
- srcWidth, srcData[0],
- dstWidth, dstData[0]);
- break;
- case GL_TEXTURE_2D:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
- make_2d_mipmap(datatype, comps, border,
- srcWidth, srcHeight, srcData[0], srcRowStride,
- dstWidth, dstHeight, dstData[0], dstRowStride);
- break;
- case GL_TEXTURE_3D:
- make_3d_mipmap(datatype, comps, border,
- srcWidth, srcHeight, srcDepth,
- srcData, srcRowStride,
- dstWidth, dstHeight, dstDepth,
- dstData, dstRowStride);
- break;
- default:
- _mesa_problem(NULL, "bad tex target in _mesa_generate_mipmaps");
- return;
- }
-}
-
-
-/**
- * compute next (level+1) image size
- * \return GL_FALSE if no smaller size can be generated (eg. src is 1x1x1 size)
- */
-static GLboolean
-next_mipmap_level_size(GLenum target, GLint border,
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- GLint *dstWidth, GLint *dstHeight, GLint *dstDepth)
-{
- if (srcWidth - 2 * border > 1) {
- *dstWidth = (srcWidth - 2 * border) / 2 + 2 * border;
- }
- else {
- *dstWidth = srcWidth; /* can't go smaller */
- }
-
- if (srcHeight - 2 * border > 1) {
- *dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;
- }
- else {
- *dstHeight = srcHeight; /* can't go smaller */
- }
-
- if (srcDepth - 2 * border > 1) {
- *dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;
- }
- else {
- *dstDepth = srcDepth; /* can't go smaller */
- }
-
- if (*dstWidth == srcWidth &&
- *dstHeight == srcHeight &&
- *dstDepth == srcDepth) {
- return GL_FALSE;
- }
- else {
- return GL_TRUE;
- }
-}
-
-
-/**
- * Helper function for mipmap generation.
- * Make sure the specified destination mipmap level is the right size/format
- * for mipmap generation. If not, (re) allocate it.
- * \return GL_TRUE if successful, GL_FALSE if mipmap generation should stop
- */
-GLboolean
-_mesa_prepare_mipmap_level(struct gl_context *ctx,
- struct gl_texture_object *texObj, GLuint level,
- GLsizei width, GLsizei height, GLsizei depth,
- GLsizei border, GLenum intFormat, gl_format format)
-{
- const GLuint numFaces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1;
- GLuint face;
-
- if (texObj->Immutable) {
- /* The texture was created with glTexStorage() so the number/size of
- * mipmap levels is fixed and the storage for all images is already
- * allocated.
- */
- if (!texObj->Image[0][level]) {
- /* No more levels to create - we're done */
- return GL_FALSE;
- }
- else {
- /* Nothing to do - the texture memory must have already been
- * allocated to the right size so we're all set.
- */
- return GL_TRUE;
- }
- }
-
- for (face = 0; face < numFaces; face++) {
- struct gl_texture_image *dstImage;
- GLenum target;
-
- if (numFaces == 1)
- target = texObj->Target;
- else
- target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
-
- dstImage = _mesa_get_tex_image(ctx, texObj, target, level);
- if (!dstImage) {
- /* out of memory */
- return GL_FALSE;
- }
-
- if (dstImage->Width != width ||
- dstImage->Height != height ||
- dstImage->Depth != depth ||
- dstImage->Border != border ||
- dstImage->InternalFormat != intFormat ||
- dstImage->TexFormat != format) {
- /* need to (re)allocate image */
- ctx->Driver.FreeTextureImageBuffer(ctx, dstImage);
-
- _mesa_init_teximage_fields(ctx, dstImage,
- width, height, depth,
- border, intFormat, format);
-
- ctx->Driver.AllocTextureImageBuffer(ctx, dstImage,
- format, width, height, depth);
-
- /* in case the mipmap level is part of an FBO: */
- _mesa_update_fbo_texture(ctx, texObj, face, level);
-
- ctx->NewState |= _NEW_TEXTURE;
- }
- }
-
- return GL_TRUE;
-}
-
-
-static void
-generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
- struct gl_texture_object *texObj,
- const struct gl_texture_image *srcImage,
- GLuint maxLevel)
-{
- GLint level;
- GLenum datatype;
- GLuint comps;
-
- _mesa_format_to_type_and_comps(srcImage->TexFormat, &datatype, &comps);
-
- for (level = texObj->BaseLevel; level < maxLevel; level++) {
- /* generate image[level+1] from image[level] */
- struct gl_texture_image *srcImage, *dstImage;
- GLint srcRowStride, dstRowStride;
- GLint srcWidth, srcHeight, srcDepth;
- GLint dstWidth, dstHeight, dstDepth;
- GLint border;
- GLint slice;
- GLboolean nextLevel;
- GLubyte **srcMaps, **dstMaps;
- GLboolean success = GL_TRUE;
-
- /* get src image parameters */
- srcImage = _mesa_select_tex_image(ctx, texObj, target, level);
- ASSERT(srcImage);
- srcWidth = srcImage->Width;
- srcHeight = srcImage->Height;
- srcDepth = srcImage->Depth;
- border = srcImage->Border;
-
- nextLevel = next_mipmap_level_size(target, border,
- srcWidth, srcHeight, srcDepth,
- &dstWidth, &dstHeight, &dstDepth);
- if (!nextLevel)
- return;
-
- if (!_mesa_prepare_mipmap_level(ctx, texObj, level + 1,
- dstWidth, dstHeight, dstDepth,
- border, srcImage->InternalFormat,
- srcImage->TexFormat)) {
- return;
- }
-
- /* get dest gl_texture_image */
- dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1);
- if (!dstImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
- return;
- }
-
- /* Map src texture image slices */
- srcMaps = (GLubyte **) calloc(srcDepth, sizeof(GLubyte *));
- if (srcMaps) {
- for (slice = 0; slice < srcDepth; slice++) {
- ctx->Driver.MapTextureImage(ctx, srcImage, slice,
- 0, 0, srcWidth, srcHeight,
- GL_MAP_READ_BIT,
- &srcMaps[slice], &srcRowStride);
- if (!srcMaps[slice]) {
- success = GL_FALSE;
- break;
- }
- }
- }
- else {
- success = GL_FALSE;
- }
-
- /* Map dst texture image slices */
- dstMaps = (GLubyte **) calloc(dstDepth, sizeof(GLubyte *));
- if (dstMaps) {
- for (slice = 0; slice < dstDepth; slice++) {
- ctx->Driver.MapTextureImage(ctx, dstImage, slice,
- 0, 0, dstWidth, dstHeight,
- GL_MAP_WRITE_BIT,
- &dstMaps[slice], &dstRowStride);
- if (!dstMaps[slice]) {
- success = GL_FALSE;
- break;
- }
- }
- }
- else {
- success = GL_FALSE;
- }
-
- if (success) {
- /* generate one mipmap level (for 1D/2D/3D/array/etc texture) */
- _mesa_generate_mipmap_level(target, datatype, comps, border,
- srcWidth, srcHeight, srcDepth,
- (const GLubyte **) srcMaps, srcRowStride,
- dstWidth, dstHeight, dstDepth,
- dstMaps, dstRowStride);
- }
-
- /* Unmap src image slices */
- if (srcMaps) {
- for (slice = 0; slice < srcDepth; slice++) {
- if (srcMaps[slice]) {
- ctx->Driver.UnmapTextureImage(ctx, srcImage, slice);
- }
- }
- free(srcMaps);
- }
-
- /* Unmap dst image slices */
- if (dstMaps) {
- for (slice = 0; slice < dstDepth; slice++) {
- if (dstMaps[slice]) {
- ctx->Driver.UnmapTextureImage(ctx, dstImage, slice);
- }
- }
- free(dstMaps);
- }
-
- if (!success) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "mipmap generation");
- break;
- }
- } /* loop over mipmap levels */
-}
-
-/**
- * Automatic mipmap generation.
- * This is the fallback/default function for ctx->Driver.GenerateMipmap().
- * Generate a complete set of mipmaps from texObj's BaseLevel image.
- * Stop at texObj's MaxLevel or when we get to the 1x1 texture.
- * For cube maps, target will be one of
- * GL_TEXTURE_CUBE_MAP_POSITIVE/NEGATIVE_X/Y/Z; never GL_TEXTURE_CUBE_MAP.
- */
-void
-_mesa_generate_mipmap(struct gl_context *ctx, GLenum target,
- struct gl_texture_object *texObj)
-{
- struct gl_texture_image *srcImage;
- GLint maxLevel;
-
- ASSERT(texObj);
- srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel);
- ASSERT(srcImage);
-
- maxLevel = _mesa_max_texture_levels(ctx, texObj->Target) - 1;
- ASSERT(maxLevel >= 0); /* bad target */
-
- maxLevel = MIN2(maxLevel, texObj->MaxLevel);
-
- generate_mipmap_uncompressed(ctx, target, texObj, srcImage, maxLevel);
-}
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.2
- *
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#ifndef MIPMAP_H
-#define MIPMAP_H
-
-#include "mtypes.h"
-
-
-extern void
-_mesa_generate_mipmap_level(GLenum target,
- GLenum datatype, GLuint comps,
- GLint border,
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- const GLubyte **srcData,
- GLint srcRowStride,
- GLint dstWidth, GLint dstHeight, GLint dstDepth,
- GLubyte **dstData,
- GLint dstRowStride);
-
-
-extern GLboolean
-_mesa_prepare_mipmap_level(struct gl_context *ctx,
- struct gl_texture_object *texObj, GLuint level,
- GLsizei width, GLsizei height, GLsizei depth,
- GLsizei border, GLenum intFormat, gl_format format);
-
-extern void
-_mesa_generate_mipmap(struct gl_context *ctx, GLenum target,
- struct gl_texture_object *texObj);
-
-
-#endif /* MIPMAP_H */
BUFFER_ACCUM,
/* optional aux buffer */
BUFFER_AUX0,
- /* generic renderbuffers */
- BUFFER_COLOR0,
- BUFFER_COLOR1,
- BUFFER_COLOR2,
- BUFFER_COLOR3,
- BUFFER_COLOR4,
- BUFFER_COLOR5,
- BUFFER_COLOR6,
- BUFFER_COLOR7,
BUFFER_COUNT
} gl_buffer_index;
#define BUFFER_BIT_DEPTH (1 << BUFFER_DEPTH)
#define BUFFER_BIT_STENCIL (1 << BUFFER_STENCIL)
#define BUFFER_BIT_ACCUM (1 << BUFFER_ACCUM)
-#define BUFFER_BIT_COLOR0 (1 << BUFFER_COLOR0)
-#define BUFFER_BIT_COLOR1 (1 << BUFFER_COLOR1)
-#define BUFFER_BIT_COLOR2 (1 << BUFFER_COLOR2)
-#define BUFFER_BIT_COLOR3 (1 << BUFFER_COLOR3)
-#define BUFFER_BIT_COLOR4 (1 << BUFFER_COLOR4)
-#define BUFFER_BIT_COLOR5 (1 << BUFFER_COLOR5)
-#define BUFFER_BIT_COLOR6 (1 << BUFFER_COLOR6)
-#define BUFFER_BIT_COLOR7 (1 << BUFFER_COLOR7)
/**
* Mask of all the color buffer bits (but not accum).
BUFFER_BIT_BACK_LEFT | \
BUFFER_BIT_FRONT_RIGHT | \
BUFFER_BIT_BACK_RIGHT | \
- BUFFER_BIT_AUX0 | \
- BUFFER_BIT_COLOR0 | \
- BUFFER_BIT_COLOR1 | \
- BUFFER_BIT_COLOR2 | \
- BUFFER_BIT_COLOR3 | \
- BUFFER_BIT_COLOR4 | \
- BUFFER_BIT_COLOR5 | \
- BUFFER_BIT_COLOR6 | \
- BUFFER_BIT_COLOR7)
+ BUFFER_BIT_AUX0)
/**
struct gl_config
{
GLboolean rgbMode;
- GLboolean floatMode;
GLboolean colorIndexMode; /* XXX is this used anywhere? */
GLuint doubleBufferMode;
GLuint stereoMode;
GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha;
GLint transparentIndex;
- /* ARB_multisample / SGIS_multisample */
- GLint sampleBuffers;
- GLint samples;
-
/* SGIX_pbuffer / GLX 1.3 */
GLint maxPbufferWidth;
GLint maxPbufferHeight;
/*@{*/
GLboolean AlphaEnabled; /**< Alpha test enabled flag */
GLenum AlphaFunc; /**< Alpha test function */
- GLfloat AlphaRefUnclamped;
GLclampf AlphaRef; /**< Alpha reference value */
/*@}*/
* control, only on the fixed-pointness of the render target.
* The query does however depend on fragment color clamping.
*/
- GLfloat BlendColorUnclamped[4]; /**< Blending color */
- GLfloat BlendColor[4]; /**< Blending color */
+ GLfloat BlendColor[4]; /**< Blending color */
GLenum SrcRGB; /**< RGB blend source term */
GLenum DstRGB; /**< RGB blend dest term */
/*@}*/
GLboolean DitherFlag; /**< Dither enable flag */
-
- GLenum ClampFragmentColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */
- GLboolean _ClampFragmentColor; /** < with GL_FIXED_ONLY_ARB resolved */
- GLenum ClampReadColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */
- GLboolean _ClampReadColor; /** < with GL_FIXED_ONLY_ARB resolved */
};
struct gl_fog_attrib
{
GLboolean Enabled; /**< Fog enabled flag */
- GLfloat ColorUnclamped[4]; /**< Fog color */
GLfloat Color[4]; /**< Fog color */
GLfloat Density; /**< Density >= 0.0 */
GLfloat Start; /**< Start distance in eye coords */
GLenum PolygonSmooth;
GLenum Fog;
GLenum ClipVolumeClipping; /**< GL_EXT_clip_volume_hint */
- GLenum TextureCompression; /**< GL_ARB_texture_compression */
- GLenum GenerateMipmap; /**< GL_SGIS_generate_mipmap */
GLenum FragmentShaderDerivative; /**< GL_ARB_fragment_shader */
};
GLenum ColorMaterialMode; /**< GL_AMBIENT, GL_DIFFUSE, etc */
GLbitfield ColorMaterialBitmask; /**< bitmask formed from Face and Mode */
GLboolean ColorMaterialEnabled;
- GLenum ClampVertexColor;
- GLboolean _ClampVertexColor;
struct gl_light EnabledList; /**< List sentinel */
GLenum MinFilter; /**< minification filter */
GLenum MagFilter; /**< magnification filter */
union gl_color_union BorderColor; /**< Interpreted according to texture format */
- GLfloat MinLod; /**< min lambda, OpenGL 1.2 */
- GLfloat MaxLod; /**< max lambda, OpenGL 1.2 */
- GLfloat LodBias; /**< OpenGL 1.4 */
GLfloat MaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */
};
GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */
GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */
GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */
- GLboolean GenerateMipmap; /**< GL_SGIS_generate_mipmap */
GLboolean _Complete; /**< Is texture object complete? */
- GLboolean _RenderToTexture; /**< Any rendering to this texture? */
GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
GLboolean Immutable; /**< GL_ARB_texture_storage */
GLenum EnvMode; /**< GL_MODULATE, GL_DECAL, GL_BLEND, etc. */
GLclampf EnvColor[4];
- GLfloat EnvColorUnclamped[4];
struct gl_texgen GenS;
struct gl_texgen GenT;
{
_glthread_Mutex Mutex; /**< for thread safety */
GLuint ClassID; /**< Useful for drivers */
- GLuint Name;
GLint RefCount;
GLuint Width, Height;
GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
GLboolean AttachedAnytime; /**< TRUE if it was attached to a framebuffer */
- GLubyte NumSamples;
GLenum InternalFormat; /**< The user-specified format */
GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT or
GL_STENCIL_INDEX. */
*/
struct gl_renderbuffer_attachment
{
- GLenum Type; /**< \c GL_NONE or \c GL_TEXTURE or \c GL_RENDERBUFFER_EXT */
- GLboolean Complete;
-
/**
* If \c Type is \c GL_RENDERBUFFER_EXT, this stores a pointer to the
* application supplied renderbuffer object.
*/
struct gl_renderbuffer *Renderbuffer;
-
- /**
- * If \c Type is \c GL_TEXTURE, this stores a pointer to the application
- * supplied texture object.
- */
- struct gl_texture_object *Texture;
- GLuint TextureLevel; /**< Attached mipmap level. */
- GLuint CubeMapFace; /**< 0 .. 5, for cube map textures. */
- GLuint Zoffset; /**< Slice for 3D textures, or layer for both 1D
- * and 2D array textures */
};
struct gl_framebuffer
{
_glthread_Mutex Mutex; /**< for thread safety */
- /**
- * If zero, this is a window system framebuffer. If non-zero, this
- * is a FBO framebuffer; note that for some devices (i.e. those with
- * a natural pixel coordinate system for FBOs that differs from the
- * OpenGL/Mesa coordinate system), this means that the viewport,
- * polygon face orientation, and polygon stipple will have to be inverted.
- */
- GLuint Name;
GLint RefCount;
GLboolean DeletePending;
GLfloat _MRD; /**< minimum resolvable difference in Z values */
/*@}*/
- /** One of the GL_FRAMEBUFFER_(IN)COMPLETE_* tokens */
- GLenum _Status;
-
/** Integer color values */
GLboolean _IntegerColor;
GLuint MaxCombinedTextureImageUnits;
GLuint MaxTextureUnits; /**< = MIN(CoordUnits, ImageUnits) */
GLfloat MaxTextureMaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */
- GLfloat MaxTextureLodBias; /**< GL_EXT_texture_lod_bias */
GLuint MaxArrayLockSize;
/** vertex array / buffer object bounds checking */
GLboolean CheckArrayBounds;
- GLuint MaxColorAttachments; /**< GL_EXT_framebuffer_object */
- GLuint MaxRenderbufferSize; /**< GL_EXT_framebuffer_object */
- GLuint MaxSamples; /**< GL_ARB_framebuffer_object */
-
/** Number of varying vectors between vertex and fragment shaders */
GLuint MaxVarying;
GLboolean dummy; /* don't remove this! */
GLboolean dummy_true; /* Set true by _mesa_init_extensions(). */
GLboolean dummy_false; /* Set false by _mesa_init_extensions(). */
- GLboolean ARB_color_buffer_float;
GLboolean ARB_conservative_depth;
GLboolean ARB_fragment_program;
GLboolean ARB_fragment_program_shadow;
GLboolean ARB_fragment_shader;
- GLboolean ARB_framebuffer_object;
GLboolean ARB_half_float_pixel;
GLboolean ARB_half_float_vertex;
GLboolean ARB_map_buffer_range;
GLboolean EXT_depth_bounds_test;
GLboolean EXT_draw_range_elements;
GLboolean EXT_fog_coord;
- GLboolean EXT_framebuffer_blit;
- GLboolean EXT_framebuffer_multisample;
- GLboolean EXT_framebuffer_object;
GLboolean EXT_gpu_program_parameters;
GLboolean EXT_gpu_shader4;
GLboolean EXT_packed_pixels;
GLboolean NV_texture_env_combine4;
GLboolean NV_vertex_program;
GLboolean NV_vertex_program1_1;
- GLboolean SGIS_texture_lod;
GLboolean extension_sentinel;
/** The extension string */
const GLubyte *String;
#define _NEW_PROGRAM (1 << 26) /**< New program/shader state */
#define _NEW_PROGRAM_CONSTANTS (1 << 27)
#define _NEW_BUFFER_OBJECT (1 << 28)
-#define _NEW_FRAG_CLAMP (1 << 29)
#define _NEW_ALL ~0
/**
if (!rb)
return;
- if ((ctx->Color._ClampReadColor == GL_TRUE || type != GL_FLOAT) &&
- !_mesa_is_integer_format(format)) {
+ if (!_mesa_is_integer_format(format)) {
transferOps |= IMAGE_CLAMP_BIT;
}
return;
}
- if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glReadPixels(incomplete framebuffer)" );
- return;
- }
-
/* Check that the destination format and source buffer are both
* integer-valued or both non-integer-valued.
*/
}
}
- if (ctx->ReadBuffer->Name != 0 && ctx->ReadBuffer->Visual.samples > 0) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)");
- return;
- }
-
if (!_mesa_source_buffer_exists(ctx, format)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)");
return;
#include "glheader.h"
#include "imports.h"
#include "context.h"
-#include "fbobject.h"
#include "formats.h"
#include "mtypes.h"
#include "renderbuffer.h"
_glthread_INIT_MUTEX(rb->Mutex);
rb->ClassID = 0;
- rb->Name = name;
rb->RefCount = 0;
rb->Delete = _mesa_delete_renderbuffer;
}
-/**
- * Allocate a new gl_renderbuffer object. This can be used for user-created
- * renderbuffers or window-system renderbuffers.
- */
-struct gl_renderbuffer *
-_mesa_new_renderbuffer(struct gl_context *ctx, GLuint name)
-{
- struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
- if (rb) {
- _mesa_init_renderbuffer(rb, name);
- }
- return rb;
-}
-
-
/**
* Delete a gl_framebuffer.
* This is the default function for renderbuffer->Delete().
bufferName == BUFFER_STENCIL ||
fb->Attachment[bufferName].Renderbuffer == NULL);
- /* winsys vs. user-created buffer cross check */
- if (fb->Name) {
- assert(rb->Name);
- }
- else {
- assert(!rb->Name);
- }
-
- fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT;
- fb->Attachment[bufferName].Complete = GL_TRUE;
_mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb);
}
extern void
_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name);
-extern struct gl_renderbuffer *
-_mesa_new_renderbuffer(struct gl_context *ctx, GLuint name);
-
extern void
_mesa_delete_renderbuffer(struct gl_renderbuffer *rb);
}
-/**
- * Update derived multisample state.
- */
-static void
-update_multisample(struct gl_context *ctx)
-{
- ctx->Multisample._Enabled = GL_FALSE;
- if (ctx->Multisample.Enabled &&
- ctx->DrawBuffer &&
- ctx->DrawBuffer->Visual.sampleBuffers)
- ctx->Multisample._Enabled = GL_TRUE;
-}
-
-
-/**
- * Update the ctx->Color._ClampFragmentColor field
- */
-static void
-update_clamp_fragment_color(struct gl_context *ctx)
-{
- if (ctx->Color.ClampFragmentColor == GL_FIXED_ONLY_ARB)
- ctx->Color._ClampFragmentColor =
- !ctx->DrawBuffer || !ctx->DrawBuffer->Visual.floatMode;
- else
- ctx->Color._ClampFragmentColor = ctx->Color.ClampFragmentColor;
-}
-
-
-/**
- * Update the ctx->Color._ClampVertexColor field
- */
-static void
-update_clamp_vertex_color(struct gl_context *ctx)
-{
- if (ctx->Light.ClampVertexColor == GL_FIXED_ONLY_ARB)
- ctx->Light._ClampVertexColor =
- !ctx->DrawBuffer || !ctx->DrawBuffer->Visual.floatMode;
- else
- ctx->Light._ClampVertexColor = ctx->Light.ClampVertexColor;
-}
-
-
-/**
- * Update the ctx->Color._ClampReadColor field
- */
-static void
-update_clamp_read_color(struct gl_context *ctx)
-{
- if (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB)
- ctx->Color._ClampReadColor =
- !ctx->ReadBuffer || !ctx->ReadBuffer->Visual.floatMode;
- else
- ctx->Color._ClampReadColor = ctx->Color.ClampReadColor;
-}
-
/**
* Update the ctx->VertexProgram._TwoSideEnabled flag.
*/
if (new_state & (_NEW_LIGHT | _NEW_PROGRAM))
update_twoside( ctx );
- if (new_state & (_NEW_LIGHT | _NEW_BUFFERS))
- update_clamp_vertex_color(ctx);
-
if (new_state & (_NEW_STENCIL | _NEW_BUFFERS))
_mesa_update_stencil( ctx );
if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT))
update_viewport_matrix(ctx);
- if (new_state & (_NEW_MULTISAMPLE | _NEW_BUFFERS))
- update_multisample( ctx );
-
- if (new_state & (_NEW_COLOR | _NEW_BUFFERS))
- update_clamp_read_color(ctx);
-
- if(new_state & (_NEW_FRAG_CLAMP | _NEW_BUFFERS))
- update_clamp_fragment_color(ctx);
-
#if 0
if (new_state & (_NEW_POINT | _NEW_LINE | _NEW_POLYGON | _NEW_LIGHT
| _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR))
struct gl_texture_unit *texUnit,
const GLfloat *color)
{
- if (TEST_EQ_4V(color, texUnit->EnvColorUnclamped))
+ if (TEST_EQ_4V(color, texUnit->EnvColor))
return;
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
- COPY_4FV(texUnit->EnvColorUnclamped, color);
- texUnit->EnvColor[0] = CLAMP(color[0], 0.0F, 1.0F);
- texUnit->EnvColor[1] = CLAMP(color[1], 0.0F, 1.0F);
- texUnit->EnvColor[2] = CLAMP(color[2], 0.0F, 1.0F);
- texUnit->EnvColor[3] = CLAMP(color[3], 0.0F, 1.0F);
+ COPY_4FV(texUnit->EnvColor, color);
}
if (target == GL_TEXTURE_ENV) {
if (pname == GL_TEXTURE_ENV_COLOR) {
- if(ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
+ if(ctx->NewState & _NEW_BUFFERS)
_mesa_update_state(ctx);
- if(ctx->Color._ClampFragmentColor)
- COPY_4FV( params, texUnit->EnvColor );
- else
- COPY_4FV( params, texUnit->EnvColorUnclamped );
+ COPY_4FV( params, texUnit->EnvColor );
}
else {
GLint val = get_texenvi(ctx, texUnit, pname);
#include "bufferobj.h"
#include "context.h"
#include "enums.h"
-#include "fbobject.h"
#include "framebuffer.h"
#include "hash.h"
#include "image.h"
return GL_TRUE;
}
- /* Check that the source buffer is complete */
- if (ctx->ReadBuffer->Name) {
- if (ctx->ReadBuffer->_Status == 0) {
- _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
- }
- if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glCopyTexImage%dD(invalid readbuffer)", dimensions);
- return GL_TRUE;
- }
-
- if (ctx->ReadBuffer->Visual.samples > 0) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION,
- "glCopyTexImage%dD(multisample FBO)",
- dimensions);
- return GL_TRUE;
- }
- }
-
/* Check border */
if (border < 0 || border > 1) {
return GL_TRUE;
copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions,
GLenum target, GLint level)
{
- /* Check that the source buffer is complete */
- if (ctx->ReadBuffer->Name) {
- if (ctx->ReadBuffer->_Status == 0) {
- _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
- }
- if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glCopyTexImage%dD(invalid readbuffer)", dimensions);
- return GL_TRUE;
- }
-
- if (ctx->ReadBuffer->Visual.samples > 0) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION,
- "glCopyTexSubImage%dD(multisample FBO)",
- dimensions);
- return GL_TRUE;
- }
- }
-
/* check target (proxies not allowed) */
if (!legal_texsubimage_target(ctx, dimensions, target)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%uD(target=%s)",
GLuint level, face;
};
-
-/**
- * Check render to texture callback. Called from _mesa_HashWalk().
- */
-static void
-check_rtt_cb(GLuint key, void *data, void *userData)
-{
- struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
- const struct cb_info *info = (struct cb_info *) userData;
- struct gl_context *ctx = info->ctx;
- const struct gl_texture_object *texObj = info->texObj;
- const GLuint level = info->level, face = info->face;
-
- /* If this is a user-created FBO */
- if (fb->Name) {
- GLuint i;
- /* check if any of the FBO's attachments point to 'texObj' */
- for (i = 0; i < BUFFER_COUNT; i++) {
- struct gl_renderbuffer_attachment *att = fb->Attachment + i;
- if (att->Type == GL_TEXTURE &&
- att->Texture == texObj &&
- att->TextureLevel == level &&
- att->CubeMapFace == face) {
- ASSERT(_mesa_get_attachment_teximage(att));
- /* Tell driver about the new renderbuffer texture */
- ctx->Driver.RenderTexture(ctx, ctx->DrawBuffer, att);
- /* Mark fb status as indeterminate to force re-validation */
- fb->_Status = 0;
- }
- }
- }
-}
-
-
-/**
- * When a texture image is specified we have to check if it's bound to
- * any framebuffer objects (render to texture) in order to detect changes
- * in size or format since that effects FBO completeness.
- * Any FBOs rendering into the texture must be re-validated.
- */
-void
-_mesa_update_fbo_texture(struct gl_context *ctx,
- struct gl_texture_object *texObj,
- GLuint face, GLuint level)
-{
- /* Only check this texture if it's been marked as RenderToTexture */
- if (texObj->_RenderToTexture) {
- struct cb_info info;
- info.ctx = ctx;
- info.texObj = texObj;
- info.level = level;
- info.face = face;
- _mesa_HashWalk(ctx->Shared->FrameBuffers, check_rtt_cb, &info);
- }
-}
-
-
-/**
- * If the texture object's GenerateMipmap flag is set and we've
- * changed the texture base level image, regenerate the rest of the
- * mipmap levels now.
- */
-static inline void
-check_gen_mipmap(struct gl_context *ctx, GLenum target,
- struct gl_texture_object *texObj, GLint level)
-{
- ASSERT(target != GL_TEXTURE_CUBE_MAP);
- if (texObj->GenerateMipmap &&
- level == texObj->BaseLevel &&
- level < texObj->MaxLevel) {
- ASSERT(ctx->Driver.GenerateMipmap);
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
-}
-
-
/** Debug helper: override the user-requested internal format */
static GLenum
override_internal_format(GLenum internalFormat, GLint width, GLint height)
}
else {
/* non-proxy target */
- const GLuint face = _mesa_tex_target_to_face(target);
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
_mesa_problem(ctx, "invalid dims=%u in teximage()", dims);
}
- check_gen_mipmap(ctx, target, texObj, level);
-
- _mesa_update_fbo_texture(ctx, texObj, face, level);
-
/* state update */
texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
_mesa_problem(ctx, "unexpected dims in subteximage()");
}
- check_gen_mipmap(ctx, target, texObj, level);
-
ctx->NewState |= _NEW_TEXTURE;
}
}
{
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- const GLuint face = _mesa_tex_target_to_face(target);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
srcRb, srcX, srcY, width, height);
}
- check_gen_mipmap(ctx, target, texObj, level);
-
- _mesa_update_fbo_texture(ctx, texObj, face, level);
-
/* state update */
texObj->_Complete = GL_FALSE;
ctx->NewState |= _NEW_TEXTURE;
_mesa_problem(ctx, "bad dims in copytexsubimage()");
}
- check_gen_mipmap(ctx, target, texObj, level);
-
ctx->NewState |= _NEW_TEXTURE;
}
}
GLenum target, GLint level,
GLenum internalFormat, GLenum format, GLenum type);
-extern void
-_mesa_update_fbo_texture(struct gl_context *ctx,
- struct gl_texture_object *texObj,
- GLuint face, GLuint level);
-
extern void
_mesa_clear_texture_image(struct gl_context *ctx,
struct gl_texture_image *texImage);
#include "colortab.h"
#include "context.h"
#include "enums.h"
-#include "fbobject.h"
#include "formats.h"
#include "hash.h"
#include "imports.h"
obj->Sampler.MinFilter = GL_NEAREST_MIPMAP_LINEAR;
obj->Sampler.MagFilter = GL_LINEAR;
- obj->Sampler.MinLod = -1000.0;
- obj->Sampler.MaxLod = 1000.0;
- obj->Sampler.LodBias = 0.0;
obj->Sampler.MaxAnisotropy = 1.0;
}
dest->Sampler.WrapR = src->Sampler.WrapR;
dest->Sampler.MinFilter = src->Sampler.MinFilter;
dest->Sampler.MagFilter = src->Sampler.MagFilter;
- dest->Sampler.MinLod = src->Sampler.MinLod;
- dest->Sampler.MaxLod = src->Sampler.MaxLod;
- dest->Sampler.LodBias = src->Sampler.LodBias;
dest->BaseLevel = src->BaseLevel;
dest->MaxLevel = src->MaxLevel;
dest->Sampler.MaxAnisotropy = src->Sampler.MaxAnisotropy;
dest->_MaxLevel = src->_MaxLevel;
dest->_MaxLambda = src->_MaxLambda;
- dest->GenerateMipmap = src->GenerateMipmap;
dest->_Complete = src->_Complete;
}
_glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
}
-
-/**
- * Check if the given texture object is bound to the current draw or
- * read framebuffer. If so, Unbind it.
- */
-static void
-unbind_texobj_from_fbo(struct gl_context *ctx,
- struct gl_texture_object *texObj)
-{
- const GLuint n = (ctx->DrawBuffer == ctx->ReadBuffer) ? 1 : 2;
- GLuint i;
-
- for (i = 0; i < n; i++) {
- struct gl_framebuffer *fb = (i == 0) ? ctx->DrawBuffer : ctx->ReadBuffer;
- if (fb->Name) {
- GLuint j;
- for (j = 0; j < BUFFER_COUNT; j++) {
- if (fb->Attachment[j].Type == GL_TEXTURE &&
- fb->Attachment[j].Texture == texObj) {
- /* Vertices are already flushed by _mesa_DeleteTextures */
- ctx->NewState |= _NEW_BUFFERS;
- _mesa_remove_attachment(ctx, fb->Attachment + j);
- }
- }
- }
- }
-}
-
-
/**
* Check if the given texture object is bound to any texture image units and
* unbind it if so (revert to default textures).
if (delObj) {
_mesa_lock_texture(ctx, delObj);
- /* Check if texture is bound to any framebuffer objects.
- * If so, unbind.
- * See section 4.4.2.3 of GL_EXT_framebuffer_object.
- */
- unbind_texobj_from_fbo(ctx, delObj);
-
/* Check if this texture is currently bound to any texture units.
* If so, unbind it.
*/
}
return GL_FALSE;
- case GL_TEXTURE_BASE_LEVEL:
- if (texObj->BaseLevel == params[0])
- return GL_FALSE;
- if (params[0] < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexParameter(param=%d)", params[0]);
- return GL_FALSE;
- }
- incomplete(ctx, texObj);
- texObj->BaseLevel = params[0];
- return GL_TRUE;
-
- case GL_TEXTURE_MAX_LEVEL:
- if (texObj->MaxLevel == params[0])
- return GL_FALSE;
- if (params[0] < 0) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexParameter(param=%d)", params[0]);
- return GL_FALSE;
- }
- incomplete(ctx, texObj);
- texObj->MaxLevel = params[0];
- return GL_TRUE;
-
- case GL_GENERATE_MIPMAP_SGIS:
- if (texObj->GenerateMipmap != params[0]) {
- /* no flush() */
- texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
- return GL_TRUE;
- }
- return GL_FALSE;
-
default:
goto invalid_pname;
}
GLenum pname, const GLfloat *params)
{
switch (pname) {
- case GL_TEXTURE_MIN_LOD:
- if (texObj->Sampler.MinLod == params[0])
- return GL_FALSE;
- flush(ctx);
- texObj->Sampler.MinLod = params[0];
- return GL_TRUE;
-
- case GL_TEXTURE_MAX_LOD:
- if (texObj->Sampler.MaxLod == params[0])
- return GL_FALSE;
- flush(ctx);
- texObj->Sampler.MaxLod = params[0];
- return GL_TRUE;
case GL_TEXTURE_PRIORITY:
flush(ctx);
}
return GL_FALSE;
- case GL_TEXTURE_LOD_BIAS:
- /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias */
- if (texObj->Sampler.LodBias != params[0]) {
- flush(ctx);
- texObj->Sampler.LodBias = params[0];
- return GL_TRUE;
- }
- break;
-
case GL_TEXTURE_BORDER_COLOR:
flush(ctx);
/* ARB_texture_float disables clamping */
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
case GL_TEXTURE_WRAP_R:
- case GL_TEXTURE_BASE_LEVEL:
- case GL_TEXTURE_MAX_LEVEL:
- case GL_GENERATE_MIPMAP_SGIS:
case GL_TEXTURE_COMPARE_MODE_ARB:
case GL_TEXTURE_COMPARE_FUNC_ARB:
case GL_DEPTH_TEXTURE_MODE_ARB:
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
case GL_TEXTURE_WRAP_R:
- case GL_TEXTURE_BASE_LEVEL:
- case GL_TEXTURE_MAX_LEVEL:
- case GL_GENERATE_MIPMAP_SGIS:
case GL_TEXTURE_COMPARE_MODE_ARB:
case GL_TEXTURE_COMPARE_FUNC_ARB:
case GL_DEPTH_TEXTURE_MODE_ARB:
*params = ENUM_TO_FLOAT(obj->Sampler.WrapR);
break;
case GL_TEXTURE_BORDER_COLOR:
- if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
+ if (ctx->NewState & _NEW_BUFFERS)
_mesa_update_state_locked(ctx);
- if (ctx->Color._ClampFragmentColor) {
- params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
- params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
- params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
- params[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
- }
- else {
- params[0] = obj->Sampler.BorderColor.f[0];
- params[1] = obj->Sampler.BorderColor.f[1];
- params[2] = obj->Sampler.BorderColor.f[2];
- params[3] = obj->Sampler.BorderColor.f[3];
- }
+ params[0] = obj->Sampler.BorderColor.f[0];
+ params[1] = obj->Sampler.BorderColor.f[1];
+ params[2] = obj->Sampler.BorderColor.f[2];
+ params[3] = obj->Sampler.BorderColor.f[3];
break;
case GL_TEXTURE_RESIDENT:
*params = 1.0F;
case GL_TEXTURE_PRIORITY:
*params = obj->Priority;
break;
- case GL_TEXTURE_MIN_LOD:
- *params = obj->Sampler.MinLod;
- break;
- case GL_TEXTURE_MAX_LOD:
- *params = obj->Sampler.MaxLod;
- break;
- case GL_TEXTURE_BASE_LEVEL:
- *params = (GLfloat) obj->BaseLevel;
- break;
- case GL_TEXTURE_MAX_LEVEL:
- *params = (GLfloat) obj->MaxLevel;
- break;
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (!ctx->Extensions.EXT_texture_filter_anisotropic)
goto invalid_pname;
*params = obj->Sampler.MaxAnisotropy;
break;
- case GL_GENERATE_MIPMAP_SGIS:
- *params = (GLfloat) obj->GenerateMipmap;
- break;
- case GL_TEXTURE_LOD_BIAS:
- *params = obj->Sampler.LodBias;
- break;
case GL_TEXTURE_IMMUTABLE_FORMAT:
if (!ctx->Extensions.ARB_texture_storage)
break;;
case GL_TEXTURE_PRIORITY:
*params = FLOAT_TO_INT(obj->Priority);
- break;;
- case GL_TEXTURE_MIN_LOD:
- *params = (GLint) obj->Sampler.MinLod;
- break;;
- case GL_TEXTURE_MAX_LOD:
- *params = (GLint) obj->Sampler.MaxLod;
- break;;
- case GL_TEXTURE_BASE_LEVEL:
- *params = obj->BaseLevel;
- break;;
- case GL_TEXTURE_MAX_LEVEL:
- *params = obj->MaxLevel;
- break;;
+ break;
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (!ctx->Extensions.EXT_texture_filter_anisotropic)
goto invalid_pname;
*params = (GLint) obj->Sampler.MaxAnisotropy;
break;
- case GL_GENERATE_MIPMAP_SGIS:
- *params = (GLint) obj->GenerateMipmap;
- break;
- case GL_TEXTURE_LOD_BIAS:
- *params = (GLint) obj->Sampler.LodBias;
- break;
case GL_TEXTURE_IMMUTABLE_FORMAT:
if (!ctx->Extensions.ARB_texture_storage)
#include "colormac.h"
#include "image.h"
#include "macros.h"
-#include "mipmap.h"
#include "mfeatures.h"
#include "mtypes.h"
#include "pack.h"
ctx->Extensions.EXT_pixel_buffer_object);
const GLboolean ver_3_0 = (ver_2_1 &&
ctx->Const.GLSLVersion >= 130 &&
- ctx->Const.MaxSamples >= 4 &&
- ctx->Extensions.ARB_color_buffer_float &&
ctx->Extensions.ARB_half_float_pixel &&
ctx->Extensions.ARB_half_float_vertex &&
ctx->Extensions.ARB_map_buffer_range &&
ctx->Extensions.ARB_shader_texture_lod &&
ctx->Extensions.ARB_texture_float &&
- ctx->Extensions.APPLE_vertex_array_object &&
- ctx->Extensions.ARB_framebuffer_object);
+ ctx->Extensions.APPLE_vertex_array_object);
if (ver_3_0) {
{
/* state[1] is the texture unit */
const GLuint unit = (GLuint) state[1];
- if(ctx->Color._ClampFragmentColor)
- COPY_4V(value, ctx->Texture.Unit[unit].EnvColor);
- else
- COPY_4V(value, ctx->Texture.Unit[unit].EnvColorUnclamped);
+ COPY_4V(value, ctx->Texture.Unit[unit].EnvColor);
}
return;
case STATE_FOG_COLOR:
- if(ctx->Color._ClampFragmentColor)
- COPY_4V(value, ctx->Fog.Color);
- else
- COPY_4V(value, ctx->Fog.ColorUnclamped);
+ COPY_4V(value, ctx->Fog.Color);
return;
case STATE_FOG_PARAMS:
value[0] = ctx->Fog.Density;
case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED:
{
const GLuint idx = (GLuint) state[2];
- if(ctx->Light._ClampVertexColor &&
- (idx == VERT_ATTRIB_COLOR0 ||
- idx == VERT_ATTRIB_COLOR1)) {
+ if(idx == VERT_ATTRIB_COLOR0 ||
+ idx == VERT_ATTRIB_COLOR1) {
value[0] = CLAMP(ctx->Current.Attrib[idx][0], 0.0f, 1.0f);
value[1] = CLAMP(ctx->Current.Attrib[idx][1], 0.0f, 1.0f);
value[2] = CLAMP(ctx->Current.Attrib[idx][2], 0.0f, 1.0f);
case STATE_FB_WPOS_Y_TRANSFORM:
/* A driver may negate this conditional by using ZW swizzle
* instead of XY (based on e.g. some other state). */
- if (ctx->DrawBuffer->Name != 0) {
- /* Identity (XY) followed by flipping Y upside down (ZW). */
- value[0] = 1.0F;
- value[1] = 0.0F;
- value[2] = -1.0F;
- value[3] = (GLfloat) ctx->DrawBuffer->Height;
- } else {
- /* Flipping Y upside down (XY) followed by identity (ZW). */
- value[0] = -1.0F;
- value[1] = (GLfloat) ctx->DrawBuffer->Height;
- value[2] = 1.0F;
- value[3] = 0.0F;
- }
+ /* Flipping Y upside down (XY) followed by identity (ZW). */
+ value[0] = -1.0F;
+ value[1] = (GLfloat) ctx->DrawBuffer->Height;
+ value[2] = 1.0F;
+ value[3] = 0.0F;
return;
case STATE_ROT_MATRIX_0:
case STATE_TEXGEN:
return _NEW_TEXTURE;
case STATE_TEXENV_COLOR:
- return _NEW_TEXTURE | _NEW_BUFFERS | _NEW_FRAG_CLAMP;
+ return _NEW_TEXTURE | _NEW_BUFFERS;
case STATE_FOG_COLOR:
- return _NEW_FOG | _NEW_BUFFERS | _NEW_FRAG_CLAMP;
+ return _NEW_FOG | _NEW_BUFFERS;
case STATE_FOG_PARAMS:
return _NEW_FOG;
return _NEW_FOG;
case STATE_POINT_SIZE_CLAMPED:
case STATE_POINT_SIZE_IMPL_CLAMP:
- return _NEW_POINT | _NEW_MULTISAMPLE;
+ return _NEW_POINT;
case STATE_LIGHT_SPOT_DIR_NORMALIZED:
case STATE_LIGHT_POSITION:
case STATE_LIGHT_POSITION_NORMALIZED:
s_alpha.c
s_bitmap.c
s_blend.c
- s_blit.c
s_clear.c
s_context.c
s_copypix.c
s_texcombine.c
s_texfetch.c
s_texfilter.c
- s_texrender.c
s_texture.c
s_triangle.c
s_zoom.c
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#include "main/glheader.h"
-#include "main/formats.h"
-#include "main/image.h"
-#include "main/macros.h"
-#include "main/format_unpack.h"
-#include "main/format_pack.h"
-#include "s_context.h"
-
-
-#define ABS(X) ((X) < 0 ? -(X) : (X))
-
-
-/**
- * Generate a row resampler function for GL_NEAREST mode.
- */
-#define RESAMPLE(NAME, PIXELTYPE, SIZE) \
-static void \
-NAME(GLint srcWidth, GLint dstWidth, \
- const GLvoid *srcBuffer, GLvoid *dstBuffer, \
- GLboolean flip) \
-{ \
- const PIXELTYPE *src = (const PIXELTYPE *) srcBuffer;\
- PIXELTYPE *dst = (PIXELTYPE *) dstBuffer; \
- GLint dstCol; \
- \
- if (flip) { \
- for (dstCol = 0; dstCol < dstWidth; dstCol++) { \
- GLint srcCol = (dstCol * srcWidth) / dstWidth; \
- ASSERT(srcCol >= 0); \
- ASSERT(srcCol < srcWidth); \
- srcCol = srcWidth - 1 - srcCol; /* flip */ \
- if (SIZE == 1) { \
- dst[dstCol] = src[srcCol]; \
- } \
- else if (SIZE == 2) { \
- dst[dstCol*2+0] = src[srcCol*2+0]; \
- dst[dstCol*2+1] = src[srcCol*2+1]; \
- } \
- else if (SIZE == 4) { \
- dst[dstCol*4+0] = src[srcCol*4+0]; \
- dst[dstCol*4+1] = src[srcCol*4+1]; \
- dst[dstCol*4+2] = src[srcCol*4+2]; \
- dst[dstCol*4+3] = src[srcCol*4+3]; \
- } \
- } \
- } \
- else { \
- for (dstCol = 0; dstCol < dstWidth; dstCol++) { \
- GLint srcCol = (dstCol * srcWidth) / dstWidth; \
- ASSERT(srcCol >= 0); \
- ASSERT(srcCol < srcWidth); \
- if (SIZE == 1) { \
- dst[dstCol] = src[srcCol]; \
- } \
- else if (SIZE == 2) { \
- dst[dstCol*2+0] = src[srcCol*2+0]; \
- dst[dstCol*2+1] = src[srcCol*2+1]; \
- } \
- else if (SIZE == 4) { \
- dst[dstCol*4+0] = src[srcCol*4+0]; \
- dst[dstCol*4+1] = src[srcCol*4+1]; \
- dst[dstCol*4+2] = src[srcCol*4+2]; \
- dst[dstCol*4+3] = src[srcCol*4+3]; \
- } \
- } \
- } \
-}
-
-/**
- * Resamplers for 1, 2, 4, 8 and 16-byte pixels.
- */
-RESAMPLE(resample_row_1, GLubyte, 1)
-RESAMPLE(resample_row_2, GLushort, 1)
-RESAMPLE(resample_row_4, GLuint, 1)
-RESAMPLE(resample_row_8, GLuint, 2)
-RESAMPLE(resample_row_16, GLuint, 4)
-
-
-/**
- * Blit color, depth or stencil with GL_NEAREST filtering.
- */
-static void
-blit_nearest(struct gl_context *ctx,
- GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield buffer)
-{
- struct gl_renderbuffer *readRb, *drawRb;
-
- const GLint srcWidth = ABS(srcX1 - srcX0);
- const GLint dstWidth = ABS(dstX1 - dstX0);
- const GLint srcHeight = ABS(srcY1 - srcY0);
- const GLint dstHeight = ABS(dstY1 - dstY0);
-
- const GLint srcXpos = MIN2(srcX0, srcX1);
- const GLint srcYpos = MIN2(srcY0, srcY1);
- const GLint dstXpos = MIN2(dstX0, dstX1);
- const GLint dstYpos = MIN2(dstY0, dstY1);
-
- const GLboolean invertX = (srcX1 < srcX0) ^ (dstX1 < dstX0);
- const GLboolean invertY = (srcY1 < srcY0) ^ (dstY1 < dstY0);
- enum mode {
- DIRECT,
- UNPACK_RGBA_FLOAT,
- UNPACK_Z_INT,
- UNPACK_S,
- } mode;
- GLubyte *srcMap, *dstMap;
- GLint srcRowStride, dstRowStride;
- GLint dstRow;
-
- GLint pixelSize;
- GLvoid *srcBuffer, *dstBuffer;
- GLint prevY = -1;
-
- typedef void (*resample_func)(GLint srcWidth, GLint dstWidth,
- const GLvoid *srcBuffer, GLvoid *dstBuffer,
- GLboolean flip);
- resample_func resampleRow;
-
- switch (buffer) {
- case GL_COLOR_BUFFER_BIT:
- readRb = ctx->ReadBuffer->_ColorReadBuffer;
- drawRb = ctx->DrawBuffer->_ColorDrawBuffer;
-
- if (readRb->Format == drawRb->Format) {
- mode = DIRECT;
- pixelSize = _mesa_get_format_bytes(readRb->Format);
- } else {
- mode = UNPACK_RGBA_FLOAT;
- pixelSize = 16;
- }
-
- break;
- case GL_DEPTH_BUFFER_BIT:
- readRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
- drawRb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
- mode = UNPACK_Z_INT;
- pixelSize = 4;
- break;
- case GL_STENCIL_BUFFER_BIT:
- readRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
- drawRb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
- mode = UNPACK_S;
- pixelSize = 1;
- break;
- default:
- _mesa_problem(ctx, "unexpected buffer in blit_nearest()");
- return;
- }
-
- /* choose row resampler */
- switch (pixelSize) {
- case 1:
- resampleRow = resample_row_1;
- break;
- case 2:
- resampleRow = resample_row_2;
- break;
- case 4:
- resampleRow = resample_row_4;
- break;
- case 8:
- resampleRow = resample_row_8;
- break;
- case 16:
- resampleRow = resample_row_16;
- break;
- default:
- _mesa_problem(ctx, "unexpected pixel size (%d) in blit_nearest",
- pixelSize);
- return;
- }
-
- if (readRb == drawRb) {
- /* map whole buffer for read/write */
- /* XXX we could be clever and just map the union region of the
- * source and dest rects.
- */
- GLubyte *map;
- GLint rowStride;
- GLint formatSize = _mesa_get_format_bytes(readRb->Format);
-
- ctx->Driver.MapRenderbuffer(ctx, readRb, 0, 0,
- readRb->Width, readRb->Height,
- GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
- &map, &rowStride);
- if (!map) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
- return;
- }
-
- srcMap = map + srcYpos * rowStride + srcXpos * formatSize;
- dstMap = map + dstYpos * rowStride + dstXpos * formatSize;
-
- /* this handles overlapping copies */
- if (srcY0 < dstY0) {
- /* copy in reverse (top->down) order */
- srcMap += rowStride * (readRb->Height - 1);
- dstMap += rowStride * (readRb->Height - 1);
- srcRowStride = -rowStride;
- dstRowStride = -rowStride;
- }
- else {
- /* copy in normal (bottom->up) order */
- srcRowStride = rowStride;
- dstRowStride = rowStride;
- }
- }
- else {
- /* different src/dst buffers */
- ctx->Driver.MapRenderbuffer(ctx, readRb,
- srcXpos, srcYpos,
- srcWidth, srcHeight,
- GL_MAP_READ_BIT, &srcMap, &srcRowStride);
- if (!srcMap) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
- return;
- }
- ctx->Driver.MapRenderbuffer(ctx, drawRb,
- dstXpos, dstYpos,
- dstWidth, dstHeight,
- GL_MAP_WRITE_BIT, &dstMap, &dstRowStride);
- if (!dstMap) {
- ctx->Driver.UnmapRenderbuffer(ctx, readRb);
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
- return;
- }
- }
-
- /* allocate the src/dst row buffers */
- srcBuffer = malloc(pixelSize * srcWidth);
- if (!srcBuffer) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
- return;
- }
- dstBuffer = malloc(pixelSize * dstWidth);
- if (!dstBuffer) {
- free(srcBuffer);
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
- return;
- }
-
- for (dstRow = 0; dstRow < dstHeight; dstRow++) {
- GLint srcRow = (dstRow * srcHeight) / dstHeight;
- GLubyte *dstRowStart = dstMap + dstRowStride * dstRow;
-
- ASSERT(srcRow >= 0);
- ASSERT(srcRow < srcHeight);
-
- if (invertY) {
- srcRow = srcHeight - 1 - srcRow;
- }
-
- /* get pixel row from source and resample to match dest width */
- if (prevY != srcRow) {
- GLubyte *srcRowStart = srcMap + srcRowStride * srcRow;
-
- switch (mode) {
- case DIRECT:
- memcpy(srcBuffer, srcRowStart, pixelSize * srcWidth);
- break;
- case UNPACK_RGBA_FLOAT:
- _mesa_unpack_rgba_row(readRb->Format, srcWidth, srcRowStart,
- srcBuffer);
- break;
- case UNPACK_Z_INT:
- _mesa_unpack_uint_z_row(readRb->Format, srcWidth, srcRowStart,
- srcBuffer);
- break;
- case UNPACK_S:
- _mesa_unpack_ubyte_stencil_row(readRb->Format, srcWidth,
- srcRowStart, srcBuffer);
- break;
- }
-
- (*resampleRow)(srcWidth, dstWidth, srcBuffer, dstBuffer, invertX);
- prevY = srcRow;
- }
-
- /* store pixel row in destination */
- switch (mode) {
- case DIRECT:
- memcpy(dstRowStart, dstBuffer, pixelSize * srcWidth);
- break;
- case UNPACK_RGBA_FLOAT:
- _mesa_pack_float_rgba_row(drawRb->Format, dstWidth, dstBuffer,
- dstRowStart);
- break;
- case UNPACK_Z_INT:
- _mesa_pack_uint_z_row(drawRb->Format, dstWidth, dstBuffer,
- dstRowStart);
- break;
- case UNPACK_S:
- _mesa_pack_ubyte_stencil_row(drawRb->Format, dstWidth, dstBuffer,
- dstRowStart);
- break;
- }
- }
-
- free(srcBuffer);
- free(dstBuffer);
-
- ctx->Driver.UnmapRenderbuffer(ctx, readRb);
- if (drawRb != readRb) {
- ctx->Driver.UnmapRenderbuffer(ctx, drawRb);
- }
-}
-
-
-
-#define LERP(T, A, B) ( (A) + (T) * ((B) - (A)) )
-
-static inline GLfloat
-lerp_2d(GLfloat a, GLfloat b,
- GLfloat v00, GLfloat v10, GLfloat v01, GLfloat v11)
-{
- const GLfloat temp0 = LERP(a, v00, v10);
- const GLfloat temp1 = LERP(a, v01, v11);
- return LERP(b, temp0, temp1);
-}
-
-
-/**
- * Bilinear interpolation of two source rows.
- * GLubyte pixels.
- */
-static void
-resample_linear_row_ub(GLint srcWidth, GLint dstWidth,
- const GLvoid *srcBuffer0, const GLvoid *srcBuffer1,
- GLvoid *dstBuffer, GLboolean flip, GLfloat rowWeight)
-{
- const GLubyte (*srcColor0)[4] = (const GLubyte (*)[4]) srcBuffer0;
- const GLubyte (*srcColor1)[4] = (const GLubyte (*)[4]) srcBuffer1;
- GLubyte (*dstColor)[4] = (GLubyte (*)[4]) dstBuffer;
- const GLfloat dstWidthF = (GLfloat) dstWidth;
- GLint dstCol;
-
- for (dstCol = 0; dstCol < dstWidth; dstCol++) {
- const GLfloat srcCol = (dstCol * srcWidth) / dstWidthF;
- GLint srcCol0 = IFLOOR(srcCol);
- GLint srcCol1 = srcCol0 + 1;
- GLfloat colWeight = srcCol - srcCol0; /* fractional part of srcCol */
- GLfloat red, green, blue, alpha;
-
- ASSERT(srcCol0 >= 0);
- ASSERT(srcCol0 < srcWidth);
- ASSERT(srcCol1 <= srcWidth);
-
- if (srcCol1 == srcWidth) {
- /* last column fudge */
- srcCol1--;
- colWeight = 0.0;
- }
-
- if (flip) {
- srcCol0 = srcWidth - 1 - srcCol0;
- srcCol1 = srcWidth - 1 - srcCol1;
- }
-
- red = lerp_2d(colWeight, rowWeight,
- srcColor0[srcCol0][RCOMP], srcColor0[srcCol1][RCOMP],
- srcColor1[srcCol0][RCOMP], srcColor1[srcCol1][RCOMP]);
- green = lerp_2d(colWeight, rowWeight,
- srcColor0[srcCol0][GCOMP], srcColor0[srcCol1][GCOMP],
- srcColor1[srcCol0][GCOMP], srcColor1[srcCol1][GCOMP]);
- blue = lerp_2d(colWeight, rowWeight,
- srcColor0[srcCol0][BCOMP], srcColor0[srcCol1][BCOMP],
- srcColor1[srcCol0][BCOMP], srcColor1[srcCol1][BCOMP]);
- alpha = lerp_2d(colWeight, rowWeight,
- srcColor0[srcCol0][ACOMP], srcColor0[srcCol1][ACOMP],
- srcColor1[srcCol0][ACOMP], srcColor1[srcCol1][ACOMP]);
-
- dstColor[dstCol][RCOMP] = IFLOOR(red);
- dstColor[dstCol][GCOMP] = IFLOOR(green);
- dstColor[dstCol][BCOMP] = IFLOOR(blue);
- dstColor[dstCol][ACOMP] = IFLOOR(alpha);
- }
-}
-
-
-/**
- * Bilinear interpolation of two source rows. floating point pixels.
- */
-static void
-resample_linear_row_float(GLint srcWidth, GLint dstWidth,
- const GLvoid *srcBuffer0, const GLvoid *srcBuffer1,
- GLvoid *dstBuffer, GLboolean flip, GLfloat rowWeight)
-{
- const GLfloat (*srcColor0)[4] = (const GLfloat (*)[4]) srcBuffer0;
- const GLfloat (*srcColor1)[4] = (const GLfloat (*)[4]) srcBuffer1;
- GLfloat (*dstColor)[4] = (GLfloat (*)[4]) dstBuffer;
- const GLfloat dstWidthF = (GLfloat) dstWidth;
- GLint dstCol;
-
- for (dstCol = 0; dstCol < dstWidth; dstCol++) {
- const GLfloat srcCol = (dstCol * srcWidth) / dstWidthF;
- GLint srcCol0 = IFLOOR(srcCol);
- GLint srcCol1 = srcCol0 + 1;
- GLfloat colWeight = srcCol - srcCol0; /* fractional part of srcCol */
- GLfloat red, green, blue, alpha;
-
- ASSERT(srcCol0 >= 0);
- ASSERT(srcCol0 < srcWidth);
- ASSERT(srcCol1 <= srcWidth);
-
- if (srcCol1 == srcWidth) {
- /* last column fudge */
- srcCol1--;
- colWeight = 0.0;
- }
-
- if (flip) {
- srcCol0 = srcWidth - 1 - srcCol0;
- srcCol1 = srcWidth - 1 - srcCol1;
- }
-
- red = lerp_2d(colWeight, rowWeight,
- srcColor0[srcCol0][RCOMP], srcColor0[srcCol1][RCOMP],
- srcColor1[srcCol0][RCOMP], srcColor1[srcCol1][RCOMP]);
- green = lerp_2d(colWeight, rowWeight,
- srcColor0[srcCol0][GCOMP], srcColor0[srcCol1][GCOMP],
- srcColor1[srcCol0][GCOMP], srcColor1[srcCol1][GCOMP]);
- blue = lerp_2d(colWeight, rowWeight,
- srcColor0[srcCol0][BCOMP], srcColor0[srcCol1][BCOMP],
- srcColor1[srcCol0][BCOMP], srcColor1[srcCol1][BCOMP]);
- alpha = lerp_2d(colWeight, rowWeight,
- srcColor0[srcCol0][ACOMP], srcColor0[srcCol1][ACOMP],
- srcColor1[srcCol0][ACOMP], srcColor1[srcCol1][ACOMP]);
-
- dstColor[dstCol][RCOMP] = red;
- dstColor[dstCol][GCOMP] = green;
- dstColor[dstCol][BCOMP] = blue;
- dstColor[dstCol][ACOMP] = alpha;
- }
-}
-
-
-
-/**
- * Bilinear filtered blit (color only, non-integer values).
- */
-static void
-blit_linear(struct gl_context *ctx,
- GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1)
-{
- struct gl_renderbuffer *readRb = ctx->ReadBuffer->_ColorReadBuffer;
- struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_ColorDrawBuffer;
-
- const GLint srcWidth = ABS(srcX1 - srcX0);
- const GLint dstWidth = ABS(dstX1 - dstX0);
- const GLint srcHeight = ABS(srcY1 - srcY0);
- const GLint dstHeight = ABS(dstY1 - dstY0);
- const GLfloat dstHeightF = (GLfloat) dstHeight;
-
- const GLint srcXpos = MIN2(srcX0, srcX1);
- const GLint srcYpos = MIN2(srcY0, srcY1);
- const GLint dstXpos = MIN2(dstX0, dstX1);
- const GLint dstYpos = MIN2(dstY0, dstY1);
-
- const GLboolean invertX = (srcX1 < srcX0) ^ (dstX1 < dstX0);
- const GLboolean invertY = (srcY1 < srcY0) ^ (dstY1 < dstY0);
-
- GLint dstRow;
-
- GLint pixelSize;
- GLvoid *srcBuffer0, *srcBuffer1;
- GLint srcBufferY0 = -1, srcBufferY1 = -1;
- GLvoid *dstBuffer;
-
- gl_format readFormat = readRb->Format;
- gl_format drawFormat = drawRb->Format;
- GLuint bpp = _mesa_get_format_bytes(readFormat);
-
- GLenum pixelType;
-
- GLubyte *srcMap, *dstMap;
- GLint srcRowStride, dstRowStride;
-
-
- /* Determine datatype for resampling */
- if (_mesa_get_format_max_bits(readFormat) == 8 &&
- _mesa_get_format_datatype(readFormat) == GL_UNSIGNED_NORMALIZED) {
- pixelType = GL_UNSIGNED_BYTE;
- pixelSize = 4 * sizeof(GLubyte);
- }
- else {
- pixelType = GL_FLOAT;
- pixelSize = 4 * sizeof(GLfloat);
- }
-
- /* Allocate the src/dst row buffers.
- * Keep two adjacent src rows around for bilinear sampling.
- */
- srcBuffer0 = malloc(pixelSize * srcWidth);
- if (!srcBuffer0) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
- return;
- }
- srcBuffer1 = malloc(pixelSize * srcWidth);
- if (!srcBuffer1) {
- free(srcBuffer0);
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
- return;
- }
- dstBuffer = malloc(pixelSize * dstWidth);
- if (!dstBuffer) {
- free(srcBuffer0);
- free(srcBuffer1);
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
- return;
- }
-
- /*
- * Map src / dst renderbuffers
- */
- if (readRb == drawRb) {
- /* map whole buffer for read/write */
- ctx->Driver.MapRenderbuffer(ctx, readRb,
- 0, 0, readRb->Width, readRb->Height,
- GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
- &srcMap, &srcRowStride);
- if (!srcMap) {
- free(srcBuffer0);
- free(srcBuffer1);
- free(dstBuffer);
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
- return;
- }
-
- dstMap = srcMap;
- dstRowStride = srcRowStride;
- }
- else {
- /* different src/dst buffers */
- /* XXX with a bit of work we could just map the regions to be
- * read/written instead of the whole buffers.
- */
- ctx->Driver.MapRenderbuffer(ctx, readRb,
- 0, 0, readRb->Width, readRb->Height,
- GL_MAP_READ_BIT, &srcMap, &srcRowStride);
- if (!srcMap) {
- free(srcBuffer0);
- free(srcBuffer1);
- free(dstBuffer);
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
- return;
- }
- ctx->Driver.MapRenderbuffer(ctx, drawRb,
- 0, 0, drawRb->Width, drawRb->Height,
- GL_MAP_WRITE_BIT, &dstMap, &dstRowStride);
- if (!dstMap) {
- ctx->Driver.UnmapRenderbuffer(ctx, readRb);
- free(srcBuffer0);
- free(srcBuffer1);
- free(dstBuffer);
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
- return;
- }
- }
-
- for (dstRow = 0; dstRow < dstHeight; dstRow++) {
- const GLint dstY = dstYpos + dstRow;
- const GLfloat srcRow = (dstRow * srcHeight) / dstHeightF;
- GLint srcRow0 = IFLOOR(srcRow);
- GLint srcRow1 = srcRow0 + 1;
- GLfloat rowWeight = srcRow - srcRow0; /* fractional part of srcRow */
-
- ASSERT(srcRow >= 0);
- ASSERT(srcRow < srcHeight);
-
- if (srcRow1 == srcHeight) {
- /* last row fudge */
- srcRow1 = srcRow0;
- rowWeight = 0.0;
- }
-
- if (invertY) {
- srcRow0 = srcHeight - 1 - srcRow0;
- srcRow1 = srcHeight - 1 - srcRow1;
- }
-
- srcY0 = srcYpos + srcRow0;
- srcY1 = srcYpos + srcRow1;
-
- /* get the two source rows */
- if (srcY0 == srcBufferY0 && srcY1 == srcBufferY1) {
- /* use same source row buffers again */
- }
- else if (srcY0 == srcBufferY1) {
- /* move buffer1 into buffer0 by swapping pointers */
- GLvoid *tmp = srcBuffer0;
- srcBuffer0 = srcBuffer1;
- srcBuffer1 = tmp;
- /* get y1 row */
- {
- GLubyte *src = srcMap + srcY1 * srcRowStride + srcXpos * bpp;
- if (pixelType == GL_UNSIGNED_BYTE) {
- _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth,
- src, srcBuffer1);
- }
- else {
- _mesa_unpack_rgba_row(readFormat, srcWidth,
- src, srcBuffer1);
- }
- }
- srcBufferY0 = srcY0;
- srcBufferY1 = srcY1;
- }
- else {
- /* get both new rows */
- {
- GLubyte *src0 = srcMap + srcY0 * srcRowStride + srcXpos * bpp;
- GLubyte *src1 = srcMap + srcY1 * srcRowStride + srcXpos * bpp;
- if (pixelType == GL_UNSIGNED_BYTE) {
- _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth,
- src0, srcBuffer0);
- _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth,
- src1, srcBuffer1);
- }
- else {
- _mesa_unpack_rgba_row(readFormat, srcWidth, src0, srcBuffer0);
- _mesa_unpack_rgba_row(readFormat, srcWidth, src1, srcBuffer1);
- }
- }
- srcBufferY0 = srcY0;
- srcBufferY1 = srcY1;
- }
-
- if (pixelType == GL_UNSIGNED_BYTE) {
- resample_linear_row_ub(srcWidth, dstWidth, srcBuffer0, srcBuffer1,
- dstBuffer, invertX, rowWeight);
- }
- else {
- resample_linear_row_float(srcWidth, dstWidth, srcBuffer0, srcBuffer1,
- dstBuffer, invertX, rowWeight);
- }
-
- /* store pixel row in destination */
- {
- GLubyte *dst = dstMap + dstY * dstRowStride + dstXpos * bpp;
- if (pixelType == GL_UNSIGNED_BYTE) {
- _mesa_pack_ubyte_rgba_row(drawFormat, dstWidth, dstBuffer, dst);
- }
- else {
- _mesa_pack_float_rgba_row(drawFormat, dstWidth, dstBuffer, dst);
- }
- }
- }
-
- free(srcBuffer0);
- free(srcBuffer1);
- free(dstBuffer);
-
- ctx->Driver.UnmapRenderbuffer(ctx, readRb);
- if (drawRb != readRb) {
- ctx->Driver.UnmapRenderbuffer(ctx, drawRb);
- }
-}
-
-
-
-/**
- * Software fallback for glBlitFramebufferEXT().
- */
-void
-_swrast_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)
-{
- static const GLbitfield buffers[3] = {
- GL_COLOR_BUFFER_BIT,
- GL_DEPTH_BUFFER_BIT,
- GL_STENCIL_BUFFER_BIT
- };
- static const GLenum buffer_enums[3] = {
- GL_COLOR,
- GL_DEPTH,
- GL_STENCIL,
- };
- GLint i;
-
- if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
- &dstX0, &dstY0, &dstX1, &dstY1)) {
- return;
- }
-
- if (SWRAST_CONTEXT(ctx)->NewState)
- _swrast_validate_derived(ctx);
-
- /* First, try covering whatever buffers possible using the fast 1:1 copy
- * path.
- */
- if (srcX1 - srcX0 == dstX1 - dstX0 &&
- srcY1 - srcY0 == dstY1 - dstY0 &&
- srcX0 < srcX1 &&
- srcY0 < srcY1 &&
- dstX0 < dstX1 &&
- dstY0 < dstY1) {
- for (i = 0; i < 3; i++) {
- if (mask & buffers[i]) {
- if (swrast_fast_copy_pixels(ctx,
- srcX0, srcY0,
- srcX1 - srcX0, srcY1 - srcY0,
- dstX0, dstY0,
- buffer_enums[i])) {
- mask &= ~buffers[i];
- }
- }
- }
-
- if (!mask)
- return;
- }
-
- if (filter == GL_NEAREST) {
- for (i = 0; i < 3; i++) {
- if (mask & buffers[i]) {
- blit_nearest(ctx, srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1, buffers[i]);
- }
- }
- }
- else {
- ASSERT(filter == GL_LINEAR);
- if (mask & GL_COLOR_BUFFER_BIT) { /* depth/stencil not allowed */
- blit_linear(ctx, srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1);
- }
- }
-
-}
span.arrayMask = SPAN_RGBA;
span.arrayAttribs = FRAG_BIT_COL0; /* we're fill in COL0 attrib values */
- if (_mesa_get_format_datatype(ctx->DrawBuffer->_ColorDrawBuffer->Format) != GL_FLOAT &&
- ctx->Color.ClampFragmentColor != GL_FALSE) {
+ if (_mesa_get_format_datatype(ctx->DrawBuffer->_ColorDrawBuffer->Format) != GL_FLOAT) {
/* need to clamp colors before applying fragment ops */
transferOps |= IMAGE_CLAMP_BIT;
}
#include "main/glheader.h"
#include "main/imports.h"
#include "main/context.h"
-#include "main/fbobject.h"
#include "main/formats.h"
#include "main/mtypes.h"
#include "main/renderbuffer.h"
#include "swrast/s_context.h"
#include "swrast/s_renderbuffer.h"
+static
+GLenum
+_mesa_base_fb_format(struct gl_context *ctx, GLenum internalFormat)
+{
+ /*
+ * Notes: some formats such as alpha, luminance, etc. were added
+ * with GL_ARB_framebuffer_object.
+ */
+ switch (internalFormat) {
+ case GL_RGB:
+ case GL_R3_G3_B2:
+ case GL_RGB4:
+ case GL_RGB5:
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ return GL_RGB;
+ case GL_RGBA:
+ case GL_RGBA2:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ return GL_RGBA;
+ case GL_STENCIL_INDEX:
+ case GL_STENCIL_INDEX1_EXT:
+ case GL_STENCIL_INDEX4_EXT:
+ case GL_STENCIL_INDEX8_EXT:
+ case GL_STENCIL_INDEX16_EXT:
+ return GL_STENCIL_INDEX;
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32:
+ return GL_DEPTH_COMPONENT;
+
+ default:
+ return 0;
+ }
+}
+
/**
* This is a software fallback for the gl_renderbuffer->AllocStorage
rb->Width = width;
rb->Height = height;
- rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
+ rb->_BaseFormat = _mesa_base_fb_format(ctx, internalFormat);
/* the internalFormat should have been error checked long ago */
ASSERT(rb->_BaseFormat);
* renderbuffer.
* This would not be used for hardware-based renderbuffers.
*/
+static
struct gl_renderbuffer *
_swrast_new_soft_renderbuffer(struct gl_context *ctx, GLuint name)
{
return &srb->Base;
}
-
-/**
- * Add software-based color renderbuffers to the given framebuffer.
- * This is a helper routine for device drivers when creating a
- * window system framebuffer (not a user-created render/framebuffer).
- * Once this function is called, you can basically forget about this
- * renderbuffer; core Mesa will handle all the buffer management and
- * rendering!
- */
-static GLboolean
-add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
- GLuint rgbBits, GLuint alphaBits,
- GLboolean frontLeft, GLboolean backLeft,
- GLboolean frontRight, GLboolean backRight)
-{
- gl_buffer_index b;
-
- if (rgbBits > 16 || alphaBits > 16) {
- _mesa_problem(ctx,
- "Unsupported bit depth in add_color_renderbuffers");
- return GL_FALSE;
- }
-
- assert(MAX_COLOR_ATTACHMENTS >= 4);
-
- for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
- struct gl_renderbuffer *rb;
-
- if (b == BUFFER_FRONT_LEFT && !frontLeft)
- continue;
- else if (b == BUFFER_BACK_LEFT && !backLeft)
- continue;
- else if (b == BUFFER_FRONT_RIGHT && !frontRight)
- continue;
- else if (b == BUFFER_BACK_RIGHT && !backRight)
- continue;
-
- assert(fb->Attachment[b].Renderbuffer == NULL);
-
- rb = ctx->Driver.NewRenderbuffer(ctx, 0);
- if (!rb) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
- return GL_FALSE;
- }
-
- rb->InternalFormat = GL_RGBA;
-
- rb->AllocStorage = soft_renderbuffer_storage;
- _mesa_add_renderbuffer(fb, b, rb);
- }
-
- return GL_TRUE;
-}
-
-
/**
* Add a software-based depth renderbuffer to the given framebuffer.
* This is a helper routine for device drivers when creating a
GLboolean alpha,
GLboolean aux)
{
- GLboolean frontLeft = GL_TRUE;
- GLboolean backLeft = fb->Visual.doubleBufferMode;
- GLboolean frontRight = fb->Visual.stereoMode;
- GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode;
-
- if (color) {
- assert(fb->Visual.redBits == fb->Visual.greenBits);
- assert(fb->Visual.redBits == fb->Visual.blueBits);
- add_color_renderbuffers(NULL, fb,
- fb->Visual.redBits,
- fb->Visual.alphaBits,
- frontLeft, backLeft,
- frontRight, backRight);
- }
+ (void)color;
+
if (depth) {
assert(fb->Visual.depthBits > 0);
add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits);
struct gl_framebuffer *fb,
gl_buffer_index buffer)
{
- struct gl_texture_object *texObj = fb->Attachment[buffer].Texture;
struct gl_renderbuffer *rb = fb->Attachment[buffer].Renderbuffer;
struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
- if (texObj) {
- /* map texture image (render to texture) */
- const GLuint level = fb->Attachment[buffer].TextureLevel;
- const GLuint face = fb->Attachment[buffer].CubeMapFace;
- const GLuint slice = fb->Attachment[buffer].Zoffset;
- struct gl_texture_image *texImage = texObj->Image[face][level];
- if (texImage) {
- ctx->Driver.MapTextureImage(ctx, texImage, slice,
- 0, 0, texImage->Width, texImage->Height,
- GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
- &srb->Map, &srb->RowStride);
- }
- }
- else if (rb) {
+ if (rb) {
/* Map ordinary renderbuffer */
ctx->Driver.MapRenderbuffer(ctx, rb,
0, 0, rb->Width, rb->Height,
struct gl_framebuffer *fb,
gl_buffer_index buffer)
{
- struct gl_texture_object *texObj = fb->Attachment[buffer].Texture;
struct gl_renderbuffer *rb = fb->Attachment[buffer].Renderbuffer;
struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
- if (texObj) {
- /* unmap texture image (render to texture) */
- const GLuint level = fb->Attachment[buffer].TextureLevel;
- const GLuint face = fb->Attachment[buffer].CubeMapFace;
- const GLuint slice = fb->Attachment[buffer].Zoffset;
- struct gl_texture_image *texImage = texObj->Image[face][level];
- if (texImage) {
- ctx->Driver.UnmapTextureImage(ctx, texImage, slice);
- }
- }
- else if (rb) {
+ if (rb) {
/* unmap ordinary renderbuffer */
ctx->Driver.UnmapRenderbuffer(ctx, rb);
}
struct gl_framebuffer;
struct gl_renderbuffer;
-
-extern struct gl_renderbuffer *
-_swrast_new_soft_renderbuffer(struct gl_context *ctx, GLuint name);
-
extern void
_swrast_map_soft_renderbuffer(struct gl_context *ctx,
struct gl_renderbuffer *rb,
apply_aa_coverage(span);
}
- /* Clamp color/alpha values over the range [0.0, 1.0] before storage */
- if (ctx->Color.ClampFragmentColor == GL_TRUE &&
- span->array->ChanType == GL_FLOAT) {
- clamp_colors(span);
- }
-
/*
* Write to renderbuffers.
* Depending on glDrawBuffer() state and the which color outputs are
span->array->attribs[FRAG_ATTRIB_TEX0 +
ctx->Texture.Unit[unit].BumpTarget - GL_TEXTURE0];
- const struct gl_texture_object *curObj = texUnit->_Current;
GLfloat *lambda = span->array->lambda[unit];
float4_array texels = get_texel_array(swrast, unit);
GLuint i;
GLfloat rotMatrix10 = ctx->Texture.Unit[unit].RotMatrix[2];
GLfloat rotMatrix11 = ctx->Texture.Unit[unit].RotMatrix[3];
- /* adjust texture lod (lambda) */
- if (span->arrayMask & SPAN_LAMBDA) {
- if (texUnit->LodBias + curObj->Sampler.LodBias != 0.0F) {
- /* apply LOD bias, but don't clamp yet */
- const GLfloat bias = CLAMP(texUnit->LodBias + curObj->Sampler.LodBias,
- -ctx->Const.MaxTextureLodBias,
- ctx->Const.MaxTextureLodBias);
- GLuint i;
- for (i = 0; i < span->end; i++) {
- lambda[i] += bias;
- }
- }
-
- if (curObj->Sampler.MinLod != -1000.0 ||
- curObj->Sampler.MaxLod != 1000.0) {
- /* apply LOD clamping to lambda */
- const GLfloat min = curObj->Sampler.MinLod;
- const GLfloat max = curObj->Sampler.MaxLod;
- GLuint i;
- for (i = 0; i < span->end; i++) {
- GLfloat l = lambda[i];
- lambda[i] = CLAMP(l, min, max);
- }
- }
- }
-
/* Sample the texture (span->end = number of fragments) */
swrast->TextureSample[unit]( ctx, texUnit->_Current, span->end,
texcoords, lambda, texels );
GLfloat *lambda = span->array->lambda[unit];
float4_array texels = get_texel_array(swrast, unit);
- /* adjust texture lod (lambda) */
- if (span->arrayMask & SPAN_LAMBDA) {
- if (texUnit->LodBias + curObj->Sampler.LodBias != 0.0F) {
- /* apply LOD bias, but don't clamp yet */
- const GLfloat bias = CLAMP(texUnit->LodBias + curObj->Sampler.LodBias,
- -ctx->Const.MaxTextureLodBias,
- ctx->Const.MaxTextureLodBias);
- GLuint i;
- for (i = 0; i < span->end; i++) {
- lambda[i] += bias;
- }
- }
-
- if (curObj->Sampler.MinLod != -1000.0 ||
- curObj->Sampler.MaxLod != 1000.0) {
- /* apply LOD clamping to lambda */
- const GLfloat min = curObj->Sampler.MinLod;
- const GLfloat max = curObj->Sampler.MaxLod;
- GLuint i;
- for (i = 0; i < span->end; i++) {
- GLfloat l = lambda[i];
- lambda[i] = CLAMP(l, min, max);
- }
- }
- }
- else if (curObj->Sampler.MaxAnisotropy > 1.0 &&
+ if (curObj->Sampler.MaxAnisotropy > 1.0 &&
curObj->Sampler.MinFilter == GL_LINEAR_MIPMAP_LINEAR) {
/* sample_lambda_2d_aniso is beeing used as texture_sample_func,
* it requires the current SWspan *span as an additional parameter.
GLfloat t = span->attrStart[attr][1] + span->leftClip * dtdx;
GLfloat q = span->attrStart[attr][3] + span->leftClip * dqdx;
- /* from swrast/s_texcombine.c _swrast_texture_span */
- const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
- const GLboolean adjustLOD =
- (texUnit->LodBias + tObj->Sampler.LodBias != 0.0F)
- || (tObj->Sampler.MinLod != -1000.0 || tObj->Sampler.MaxLod != 1000.0);
-
GLuint i;
/* on first access create the lookup table containing the filter weights. */
*/
lod = 0.5 * LOG2(Pmin2);
- if (adjustLOD) {
- /* from swrast/s_texcombine.c _swrast_texture_span */
- if (texUnit->LodBias + tObj->Sampler.LodBias != 0.0F) {
- /* apply LOD bias, but don't clamp yet */
- const GLfloat bias =
- CLAMP(texUnit->LodBias + tObj->Sampler.LodBias,
- -ctx->Const.MaxTextureLodBias,
- ctx->Const.MaxTextureLodBias);
- lod += bias;
-
- if (tObj->Sampler.MinLod != -1000.0 ||
- tObj->Sampler.MaxLod != 1000.0) {
- /* apply LOD clamping to lambda */
- lod = CLAMP(lod, tObj->Sampler.MinLod, tObj->Sampler.MaxLod);
- }
- }
- }
-
/* If the ellipse covers the whole image, we can
* simply return the average of the whole image.
*/
+++ /dev/null
-
-#include "main/context.h"
-#include "main/colormac.h"
-#include "main/fbobject.h"
-#include "main/macros.h"
-#include "main/teximage.h"
-#include "main/renderbuffer.h"
-#include "swrast/swrast.h"
-#include "swrast/s_context.h"
-#include "swrast/s_texfetch.h"
-
-
-/*
- * Render-to-texture code for GL_EXT_framebuffer_object
- */
-
-
-static void
-delete_texture_wrapper(struct gl_renderbuffer *rb)
-{
- ASSERT(rb->RefCount == 0);
- free(rb);
-}
-
-
-/**
- * This function creates a renderbuffer object which wraps a texture image.
- * The new renderbuffer is plugged into the given attachment point.
- * This allows rendering into the texture as if it were a renderbuffer.
- */
-static void
-wrap_texture(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
-{
- struct gl_renderbuffer *rb;
- const GLuint name = 0;
-
- ASSERT(att->Type == GL_TEXTURE);
- ASSERT(att->Renderbuffer == NULL);
-
- rb = ctx->Driver.NewRenderbuffer(ctx, name);
- if (!rb) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "wrap_texture");
- return;
- }
-
- /* init base gl_renderbuffer fields */
- _mesa_init_renderbuffer(rb, name);
- /* plug in our texture_renderbuffer-specific functions */
- rb->Delete = delete_texture_wrapper;
- rb->AllocStorage = NULL; /* illegal! */
-
- /* update attachment point */
- _mesa_reference_renderbuffer(&att->Renderbuffer, rb);
-}
-
-/**
- * Update the renderbuffer wrapper for rendering to a texture.
- * For example, update the width, height of the RB based on the texture size,
- * update the internal format info, etc.
- */
-static void
-update_wrapper(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
-{
- struct gl_renderbuffer *rb = att->Renderbuffer;
- struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
- struct swrast_texture_image *swImage;
- gl_format format;
- GLuint zOffset;
-
- (void) ctx;
-
- swImage = swrast_texture_image(_mesa_get_attachment_teximage(att));
- assert(swImage);
-
- format = swImage->Base.TexFormat;
-
- zOffset = att->Zoffset;
-
- rb->Width = swImage->Base.Width;
- rb->Height = swImage->Base.Height;
- rb->InternalFormat = swImage->Base.InternalFormat;
- rb->_BaseFormat = _mesa_get_format_base_format(format);
-
- rb->Format = format;
-
- /* Set the gl_renderbuffer::Buffer field so that mapping the buffer
- * succeeds.
- */
- if (att->Texture->Target == GL_TEXTURE_3D) {
- srb->Buffer = swImage->Buffer +
- swImage->ImageOffsets[zOffset] * _mesa_get_format_bytes(format);
- }
- else {
- srb->Buffer = swImage->Buffer;
- }
-}
-
-
-
-/**
- * Called when rendering to a texture image begins, or when changing
- * the dest mipmap level, cube face, etc.
- * This is a fallback routine for software render-to-texture.
- *
- * Called via the glRenderbufferTexture1D/2D/3D() functions
- * and elsewhere (such as glTexImage2D).
- *
- * The image we're rendering into is
- * att->Texture->Image[att->CubeMapFace][att->TextureLevel];
- * It'll never be NULL.
- *
- * \param fb the framebuffer object the texture is being bound to
- * \param att the fb attachment point of the texture
- *
- * \sa _mesa_framebuffer_renderbuffer
- */
-void
-_swrast_render_texture(struct gl_context *ctx,
- struct gl_framebuffer *fb,
- struct gl_renderbuffer_attachment *att)
-{
- (void) fb;
-
- if (!att->Renderbuffer) {
- wrap_texture(ctx, att);
- }
- update_wrapper(ctx, att);
-}
-
-
-void
-_swrast_finish_render_texture(struct gl_context *ctx,
- struct gl_renderbuffer_attachment *att)
-{
- /* do nothing */
- /* The renderbuffer texture wrapper will get deleted by the
- * normal mechanism for deleting renderbuffers.
- */
- (void) ctx;
- (void) att;
-}
#include "main/context.h"
-#include "main/fbobject.h"
#include "main/teximage.h"
#include "swrast/swrast.h"
#include "swrast/s_context.h"
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels );
-extern void
-_swrast_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
_swrast_Clear(struct gl_context *ctx, GLbitfield buffers);
struct gl_framebuffer *fb,
struct gl_renderbuffer_attachment *att);
-extern void
-_swrast_finish_render_texture(struct gl_context *ctx,
- struct gl_renderbuffer_attachment *att);
-
extern GLboolean