#include "main/teximage.h"
#include "main/texparam.h"
#include "main/texstate.h"
+#include "main/transformfeedback.h"
#include "main/uniforms.h"
#include "main/varray.h"
#include "main/viewport.h"
/** Miscellaneous (always disabled) */
GLboolean Lighting;
+ GLboolean RasterDiscard;
+ GLboolean TransformFeedbackNeedsResume;
};
/**
memset(save, 0, sizeof(*save));
save->SavedState = state;
+ /* Pausing transform feedback needs to be done early, or else we won't be
+ * able to change other state.
+ */
+ save->TransformFeedbackNeedsResume =
+ ctx->TransformFeedback.CurrentObject->Active &&
+ !ctx->TransformFeedback.CurrentObject->Paused;
+ if (save->TransformFeedbackNeedsResume)
+ _mesa_PauseTransformFeedback();
+
if (state & MESA_META_ALPHA_TEST) {
save->AlphaEnabled = ctx->Color.AlphaEnabled;
save->AlphaFunc = ctx->Color.AlphaFunc;
_mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE);
if (ctx->Extensions.NV_texture_rectangle)
_mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_FALSE);
+ if (ctx->Extensions.OES_EGL_image_external)
+ _mesa_set_enable(ctx, GL_TEXTURE_EXTERNAL_OES, GL_FALSE);
_mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_FALSE);
_mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_FALSE);
_mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_FALSE);
save->Lighting = ctx->Light.Enabled;
if (ctx->Light.Enabled)
_mesa_set_enable(ctx, GL_LIGHTING, GL_FALSE);
+ save->RasterDiscard = ctx->RasterDiscard;
+ if (ctx->RasterDiscard)
+ _mesa_set_enable(ctx, GL_RASTERIZER_DISCARD, GL_FALSE);
}
}
/* restore texture objects for unit[0] only */
for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
- _mesa_reference_texobj(&ctx->Texture.Unit[0].CurrentTex[tgt],
- save->CurrentTexture[tgt]);
+ if (ctx->Texture.Unit[0].CurrentTex[tgt] != save->CurrentTexture[tgt]) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ _mesa_reference_texobj(&ctx->Texture.Unit[0].CurrentTex[tgt],
+ save->CurrentTexture[tgt]);
+ }
_mesa_reference_texobj(&save->CurrentTexture[tgt], NULL);
}
- /* Re-enable textures, texgen */
+ /* Restore fixed function texture enables, texgen */
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
- if (save->TexEnabled[u]) {
- _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
-
- if (save->TexEnabled[u] & TEXTURE_1D_BIT)
- _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_TRUE);
- if (save->TexEnabled[u] & TEXTURE_2D_BIT)
- _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_TRUE);
- if (save->TexEnabled[u] & TEXTURE_3D_BIT)
- _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_TRUE);
- if (save->TexEnabled[u] & TEXTURE_CUBE_BIT)
- _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_TRUE);
- if (save->TexEnabled[u] & TEXTURE_RECT_BIT)
- _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_TRUE);
- }
-
- if (save->TexGenEnabled[u]) {
- _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
+ if (ctx->Texture.Unit[u].Enabled != save->TexEnabled[u]) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ ctx->Texture.Unit[u].Enabled = save->TexEnabled[u];
+ }
- if (save->TexGenEnabled[u] & S_BIT)
- _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_TRUE);
- if (save->TexGenEnabled[u] & T_BIT)
- _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_TRUE);
- if (save->TexGenEnabled[u] & R_BIT)
- _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_TRUE);
- if (save->TexGenEnabled[u] & Q_BIT)
- _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_TRUE);
- }
+ if (ctx->Texture.Unit[u].TexGenEnabled != save->TexGenEnabled[u]) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ ctx->Texture.Unit[u].TexGenEnabled = save->TexGenEnabled[u];
+ }
}
/* restore current unit state */
if (save->Lighting) {
_mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE);
}
+ if (save->RasterDiscard) {
+ _mesa_set_enable(ctx, GL_RASTERIZER_DISCARD, GL_TRUE);
+ }
+ if (save->TransformFeedbackNeedsResume)
+ _mesa_ResumeTransformFeedback();
+}
+
+
+/**
+ * Determine whether Mesa is currently in a meta state.
+ */
+GLboolean
+_mesa_meta_in_progress(struct gl_context *ctx)
+{
+ return ctx->Meta->SaveStackDepth != 0;
}
static INLINE GLfloat
invert_z(GLfloat normZ)
{
- GLfloat objZ = 1.0 - 2.0 * normZ;
+ GLfloat objZ = 1.0f - 2.0f * normZ;
return objZ;
}
struct vertex verts[4];
GLboolean newTex;
- if (srcW > maxTexSize || srcH > maxTexSize) {
+ /* In addition to falling back if the blit size is larger than the maximum
+ * texture size, fallback if the source is multisampled. This fallback can
+ * be removed once Mesa gets support ARB_texture_multisample.
+ */
+ if (srcW > maxTexSize || srcH > maxTexSize
+ || ctx->ReadBuffer->Visual.samples > 0) {
/* XXX avoid this fallback */
_swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1, mask, filter);
/* setup texcoords (XXX what about border?) */
setup_texture_coords(faceTarget,
- 0.0, 0.0, /* width, height never used here */
slice,
+ 0, 0, /* width, height never used here */
verts[0].tex,
verts[1].tex,
verts[2].tex,
break;
}
- /* Set MaxLevel large enough to hold the new level when we allocate it */
+ /* Allocate storage for the destination mipmap image(s) */
+
+ /* Set MaxLevel large enough to hold the new level when we allocate it */
_mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, dstLevel);
- /* Create empty dest image */
- if (target == GL_TEXTURE_1D) {
- _mesa_TexImage1D(target, dstLevel, srcImage->InternalFormat,
- dstWidth, border,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
- else if (target == GL_TEXTURE_3D) {
- _mesa_TexImage3D(target, dstLevel, srcImage->InternalFormat,
- dstWidth, dstHeight, dstDepth, border,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
- else {
- /* 2D or cube */
- _mesa_TexImage2D(faceTarget, dstLevel, srcImage->InternalFormat,
- dstWidth, dstHeight, border,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
- if (target == GL_TEXTURE_CUBE_MAP) {
- /* If texturing from a cube, we need to make sure all src faces
- * have been defined (even if we're not sampling from them.)
- * Otherwise the texture object will be 'incomplete' and
- * texturing from it will not be allowed.
- */
- GLuint face;
- for (face = 0; face < 6; face++) {
- if (!texObj->Image[face][srcLevel] ||
- texObj->Image[face][srcLevel]->Width != srcWidth) {
- _mesa_TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
- srcLevel, srcImage->InternalFormat,
- srcWidth, srcHeight, border,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
- }
- }
+ if (!_mesa_prepare_mipmap_level(ctx, texObj, dstLevel,
+ dstWidth, dstHeight, dstDepth,
+ srcImage->Border,
+ srcImage->InternalFormat,
+ srcImage->TexFormat)) {
+ /* All done. We either ran out of memory or we would go beyond the
+ * last valid level of an immutable texture if we continued.
+ */
+ break;
}
/* limit minification to src level */
/* sanity check */
status = _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- abort();
+ _mesa_problem(ctx, "Unexpected incomplete framebuffer in "
+ "_mesa_meta_GenerateMipmap()");
break;
}
switch (baseFormat) {
case GL_RGBA:
case GL_RGB:
+ case GL_RG:
+ case GL_RED:
case GL_ALPHA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
case GL_DEPTH_STENCIL:
return GL_UNSIGNED_INT_24_8;
default:
- _mesa_problem(ctx, "Unexpected format in get_temp_image_type()");
+ _mesa_problem(ctx, "Unexpected format %d in get_temp_image_type()",
+ baseFormat);
return 0;
}
}
*/
static void
copy_tex_sub_image(struct gl_context *ctx,
- GLuint dims, GLenum target, GLint level,
+ GLuint dims,
+ struct gl_texture_image *texImage,
GLint xoffset, GLint yoffset, GLint zoffset,
+ struct gl_renderbuffer *rb,
GLint x, GLint y,
GLsizei width, GLsizei height)
{
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
+ struct gl_texture_object *texObj = texImage->TexObject;
+ const GLenum target = texObj->Target;
GLenum format, type;
GLint bpp;
void *buf;
- texObj = _mesa_get_current_tex_object(ctx, target);
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
-
/* Choose format/type for temporary image buffer */
format = _mesa_get_format_base_format(texImage->TexFormat);
if (format == GL_LUMINANCE ||
format = GL_RGBA;
}
+ if (_mesa_is_format_integer_color(texImage->TexFormat)) {
+ _mesa_problem(ctx, "unsupported integer color copyteximage");
+ return;
+ }
+
type = get_temp_image_type(ctx, format);
bpp = _mesa_bytes_per_pixel(format, type);
if (bpp <= 0) {
*/
_mesa_meta_begin(ctx, MESA_META_PIXEL_STORE);
if (target == GL_TEXTURE_1D) {
- ctx->Driver.TexSubImage1D(ctx, target, level, xoffset,
- width, format, type, buf,
- &ctx->Unpack, texObj, texImage);
+ ctx->Driver.TexSubImage1D(ctx, texImage,
+ xoffset, width,
+ format, type, buf, &ctx->Unpack);
}
else if (target == GL_TEXTURE_3D) {
- ctx->Driver.TexSubImage3D(ctx, target, level, xoffset, yoffset, zoffset,
- width, height, 1, format, type, buf,
- &ctx->Unpack, texObj, texImage);
+ ctx->Driver.TexSubImage3D(ctx, texImage,
+ xoffset, yoffset, zoffset, width, height, 1,
+ format, type, buf, &ctx->Unpack);
}
else {
- ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset,
- width, height, format, type, buf,
- &ctx->Unpack, texObj, texImage);
+ ctx->Driver.TexSubImage2D(ctx, texImage,
+ xoffset, yoffset, width, height,
+ format, type, buf, &ctx->Unpack);
}
_mesa_meta_end(ctx);
void
-_mesa_meta_CopyTexSubImage1D(struct gl_context *ctx, GLenum target, GLint level,
+_mesa_meta_CopyTexSubImage1D(struct gl_context *ctx,
+ struct gl_texture_image *texImage,
GLint xoffset,
+ struct gl_renderbuffer *rb,
GLint x, GLint y, GLsizei width)
{
- copy_tex_sub_image(ctx, 1, target, level, xoffset, 0, 0,
- x, y, width, 1);
+ copy_tex_sub_image(ctx, 1, texImage, xoffset, 0, 0,
+ rb, x, y, width, 1);
}
void
-_mesa_meta_CopyTexSubImage2D(struct gl_context *ctx, GLenum target, GLint level,
+_mesa_meta_CopyTexSubImage2D(struct gl_context *ctx,
+ struct gl_texture_image *texImage,
GLint xoffset, GLint yoffset,
+ struct gl_renderbuffer *rb,
GLint x, GLint y,
GLsizei width, GLsizei height)
{
- copy_tex_sub_image(ctx, 2, target, level, xoffset, yoffset, 0,
- x, y, width, height);
+ copy_tex_sub_image(ctx, 2, texImage, xoffset, yoffset, 0,
+ rb, x, y, width, height);
}
void
-_mesa_meta_CopyTexSubImage3D(struct gl_context *ctx, GLenum target, GLint level,
+_mesa_meta_CopyTexSubImage3D(struct gl_context *ctx,
+ struct gl_texture_image *texImage,
GLint xoffset, GLint yoffset, GLint zoffset,
+ struct gl_renderbuffer *rb,
GLint x, GLint y,
GLsizei width, GLsizei height)
{
- copy_tex_sub_image(ctx, 3, target, level, xoffset, yoffset, zoffset,
- x, y, width, height);
+ copy_tex_sub_image(ctx, 3, texImage, xoffset, yoffset, zoffset,
+ rb, x, y, width, height);
}
struct gl_texture_image *texImage,
GLuint slice,
GLenum destFormat, GLenum destType,
- GLvoid *dest, GLint destRowLength)
+ GLvoid *dest)
{
struct decompress_state *decompress = &ctx->Meta->Decompress;
struct gl_texture_object *texObj = texImage->TexObject;
fboDrawSave = ctx->DrawBuffer->Name;
fboReadSave = ctx->ReadBuffer->Name;
- _mesa_meta_begin(ctx, MESA_META_ALL);
+ _mesa_meta_begin(ctx, MESA_META_ALL & ~MESA_META_PIXEL_STORE);
/* Create/bind FBO/renderbuffer */
if (decompress->FBO == 0) {
}
/* alloc dest surface */
- if (width != decompress->Width || height != decompress->Height) {
+ if (width > decompress->Width || height > decompress->Height) {
_mesa_RenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA,
width, height);
decompress->Width = width;
_mesa_PixelTransferf(GL_BLUE_SCALE, 0.0f);
}
- ctx->Pack.RowLength = destRowLength;
_mesa_ReadPixels(0, 0, width, height, destFormat, destType, dest);
}
const GLuint slice = 0; /* only 2D compressed textures for now */
/* Need to unlock the texture here to prevent deadlock... */
_mesa_unlock_texture(ctx, texObj);
- decompress_texture_image(ctx, texImage, slice, format, type, pixels,
- ctx->Pack.RowLength);
+ decompress_texture_image(ctx, texImage, slice, format, type, pixels);
/* ... and relock it */
_mesa_lock_texture(ctx, texObj);
}