summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/arbprogram.c229
-rw-r--r--src/mesa/main/bufferobj.c11
-rw-r--r--src/mesa/main/bufferobj.h12
-rw-r--r--src/mesa/main/buffers.c21
-rw-r--r--src/mesa/main/buffers.h4
-rw-r--r--src/mesa/main/context.c26
-rw-r--r--src/mesa/main/dd.h69
-rw-r--r--src/mesa/main/depthstencil.c325
-rw-r--r--src/mesa/main/depthstencil.h5
-rw-r--r--src/mesa/main/dlist.c12
-rw-r--r--src/mesa/main/fbobject.c106
-rw-r--r--src/mesa/main/feedback.c2
-rw-r--r--src/mesa/main/formats.c33
-rw-r--r--src/mesa/main/formats.h3
-rw-r--r--src/mesa/main/framebuffer.c22
-rw-r--r--src/mesa/main/framebuffer.h10
-rw-r--r--src/mesa/main/image.c18
-rw-r--r--src/mesa/main/imports.c6
-rw-r--r--src/mesa/main/imports.h21
-rw-r--r--src/mesa/main/mipmap.c340
-rw-r--r--src/mesa/main/mtypes.h5
-rw-r--r--src/mesa/main/pack.c98
-rw-r--r--src/mesa/main/pack.h4
-rw-r--r--src/mesa/main/readpix.c29
-rw-r--r--src/mesa/main/renderbuffer.c38
-rw-r--r--src/mesa/main/renderbuffer.h14
-rw-r--r--src/mesa/main/samplerobj.c2
-rw-r--r--src/mesa/main/shaderapi.c4
-rw-r--r--src/mesa/main/state.c65
-rw-r--r--src/mesa/main/texenv.c6
-rw-r--r--src/mesa/main/texfetch.c14
-rw-r--r--src/mesa/main/texfetch_tmp.h29
-rw-r--r--src/mesa/main/texformat.c13
-rw-r--r--src/mesa/main/texgetimage.c28
-rw-r--r--src/mesa/main/teximage.c80
-rw-r--r--src/mesa/main/texobj.c14
-rw-r--r--src/mesa/main/texobj.h12
-rw-r--r--src/mesa/main/texrender.c654
-rw-r--r--src/mesa/main/texrender.h18
-rw-r--r--src/mesa/main/texstore.c118
-rw-r--r--src/mesa/main/uniforms.c4
-rw-r--r--src/mesa/main/version.h4
42 files changed, 1248 insertions, 1280 deletions
diff --git a/src/mesa/main/arbprogram.c b/src/mesa/main/arbprogram.c
index 26d781954ed..b83369d9e04 100644
--- a/src/mesa/main/arbprogram.c
+++ b/src/mesa/main/arbprogram.c
@@ -269,6 +269,71 @@ _mesa_IsProgramARB(GLuint id)
return GL_FALSE;
}
+static GLboolean
+get_local_param_pointer(struct gl_context *ctx, const char *func,
+ GLenum target, GLuint index, GLfloat **param)
+{
+ struct gl_program *prog;
+ GLuint maxParams;
+
+ if (target == GL_VERTEX_PROGRAM_ARB
+ && ctx->Extensions.ARB_vertex_program) {
+ prog = &(ctx->VertexProgram.Current->Base);
+ maxParams = ctx->Const.VertexProgram.MaxLocalParams;
+ }
+ else if (target == GL_FRAGMENT_PROGRAM_ARB
+ && ctx->Extensions.ARB_fragment_program) {
+ prog = &(ctx->FragmentProgram.Current->Base);
+ maxParams = ctx->Const.FragmentProgram.MaxLocalParams;
+ }
+ else if (target == GL_FRAGMENT_PROGRAM_NV
+ && ctx->Extensions.NV_fragment_program) {
+ prog = &(ctx->FragmentProgram.Current->Base);
+ maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "%s(target)", func);
+ return GL_FALSE;
+ }
+
+ if (index >= maxParams) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func);
+ return GL_FALSE;
+ }
+
+ *param = prog->LocalParams[index];
+ return GL_TRUE;
+}
+
+
+static GLboolean
+get_env_param_pointer(struct gl_context *ctx, const char *func,
+ GLenum target, GLuint index, GLfloat **param)
+{
+ if (target == GL_FRAGMENT_PROGRAM_ARB
+ && ctx->Extensions.ARB_fragment_program) {
+ if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func);
+ return GL_FALSE;
+ }
+ *param = ctx->FragmentProgram.Parameters[index];
+ return GL_TRUE;
+ }
+ else if (target == GL_VERTEX_PROGRAM_ARB &&
+ (ctx->Extensions.ARB_vertex_program ||
+ ctx->Extensions.NV_vertex_program)) {
+ if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func);
+ return GL_FALSE;
+ }
+ *param = ctx->VertexProgram.Parameters[index];
+ return GL_TRUE;
+ } else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func);
+ return GL_FALSE;
+ }
+}
void GLAPIENTRY
_mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
@@ -383,30 +448,16 @@ void GLAPIENTRY
_mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
+ GLfloat *param;
+
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
- if (target == GL_FRAGMENT_PROGRAM_ARB
- && ctx->Extensions.ARB_fragment_program) {
- if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
- return;
- }
- ASSIGN_4V(ctx->FragmentProgram.Parameters[index], x, y, z, w);
- }
- else if (target == GL_VERTEX_PROGRAM_ARB /* == GL_VERTEX_PROGRAM_NV */
- && (ctx->Extensions.ARB_vertex_program || ctx->Extensions.NV_vertex_program)) {
- if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
- return;
- }
- ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w);
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
- return;
+ if (get_env_param_pointer(ctx, "glProgramEnvParameter",
+ target, index, &param)) {
+ ASSIGN_4V(param, x, y, z, w);
}
}
@@ -422,32 +473,16 @@ void GLAPIENTRY
_mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
const GLfloat *params)
{
+ GLfloat *param;
+
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
- if (target == GL_FRAGMENT_PROGRAM_ARB
- && ctx->Extensions.ARB_fragment_program) {
- if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter4fv(index)");
- return;
- }
- memcpy(ctx->FragmentProgram.Parameters[index], params,
- 4 * sizeof(GLfloat));
- }
- else if (target == GL_VERTEX_PROGRAM_ARB /* == GL_VERTEX_PROGRAM_NV */
- && (ctx->Extensions.ARB_vertex_program || ctx->Extensions.NV_vertex_program)) {
- if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter4fv(index)");
- return;
- }
- memcpy(ctx->VertexProgram.Parameters[index], params,
- 4 * sizeof(GLfloat));
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter4fv(target)");
- return;
+ if (get_env_param_pointer(ctx, "glProgramEnvParameter4fv",
+ target, index, &param)) {
+ memcpy(param, params, 4 * sizeof(GLfloat));
}
}
@@ -496,14 +531,11 @@ _mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
GLdouble *params)
{
GET_CURRENT_CONTEXT(ctx);
- GLfloat fparams[4];
+ GLfloat *fparam;
- _mesa_GetProgramEnvParameterfvARB(target, index, fparams);
- if (ctx->ErrorValue == GL_NO_ERROR) {
- params[0] = fparams[0];
- params[1] = fparams[1];
- params[2] = fparams[2];
- params[3] = fparams[3];
+ if (get_env_param_pointer(ctx, "glGetProgramEnvParameterdv",
+ target, index, &fparam)) {
+ COPY_4V(params, fparam);
}
}
@@ -512,29 +544,15 @@ void GLAPIENTRY
_mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
GLfloat *params)
{
+ GLfloat *param;
+
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- if (target == GL_FRAGMENT_PROGRAM_ARB
- && ctx->Extensions.ARB_fragment_program) {
- if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
- return;
- }
- COPY_4V(params, ctx->FragmentProgram.Parameters[index]);
- }
- else if (target == GL_VERTEX_PROGRAM_ARB
- && ctx->Extensions.ARB_vertex_program) {
- if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
- return;
- }
- COPY_4V(params, ctx->VertexProgram.Parameters[index]);
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
- return;
+ if (get_env_param_pointer(ctx, "glGetProgramEnvParameterfv",
+ target, index, &param)) {
+ COPY_4V(params, param);
}
}
@@ -547,39 +565,16 @@ _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_program *prog;
+ GLfloat *param;
ASSERT_OUTSIDE_BEGIN_END(ctx);
FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
- if ((target == GL_FRAGMENT_PROGRAM_NV
- && ctx->Extensions.NV_fragment_program) ||
- (target == GL_FRAGMENT_PROGRAM_ARB
- && ctx->Extensions.ARB_fragment_program)) {
- if (index >= ctx->Const.FragmentProgram.MaxLocalParams) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
- return;
- }
- prog = &(ctx->FragmentProgram.Current->Base);
- }
- else if (target == GL_VERTEX_PROGRAM_ARB
- && ctx->Extensions.ARB_vertex_program) {
- if (index >= ctx->Const.VertexProgram.MaxLocalParams) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
- return;
- }
- prog = &(ctx->VertexProgram.Current->Base);
+ if (get_local_param_pointer(ctx, "glProgramLocalParameterARB",
+ target, index, &param)) {
+ ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
+ ASSIGN_4V(param, x, y, z, w);
}
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
- return;
- }
-
- ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
- prog->LocalParams[index][0] = x;
- prog->LocalParams[index][1] = y;
- prog->LocalParams[index][2] = z;
- prog->LocalParams[index][3] = w;
}
@@ -667,41 +662,14 @@ void GLAPIENTRY
_mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
GLfloat *params)
{
- const struct gl_program *prog;
- GLuint maxParams;
+ GLfloat *param;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- if (target == GL_VERTEX_PROGRAM_ARB
- && ctx->Extensions.ARB_vertex_program) {
- prog = &(ctx->VertexProgram.Current->Base);
- maxParams = ctx->Const.VertexProgram.MaxLocalParams;
- }
- else if (target == GL_FRAGMENT_PROGRAM_ARB
- && ctx->Extensions.ARB_fragment_program) {
- prog = &(ctx->FragmentProgram.Current->Base);
- maxParams = ctx->Const.FragmentProgram.MaxLocalParams;
- }
- else if (target == GL_FRAGMENT_PROGRAM_NV
- && ctx->Extensions.NV_fragment_program) {
- prog = &(ctx->FragmentProgram.Current->Base);
- maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetProgramLocalParameterARB(target)");
- return;
- }
-
- if (index >= maxParams) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glGetProgramLocalParameterARB(index)");
- return;
+ if (get_local_param_pointer(ctx, "glProgramLocalParameters4fvEXT",
+ target, index, &param)) {
+ COPY_4V(params, param);
}
-
- ASSERT(prog);
- ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
- COPY_4V(params, prog->LocalParams[index]);
}
@@ -712,12 +680,13 @@ void GLAPIENTRY
_mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
GLdouble *params)
{
+ GLfloat *param;
GET_CURRENT_CONTEXT(ctx);
- GLfloat floatParams[4];
- ASSIGN_4V(floatParams, 0.0F, 0.0F, 0.0F, 0.0F);
- _mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
- if (ctx->ErrorValue == GL_NO_ERROR) {
- COPY_4V(params, floatParams);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (get_local_param_pointer(ctx, "glProgramLocalParameters4fvEXT",
+ target, index, &param)) {
+ COPY_4V(params, param);
}
}
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index 3e28d342674..c52358ecb04 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -241,15 +241,14 @@ _mesa_delete_buffer_object(struct gl_context *ctx,
/**
* Set ptr to bufObj w/ reference counting.
+ * This is normally only called from the _mesa_reference_buffer_object() macro
+ * when there's a real pointer change.
*/
void
-_mesa_reference_buffer_object(struct gl_context *ctx,
- struct gl_buffer_object **ptr,
- struct gl_buffer_object *bufObj)
+_mesa_reference_buffer_object_(struct gl_context *ctx,
+ struct gl_buffer_object **ptr,
+ struct gl_buffer_object *bufObj)
{
- if (*ptr == bufObj)
- return;
-
if (*ptr) {
/* Unreference the old buffer */
GLboolean deleteFlag = GL_FALSE;
diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h
index 91fa073b649..f82e41411b7 100644
--- a/src/mesa/main/bufferobj.h
+++ b/src/mesa/main/bufferobj.h
@@ -75,9 +75,19 @@ _mesa_initialize_buffer_object( struct gl_buffer_object *obj,
GLuint name, GLenum target );
extern void
+_mesa_reference_buffer_object_(struct gl_context *ctx,
+ struct gl_buffer_object **ptr,
+ struct gl_buffer_object *bufObj);
+
+static INLINE void
_mesa_reference_buffer_object(struct gl_context *ctx,
struct gl_buffer_object **ptr,
- struct gl_buffer_object *bufObj);
+ struct gl_buffer_object *bufObj)
+{
+ if (*ptr != bufObj)
+ _mesa_reference_buffer_object_(ctx, ptr, bufObj);
+}
+
extern void
_mesa_init_buffer_object_functions(struct dd_function_table *driver);
diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c
index 63f53e2b080..a75c9c2e782 100644
--- a/src/mesa/main/buffers.c
+++ b/src/mesa/main/buffers.c
@@ -462,6 +462,27 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
/**
+ * Update the current drawbuffer's _ColorDrawBufferIndex[] list, etc.
+ * from the context's Color.DrawBuffer[] state.
+ * Use when changing contexts.
+ */
+void
+_mesa_update_draw_buffers(struct gl_context *ctx)
+{
+ GLenum buffers[MAX_DRAW_BUFFERS];
+ GLuint i;
+
+ /* should be a window system FBO */
+ assert(ctx->DrawBuffer->Name == 0);
+
+ for (i = 0; i < ctx->Const.MaxDrawBuffers; i++)
+ buffers[i] = ctx->Color.DrawBuffer[i];
+
+ _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, buffers, NULL);
+}
+
+
+/**
* Like \sa _mesa_drawbuffers(), this is a helper function for setting
* GL_READ_BUFFER state in the context and current FBO.
* \param ctx the rendering context
diff --git a/src/mesa/main/buffers.h b/src/mesa/main/buffers.h
index 1404112c411..8083bc3d353 100644
--- a/src/mesa/main/buffers.h
+++ b/src/mesa/main/buffers.h
@@ -50,6 +50,10 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
extern void
_mesa_readbuffer(struct gl_context *ctx, GLenum buffer, GLint bufferIndex);
+extern void
+_mesa_update_draw_buffers(struct gl_context *ctx);
+
+
extern void GLAPIENTRY
_mesa_ReadBuffer( GLenum mode );
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index ea13bdd6835..b83a5d621fa 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -1430,7 +1430,8 @@ _mesa_make_current( struct gl_context *newCtx,
}
if (curCtx &&
- (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) && /* make sure this context is valid for flushing */
+ (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) &&
+ /* make sure this context is valid for flushing */
curCtx != newCtx)
_mesa_flush(curCtx);
@@ -1445,8 +1446,6 @@ _mesa_make_current( struct gl_context *newCtx,
_glapi_set_dispatch(newCtx->CurrentDispatch);
if (drawBuffer && readBuffer) {
- /* TODO: check if newCtx and buffer's visual match??? */
-
ASSERT(drawBuffer->Name == 0);
ASSERT(readBuffer->Name == 0);
_mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer);
@@ -1457,23 +1456,12 @@ _mesa_make_current( struct gl_context *newCtx,
* or not bound to a user-created FBO.
*/
if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {
- /* KW: merge conflict here, revisit.
- */
- /* fix up the fb fields - these will end up wrong otherwise
- * if the DRIdrawable changes, and everything relies on them.
- * This is a bit messy (same as needed in _mesa_BindFramebufferEXT)
- */
- unsigned int i;
- GLenum buffers[MAX_DRAW_BUFFERS];
-
_mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);
-
- for(i = 0; i < newCtx->Const.MaxDrawBuffers; i++) {
- buffers[i] = newCtx->Color.DrawBuffer[i];
- }
-
- _mesa_drawbuffers(newCtx, newCtx->Const.MaxDrawBuffers,
- buffers, NULL);
+ /* 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_buffers(newCtx);
}
if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) {
_mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 9fe6d527f92..e0c5844e193 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -189,31 +189,22 @@ struct dd_function_table {
/*@{*/
/**
- * Choose texture format.
- *
- * This is called by the \c _mesa_store_tex[sub]image[123]d() fallback
- * functions. The driver should examine \p internalFormat and return a
- * gl_format value.
+ * Choose actual hardware texture format given the user-provided source
+ * image format and type and the desired internal format. In some
+ * cases, srcFormat and srcType can be GL_NONE.
+ * Called by glTexImage(), etc.
*/
GLuint (*ChooseTextureFormat)( struct gl_context *ctx, GLint internalFormat,
GLenum srcFormat, GLenum srcType );
/**
- * Called by glTexImage1D().
- *
- * \param target user specified.
- * \param format user specified.
- * \param type user specified.
- * \param pixels user specified.
- * \param packing indicates the image packing of pixels.
+ * Called by glTexImage1D(). Simply copy the source texture data into the
+ * destination texture memory. The gl_texture_image fields, etc. will be
+ * fully initialized.
+ * The parameters are the same as glTexImage1D(), plus:
+ * \param packing describes how to unpack the source data.
* \param texObj is the target texture object.
- * \param texImage is the target texture image. It will have the texture \p
- * width, \p height, \p depth, \p border and \p internalFormat information.
- *
- * \p retainInternalCopy is returned by this function and indicates whether
- * core Mesa should keep an internal copy of the texture image.
- *
- * Drivers should call a fallback routine from texstore.c if needed.
+ * \param texImage is the target texture image.
*/
void (*TexImage1D)( struct gl_context *ctx, GLenum target, GLint level,
GLint internalFormat,
@@ -250,25 +241,9 @@ struct dd_function_table {
struct gl_texture_image *texImage );
/**
- * Called by glTexSubImage1D().
- *
- * \param target user specified.
- * \param level user specified.
- * \param xoffset user specified.
- * \param yoffset user specified.
- * \param zoffset user specified.
- * \param width user specified.
- * \param height user specified.
- * \param depth user specified.
- * \param format user specified.
- * \param type user specified.
- * \param pixels user specified.
- * \param packing indicates the image packing of pixels.
- * \param texObj is the target texture object.
- * \param texImage is the target texture image. It will have the texture \p
- * width, \p height, \p border and \p internalFormat information.
- *
- * The driver should use a fallback routine from texstore.c if needed.
+ * Called by glTexSubImage1D(). Replace a subset of the target texture
+ * with new texel data.
+ * \sa dd_function_table::TexImage1D.
*/
void (*TexSubImage1D)( struct gl_context *ctx, GLenum target, GLint level,
GLint xoffset, GLsizei width,
@@ -315,24 +290,6 @@ struct dd_function_table {
struct gl_texture_image *texImage );
/**
- * Called by glCopyTexImage1D().
- *
- * Drivers should use a fallback routine from texstore.c if needed.
- */
- void (*CopyTexImage1D)( struct gl_context *ctx, GLenum target, GLint level,
- GLenum internalFormat, GLint x, GLint y,
- GLsizei width, GLint border );
-
- /**
- * Called by glCopyTexImage2D().
- *
- * Drivers should use a fallback routine from texstore.c if needed.
- */
- void (*CopyTexImage2D)( struct gl_context *ctx, GLenum target, GLint level,
- GLenum internalFormat, GLint x, GLint y,
- GLsizei width, GLsizei height, GLint border );
-
- /**
* Called by glCopyTexSubImage1D().
*
* Drivers should use a fallback routine from texstore.c if needed.
diff --git a/src/mesa/main/depthstencil.c b/src/mesa/main/depthstencil.c
index ab62c97fe5a..40d6c9612a2 100644
--- a/src/mesa/main/depthstencil.c
+++ b/src/mesa/main/depthstencil.c
@@ -63,7 +63,8 @@ static void
delete_wrapper(struct gl_renderbuffer *rb)
{
ASSERT(rb->Format == MESA_FORMAT_S8 ||
- rb->Format == MESA_FORMAT_X8_Z24);
+ rb->Format == MESA_FORMAT_X8_Z24 ||
+ rb->Format == MESA_FORMAT_Z32_FLOAT);
_mesa_reference_renderbuffer(&rb->Wrapped, NULL);
free(rb);
}
@@ -393,6 +394,217 @@ _mesa_new_z24_renderbuffer_wrapper(struct gl_context *ctx,
}
+static void
+get_row_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count,
+ GLint x, GLint y, void *values)
+{
+ struct gl_renderbuffer *dsrb = z32frb->Wrapped;
+ GLfloat temp[MAX_WIDTH*2];
+ GLfloat *dst = (GLfloat *) values;
+ const GLfloat *src = (const GLfloat *) dsrb->GetPointer(ctx, dsrb, x, y);
+ GLuint i;
+ ASSERT(z32frb->DataType == GL_FLOAT);
+ ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+ ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+ if (!src) {
+ dsrb->GetRow(ctx, dsrb, count, x, y, temp);
+ src = temp;
+ }
+ for (i = 0; i < count; i++) {
+ dst[i] = src[i*2];
+ }
+}
+
+static void
+get_values_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count,
+ const GLint x[], const GLint y[], void *values)
+{
+ struct gl_renderbuffer *dsrb = z32frb->Wrapped;
+ GLfloat temp[MAX_WIDTH*2];
+ GLfloat *dst = (GLfloat *) values;
+ GLuint i;
+ ASSERT(z32frb->DataType == GL_FLOAT);
+ ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+ ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+ ASSERT(count <= MAX_WIDTH);
+ /* don't bother trying direct access */
+ dsrb->GetValues(ctx, dsrb, count, x, y, temp);
+ for (i = 0; i < count; i++) {
+ dst[i] = temp[i*2];
+ }
+}
+
+static void
+put_row_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+ struct gl_renderbuffer *dsrb = z32frb->Wrapped;
+ const GLfloat *src = (const GLfloat *) values;
+ GLfloat *dst = (GLfloat *) dsrb->GetPointer(ctx, dsrb, x, y);
+ ASSERT(z32frb->DataType == GL_FLOAT);
+ ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+ ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+ if (dst) {
+ /* direct access */
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ dst[i*2] = src[i];
+ }
+ }
+ }
+ else {
+ /* get, modify, put */
+ GLfloat temp[MAX_WIDTH*2];
+ GLuint i;
+ dsrb->GetRow(ctx, dsrb, count, x, y, temp);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ temp[i*2] = src[i];
+ }
+ }
+ dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
+ }
+}
+
+static void
+put_mono_row_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count,
+ GLint x, GLint y, const void *value, const GLubyte *mask)
+{
+ struct gl_renderbuffer *dsrb = z32frb->Wrapped;
+ GLfloat *dst = (GLfloat *) dsrb->GetPointer(ctx, dsrb, x, y);
+ ASSERT(z32frb->DataType == GL_FLOAT);
+ ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+ ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+ if (dst) {
+ /* direct access */
+ GLuint i;
+ const GLfloat val = *(GLfloat*)value;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ dst[i*2] = val;
+ }
+ }
+ }
+ else {
+ /* get, modify, put */
+ GLfloat temp[MAX_WIDTH*2];
+ GLuint i;
+ const GLfloat val = *(GLfloat *)value;
+ dsrb->GetRow(ctx, dsrb, count, x, y, temp);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ temp[i*2] = val;
+ }
+ }
+ dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
+ }
+}
+
+static void
+put_values_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count,
+ const GLint x[], const GLint y[],
+ const void *values, const GLubyte *mask)
+{
+ struct gl_renderbuffer *dsrb = z32frb->Wrapped;
+ const GLfloat *src = (const GLfloat *) values;
+ ASSERT(z32frb->DataType == GL_FLOAT);
+ ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+ ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+ if (dsrb->GetPointer(ctx, dsrb, 0, 0)) {
+ /* direct access */
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLfloat *dst = (GLfloat *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]);
+ *dst = src[i];
+ }
+ }
+ }
+ else {
+ /* get, modify, put */
+ GLfloat temp[MAX_WIDTH*2];
+ GLuint i;
+ dsrb->GetValues(ctx, dsrb, count, x, y, temp);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ temp[i*2] = src[i];
+ }
+ }
+ dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
+ }
+}
+
+static void
+put_mono_values_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb,
+ GLuint count, const GLint x[], const GLint y[],
+ const void *value, const GLubyte *mask)
+{
+ struct gl_renderbuffer *dsrb = z32frb->Wrapped;
+ GLfloat temp[MAX_WIDTH*2];
+ GLuint i;
+ const GLfloat val = *(GLfloat *)value;
+ ASSERT(z32frb->DataType == GL_FLOAT);
+ ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+ ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+ /* get, modify, put */
+ dsrb->GetValues(ctx, dsrb, count, x, y, temp);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ temp[i*2] = val;
+ }
+ }
+ dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
+}
+
+
+/**
+ * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
+ * a depth renderbuffer.
+ * \return new depth renderbuffer
+ */
+struct gl_renderbuffer *
+_mesa_new_z32f_renderbuffer_wrapper(struct gl_context *ctx,
+ struct gl_renderbuffer *dsrb)
+{
+ struct gl_renderbuffer *z32frb;
+
+ ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+ ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+
+ z32frb = ctx->Driver.NewRenderbuffer(ctx, 0);
+ if (!z32frb)
+ return NULL;
+
+ /* NOTE: need to do manual refcounting here */
+ z32frb->Wrapped = dsrb;
+ dsrb->RefCount++;
+
+ z32frb->Name = dsrb->Name;
+ z32frb->RefCount = 0;
+ z32frb->Width = dsrb->Width;
+ z32frb->Height = dsrb->Height;
+ z32frb->RowStride = dsrb->RowStride;
+ z32frb->InternalFormat = GL_DEPTH_COMPONENT32F;
+ z32frb->Format = MESA_FORMAT_Z32_FLOAT;
+ z32frb->_BaseFormat = GL_DEPTH_COMPONENT;
+ z32frb->DataType = GL_FLOAT;
+ z32frb->Data = NULL;
+ z32frb->Delete = delete_wrapper;
+ z32frb->AllocStorage = alloc_wrapper_storage;
+ z32frb->GetPointer = nop_get_pointer;
+ z32frb->GetRow = get_row_z32f;
+ z32frb->GetValues = get_values_z32f;
+ z32frb->PutRow = put_row_z32f;
+ z32frb->PutRowRGB = NULL;
+ z32frb->PutMonoRow = put_mono_row_z32f;
+ z32frb->PutValues = put_values_z32f;
+ z32frb->PutMonoValues = put_mono_values_z32f;
+
+ return z32frb;
+}
+
+
/*======================================================================
* Stencil wrapper around depth/stencil renderbuffer
*/
@@ -402,16 +614,22 @@ get_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
GLint x, GLint y, void *values)
{
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
- GLuint temp[MAX_WIDTH], i;
+ GLuint temp[MAX_WIDTH*2], i;
GLubyte *dst = (GLubyte *) values;
const GLuint *src = (const GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
- ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
+ dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
if (!src) {
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
src = temp;
}
- if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+ if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+ for (i = 0; i < count; i++) {
+ dst[i] = src[i*2+1] & 0xff;
+ }
+ }
+ else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
dst[i] = src[i] & 0xff;
}
@@ -429,14 +647,20 @@ get_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count
const GLint x[], const GLint y[], void *values)
{
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
- GLuint temp[MAX_WIDTH], i;
+ GLuint temp[MAX_WIDTH*2], i;
GLubyte *dst = (GLubyte *) values;
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
- ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
+ dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
ASSERT(count <= MAX_WIDTH);
/* don't bother trying direct access */
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
- if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+ if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+ for (i = 0; i < count; i++) {
+ dst[i] = temp[i*2+1] & 0xff;
+ }
+ }
+ else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
dst[i] = temp[i] & 0xff;
}
@@ -457,11 +681,19 @@ put_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
const GLubyte *src = (const GLubyte *) values;
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
- ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
+ dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
if (dst) {
/* direct access */
GLuint i;
- if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+ if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ dst[i*2+1] = src[i];
+ }
+ }
+ }
+ else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
dst[i] = (dst[i] & 0xffffff00) | src[i];
@@ -479,9 +711,16 @@ put_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
}
else {
/* get, modify, put */
- GLuint temp[MAX_WIDTH], i;
+ GLuint temp[MAX_WIDTH*2], i;
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
- if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+ if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ temp[i*2+1] = src[i];
+ }
+ }
+ }
+ else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
temp[i] = (temp[i] & 0xffffff00) | src[i];
@@ -508,11 +747,19 @@ put_mono_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint cou
const GLubyte val = *((GLubyte *) value);
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
- ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
+ dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
if (dst) {
/* direct access */
GLuint i;
- if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+ if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ dst[i*2+1] = val;
+ }
+ }
+ }
+ else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
dst[i] = (dst[i] & 0xffffff00) | val;
@@ -530,9 +777,16 @@ put_mono_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint cou
}
else {
/* get, modify, put */
- GLuint temp[MAX_WIDTH], i;
+ GLuint temp[MAX_WIDTH*2], i;
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
- if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+ if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ temp[i*2+1] = val;
+ }
+ }
+ }
+ else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
temp[i] = (temp[i] & 0xffffff00) | val;
@@ -559,11 +813,20 @@ put_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
const GLubyte *src = (const GLubyte *) values;
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
- ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
+ dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
if (dsrb->GetPointer(ctx, dsrb, 0, 0)) {
/* direct access */
GLuint i;
- if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+ if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]);
+ dst[1] = src[i];
+ }
+ }
+ }
+ else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]);
@@ -583,9 +846,16 @@ put_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count
}
else {
/* get, modify, put */
- GLuint temp[MAX_WIDTH], i;
+ GLuint temp[MAX_WIDTH*2], i;
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
- if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+ if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ temp[i*2+1] = src[i];
+ }
+ }
+ }
+ else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
temp[i] = (temp[i] & 0xffffff00) | src[i];
@@ -610,11 +880,18 @@ put_mono_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint
const void *value, const GLubyte *mask)
{
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
- GLuint temp[MAX_WIDTH], i;
+ GLuint temp[MAX_WIDTH*2], i;
const GLubyte val = *((GLubyte *) value);
/* get, modify, put */
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
- if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+ if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ temp[i*2+1] = val;
+ }
+ }
+ }
+ else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
temp[i] = (temp[i] & 0xffffff00) | val;
@@ -644,8 +921,10 @@ _mesa_new_s8_renderbuffer_wrapper(struct gl_context *ctx, struct gl_renderbuffer
struct gl_renderbuffer *s8rb;
ASSERT(dsrb->Format == MESA_FORMAT_Z24_S8 ||
- dsrb->Format == MESA_FORMAT_S8_Z24);
- ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ dsrb->Format == MESA_FORMAT_S8_Z24 ||
+ dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
+ dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
s8rb = ctx->Driver.NewRenderbuffer(ctx, 0);
if (!s8rb)
diff --git a/src/mesa/main/depthstencil.h b/src/mesa/main/depthstencil.h
index ef63c5d7a31..b47a2e482c2 100644
--- a/src/mesa/main/depthstencil.h
+++ b/src/mesa/main/depthstencil.h
@@ -34,6 +34,11 @@ _mesa_new_z24_renderbuffer_wrapper(struct gl_context *ctx,
extern struct gl_renderbuffer *
+_mesa_new_z32f_renderbuffer_wrapper(struct gl_context *ctx,
+ struct gl_renderbuffer *dsrb);
+
+
+extern struct gl_renderbuffer *
_mesa_new_s8_renderbuffer_wrapper(struct gl_context *ctx,
struct gl_renderbuffer *dsrb);
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index 958f5a69739..f9282398c21 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -7542,32 +7542,32 @@ execute_list(struct gl_context *ctx, GLuint list)
break;
case OPCODE_CLEAR_BUFFER_IV:
{
- GLint value[4];
+ /*GLint value[4];
value[0] = n[3].i;
value[1] = n[4].i;
value[2] = n[5].i;
value[3] = n[6].i;
- /*CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));*/
+ CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));*/
}
break;
case OPCODE_CLEAR_BUFFER_UIV:
{
- GLuint value[4];
+ /*GLuint value[4];
value[0] = n[3].ui;
value[1] = n[4].ui;
value[2] = n[5].ui;
value[3] = n[6].ui;
- /*CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));*/
+ CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));*/
}
break;
case OPCODE_CLEAR_BUFFER_FV:
{
- GLfloat value[4];
+ /*GLfloat value[4];
value[0] = n[3].f;
value[1] = n[4].f;
value[2] = n[5].f;
value[3] = n[6].f;
- /*CALL_ClearBufferfv(ctx->Exec, (n[1].e, n[2].i, value));*/
+ CALL_ClearBufferfv(ctx->Exec, (n[1].e, n[2].i, value));*/
}
break;
case OPCODE_CLEAR_BUFFER_FI:
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 2230b262336..82eb7fb718d 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -78,9 +78,32 @@ static struct gl_renderbuffer DummyRenderbuffer;
static struct gl_framebuffer IncompleteFramebuffer;
-#define IS_CUBE_FACE(TARGET) \
- ((TARGET) >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && \
- (TARGET) <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
+static INLINE GLboolean
+is_cube_face(GLenum target)
+{
+ return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
+}
+
+
+/**
+ * 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
@@ -196,7 +219,7 @@ _mesa_get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
{
GLuint i;
- assert(fb->Name > 0);
+ assert(is_user_fbo(fb));
switch (attachment) {
case GL_COLOR_ATTACHMENT0_EXT:
@@ -244,7 +267,7 @@ static struct gl_renderbuffer_attachment *
_mesa_get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
GLenum attachment)
{
- assert(fb->Name == 0);
+ assert(is_winsys_fbo(fb));
switch (attachment) {
case GL_FRONT_LEFT:
@@ -669,7 +692,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
GLint i;
GLuint j;
- assert(fb->Name != 0);
+ assert(is_user_fbo(fb));
numImages = 0;
fb->Width = 0;
@@ -968,10 +991,11 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
_mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
}
- if (ctx->DrawBuffer->Name) {
+ if (is_user_fbo(ctx->DrawBuffer)) {
detach_renderbuffer(ctx, ctx->DrawBuffer, rb);
}
- if (ctx->ReadBuffer->Name && ctx->ReadBuffer != ctx->DrawBuffer) {
+ if (is_user_fbo(ctx->ReadBuffer)
+ && ctx->ReadBuffer != ctx->DrawBuffer) {
detach_renderbuffer(ctx, ctx->ReadBuffer, rb);
}
@@ -1107,6 +1131,16 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
return GL_DEPTH_STENCIL_EXT;
else
return 0;
+ case GL_DEPTH_COMPONENT32F:
+ if (ctx->Extensions.ARB_depth_buffer_float)
+ return GL_DEPTH_COMPONENT;
+ else
+ return 0;
+ case GL_DEPTH32F_STENCIL8:
+ if (ctx->Extensions.ARB_depth_buffer_float)
+ return GL_DEPTH_STENCIL;
+ else
+ return 0;
case GL_RED:
case GL_R8:
case GL_R16:
@@ -1203,7 +1237,7 @@ invalidate_rb(GLuint key, void *data, void *userData)
struct gl_renderbuffer *rb = (struct gl_renderbuffer *) userData;
/* If this is a user-created FBO */
- if (fb->Name) {
+ if (is_user_fbo(fb)) {
GLuint i;
for (i = 0; i < BUFFER_COUNT; i++) {
struct gl_renderbuffer_attachment *att = fb->Attachment + i;
@@ -1532,7 +1566,7 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
GLuint i;
ASSERT(ctx->Driver.RenderTexture);
- if (fb->Name == 0)
+ if (is_winsys_fbo(fb))
return; /* can't render to texture with winsys framebuffers */
for (i = 0; i < BUFFER_COUNT; i++) {
@@ -1552,7 +1586,7 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
static void
check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
{
- if (fb->Name == 0)
+ if (is_winsys_fbo(fb))
return; /* can't render to texture with winsys framebuffers */
if (ctx->Driver.FinishRenderTexture) {
@@ -1805,7 +1839,7 @@ _mesa_CheckFramebufferStatusEXT(GLenum target)
return 0;
}
- if (buffer->Name == 0) {
+ if (is_winsys_fbo(buffer)) {
/* The window system / default framebuffer is always complete */
return GL_FRAMEBUFFER_COMPLETE_EXT;
}
@@ -1843,7 +1877,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
}
/* check framebuffer binding */
- if (fb->Name == 0) {
+ if (is_winsys_fbo(fb)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glFramebufferTexture%sEXT", caller);
return;
@@ -1866,7 +1900,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
}
else {
err = (texObj->Target == GL_TEXTURE_CUBE_MAP)
- ? !IS_CUBE_FACE(textarget)
+ ? !is_cube_face(textarget)
: (texObj->Target != textarget);
}
}
@@ -1970,7 +2004,7 @@ _mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
if ((texture != 0) &&
(textarget != GL_TEXTURE_2D) &&
(textarget != GL_TEXTURE_RECTANGLE_ARB) &&
- (!IS_CUBE_FACE(textarget))) {
+ (!is_cube_face(textarget))) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glFramebufferTexture2DEXT(textarget=0x%x)", textarget);
return;
@@ -2034,7 +2068,7 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
return;
}
- if (fb->Name == 0) {
+ if (is_winsys_fbo(fb)) {
/* Can't attach new renderbuffers to a window system framebuffer */
_mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT");
return;
@@ -2100,10 +2134,14 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
{
const struct gl_renderbuffer_attachment *att;
struct gl_framebuffer *buffer;
+ GLenum err;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
+ /* The error differs in GL andd GLES. */
+ err = ctx->API == API_OPENGL ? GL_INVALID_OPERATION : GL_INVALID_ENUM;
+
buffer = get_framebuffer_target(ctx, target);
if (!buffer) {
_mesa_error(ctx, GL_INVALID_ENUM,
@@ -2111,7 +2149,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
return;
}
- if (buffer->Name == 0) {
+ if (is_winsys_fbo(buffer)) {
/* the default / window-system FBO */
att = _mesa_get_fb0_attachment(ctx, buffer, attachment);
}
@@ -2143,7 +2181,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
switch (pname) {
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
- *params = buffer->Name == 0 ? GL_FRAMEBUFFER_DEFAULT : att->Type;
+ *params = is_winsys_fbo(buffer) ? GL_FRAMEBUFFER_DEFAULT : att->Type;
return;
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
if (att->Type == GL_RENDERBUFFER_EXT) {
@@ -2154,7 +2192,12 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
}
else {
assert(att->Type == GL_NONE);
- *params = 0;
+ if (ctx->API == API_OPENGL) {
+ *params = 0;
+ } else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ }
}
return;
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT:
@@ -2162,7 +2205,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
*params = att->TextureLevel;
}
else if (att->Type == GL_NONE) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
+ _mesa_error(ctx, err,
"glGetFramebufferAttachmentParameterivEXT(pname)");
}
else {
@@ -2180,7 +2223,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
}
}
else if (att->Type == GL_NONE) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
+ _mesa_error(ctx, err,
"glGetFramebufferAttachmentParameterivEXT(pname)");
}
else {
@@ -2198,7 +2241,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
}
}
else if (att->Type == GL_NONE) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
+ _mesa_error(ctx, err,
"glGetFramebufferAttachmentParameterivEXT(pname)");
}
else {
@@ -2212,7 +2255,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
"glGetFramebufferAttachmentParameterivEXT(pname)");
}
else if (att->Type == GL_NONE) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
+ _mesa_error(ctx, err,
"glGetFramebufferAttachmentParameterivEXT(pname)");
}
else {
@@ -2233,7 +2276,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
return;
}
else if (att->Type == GL_NONE) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
+ _mesa_error(ctx, err,
"glGetFramebufferAttachmentParameterivEXT(pname)");
}
else {
@@ -2242,6 +2285,15 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
/* special cases */
*params = GL_INDEX;
}
+ else if (format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+ /* depends on the attachment parameter */
+ if (attachment == GL_STENCIL_ATTACHMENT) {
+ *params = GL_INDEX;
+ }
+ else {
+ *params = GL_FLOAT;
+ }
+ }
else {
*params = _mesa_get_format_datatype(format);
}
@@ -2258,7 +2310,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
"glGetFramebufferAttachmentParameterivEXT(pname)");
}
else if (att->Type == GL_NONE) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
+ _mesa_error(ctx, err,
"glGetFramebufferAttachmentParameterivEXT(pname)");
}
else if (att->Texture) {
@@ -2560,6 +2612,10 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
}
}
+ if (!mask) {
+ return;
+ }
+
ASSERT(ctx->Driver.BlitFramebuffer);
ctx->Driver.BlitFramebuffer(ctx,
srcX0, srcY0, srcX1, srcY1,
diff --git a/src/mesa/main/feedback.c b/src/mesa/main/feedback.c
index fcb089f1f31..597ec1e3f9a 100644
--- a/src/mesa/main/feedback.c
+++ b/src/mesa/main/feedback.c
@@ -64,7 +64,7 @@ _mesa_FeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer )
_mesa_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(size<0)" );
return;
}
- if (!buffer) {
+ if (!buffer && size > 0) {
_mesa_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(buffer==NULL)" );
ctx->Feedback.BufferSize = 0;
return;
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
index e88ba43971b..f9298d2d1e9 100644
--- a/src/mesa/main/formats.c
+++ b/src/mesa/main/formats.c
@@ -1091,6 +1091,25 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] =
0, 0, 0, 0, 0,
1, 1, 4
},
+ /* ARB_depth_buffer_float */
+ {
+ MESA_FORMAT_Z32_FLOAT, /* Name */
+ "MESA_FORMAT_Z32_FLOAT", /* StrName */
+ GL_DEPTH_COMPONENT, /* BaseFormat */
+ GL_FLOAT, /* DataType */
+ 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
+ 0, 0, 0, 32, 0, /* Lum/Int/Index/Depth/StencilBits */
+ 1, 1, 4 /* BlockWidth/Height,Bytes */
+ },
+ {
+ MESA_FORMAT_Z32_FLOAT_X24S8, /* Name */
+ "MESA_FORMAT_Z32_FLOAT_X24S8", /* StrName */
+ GL_DEPTH_STENCIL, /* BaseFormat */
+ GL_NONE /* XXX */, /* DataType */
+ 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
+ 0, 0, 0, 32, 8, /* Lum/Int/Index/Depth/StencilBits */
+ 1, 1, 8 /* BlockWidth/Height,Bytes */
+ },
};
@@ -1466,7 +1485,9 @@ _mesa_test_formats(void)
info->DataType == GL_SIGNED_NORMALIZED ||
info->DataType == GL_UNSIGNED_INT ||
info->DataType == GL_INT ||
- info->DataType == GL_FLOAT);
+ info->DataType == GL_FLOAT ||
+ /* Z32_FLOAT_X24S8 has DataType of GL_NONE */
+ info->DataType == GL_NONE);
if (info->BaseFormat == GL_RGB) {
assert(info->RedBits > 0);
@@ -1654,6 +1675,16 @@ _mesa_format_to_type_and_comps(gl_format format,
*comps = 1;
return;
+ case MESA_FORMAT_Z32_FLOAT:
+ *datatype = GL_FLOAT;
+ *comps = 1;
+ return;
+
+ case MESA_FORMAT_Z32_FLOAT_X24S8:
+ *datatype = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
+ *comps = 1;
+ return;
+
case MESA_FORMAT_DUDV8:
*datatype = GL_BYTE;
*comps = 2;
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
index 0640bbc4af1..5b8c01781a6 100644
--- a/src/mesa/main/formats.h
+++ b/src/mesa/main/formats.h
@@ -209,6 +209,9 @@ typedef enum
MESA_FORMAT_RGB9_E5_FLOAT,
MESA_FORMAT_R11_G11_B10_FLOAT,
+ MESA_FORMAT_Z32_FLOAT,
+ MESA_FORMAT_Z32_FLOAT_X24S8,
+
MESA_FORMAT_COUNT
} gl_format;
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index 66c9bd91096..e27569a6fac 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -232,17 +232,13 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
/**
* Set *ptr to point to fb, with refcounting and locking.
+ * This is normally only called from the _mesa_reference_framebuffer() macro
+ * when there's a real pointer change.
*/
void
-_mesa_reference_framebuffer(struct gl_framebuffer **ptr,
- struct gl_framebuffer *fb)
+_mesa_reference_framebuffer_(struct gl_framebuffer **ptr,
+ struct gl_framebuffer *fb)
{
- assert(ptr);
- if (*ptr == fb) {
- /* no change */
- return;
- }
-
if (*ptr) {
/* unreference old renderbuffer */
GLboolean deleteFlag = GL_FALSE;
@@ -631,8 +627,14 @@ _mesa_update_depth_buffer(struct gl_context *ctx,
|| fb->_DepthBuffer->Wrapped != depthRb
|| _mesa_get_format_base_format(fb->_DepthBuffer->Format) != GL_DEPTH_COMPONENT) {
/* need to update wrapper */
- struct gl_renderbuffer *wrapper
- = _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb);
+ struct gl_renderbuffer *wrapper;
+
+ if (depthRb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+ wrapper = _mesa_new_z32f_renderbuffer_wrapper(ctx, depthRb);
+ }
+ else {
+ wrapper = _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb);
+ }
_mesa_reference_renderbuffer(&fb->_DepthBuffer, wrapper);
ASSERT(fb->_DepthBuffer->Wrapped == depthRb);
}
diff --git a/src/mesa/main/framebuffer.h b/src/mesa/main/framebuffer.h
index c3bd638c9de..b2b29a7a1db 100644
--- a/src/mesa/main/framebuffer.h
+++ b/src/mesa/main/framebuffer.h
@@ -51,8 +51,16 @@ extern void
_mesa_free_framebuffer_data(struct gl_framebuffer *buffer);
extern void
+_mesa_reference_framebuffer_(struct gl_framebuffer **ptr,
+ struct gl_framebuffer *fb);
+
+static INLINE void
_mesa_reference_framebuffer(struct gl_framebuffer **ptr,
- struct gl_framebuffer *fb);
+ struct gl_framebuffer *fb)
+{
+ if (*ptr != fb)
+ _mesa_reference_framebuffer_(ptr, fb);
+}
extern void
_mesa_resize_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c
index 6d7bc735887..37127dcb7a2 100644
--- a/src/mesa/main/image.c
+++ b/src/mesa/main/image.c
@@ -84,6 +84,7 @@ _mesa_type_is_packed(GLenum type)
case GL_UNSIGNED_INT_24_8_EXT:
case GL_UNSIGNED_INT_5_9_9_9_REV:
case GL_UNSIGNED_INT_10F_11F_11F_REV:
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
return GL_TRUE;
}
@@ -228,6 +229,8 @@ _mesa_sizeof_packed_type( GLenum type )
return sizeof(GLuint);
case GL_UNSIGNED_INT_10F_11F_11F_REV:
return sizeof(GLuint);
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ return 8;
default:
return -1;
}
@@ -379,6 +382,11 @@ _mesa_bytes_per_pixel( GLenum format, GLenum type )
return sizeof(GLuint);
else
return -1;
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ if (format == GL_DEPTH_STENCIL)
+ return 8;
+ else
+ return -1;
default:
return -1;
}
@@ -531,8 +539,10 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx,
else
return GL_FALSE;
case GL_DEPTH_STENCIL_EXT:
- if (ctx->Extensions.EXT_packed_depth_stencil
- && type == GL_UNSIGNED_INT_24_8_EXT)
+ if ((ctx->Extensions.EXT_packed_depth_stencil &&
+ type == GL_UNSIGNED_INT_24_8_EXT) ||
+ (ctx->Extensions.ARB_depth_buffer_float &&
+ type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV))
return GL_TRUE;
else
return GL_FALSE;
@@ -884,6 +894,7 @@ _mesa_is_depth_format(GLenum format)
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32:
+ case GL_DEPTH_COMPONENT32F:
return GL_TRUE;
default:
return GL_FALSE;
@@ -931,6 +942,7 @@ _mesa_is_depthstencil_format(GLenum format)
switch (format) {
case GL_DEPTH24_STENCIL8_EXT:
case GL_DEPTH_STENCIL_EXT:
+ case GL_DEPTH32F_STENCIL8:
return GL_TRUE;
default:
return GL_FALSE;
@@ -956,6 +968,8 @@ _mesa_is_depth_or_stencil_format(GLenum format)
case GL_STENCIL_INDEX16_EXT:
case GL_DEPTH_STENCIL_EXT:
case GL_DEPTH24_STENCIL8_EXT:
+ case GL_DEPTH_COMPONENT32F:
+ case GL_DEPTH32F_STENCIL8:
return GL_TRUE;
default:
return GL_FALSE;
diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c
index f262b25c718..0a572ec225d 100644
--- a/src/mesa/main/imports.c
+++ b/src/mesa/main/imports.c
@@ -511,9 +511,10 @@ _mesa_ffsll(int64_t val)
return 0;
}
+#endif
-
-#if ((_GNUC__ == 3 && __GNUC_MINOR__ < 4) || __GNUC__ < 4)
+#if !defined(__GNUC__) ||\
+ ((_GNUC__ == 3 && __GNUC_MINOR__ < 4) && __GNUC__ < 4)
/**
* Return number of bits set in given GLuint.
*/
@@ -527,7 +528,6 @@ _mesa_bitcount(unsigned int n)
return bits;
}
#endif
-#endif
/**
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index ce7baabe2c7..3fa1db02aee 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -486,6 +486,27 @@ _mesa_next_pow_two_64(uint64_t x)
}
+/*
+ * Returns the floor form of binary logarithm for a 32-bit integer.
+ */
+static INLINE GLuint
+_mesa_logbase2(GLuint n)
+{
+#if defined(__GNUC__) && \
+ ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+ return (31 - __builtin_clz(n | 1));
+#else
+ GLuint pos = 0;
+ if (n >= 1<<16) { n >>= 16; pos += 16; }
+ if (n >= 1<< 8) { n >>= 8; pos += 8; }
+ if (n >= 1<< 4) { n >>= 4; pos += 4; }
+ if (n >= 1<< 2) { n >>= 2; pos += 2; }
+ if (n >= 1<< 1) { pos += 1; }
+ return pos;
+#endif
+}
+
+
/**
* Return 1 if this is a little endian machine, 0 if big endian.
*/
diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c
index e9fcb545a1e..8a811cb7225 100644
--- a/src/mesa/main/mipmap.c
+++ b/src/mesa/main/mipmap.c
@@ -706,6 +706,17 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth,
}
}
+ else if (datatype == GL_FLOAT_32_UNSIGNED_INT_24_8_REV && 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*2] = (rowA[j*2] + rowA[k*2] + rowB[j*2] + rowB[k*2]) * 0.25F;
+ }
+ }
+
else {
_mesa_problem(NULL, "bad format in do_row()");
}
@@ -1341,6 +1352,15 @@ do_row_3D(GLenum datatype, GLuint comps, GLint srcWidth,
}
}
+ else if (datatype == GL_FLOAT_32_UNSIGNED_INT_24_8_REV && comps == 1) {
+ DECLARE_ROW_POINTERS(GLfloat, 2);
+
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ FILTER_F_3D(0);
+ }
+ }
+
else {
_mesa_problem(NULL, "bad format in do_row()");
}
@@ -1885,107 +1905,19 @@ next_mipmap_level_size(GLenum target, GLint border,
}
}
-
-
-
-/**
- * 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)
+static void
+generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
+ struct gl_texture_object *texObj,
+ const struct gl_texture_image *srcImage,
+ GLuint maxLevel)
{
- const struct gl_texture_image *srcImage;
- gl_format convertFormat;
- const GLubyte *srcData = NULL;
- GLubyte *dstData = NULL;
- GLint level, maxLevels;
+ GLint level;
GLenum datatype;
GLuint comps;
- ASSERT(texObj);
- srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel);
- ASSERT(srcImage);
-
- maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
- ASSERT(maxLevels > 0); /* bad target */
-
- /* Find convertFormat - the format that do_row() will process */
-
- if (_mesa_is_format_compressed(srcImage->TexFormat)) {
- /* setup for compressed textures - need to allocate temporary
- * image buffers to hold uncompressed images.
- */
- GLuint row;
- GLint components, size;
- GLchan *dst;
-
- assert(texObj->Target == GL_TEXTURE_2D ||
- texObj->Target == GL_TEXTURE_CUBE_MAP_ARB);
-
- if (srcImage->_BaseFormat == GL_RGB) {
- convertFormat = MESA_FORMAT_RGB888;
- components = 3;
- } else if (srcImage->_BaseFormat == GL_RED) {
- convertFormat = MESA_FORMAT_R8;
- components = 1;
- } else if (srcImage->_BaseFormat == GL_RG) {
- convertFormat = MESA_FORMAT_RG88;
- components = 2;
- } else if (srcImage->_BaseFormat == GL_RGBA) {
- convertFormat = MESA_FORMAT_RGBA8888;
- components = 4;
- } else if (srcImage->_BaseFormat == GL_LUMINANCE) {
- convertFormat = MESA_FORMAT_L8;
- components = 1;
- } else if (srcImage->_BaseFormat == GL_LUMINANCE_ALPHA) {
- convertFormat = MESA_FORMAT_AL88;
- components = 2;
- } else {
- _mesa_problem(ctx, "bad srcImage->_BaseFormat in _mesa_generate_mipmaps");
- return;
- }
-
- /* allocate storage for uncompressed GL_RGB or GL_RGBA images */
- size = _mesa_bytes_per_pixel(srcImage->_BaseFormat, CHAN_TYPE)
- * srcImage->Width * srcImage->Height * srcImage->Depth + 20;
- /* 20 extra bytes, just be safe when calling last FetchTexel */
- srcData = (GLubyte *) malloc(size);
- if (!srcData) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
- return;
- }
- dstData = (GLubyte *) malloc(size / 2); /* 1/4 would probably be OK */
- if (!dstData) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
- free((void *) srcData);
- return;
- }
-
- /* decompress base image here */
- dst = (GLchan *) srcData;
- for (row = 0; row < srcImage->Height; row++) {
- GLuint col;
- for (col = 0; col < srcImage->Width; col++) {
- srcImage->FetchTexelc(srcImage, col, row, 0, dst);
- dst += components;
- }
- }
- }
- else {
- /* uncompressed */
- convertFormat = srcImage->TexFormat;
- }
-
- _mesa_format_to_type_and_comps(convertFormat, &datatype, &comps);
+ _mesa_format_to_type_and_comps(srcImage->TexFormat, &datatype, &comps);
- for (level = texObj->BaseLevel; level < texObj->MaxLevel
- && level < maxLevels - 1; level++) {
+ for (level = texObj->BaseLevel; level < maxLevel; level++) {
/* generate image[level+1] from image[level] */
const struct gl_texture_image *srcImage;
struct gl_texture_image *dstImage;
@@ -2005,14 +1937,8 @@ _mesa_generate_mipmap(struct gl_context *ctx, GLenum target,
nextLevel = next_mipmap_level_size(target, border,
srcWidth, srcHeight, srcDepth,
&dstWidth, &dstHeight, &dstDepth);
- if (!nextLevel) {
- /* all done */
- if (_mesa_is_format_compressed(srcImage->TexFormat)) {
- free((void *) srcData);
- free(dstData);
- }
+ if (!nextLevel)
return;
- }
/* get dest gl_texture_image */
dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1);
@@ -2044,52 +1970,184 @@ _mesa_generate_mipmap(struct gl_context *ctx, GLenum target,
}
}
- /* Setup src and dest data pointers */
- if (_mesa_is_format_compressed(dstImage->TexFormat)) {
- /* srcData and dstData are already set */
- ASSERT(srcData);
- ASSERT(dstData);
- }
- else {
- srcData = (const GLubyte *) srcImage->Data;
- dstData = (GLubyte *) dstImage->Data;
- }
-
ASSERT(dstImage->TexFormat);
ASSERT(dstImage->FetchTexelc);
ASSERT(dstImage->FetchTexelf);
_mesa_generate_mipmap_level(target, datatype, comps, border,
- srcWidth, srcHeight, srcDepth,
- srcData, srcImage->RowStride,
- dstWidth, dstHeight, dstDepth,
- dstData, dstImage->RowStride);
-
-
- if (_mesa_is_format_compressed(dstImage->TexFormat)) {
- GLubyte *temp;
- /* compress image from dstData into dstImage->Data */
- const GLenum srcFormat = _mesa_get_format_base_format(convertFormat);
- GLint dstRowStride
- = _mesa_format_row_stride(dstImage->TexFormat, dstWidth);
-
- _mesa_texstore(ctx, 2, dstImage->_BaseFormat,
- dstImage->TexFormat,
- dstImage->Data,
- 0, 0, 0, /* dstX/Y/Zoffset */
- dstRowStride, 0, /* strides */
- dstWidth, dstHeight, 1, /* size */
- srcFormat, CHAN_TYPE,
- dstData, /* src data, actually */
- &ctx->DefaultPacking);
-
- /* swap src and dest pointers */
- temp = (GLubyte *) srcData;
- srcData = dstData;
- dstData = temp;
+ srcWidth, srcHeight, srcDepth,
+ srcImage->Data, srcImage->RowStride,
+ dstWidth, dstHeight, dstDepth,
+ dstImage->Data, dstImage->RowStride);
+
+ } /* loop over mipmap levels */
+}
+
+static void
+generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
+ struct gl_texture_object *texObj,
+ const struct gl_texture_image *srcImage,
+ GLuint maxLevel)
+{
+ GLint level;
+ gl_format temp_format;
+ GLenum datatype;
+ GLuint comps;
+ GLuint row;
+ GLint components;
+ GLuint temp_src_stride, temp_dst_stride; /* in bytes */
+ GLchan *temp_src = NULL, *temp_dst = NULL;
+
+ /* Choose the format we will do _mesa_generate_mipmap_level() in,
+ * and uncompress the firstImage into a temporary of that format.
+ */
+ assert(texObj->Target == GL_TEXTURE_2D ||
+ texObj->Target == GL_TEXTURE_CUBE_MAP_ARB);
+
+ if (srcImage->_BaseFormat == GL_RGB) {
+ temp_format = MESA_FORMAT_RGB888;
+ components = 3;
+ } else if (srcImage->_BaseFormat == GL_RED) {
+ temp_format = MESA_FORMAT_R8;
+ components = 1;
+ } else if (srcImage->_BaseFormat == GL_RG) {
+ temp_format = MESA_FORMAT_RG88;
+ components = 2;
+ } else if (srcImage->_BaseFormat == GL_RGBA) {
+ temp_format = MESA_FORMAT_RGBA8888;
+ components = 4;
+ } else if (srcImage->_BaseFormat == GL_LUMINANCE) {
+ temp_format = MESA_FORMAT_L8;
+ components = 1;
+ } else if (srcImage->_BaseFormat == GL_LUMINANCE_ALPHA) {
+ temp_format = MESA_FORMAT_AL88;
+ components = 2;
+ } else {
+ _mesa_problem(ctx, "bad srcImage->_BaseFormat in _mesa_generate_mipmaps");
+ return;
+ }
+
+ /* allocate storage for uncompressed GL_RGB or GL_RGBA images */
+ temp_src_stride = _mesa_format_row_stride(temp_format, srcImage->Width);
+ /* 20 extra bytes, just be safe when calling last FetchTexel */
+ temp_src = (GLubyte *) malloc(temp_src_stride * srcImage->Height + 20);
+ if (!temp_src) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
+ return;
+ }
+
+ /* decompress base image to the temporary */
+ for (row = 0; row < srcImage->Height; row++) {
+ GLuint col;
+ GLchan *dst = (GLchan *) temp_src + temp_src_stride * row;
+ for (col = 0; col < srcImage->Width; col++) {
+ srcImage->FetchTexelc(srcImage, col, row, 0, dst);
+ dst += components;
+ }
+ }
+
+ _mesa_format_to_type_and_comps(temp_format, &datatype, &comps);
+
+ for (level = texObj->BaseLevel; level < maxLevel; level++) {
+ /* generate image[level+1] from image[level] */
+ const struct gl_texture_image *srcImage;
+ struct gl_texture_image *dstImage;
+ GLint srcWidth, srcHeight, srcDepth;
+ GLint dstWidth, dstHeight, dstDepth;
+ GLint border;
+ GLboolean nextLevel;
+
+ /* 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)
+ break;
+
+ temp_dst_stride = _mesa_format_row_stride(temp_format, dstWidth);
+ if (!temp_dst) {
+ temp_dst = (GLubyte *) malloc(temp_dst_stride * dstHeight);
+ if (!temp_dst) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
+ break;
+ }
}
+ /* 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;
+ }
+
+ _mesa_generate_mipmap_level(target, datatype, comps, border,
+ srcWidth, srcHeight, srcDepth,
+ temp_src, temp_src_stride / components,
+ dstWidth, dstHeight, dstDepth,
+ temp_dst, temp_dst_stride / components);
+
+ /* initialize new image */
+ _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
+ dstDepth, border, srcImage->InternalFormat,
+ srcImage->TexFormat);
+
+ ctx->Driver.TexImage2D(ctx, target, level + 1,
+ srcImage->InternalFormat,
+ dstWidth, dstHeight, border,
+ _mesa_get_format_base_format(temp_format),
+ GL_UNSIGNED_BYTE,
+ temp_dst, &ctx->DefaultPacking, texObj, dstImage);
+
+ /* swap src and dest pointers */
+ {
+ GLchan *temp = temp_src;
+ temp_src = temp_dst;
+ temp_dst = temp;
+
+ temp_src_stride = temp_dst_stride;
+ }
} /* loop over mipmap levels */
+
+ free((void *) temp_src);
+ free(temp_dst);
+}
+
+/**
+ * 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)
+{
+ const 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);
+
+ if (_mesa_is_format_compressed(srcImage->TexFormat)) {
+ generate_mipmap_compressed(ctx, target, texObj, srcImage, maxLevel);
+ } else {
+ generate_mipmap_uncompressed(ctx, target, texObj, srcImage, maxLevel);
+ }
}
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index eb2efc89aed..b88118366b2 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1435,8 +1435,7 @@ struct gl_texgen
/**
* Texture unit state. Contains enable flags, texture environment/function/
- * combiners, texgen state, pointers to current texture objects and
- * post-filter color tables.
+ * combiners, texgen state, and pointers to current texture objects.
*/
struct gl_texture_unit
{
@@ -1857,7 +1856,7 @@ struct gl_program
GLbitfield SystemValuesRead; /**< Bitmask of SYSTEM_VALUE_x inputs used */
GLbitfield InputFlags[MAX_PROGRAM_INPUTS]; /**< PROG_PARAM_BIT_x flags */
GLbitfield OutputFlags[MAX_PROGRAM_OUTPUTS]; /**< PROG_PARAM_BIT_x flags */
- GLbitfield TexturesUsed[MAX_TEXTURE_UNITS]; /**< TEXTURE_x_BIT bitmask */
+ GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */
GLbitfield SamplersUsed; /**< Bitfield of which samplers are used */
GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */
diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c
index d6470e351b8..7de1d05b919 100644
--- a/src/mesa/main/pack.c
+++ b/src/mesa/main/pack.c
@@ -1971,7 +1971,8 @@ extract_uint_indexes(GLuint n, GLuint indexes[],
srcType == GL_INT ||
srcType == GL_UNSIGNED_INT_24_8_EXT ||
srcType == GL_HALF_FLOAT_ARB ||
- srcType == GL_FLOAT);
+ srcType == GL_FLOAT ||
+ srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
switch (srcType) {
case GL_BITMAP:
@@ -2142,6 +2143,23 @@ extract_uint_indexes(GLuint n, GLuint indexes[],
}
}
break;
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ {
+ GLuint i;
+ const GLuint *s = (const GLuint *) src;
+ if (unpack->SwapBytes) {
+ for (i = 0; i < n; i++) {
+ GLuint value = s[i*2+1];
+ SWAP4BYTE(value);
+ indexes[i] = value & 0xff; /* lower 8 bits */
+ }
+ }
+ else {
+ for (i = 0; i < n; i++)
+ indexes[i] = s[i*2+1] & 0xff; /* lower 8 bits */
+ }
+ }
+ break;
default:
_mesa_problem(NULL, "bad srcType in extract_uint_indexes");
@@ -4412,11 +4430,13 @@ _mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n,
srcType == GL_INT ||
srcType == GL_UNSIGNED_INT_24_8_EXT ||
srcType == GL_HALF_FLOAT_ARB ||
- srcType == GL_FLOAT);
+ srcType == GL_FLOAT ||
+ srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
ASSERT(dstType == GL_UNSIGNED_BYTE ||
dstType == GL_UNSIGNED_SHORT ||
- dstType == GL_UNSIGNED_INT);
+ dstType == GL_UNSIGNED_INT ||
+ dstType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
/* only shift and offset apply to stencil */
transferOps &= IMAGE_SHIFT_OFFSET_BIT;
@@ -4488,6 +4508,15 @@ _mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n,
case GL_UNSIGNED_INT:
memcpy(dest, indexes, n * sizeof(GLuint));
break;
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ {
+ GLuint *dst = (GLuint *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i*2+1] = indexes[i] & 0xff; /* lower 8 bits */
+ }
+ }
+ break;
default:
_mesa_problem(ctx, "bad dstType in _mesa_unpack_stencil_span");
}
@@ -4683,7 +4712,7 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
GLenum srcType, const GLvoid *source,
const struct gl_pixelstore_attrib *srcPacking )
{
- GLfloat *depthTemp, *depthValues;
+ GLfloat *depthTemp = NULL, *depthValues;
GLboolean needClamp = GL_FALSE;
/* Look for special cases first.
@@ -4729,16 +4758,16 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
/* general case path follows */
- depthTemp = (GLfloat *) malloc(n * sizeof(GLfloat));
- if (!depthTemp) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
- return;
- }
-
if (dstType == GL_FLOAT) {
depthValues = (GLfloat *) dest;
}
else {
+ depthTemp = (GLfloat *) malloc(n * sizeof(GLfloat));
+ if (!depthTemp) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
+ return;
+ }
+
depthValues = depthTemp;
}
@@ -4782,6 +4811,7 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
}
zValues[i] = value & 0xffffff00;
}
+ free(depthTemp);
return;
}
else {
@@ -4797,6 +4827,20 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
}
}
break;
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ {
+ GLuint i;
+ const GLfloat *src = (const GLfloat *)source;
+ for (i = 0; i < n; i++) {
+ GLfloat value = src[i * 2];
+ if (srcPacking->SwapBytes) {
+ SWAP4BYTE(value);
+ }
+ depthValues[i] = value;
+ }
+ needClamp = GL_TRUE;
+ }
+ break;
case GL_FLOAT:
DEPTH_VALUES(GLfloat, 1*);
needClamp = GL_TRUE;
@@ -4873,9 +4917,18 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
zValues[i] = (GLushort) (depthValues[i] * (GLfloat) depthMax);
}
}
+ else if (dstType == GL_FLOAT) {
+ /* Nothing to do. depthValues is pointing to dest. */
+ }
+ else if (dstType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV) {
+ GLfloat *zValues = (GLfloat*) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ zValues[i*2] = depthValues[i];
+ }
+ }
else {
- ASSERT(dstType == GL_FLOAT);
- /*ASSERT(depthMax == 1.0F);*/
+ ASSERT(0);
}
free(depthTemp);
@@ -5003,10 +5056,11 @@ _mesa_pack_depth_span( struct gl_context *ctx, GLuint n, GLvoid *dest,
/**
- * Pack depth and stencil values as GL_DEPTH_STENCIL/GL_UNSIGNED_INT_24_8.
+ * Pack depth and stencil values as GL_DEPTH_STENCIL (GL_UNSIGNED_INT_24_8 etc)
*/
void
-_mesa_pack_depth_stencil_span(struct gl_context *ctx, GLuint n, GLuint *dest,
+_mesa_pack_depth_stencil_span(struct gl_context *ctx,GLuint n,
+ GLenum dstType, GLuint *dest,
const GLfloat *depthVals,
const GLstencil *stencilVals,
const struct gl_pixelstore_attrib *dstPacking)
@@ -5036,9 +5090,19 @@ _mesa_pack_depth_stencil_span(struct gl_context *ctx, GLuint n, GLuint *dest,
stencilVals = stencilCopy;
}
- for (i = 0; i < n; i++) {
- GLuint z = (GLuint) (depthVals[i] * 0xffffff);
- dest[i] = (z << 8) | (stencilVals[i] & 0xff);
+ switch (dstType) {
+ case GL_UNSIGNED_INT_24_8:
+ for (i = 0; i < n; i++) {
+ GLuint z = (GLuint) (depthVals[i] * 0xffffff);
+ dest[i] = (z << 8) | (stencilVals[i] & 0xff);
+ }
+ break;
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ for (i = 0; i < n; i++) {
+ ((GLfloat*)dest)[i*2] = depthVals[i];
+ dest[i*2+1] = stencilVals[i] & 0xff;
+ }
+ break;
}
if (dstPacking->SwapBytes) {
diff --git a/src/mesa/main/pack.h b/src/mesa/main/pack.h
index 78238ea5839..00aab409e42 100644
--- a/src/mesa/main/pack.h
+++ b/src/mesa/main/pack.h
@@ -130,8 +130,8 @@ _mesa_pack_depth_span(struct gl_context *ctx, GLuint n, GLvoid *dest,
extern void
-_mesa_pack_depth_stencil_span(struct gl_context *ctx,
- GLuint n, GLuint *dest,
+_mesa_pack_depth_stencil_span(struct gl_context *ctx,GLuint n,
+ GLenum dstType, GLuint *dest,
const GLfloat *depthVals,
const GLstencil *stencilVals,
const struct gl_pixelstore_attrib *dstPacking);
diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
index 0331a8ca2fe..84c5b22286a 100644
--- a/src/mesa/main/readpix.c
+++ b/src/mesa/main/readpix.c
@@ -61,6 +61,14 @@ _mesa_error_check_format_type(struct gl_context *ctx, GLenum format,
return GL_TRUE;
}
+ if (ctx->Extensions.ARB_depth_buffer_float
+ && type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV
+ && format != GL_DEPTH_STENCIL_EXT) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "gl%sPixels(format is not GL_DEPTH_STENCIL_EXT)", readDraw);
+ return GL_TRUE;
+ }
+
/* basic combinations test */
if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
_mesa_error(ctx, GL_INVALID_ENUM,
@@ -142,10 +150,23 @@ _mesa_error_check_format_type(struct gl_context *ctx, GLenum format,
}
break;
case GL_DEPTH_STENCIL_EXT:
- if (!ctx->Extensions.EXT_packed_depth_stencil ||
- type != GL_UNSIGNED_INT_24_8_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM, "gl%sPixels(type)", readDraw);
- return GL_TRUE;
+ /* Check validity of the type first. */
+ switch (type) {
+ case GL_UNSIGNED_INT_24_8_EXT:
+ if (!ctx->Extensions.EXT_packed_depth_stencil) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "gl%sPixels(type)", readDraw);
+ return GL_TRUE;
+ }
+ break;
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ if (!ctx->Extensions.ARB_depth_buffer_float) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "gl%sPixels(type)", readDraw);
+ return GL_TRUE;
+ }
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "gl%sPixels(type)", readDraw);
+ return GL_TRUE;
}
if ((drawing && !_mesa_dest_buffer_exists(ctx, format)) ||
(reading && !_mesa_source_buffer_exists(ctx, format))) {
diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c
index fa884c0de93..70011e6b24a 100644
--- a/src/mesa/main/renderbuffer.c
+++ b/src/mesa/main/renderbuffer.c
@@ -66,6 +66,9 @@ get_datatype_bytes(struct gl_renderbuffer *rb)
int component_size;
switch (rb->DataType) {
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ component_size = 8;
+ break;
case GL_FLOAT:
case GL_UNSIGNED_INT:
case GL_UNSIGNED_INT_24_8_EXT:
@@ -2527,17 +2530,13 @@ _mesa_remove_renderbuffer(struct gl_framebuffer *fb,
* Set *ptr to point to rb. If *ptr points to another renderbuffer,
* dereference that buffer first. The new renderbuffer's refcount will
* be incremented. The old renderbuffer's refcount will be decremented.
+ * This is normally only called from the _mesa_reference_renderbuffer() macro
+ * when there's a real pointer change.
*/
void
-_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
- struct gl_renderbuffer *rb)
+_mesa_reference_renderbuffer_(struct gl_renderbuffer **ptr,
+ struct gl_renderbuffer *rb)
{
- assert(ptr);
- if (*ptr == rb) {
- /* no change */
- return;
- }
-
if (*ptr) {
/* Unreference the old renderbuffer */
GLboolean deleteFlag = GL_FALSE;
@@ -2567,26 +2566,3 @@ _mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
*ptr = rb;
}
}
-
-
-/**
- * Create a new combined depth/stencil renderbuffer for implementing
- * the GL_EXT_packed_depth_stencil extension.
- * \return new depth/stencil renderbuffer
- */
-struct gl_renderbuffer *
-_mesa_new_depthstencil_renderbuffer(struct gl_context *ctx, GLuint name)
-{
- struct gl_renderbuffer *dsrb;
-
- dsrb = _mesa_new_renderbuffer(ctx, name);
- if (!dsrb)
- return NULL;
-
- /* init fields not covered by _mesa_new_renderbuffer() */
- dsrb->InternalFormat = GL_DEPTH24_STENCIL8_EXT;
- dsrb->Format = MESA_FORMAT_Z24_S8;
- dsrb->AllocStorage = _mesa_soft_renderbuffer_storage;
-
- return dsrb;
-}
diff --git a/src/mesa/main/renderbuffer.h b/src/mesa/main/renderbuffer.h
index 39d9b3035e6..f9329d55fa5 100644
--- a/src/mesa/main/renderbuffer.h
+++ b/src/mesa/main/renderbuffer.h
@@ -105,11 +105,17 @@ _mesa_remove_renderbuffer(struct gl_framebuffer *fb,
gl_buffer_index bufferName);
extern void
-_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
- struct gl_renderbuffer *rb);
+_mesa_reference_renderbuffer_(struct gl_renderbuffer **ptr,
+ struct gl_renderbuffer *rb);
-extern struct gl_renderbuffer *
-_mesa_new_depthstencil_renderbuffer(struct gl_context *ctx, GLuint name);
+static INLINE void
+_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
+ struct gl_renderbuffer *rb)
+{
+ if (*ptr != rb)
+ _mesa_reference_renderbuffer_(ptr, rb);
+}
+
#endif /* RENDERBUFFER_H */
diff --git a/src/mesa/main/samplerobj.c b/src/mesa/main/samplerobj.c
index f7774fdd7cb..8f8d87b90e8 100644
--- a/src/mesa/main/samplerobj.c
+++ b/src/mesa/main/samplerobj.c
@@ -251,7 +251,7 @@ _mesa_BindSampler(GLuint unit, GLuint sampler)
struct gl_sampler_object *sampObj;
GET_CURRENT_CONTEXT(ctx);
- if (unit >= ctx->Const.MaxTextureImageUnits) {
+ if (unit >= ctx->Const.MaxCombinedTextureImageUnits) {
_mesa_error(ctx, GL_INVALID_VALUE, "glBindSampler(unit %u)", unit);
return;
}
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index b58e30de9c4..8df25c3f988 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -1032,7 +1032,7 @@ validate_samplers(const struct gl_program *prog, char *errMsg)
"TEXTURE_2D",
"TEXTURE_1D",
};
- GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS];
+ GLint targetUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
GLbitfield samplersUsed = prog->SamplersUsed;
GLuint i;
@@ -1050,7 +1050,7 @@ validate_samplers(const struct gl_program *prog, char *errMsg)
gl_texture_index target;
GLint sampler = _mesa_ffs(samplersUsed) - 1;
assert(sampler >= 0);
- assert(sampler < MAX_TEXTURE_IMAGE_UNITS);
+ assert(sampler < Elements(prog->SamplerUnits));
unit = prog->SamplerUnits[sampler];
target = prog->SamplerTargets[sampler];
if (targetUsed[unit] != -1 && targetUsed[unit] != (int) target) {
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 4696dbb526f..7ad50bcaddc 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -192,7 +192,10 @@ update_arrays( struct gl_context *ctx )
static void
update_program_enables(struct gl_context *ctx)
{
- /* These _Enabled flags indicate if the program is enabled AND valid. */
+ /* These _Enabled flags indicate if the user-defined ARB/NV vertex/fragment
+ * program is enabled AND valid. Similarly for ATI fragment shaders.
+ * GLSL shaders not relevant here.
+ */
ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled
&& ctx->VertexProgram.Current->Base.Instructions;
ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled
@@ -203,11 +206,12 @@ update_program_enables(struct gl_context *ctx)
/**
- * Update vertex/fragment program state. In particular, update these fields:
- * ctx->VertexProgram._Current
- * ctx->VertexProgram._TnlProgram,
- * These point to the highest priority enabled vertex/fragment program or are
- * NULL if fixed-function processing is to be done.
+ * Update the ctx->Vertex/Geometry/FragmentProgram._Current pointers to point
+ * to the current/active programs. Then call ctx->Driver.BindProgram() to
+ * tell the driver which programs to use.
+ *
+ * Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment
+ * programs or programs derived from fixed-function state.
*
* This function needs to be called after texture state validation in case
* we're generating a fragment program from fixed-function texture state.
@@ -243,34 +247,33 @@ update_program(struct gl_context *ctx)
*/
if (fsProg && fsProg->LinkStatus && fsProg->FragmentProgram) {
- /* Use shader programs */
+ /* Use GLSL fragment shader */
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
fsProg->FragmentProgram);
}
else if (ctx->FragmentProgram._Enabled) {
- /* use user-defined vertex program */
+ /* Use user-defined fragment program */
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
ctx->FragmentProgram.Current);
}
else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
- /* Use fragment program generated from fixed-function state.
- */
+ /* Use fragment program generated from fixed-function state */
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
_mesa_get_fixed_func_fragment_program(ctx));
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
ctx->FragmentProgram._Current);
}
else {
- /* no fragment program */
+ /* No fragment program */
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
}
if (gsProg && gsProg->LinkStatus && gsProg->GeometryProgram) {
- /* Use shader programs */
+ /* Use GLSL geometry shader */
_mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current,
gsProg->GeometryProgram);
} else {
- /* no fragment program */
+ /* No geometry program */
_mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL);
}
@@ -279,18 +282,17 @@ update_program(struct gl_context *ctx)
* fragprog inputs.
*/
if (vsProg && vsProg->LinkStatus && vsProg->VertexProgram) {
- /* Use shader programs */
+ /* Use GLSL vertex shader */
_mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
- vsProg->VertexProgram);
+ vsProg->VertexProgram);
}
else if (ctx->VertexProgram._Enabled) {
- /* use user-defined vertex program */
+ /* Use user-defined vertex program */
_mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
ctx->VertexProgram.Current);
}
else if (ctx->VertexProgram._MaintainTnlProgram) {
- /* Use vertex program generated from fixed-function state.
- */
+ /* Use vertex program generated from fixed-function state */
_mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
_mesa_get_fixed_func_vertex_program(ctx));
_mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram,
@@ -416,29 +418,44 @@ update_color(struct gl_context *ctx)
ctx->Color._LogicOpEnabled = _mesa_rgba_logicop_enabled(ctx);
}
+
+/**
+ * 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;
+ 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;
+ 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;
+ if (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB)
+ ctx->Color._ClampReadColor =
+ !ctx->ReadBuffer || !ctx->ReadBuffer->Visual.floatMode;
else
ctx->Color._ClampReadColor = ctx->Color.ClampReadColor;
}
diff --git a/src/mesa/main/texenv.c b/src/mesa/main/texenv.c
index 9228e354a4d..c0d0f3779b2 100644
--- a/src/mesa/main/texenv.c
+++ b/src/mesa/main/texenv.c
@@ -419,7 +419,7 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
ASSERT_OUTSIDE_BEGIN_END(ctx);
maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
- ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
+ ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxCombinedTextureImageUnits;
if (ctx->Texture.CurrentUnit >= maxUnit) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glTexEnvfv(current unit)");
return;
@@ -748,7 +748,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
ASSERT_OUTSIDE_BEGIN_END(ctx);
maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
- ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
+ ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxCombinedTextureImageUnits;
if (ctx->Texture.CurrentUnit >= maxUnit) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnvfv(current unit)");
return;
@@ -817,7 +817,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
ASSERT_OUTSIDE_BEGIN_END(ctx);
maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
- ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
+ ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxCombinedTextureImageUnits;
if (ctx->Texture.CurrentUnit >= maxUnit) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnviv(current unit)");
return;
diff --git a/src/mesa/main/texfetch.c b/src/mesa/main/texfetch.c
index 6716ce1b071..72283eb68af 100644
--- a/src/mesa/main/texfetch.c
+++ b/src/mesa/main/texfetch.c
@@ -913,6 +913,20 @@ texfetch_funcs[MESA_FORMAT_COUNT] =
fetch_texel_2d_r11_g11_b10f,
fetch_texel_3d_r11_g11_b10f,
store_texel_r11_g11_b10f
+ },
+ {
+ MESA_FORMAT_Z32_FLOAT,
+ fetch_texel_1d_f_r_f32, /* Reuse the R32F functions. */
+ fetch_texel_2d_f_r_f32,
+ fetch_texel_3d_f_r_f32,
+ store_texel_r_f32
+ },
+ {
+ MESA_FORMAT_Z32_FLOAT_X24S8,
+ fetch_texel_1d_z32f_x24s8,
+ fetch_texel_2d_z32f_x24s8,
+ fetch_texel_3d_z32f_x24s8,
+ store_texel_z32f_x24s8
}
};
diff --git a/src/mesa/main/texfetch_tmp.h b/src/mesa/main/texfetch_tmp.h
index e6fd81d4d57..d170adf2e00 100644
--- a/src/mesa/main/texfetch_tmp.h
+++ b/src/mesa/main/texfetch_tmp.h
@@ -2287,7 +2287,8 @@ static void FETCH(f_z24_s8)( const struct gl_texture_image *texImage,
const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
const GLfloat scale = 1.0F / (GLfloat) 0xffffff;
texel[0] = ((*src) >> 8) * scale;
- ASSERT(texImage->TexFormat == MESA_FORMAT_Z24_S8);
+ ASSERT(texImage->TexFormat == MESA_FORMAT_Z24_S8 ||
+ texImage->TexFormat == MESA_FORMAT_Z24_X8);
ASSERT(texel[0] >= 0.0F);
ASSERT(texel[0] <= 1.0F);
}
@@ -2314,7 +2315,8 @@ static void FETCH(f_s8_z24)( const struct gl_texture_image *texImage,
const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
const GLfloat scale = 1.0F / (GLfloat) 0xffffff;
texel[0] = ((*src) & 0x00ffffff) * scale;
- ASSERT(texImage->TexFormat == MESA_FORMAT_S8_Z24);
+ ASSERT(texImage->TexFormat == MESA_FORMAT_S8_Z24 ||
+ texImage->TexFormat == MESA_FORMAT_X8_Z24);
ASSERT(texel[0] >= 0.0F);
ASSERT(texel[0] <= 1.0F);
}
@@ -2374,6 +2376,29 @@ static void store_texel_r11_g11_b10f(struct gl_texture_image *texImage,
#endif
+/* MESA_FORMAT_Z32_FLOAT_X24S8 ***********************************************/
+
+static void FETCH(z32f_x24s8)(const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel)
+{
+ const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 2);
+ texel[RCOMP] = src[0];
+ texel[GCOMP] = 0.0F;
+ texel[BCOMP] = 0.0F;
+ texel[ACOMP] = 1.0F;
+}
+
+#if DIM == 3
+static void store_texel_z32f_x24s8(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLfloat *src = (const GLfloat *) texel;
+ GLfloat *dst = TEXEL_ADDR(GLfloat, texImage, i, j, k, 2);
+ dst[0] = src[0];
+}
+#endif
+
+
#undef TEXEL_ADDR
#undef DIM
#undef FETCH
diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c
index 8cbb021d8b0..c919a74e047 100644
--- a/src/mesa/main/texformat.c
+++ b/src/mesa/main/texformat.c
@@ -416,6 +416,19 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat,
}
}
+ if (ctx->Extensions.ARB_depth_buffer_float) {
+ switch (internalFormat) {
+ case GL_DEPTH_COMPONENT32F:
+ ASSERT(ctx->TextureFormatSupported[MESA_FORMAT_Z32_FLOAT]);
+ return MESA_FORMAT_Z32_FLOAT;
+ case GL_DEPTH32F_STENCIL8:
+ ASSERT(ctx->TextureFormatSupported[MESA_FORMAT_Z32_FLOAT_X24S8]);
+ return MESA_FORMAT_Z32_FLOAT_X24S8;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
if (ctx->Extensions.ATI_envmap_bumpmap) {
switch (internalFormat) {
case GL_DUDV_ATI:
diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c
index 97d10122541..26c2ff98ba1 100644
--- a/src/mesa/main/texgetimage.c
+++ b/src/mesa/main/texgetimage.c
@@ -233,6 +233,7 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
const GLint width = texImage->Width;
const GLint height = texImage->Height;
const GLint depth = texImage->Depth;
+ const GLenum dataType = _mesa_get_format_datatype(texImage->TexFormat);
/* Normally, no pixel transfer ops are performed during glGetTexImage.
* The only possible exception is component clamping to [0,1].
*/
@@ -248,6 +249,19 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
return;
}
+ /* Clamping does not apply to GetTexImage (final conversion)?
+ * Looks like we need clamp though when going from format
+ * containing negative values to unsigned format.
+ */
+ if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) {
+ transferOps |= IMAGE_CLAMP_BIT;
+ }
+ else if (!type_with_negative_values(type) &&
+ (dataType == GL_FLOAT ||
+ dataType == GL_SIGNED_NORMALIZED)) {
+ transferOps |= IMAGE_CLAMP_BIT;
+ }
+
/* glGetTexImage always returns sRGB data for sRGB textures. Make sure the
* fetch functions return sRGB data without linearizing it.
*/
@@ -262,20 +276,6 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
width, height, format, type,
img, row, 0);
GLint col;
- GLenum dataType = _mesa_get_format_datatype(texImage->TexFormat);
-
- /* clamp does not apply to GetTexImage (final conversion)?
- * Looks like we need clamp though when going from format
- * containing negative values to unsigned format.
- */
- if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) {
- transferOps |= IMAGE_CLAMP_BIT;
- }
- else if (!type_with_negative_values(type) &&
- (dataType == GL_FLOAT ||
- dataType == GL_SIGNED_NORMALIZED)) {
- transferOps |= IMAGE_CLAMP_BIT;
- }
for (col = 0; col < width; col++) {
texImage->FetchTexelf(texImage, col, row, img, rgba[col]);
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 3e429110ae9..302fd65cb27 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -80,23 +80,6 @@ _mesa_free_texmemory(void *m)
}
-/*
- * Returns the floor form of binary logarithm for a 32-bit integer.
- */
-static GLuint
-logbase2(GLuint n)
-{
- GLuint pos = 0;
- if (n >= 1<<16) { n >>= 16; pos += 16; }
- if (n >= 1<< 8) { n >>= 8; pos += 8; }
- if (n >= 1<< 4) { n >>= 4; pos += 4; }
- if (n >= 1<< 2) { n >>= 2; pos += 2; }
- if (n >= 1<< 1) { pos += 1; }
- return pos;
-}
-
-
-
/**
* Return the simple base format for a given internal texture format.
* For example, given GL_LUMINANCE12_ALPHA4, return GL_LUMINANCE_ALPHA.
@@ -1155,7 +1138,7 @@ _mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
img->Depth = depth;
img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */
- img->WidthLog2 = logbase2(img->Width2);
+ img->WidthLog2 = _mesa_logbase2(img->Width2);
if (height == 1) { /* 1-D texture */
img->Height2 = 1;
@@ -1163,7 +1146,7 @@ _mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
}
else {
img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
- img->HeightLog2 = logbase2(img->Height2);
+ img->HeightLog2 = _mesa_logbase2(img->Height2);
}
if (depth == 1) { /* 2-D texture */
@@ -1172,7 +1155,7 @@ _mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
}
else {
img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */
- img->DepthLog2 = logbase2(img->Depth2);
+ img->DepthLog2 = _mesa_logbase2(img->Depth2);
}
img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
@@ -1702,11 +1685,15 @@ texture_error_check( struct gl_context *ctx,
/* additional checks for depth textures */
if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) {
- /* Only 1D, 2D and rectangular textures supported, not 3D or cubes */
+ /* Only 1D, 2D, rect and array textures supported, not 3D or cubes */
if (target != GL_TEXTURE_1D &&
target != GL_PROXY_TEXTURE_1D &&
target != GL_TEXTURE_2D &&
target != GL_PROXY_TEXTURE_2D &&
+ target != GL_TEXTURE_1D_ARRAY &&
+ target != GL_PROXY_TEXTURE_1D_ARRAY &&
+ target != GL_TEXTURE_2D_ARRAY &&
+ target != GL_PROXY_TEXTURE_2D_ARRAY &&
target != GL_TEXTURE_RECTANGLE_ARB &&
target != GL_PROXY_TEXTURE_RECTANGLE_ARB) {
if (!isProxy)
@@ -2810,29 +2797,43 @@ copyteximage(struct gl_context *ctx, GLuint dims,
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
}
else {
- gl_format texFormat;
-
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
- }
+ /* choose actual hw format */
+ gl_format texFormat = _mesa_choose_texture_format(ctx, texObj,
+ target, level,
+ internalFormat,
+ GL_NONE, GL_NONE);
- ASSERT(texImage->Data == NULL);
+ if (legal_texture_size(ctx, texFormat, width, height, 1)) {
+ GLint srcX = x, srcY = y, dstX = 0, dstY = 0;
- texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
- internalFormat, GL_NONE,
- GL_NONE);
+ /* Free old texture image */
+ ctx->Driver.FreeTexImageData(ctx, texImage);
- if (legal_texture_size(ctx, texFormat, width, height, 1)) {
_mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
border, internalFormat, texFormat);
- ASSERT(ctx->Driver.CopyTexImage2D);
- if (dims == 1)
- ctx->Driver.CopyTexImage1D(ctx, target, level, internalFormat,
- x, y, width, border);
- else
- ctx->Driver.CopyTexImage2D(ctx, target, level, internalFormat,
- x, y, width, height, border);
+ /* Allocate texture memory (no pixel data yet) */
+ if (dims == 1) {
+ ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
+ width, border, GL_NONE, GL_NONE, NULL,
+ &ctx->Unpack, texObj, texImage);
+ }
+ else {
+ ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
+ width, height, border, GL_NONE, GL_NONE,
+ NULL, &ctx->Unpack, texObj, texImage);
+ }
+
+ if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY,
+ &width, &height)) {
+ if (dims == 1)
+ ctx->Driver.CopyTexSubImage1D(ctx, target, level, dstX,
+ srcX, srcY, width);
+
+ else
+ ctx->Driver.CopyTexSubImage2D(ctx, target, level, dstX, dstY,
+ srcX, srcY, width, height);
+ }
check_gen_mipmap(ctx, target, texObj, level);
@@ -2843,6 +2844,7 @@ copyteximage(struct gl_context *ctx, GLuint dims,
ctx->NewState |= _NEW_TEXTURE;
}
else {
+ /* probably too large of image */
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
}
}
@@ -3287,7 +3289,7 @@ compressedteximage(struct gl_context *ctx, GLuint dims,
border, imageSize, &reason);
if (error) {
- _mesa_error(ctx, error, "glTexImage2D(%s)", reason);
+ _mesa_error(ctx, error, "glCompressedTexImage%uD(%s)", dims, reason);
return;
}
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index fdf12817c9a..3021716a0b6 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -325,16 +325,14 @@ valid_texture_object(const struct gl_texture_object *tex)
* Reference (or unreference) a texture object.
* If '*ptr', decrement *ptr's refcount (and delete if it becomes zero).
* If 'tex' is non-null, increment its refcount.
+ * This is normally only called from the _mesa_reference_texobj() macro
+ * when there's a real pointer change.
*/
void
-_mesa_reference_texobj(struct gl_texture_object **ptr,
- struct gl_texture_object *tex)
+_mesa_reference_texobj_(struct gl_texture_object **ptr,
+ struct gl_texture_object *tex)
{
assert(ptr);
- if (*ptr == tex) {
- /* no change */
- return;
- }
if (*ptr) {
/* Unreference the old texture */
@@ -879,6 +877,8 @@ unbind_texobj_from_fbo(struct gl_context *ctx,
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);
}
}
@@ -897,7 +897,7 @@ unbind_texobj_from_texunits(struct gl_context *ctx,
{
GLuint u, tex;
- for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
+ for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
if (texObj == unit->CurrentTex[tex]) {
diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
index 476a17537a3..1faae6f7e30 100644
--- a/src/mesa/main/texobj.h
+++ b/src/mesa/main/texobj.h
@@ -32,6 +32,7 @@
#define TEXTOBJ_H
+#include "compiler.h"
#include "glheader.h"
struct gl_context;
@@ -64,8 +65,17 @@ _mesa_clear_texture_object(struct gl_context *ctx,
struct gl_texture_object *obj);
extern void
+_mesa_reference_texobj_(struct gl_texture_object **ptr,
+ struct gl_texture_object *tex);
+
+static INLINE void
_mesa_reference_texobj(struct gl_texture_object **ptr,
- struct gl_texture_object *tex);
+ struct gl_texture_object *tex)
+{
+ if (*ptr != tex)
+ _mesa_reference_texobj_(ptr, tex);
+}
+
extern void
_mesa_test_texobj_completeness( const struct gl_context *ctx,
diff --git a/src/mesa/main/texrender.c b/src/mesa/main/texrender.c
deleted file mode 100644
index a7641a5f9a4..00000000000
--- a/src/mesa/main/texrender.c
+++ /dev/null
@@ -1,654 +0,0 @@
-
-#include "context.h"
-#include "colormac.h"
-#include "fbobject.h"
-#include "macros.h"
-#include "texfetch.h"
-#include "teximage.h"
-#include "texrender.h"
-#include "renderbuffer.h"
-
-
-/*
- * Render-to-texture code for GL_EXT_framebuffer_object
- */
-
-
-/**
- * Derived from gl_renderbuffer class
- */
-struct texture_renderbuffer
-{
- struct gl_renderbuffer Base; /**< Base class object */
- struct gl_texture_image *TexImage;
- StoreTexelFunc Store;
- FetchTexelFuncF Fetchf;
- GLint Yoffset; /**< Layer for 1D array textures. */
- GLint Zoffset; /**< Layer for 2D array textures, or slice
- * for 3D textures
- */
-};
-
-
-/**
- * Get row of values from the renderbuffer that wraps a texture image.
- */
-static void
-texture_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- GLint x, GLint y, void *values)
-{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
- const GLint z = trb->Zoffset;
- GLuint i;
-
- ASSERT(trb->TexImage->Width == rb->Width);
- ASSERT(trb->TexImage->Height == rb->Height);
-
- y += trb->Yoffset;
-
- if (rb->DataType == CHAN_TYPE) {
- GLchan *rgbaOut = (GLchan *) values;
- for (i = 0; i < count; i++) {
- GLfloat rgba[4];
- trb->Fetchf(trb->TexImage, x + i, y, z, rgba);
- UNCLAMPED_FLOAT_TO_RGBA_CHAN(rgbaOut + 4 * i, rgba);
- }
- }
- else if (rb->DataType == GL_UNSIGNED_SHORT) {
- GLushort *zValues = (GLushort *) values;
- for (i = 0; i < count; i++) {
- GLfloat flt;
- trb->Fetchf(trb->TexImage, x + i, y, z, &flt);
- zValues[i] = (GLushort) (flt * 0xffff);
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT) {
- GLuint *zValues = (GLuint *) values;
- /*
- const GLdouble scale = (GLdouble) 0xffffffff;
- */
- for (i = 0; i < count; i++) {
- GLfloat flt;
- trb->Fetchf(trb->TexImage, x + i, y, z, &flt);
-#if 0
- /* this should work, but doesn't (overflow due to low precision) */
- zValues[i] = (GLuint) (flt * scale);
-#else
- /* temporary hack */
- zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
-#endif
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
- GLuint *zValues = (GLuint *) values;
- for (i = 0; i < count; i++) {
- GLfloat flt;
- trb->Fetchf(trb->TexImage, x + i, y, z, &flt);
- zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) {
- GLuint *zValues = (GLuint *) values;
- for (i = 0; i < count; i++) {
- GLfloat flt;
- trb->Fetchf(trb->TexImage, x + i, y, z, &flt);
- zValues[i] = (GLuint) (flt * 0xffffff);
- }
- }
- else {
- _mesa_problem(ctx, "invalid rb->DataType in texture_get_row");
- }
-}
-
-
-static void
-texture_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- const GLint x[], const GLint y[], void *values)
-{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
- const GLint z = trb->Zoffset;
- GLuint i;
-
- if (rb->DataType == CHAN_TYPE) {
- GLchan *rgbaOut = (GLchan *) values;
- for (i = 0; i < count; i++) {
- GLfloat rgba[4];
- trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
- z, rgba);
- UNCLAMPED_FLOAT_TO_RGBA_CHAN(rgbaOut + 4 * i, rgba);
- }
- }
- else if (rb->DataType == GL_UNSIGNED_SHORT) {
- GLushort *zValues = (GLushort *) values;
- for (i = 0; i < count; i++) {
- GLfloat flt;
- trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
- z, &flt);
- zValues[i] = (GLushort) (flt * 0xffff);
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT) {
- GLuint *zValues = (GLuint *) values;
- for (i = 0; i < count; i++) {
- GLfloat flt;
- trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
- z, &flt);
-#if 0
- zValues[i] = (GLuint) (flt * 0xffffffff);
-#else
- zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
-#endif
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
- GLuint *zValues = (GLuint *) values;
- for (i = 0; i < count; i++) {
- GLfloat flt;
- trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
- z, &flt);
- zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) {
- GLuint *zValues = (GLuint *) values;
- for (i = 0; i < count; i++) {
- GLfloat flt;
- trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
- z, &flt);
- zValues[i] = (GLuint) (flt * 0xffffff);
- }
- }
- else {
- _mesa_problem(ctx, "invalid rb->DataType in texture_get_values");
- }
-}
-
-
-/**
- * Put row of values into a renderbuffer that wraps a texture image.
- */
-static void
-texture_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- GLint x, GLint y, const void *values, const GLubyte *mask)
-{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
- const GLint z = trb->Zoffset;
- GLuint i;
-
- y += trb->Yoffset;
-
- if (rb->DataType == CHAN_TYPE) {
- const GLchan *rgba = (const GLchan *) values;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x + i, y, z, rgba);
- }
- rgba += 4;
- }
- }
- else if (rb->DataType == GL_UNSIGNED_SHORT) {
- const GLushort *zValues = (const GLushort *) values;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x + i, y, z, zValues + i);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT) {
- const GLuint *zValues = (const GLuint *) values;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x + i, y, z, zValues + i);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
- const GLuint *zValues = (const GLuint *) values;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- GLfloat flt = (GLfloat) ((zValues[i] >> 8) * (1.0 / 0xffffff));
- trb->Store(trb->TexImage, x + i, y, z, &flt);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) {
- const GLuint *zValues = (const GLuint *) values;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- GLfloat flt = (GLfloat) ((zValues[i] & 0xffffff) * (1.0 / 0xffffff));
- trb->Store(trb->TexImage, x + i, y, z, &flt);
- }
- }
- }
- else {
- _mesa_problem(ctx, "invalid rb->DataType in texture_put_row");
- }
-}
-
-/**
- * Put row of RGB values into a renderbuffer that wraps a texture image.
- */
-static void
-texture_put_row_rgb(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- GLint x, GLint y, const void *values, const GLubyte *mask)
-{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
- const GLint z = trb->Zoffset;
- GLuint i;
-
- y += trb->Yoffset;
-
- if (rb->DataType == CHAN_TYPE) {
- const GLchan *rgb = (const GLchan *) values;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x + i, y, z, rgb);
- }
- rgb += 3;
- }
- }
- else if (rb->DataType == GL_UNSIGNED_SHORT) {
- const GLushort *zValues = (const GLushort *) values;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x + i, y, z, zValues + i);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT) {
- const GLuint *zValues = (const GLuint *) values;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x + i, y, z, zValues + i);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
- const GLuint *zValues = (const GLuint *) values;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- GLfloat flt = (GLfloat) ((zValues[i] >> 8) * (1.0 / 0xffffff));
- trb->Store(trb->TexImage, x + i, y, z, &flt);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) {
- const GLuint *zValues = (const GLuint *) values;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- GLfloat flt = (GLfloat) ((zValues[i] & 0xffffff) * (1.0 / 0xffffff));
- trb->Store(trb->TexImage, x + i, y, z, &flt);
- }
- }
- }
- else {
- _mesa_problem(ctx, "invalid rb->DataType in texture_put_row");
- }
-}
-
-
-static void
-texture_put_mono_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- GLint x, GLint y, const void *value, const GLubyte *mask)
-{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
- const GLint z = trb->Zoffset;
- GLuint i;
-
- y += trb->Yoffset;
-
- if (rb->DataType == CHAN_TYPE) {
- const GLchan *rgba = (const GLchan *) value;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x + i, y, z, rgba);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_SHORT) {
- const GLushort zValue = *((const GLushort *) value);
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x + i, y, z, &zValue);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT) {
- const GLuint zValue = *((const GLuint *) value);
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x + i, y, z, &zValue);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
- const GLuint zValue = *((const GLuint *) value);
- const GLfloat flt = (GLfloat) ((zValue >> 8) * (1.0 / 0xffffff));
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x + i, y, z, &flt);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) {
- const GLuint zValue = *((const GLuint *) value);
- const GLfloat flt = (GLfloat) ((zValue & 0xffffff) * (1.0 / 0xffffff));
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x + i, y, z, &flt);
- }
- }
- }
- else {
- _mesa_problem(ctx, "invalid rb->DataType in texture_put_mono_row");
- }
-}
-
-
-static void
-texture_put_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- const GLint x[], const GLint y[], const void *values,
- const GLubyte *mask)
-{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
- const GLint z = trb->Zoffset;
- GLuint i;
-
- if (rb->DataType == CHAN_TYPE) {
- const GLchan *rgba = (const GLchan *) values;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, rgba);
- }
- rgba += 4;
- }
- }
- else if (rb->DataType == GL_UNSIGNED_SHORT) {
- const GLushort *zValues = (const GLushort *) values;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, zValues + i);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT) {
- const GLuint *zValues = (const GLuint *) values;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, zValues + i);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
- const GLuint *zValues = (const GLuint *) values;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- GLfloat flt = (GLfloat) ((zValues[i] >> 8) * (1.0 / 0xffffff));
- trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) {
- const GLuint *zValues = (const GLuint *) values;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- GLfloat flt = (GLfloat) ((zValues[i] & 0xffffff) * (1.0 / 0xffffff));
- trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt);
- }
- }
- }
- else {
- _mesa_problem(ctx, "invalid rb->DataType in texture_put_values");
- }
-}
-
-
-static void
-texture_put_mono_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, const GLint x[], const GLint y[],
- const void *value, const GLubyte *mask)
-{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
- const GLint z = trb->Zoffset;
- GLuint i;
-
- if (rb->DataType == CHAN_TYPE) {
- const GLchan *rgba = (const GLchan *) value;
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, rgba);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT) {
- const GLuint zValue = *((const GLuint *) value);
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &zValue);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_SHORT) {
- const GLushort zValue = *((const GLushort *) value);
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &zValue);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
- const GLuint zValue = *((const GLuint *) value);
- const GLfloat flt = (GLfloat) ((zValue >> 8) * (1.0 / 0xffffff));
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt);
- }
- }
- }
- else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) {
- const GLuint zValue = *((const GLuint *) value);
- const GLfloat flt = (GLfloat) ((zValue & 0xffffff) * (1.0 / 0xffffff));
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
- trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt);
- }
- }
- }
- else {
- _mesa_problem(ctx, "invalid rb->DataType in texture_put_mono_values");
- }
-}
-
-
-static void
-store_nop(struct gl_texture_image *texImage,
- GLint col, GLint row, GLint img,
- const void *texel)
-{
-}
-
-
-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 texture_renderbuffer *trb;
- const GLuint name = 0;
-
- ASSERT(att->Type == GL_TEXTURE);
- ASSERT(att->Renderbuffer == NULL);
-
- trb = CALLOC_STRUCT(texture_renderbuffer);
- if (!trb) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "wrap_texture");
- return;
- }
-
- /* init base gl_renderbuffer fields */
- _mesa_init_renderbuffer(&trb->Base, name);
- /* plug in our texture_renderbuffer-specific functions */
- trb->Base.Delete = delete_texture_wrapper;
- trb->Base.AllocStorage = NULL; /* illegal! */
- trb->Base.GetRow = texture_get_row;
- trb->Base.GetValues = texture_get_values;
- trb->Base.PutRow = texture_put_row;
- trb->Base.PutRowRGB = texture_put_row_rgb;
- trb->Base.PutMonoRow = texture_put_mono_row;
- trb->Base.PutValues = texture_put_values;
- trb->Base.PutMonoValues = texture_put_mono_values;
-
- /* update attachment point */
- _mesa_reference_renderbuffer(&att->Renderbuffer, &(trb->Base));
-}
-
-/**
- * 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 texture_renderbuffer *trb
- = (struct texture_renderbuffer *) att->Renderbuffer;
-
- (void) ctx;
- ASSERT(trb);
-
- trb->TexImage = _mesa_get_attachment_teximage(att);
- ASSERT(trb->TexImage);
-
- trb->Store = _mesa_get_texel_store_func(trb->TexImage->TexFormat);
- if (!trb->Store) {
- /* we'll never draw into some textures (compressed formats) */
- trb->Store = store_nop;
- }
-
- trb->Fetchf = trb->TexImage->FetchTexelf;
-
- if (att->Texture->Target == GL_TEXTURE_1D_ARRAY_EXT) {
- trb->Yoffset = att->Zoffset;
- trb->Zoffset = 0;
- }
- else {
- trb->Yoffset = 0;
- trb->Zoffset = att->Zoffset;
- }
-
- trb->Base.Width = trb->TexImage->Width;
- trb->Base.Height = trb->TexImage->Height;
- trb->Base.InternalFormat = trb->TexImage->InternalFormat;
- trb->Base.Format = trb->TexImage->TexFormat;
-
- /* XXX may need more special cases here */
- switch (trb->TexImage->TexFormat) {
- case MESA_FORMAT_Z24_S8:
- trb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT;
- trb->Base._BaseFormat = GL_DEPTH_STENCIL;
- break;
- case MESA_FORMAT_S8_Z24:
- trb->Base.DataType = GL_UNSIGNED_INT_8_24_REV_MESA;
- trb->Base._BaseFormat = GL_DEPTH_STENCIL;
- break;
- case MESA_FORMAT_Z24_X8:
- trb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT;
- trb->Base._BaseFormat = GL_DEPTH_COMPONENT;
- break;
- case MESA_FORMAT_X8_Z24:
- trb->Base.DataType = GL_UNSIGNED_INT_8_24_REV_MESA;
- trb->Base._BaseFormat = GL_DEPTH_COMPONENT;
- break;
- case MESA_FORMAT_Z16:
- trb->Base.DataType = GL_UNSIGNED_SHORT;
- trb->Base._BaseFormat = GL_DEPTH_COMPONENT;
- break;
- case MESA_FORMAT_Z32:
- trb->Base.DataType = GL_UNSIGNED_INT;
- trb->Base._BaseFormat = GL_DEPTH_COMPONENT;
- break;
- /* SRGB formats pre EXT_framebuffer_sRGB don't do sRGB translations on FBO readback */
- case MESA_FORMAT_SRGB8:
- trb->Fetchf = _mesa_get_texel_fetch_func(MESA_FORMAT_RGB888, _mesa_get_texture_dimensions(att->Texture->Target));
- trb->Base.DataType = CHAN_TYPE;
- trb->Base._BaseFormat = GL_RGBA;
- break;
- case MESA_FORMAT_SRGBA8:
- trb->Fetchf = _mesa_get_texel_fetch_func(MESA_FORMAT_RGBA8888, _mesa_get_texture_dimensions(att->Texture->Target));
- trb->Base.DataType = CHAN_TYPE;
- trb->Base._BaseFormat = GL_RGBA;
- break;
- case MESA_FORMAT_SARGB8:
- trb->Fetchf = _mesa_get_texel_fetch_func(MESA_FORMAT_ARGB8888, _mesa_get_texture_dimensions(att->Texture->Target));
- trb->Base.DataType = CHAN_TYPE;
- trb->Base._BaseFormat = GL_RGBA;
- break;
- default:
- trb->Base.DataType = CHAN_TYPE;
- trb->Base._BaseFormat = GL_RGBA;
- }
- trb->Base.Data = trb->TexImage->Data;
-}
-
-
-
-/**
- * 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
-_mesa_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
-_mesa_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;
-}
diff --git a/src/mesa/main/texrender.h b/src/mesa/main/texrender.h
deleted file mode 100644
index cacd091160e..00000000000
--- a/src/mesa/main/texrender.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef TEXRENDER_H
-#define TEXRENDER_H
-
-struct gl_context;
-struct gl_framebuffer;
-struct gl_renderbuffer_attachment;
-
-extern void
-_mesa_render_texture(struct gl_context *ctx,
- struct gl_framebuffer *fb,
- struct gl_renderbuffer_attachment *att);
-
-extern void
-_mesa_finish_render_texture(struct gl_context *ctx,
- struct gl_renderbuffer_attachment *att);
-
-
-#endif /* TEXRENDER_H */
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index 6da3e4eb7b4..c4aeaa8f16d 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -1002,15 +1002,17 @@ memcpy_texture(struct gl_context *ctx,
/**
- * Store a 32-bit integer depth component texture image.
+ * Store a 32-bit integer or float depth component texture image.
*/
static GLboolean
_mesa_texstore_z32(TEXSTORE_PARAMS)
{
const GLuint depthScale = 0xffffffff;
const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+ const GLenum dstType = _mesa_get_format_datatype(dstFormat);
(void) dims;
- ASSERT(dstFormat == MESA_FORMAT_Z32);
+ ASSERT(dstFormat == MESA_FORMAT_Z32 ||
+ dstFormat == MESA_FORMAT_Z32_FLOAT);
ASSERT(texelBytes == sizeof(GLuint));
if (ctx->Pixel.DepthScale == 1.0f &&
@@ -1018,7 +1020,7 @@ _mesa_texstore_z32(TEXSTORE_PARAMS)
!srcPacking->SwapBytes &&
baseInternalFormat == GL_DEPTH_COMPONENT &&
srcFormat == GL_DEPTH_COMPONENT &&
- srcType == GL_UNSIGNED_INT) {
+ srcType == dstType) {
/* simple memcpy path */
memcpy_texture(ctx, dims,
dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
@@ -1039,7 +1041,7 @@ _mesa_texstore_z32(TEXSTORE_PARAMS)
const GLvoid *src = _mesa_image_address(dims, srcPacking,
srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
_mesa_unpack_depth_span(ctx, srcWidth,
- GL_UNSIGNED_INT, (GLuint *) dstRow,
+ dstType, dstRow,
depthScale, srcType, src, srcPacking);
dstRow += dstRowStride;
}
@@ -3303,15 +3305,16 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
{
const GLuint depthScale = 0xffffff;
const GLint srcRowStride
- = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
- / sizeof(GLuint);
+ = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
GLint img, row;
ASSERT(dstFormat == MESA_FORMAT_Z24_S8);
- ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || srcFormat == GL_DEPTH_COMPONENT);
+ ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
+ srcFormat == GL_DEPTH_COMPONENT ||
+ srcFormat == GL_STENCIL_INDEX);
ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
- if (srcFormat != GL_DEPTH_COMPONENT && ctx->Pixel.DepthScale == 1.0f &&
+ if (srcFormat == GL_DEPTH_STENCIL && ctx->Pixel.DepthScale == 1.0f &&
ctx->Pixel.DepthBias == 0.0f &&
!srcPacking->SwapBytes) {
/* simple path */
@@ -3322,15 +3325,16 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
}
- else if (srcFormat == GL_DEPTH_COMPONENT) {
+ else if (srcFormat == GL_DEPTH_COMPONENT ||
+ srcFormat == GL_STENCIL_INDEX) {
/* In case we only upload depth we need to preserve the stencil */
for (img = 0; img < srcDepth; img++) {
GLuint *dstRow = (GLuint *) dstAddr
+ dstImageOffsets[dstZoffset + img]
+ dstYoffset * dstRowStride / sizeof(GLuint)
+ dstXoffset;
- const GLuint *src
- = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
+ const GLubyte *src
+ = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
srcWidth, srcHeight,
srcFormat, srcType,
img, 0, 0);
@@ -3387,8 +3391,7 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
{
const GLuint depthScale = 0xffffff;
const GLint srcRowStride
- = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
- / sizeof(GLuint);
+ = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
GLint img, row;
ASSERT(dstFormat == MESA_FORMAT_S8_Z24);
@@ -3403,8 +3406,8 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
+ dstImageOffsets[dstZoffset + img]
+ dstYoffset * dstRowStride / sizeof(GLuint)
+ dstXoffset;
- const GLuint *src
- = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
+ const GLubyte *src
+ = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
srcWidth, srcHeight,
srcFormat, srcType,
img, 0, 0);
@@ -3476,8 +3479,7 @@ _mesa_texstore_s8(TEXSTORE_PARAMS)
}
else {
const GLint srcRowStride
- = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
- / sizeof(GLuint);
+ = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
GLint img, row;
for (img = 0; img < srcDepth; img++) {
@@ -3485,8 +3487,8 @@ _mesa_texstore_s8(TEXSTORE_PARAMS)
+ dstImageOffsets[dstZoffset + img]
+ dstYoffset * dstRowStride / sizeof(GLuint)
+ dstXoffset;
- const GLuint *src
- = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
+ const GLubyte *src
+ = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
srcWidth, srcHeight,
srcFormat, srcType,
img, 0, 0);
@@ -4285,6 +4287,72 @@ _mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS)
}
+static GLboolean
+_mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
+{
+ ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_X24S8);
+ ASSERT(srcFormat == GL_DEPTH_STENCIL ||
+ srcFormat == GL_DEPTH_COMPONENT ||
+ srcFormat == GL_STENCIL_INDEX);
+ ASSERT(srcFormat != GL_DEPTH_STENCIL ||
+ srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+
+ if (srcFormat == GL_DEPTH_STENCIL &&
+ ctx->Pixel.DepthScale == 1.0f &&
+ ctx->Pixel.DepthBias == 0.0f &&
+ !srcPacking->SwapBytes) {
+ /* simple path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride,
+ dstImageOffsets,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else if (srcFormat == GL_DEPTH_COMPONENT ||
+ srcFormat == GL_STENCIL_INDEX) {
+ GLint img, row;
+ const GLint srcRowStride
+ = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
+ / sizeof(uint64_t);
+
+ /* In case we only upload depth we need to preserve the stencil */
+ for (img = 0; img < srcDepth; img++) {
+ uint64_t *dstRow = (uint64_t *) dstAddr
+ + dstImageOffsets[dstZoffset + img]
+ + dstYoffset * dstRowStride / sizeof(uint64_t)
+ + dstXoffset;
+ const uint64_t *src
+ = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr,
+ srcWidth, srcHeight,
+ srcFormat, srcType,
+ img, 0, 0);
+ for (row = 0; row < srcHeight; row++) {
+ /* The unpack functions with:
+ * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
+ * only write their own dword, so the other dword (stencil
+ * or depth) is preserved. */
+ if (srcFormat != GL_STENCIL_INDEX)
+ _mesa_unpack_depth_span(ctx, srcWidth,
+ GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
+ dstRow, /* dst addr */
+ 1.0f, srcType, src, srcPacking);
+
+ if (srcFormat != GL_DEPTH_COMPONENT)
+ _mesa_unpack_stencil_span(ctx, srcWidth,
+ GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
+ dstRow, /* dst addr */
+ srcType, src, srcPacking,
+ ctx->_ImageTransferState);
+
+ src += srcRowStride;
+ dstRow += dstRowStride / sizeof(uint64_t);
+ }
+ }
+ }
+ return GL_TRUE;
+}
+
/**
* Table mapping MESA_FORMAT_* to _mesa_texstore_*()
@@ -4419,6 +4487,9 @@ texstore_funcs[MESA_FORMAT_COUNT] =
{ MESA_FORMAT_RGB9_E5_FLOAT, _mesa_texstore_rgb9_e5 },
{ MESA_FORMAT_R11_G11_B10_FLOAT, _mesa_texstore_r11_g11_b10f },
+
+ { MESA_FORMAT_Z32_FLOAT, _mesa_texstore_z32 },
+ { MESA_FORMAT_Z32_FLOAT_X24S8, _mesa_texstore_z32f_x24s8 },
};
@@ -4506,8 +4577,7 @@ texture_row_stride(const struct gl_texture_image *texImage)
/**
- * This is the software fallback for Driver.TexImage1D()
- * and Driver.CopyTexImage1D().
+ * This is the software fallback for Driver.TexImage1D().
* \sa _mesa_store_teximage2d()
*/
void
@@ -4558,8 +4628,7 @@ _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
/**
- * This is the software fallback for Driver.TexImage2D()
- * and Driver.CopyTexImage2D().
+ * This is the software fallback for Driver.TexImage2D().
*
* This function is oriented toward storing images in main memory, rather
* than VRAM. Device driver's can easily plug in their own replacement.
@@ -4613,8 +4682,7 @@ _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
/**
- * This is the software fallback for Driver.TexImage3D()
- * and Driver.CopyTexImage3D().
+ * This is the software fallback for Driver.TexImage3D().
* \sa _mesa_store_teximage2d()
*/
void
diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
index 1c4fd82baac..dd069a3a4d1 100644
--- a/src/mesa/main/uniforms.c
+++ b/src/mesa/main/uniforms.c
@@ -580,7 +580,7 @@ _mesa_update_shader_textures_used(struct gl_program *prog)
if (prog->SamplersUsed & (1 << s)) {
GLuint unit = prog->SamplerUnits[s];
GLuint tgt = prog->SamplerTargets[s];
- assert(unit < MAX_TEXTURE_IMAGE_UNITS);
+ assert(unit < Elements(prog->TexturesUsed));
assert(tgt < NUM_TEXTURE_TARGETS);
prog->TexturesUsed[unit] |= (1 << tgt);
}
@@ -674,7 +674,7 @@ set_program_uniform(struct gl_context *ctx, struct gl_program *program,
GLuint texUnit = ((GLuint *) values)[i];
/* check that the sampler (tex unit index) is legal */
- if (texUnit >= ctx->Const.MaxTextureImageUnits) {
+ if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glUniform1(invalid sampler/tex unit index for '%s')",
param->Name);
diff --git a/src/mesa/main/version.h b/src/mesa/main/version.h
index 2e6335846e3..0a0512c339d 100644
--- a/src/mesa/main/version.h
+++ b/src/mesa/main/version.h
@@ -33,9 +33,9 @@ struct gl_context;
/* Mesa version */
#define MESA_MAJOR 7
-#define MESA_MINOR 11
+#define MESA_MINOR 12
#define MESA_PATCH 0
-#define MESA_VERSION_STRING "7.11-devel"
+#define MESA_VERSION_STRING "7.12-devel"
/* To make version comparison easy */
#define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))