diff options
Diffstat (limited to 'mesalib/src/mesa/main')
-rw-r--r-- | mesalib/src/mesa/main/compiler.h | 3 | ||||
-rw-r--r-- | mesalib/src/mesa/main/dd.h | 4 | ||||
-rw-r--r-- | mesalib/src/mesa/main/fbobject.c | 39 | ||||
-rw-r--r-- | mesalib/src/mesa/main/fbobject.h | 3 | ||||
-rw-r--r-- | mesalib/src/mesa/main/ff_fragment_shader.cpp | 16 | ||||
-rw-r--r-- | mesalib/src/mesa/main/formatquery.c | 12 | ||||
-rw-r--r-- | mesalib/src/mesa/main/framebuffer.c | 4 | ||||
-rw-r--r-- | mesalib/src/mesa/main/framebuffer.h | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/main/mtypes.h | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/main/multisample.c | 77 | ||||
-rw-r--r-- | mesalib/src/mesa/main/multisample.h | 5 | ||||
-rw-r--r-- | mesalib/src/mesa/main/readpix.c | 284 | ||||
-rw-r--r-- | mesalib/src/mesa/main/readpix.h | 4 | ||||
-rw-r--r-- | mesalib/src/mesa/main/texgetimage.c | 1 | ||||
-rw-r--r-- | mesalib/src/mesa/main/teximage.c | 34 | ||||
-rw-r--r-- | mesalib/src/mesa/main/texparam.c | 12 | ||||
-rw-r--r-- | mesalib/src/mesa/main/texstorage.c | 1 |
17 files changed, 395 insertions, 108 deletions
diff --git a/mesalib/src/mesa/main/compiler.h b/mesalib/src/mesa/main/compiler.h index 48712485a..8b23665e6 100644 --- a/mesalib/src/mesa/main/compiler.h +++ b/mesalib/src/mesa/main/compiler.h @@ -307,8 +307,9 @@ static INLINE GLuint CPU_TO_LE32(GLuint x) * USE_IEEE: Determine if we're using IEEE floating point */ #if defined(__i386__) || defined(__386__) || defined(__sparc__) || \ - defined(__s390x__) || defined(__powerpc__) || \ + defined(__s390__) || defined(__s390x__) || defined(__powerpc__) || \ defined(__x86_64__) || \ + defined(__m68k__) || \ defined(ia64) || defined(__ia64__) || \ defined(__hppa__) || defined(hpux) || \ defined(__mips) || defined(_MIPS_ARCH) || \ diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h index 4860d4d12..8f3cd3d6b 100644 --- a/mesalib/src/mesa/main/dd.h +++ b/mesalib/src/mesa/main/dd.h @@ -195,9 +195,10 @@ struct dd_function_table { GLenum srcFormat, GLenum srcType ); /** - * Determine sample counts support for a particular format + * Determine sample counts support for a particular target and format * * \param ctx GL context + * \param target GL target enum * \param internalFormat GL format enum * \param samples Buffer to hold the returned sample counts. * Drivers \b must \b not return more than 16 counts. @@ -207,6 +208,7 @@ struct dd_function_table { * \c internaFormat is not renderable, zero is returned. */ size_t (*QuerySamplesForFormat)(struct gl_context *ctx, + GLenum target, GLenum internalFormat, int samples[16]); diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index 0126e2930..3fdf62667 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -43,6 +43,7 @@ #include "hash.h" #include "macros.h" #include "mfeatures.h" +#include "multisample.h" #include "mtypes.h" #include "renderbuffer.h" #include "state.h" @@ -474,6 +475,32 @@ _mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) /** + * Return true if the framebuffer has a combined depth/stencil + * renderbuffer attached. + */ +GLboolean +_mesa_has_depthstencil_combined(const struct gl_framebuffer *fb) +{ + const struct gl_renderbuffer_attachment *depth = + &fb->Attachment[BUFFER_DEPTH]; + const struct gl_renderbuffer_attachment *stencil = + &fb->Attachment[BUFFER_STENCIL]; + + if (depth->Type == stencil->Type) { + if (depth->Type == GL_RENDERBUFFER_EXT && + depth->Renderbuffer == stencil->Renderbuffer) + return GL_TRUE; + + if (depth->Type == GL_TEXTURE && + depth->Texture == stencil->Texture) + return GL_TRUE; + } + + return GL_FALSE; +} + + +/** * For debug only. */ static void @@ -1466,6 +1493,7 @@ renderbuffer_storage(GLenum target, GLenum internalFormat, "glRenderbufferStorage" : "glRenderbufferStorageMultisample"; struct gl_renderbuffer *rb; GLenum baseFormat; + GLenum sample_count_error; GET_CURRENT_CONTEXT(ctx); if (MESA_VERBOSE & VERBOSE_API) { @@ -1509,9 +1537,14 @@ renderbuffer_storage(GLenum target, GLenum internalFormat, /* NumSamples == 0 indicates non-multisampling */ samples = 0; } - else if (samples > (GLsizei) ctx->Const.MaxSamples) { - /* note: driver may choose to use more samples than what's requested */ - _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples)", func); + + /* check the sample count; + * note: driver may choose to use more samples than what's requested + */ + sample_count_error = _mesa_check_sample_count(ctx, target, + internalFormat, samples); + if (sample_count_error != GL_NO_ERROR) { + _mesa_error(ctx, sample_count_error, "%s(samples)", func); return; } diff --git a/mesalib/src/mesa/main/fbobject.h b/mesalib/src/mesa/main/fbobject.h index ec8b0afe4..0358864d7 100644 --- a/mesalib/src/mesa/main/fbobject.h +++ b/mesalib/src/mesa/main/fbobject.h @@ -113,6 +113,9 @@ _mesa_framebuffer_renderbuffer(struct gl_context *ctx, extern void _mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb); +extern GLboolean +_mesa_has_depthstencil_combined(const struct gl_framebuffer *fb); + extern void _mesa_test_framebuffer_completeness(struct gl_context *ctx, struct gl_framebuffer *fb); diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp index 186988bbd..01a4542d7 100644 --- a/mesalib/src/mesa/main/ff_fragment_shader.cpp +++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp @@ -1350,22 +1350,6 @@ create_new_program(struct gl_context *ctx, struct state_key *key) _mesa_glsl_link_shader(ctx, p.shader_program); - /* Set the sampler uniforms, and relink to get them into the linked - * program. - */ - struct gl_shader *const fs = - p.shader_program->_LinkedShaders[MESA_SHADER_FRAGMENT]; - struct gl_program *const fp = fs->Program; - - _mesa_generate_parameters_list_for_uniforms(p.shader_program, fs, - fp->Parameters); - - _mesa_associate_uniform_storage(ctx, p.shader_program, fp->Parameters); - - _mesa_update_shader_textures_used(p.shader_program, fp); - if (ctx->Driver.SamplerUniformChange) - ctx->Driver.SamplerUniformChange(ctx, fp->Target, fp); - if (!p.shader_program->LinkStatus) _mesa_problem(ctx, "Failed to link fixed function fragment shader: %s\n", p.shader_program->InfoLog); diff --git a/mesalib/src/mesa/main/formatquery.c b/mesalib/src/mesa/main/formatquery.c index bd895e874..78c5fbe5e 100644 --- a/mesalib/src/mesa/main/formatquery.c +++ b/mesalib/src/mesa/main/formatquery.c @@ -59,9 +59,10 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: - /* Mesa does not currently support GL_ARB_texture_multisample, so these - * enums are not valid on this implementation either. - */ + /* These enums are only valid if ARB_texture_multisample is supported */ + if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample) + break; + default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetInternalformativ(target=%s)", @@ -96,7 +97,8 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, switch (pname) { case GL_SAMPLES: - count = ctx->Driver.QuerySamplesForFormat(ctx, internalformat, buffer); + count = ctx->Driver.QuerySamplesForFormat(ctx, target, + internalformat, buffer); break; case GL_NUM_SAMPLE_COUNTS: { /* The driver can return 0, and we should pass that along to the @@ -115,7 +117,7 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, * returned." */ const size_t num_samples = - ctx->Driver.QuerySamplesForFormat(ctx, internalformat, buffer); + ctx->Driver.QuerySamplesForFormat(ctx, target, internalformat, buffer); /* QuerySamplesForFormat writes some stuff to buffer, so we have to * separately over-write it with the requested value. diff --git a/mesalib/src/mesa/main/framebuffer.c b/mesalib/src/mesa/main/framebuffer.c index d3abc2b30..619aaa337 100644 --- a/mesalib/src/mesa/main/framebuffer.c +++ b/mesalib/src/mesa/main/framebuffer.c @@ -923,10 +923,10 @@ _mesa_get_color_read_type(struct gl_context *ctx) * Returns the read renderbuffer for the specified format. */ struct gl_renderbuffer * -_mesa_get_read_renderbuffer_for_format(struct gl_context *ctx, +_mesa_get_read_renderbuffer_for_format(const struct gl_context *ctx, GLenum format) { - struct gl_framebuffer *rfb = ctx->ReadBuffer; + const struct gl_framebuffer *rfb = ctx->ReadBuffer; if (_mesa_is_color_format(format)) { return rfb->Attachment[rfb->_ColorReadBufferIndex].Renderbuffer; diff --git a/mesalib/src/mesa/main/framebuffer.h b/mesalib/src/mesa/main/framebuffer.h index 06db04925..9b94452d6 100644 --- a/mesalib/src/mesa/main/framebuffer.h +++ b/mesalib/src/mesa/main/framebuffer.h @@ -98,7 +98,7 @@ extern GLenum _mesa_get_color_read_format(struct gl_context *ctx); extern struct gl_renderbuffer * -_mesa_get_read_renderbuffer_for_format(struct gl_context *ctx, +_mesa_get_read_renderbuffer_for_format(const struct gl_context *ctx, GLenum format); extern void diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 83b6c8984..a0e7e281d 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1179,6 +1179,7 @@ struct gl_texture_object GLfloat Priority; /**< in [0,1] */ GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */ GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */ + GLint ImmutableLevels; /**< ES 3.0 / ARB_texture_view */ GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */ GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */ GLint CropRect[4]; /**< GL_OES_draw_texture */ @@ -1796,6 +1797,7 @@ struct gl_transform_feedback_state typedef enum { PROGRAM_TEMPORARY, /**< machine->Temporary[] */ + PROGRAM_ARRAY, /**< Arrays & Matrixes */ PROGRAM_INPUT, /**< machine->Inputs[] */ PROGRAM_OUTPUT, /**< machine->Outputs[] */ PROGRAM_LOCAL_PARAM, /**< gl_program->LocalParams[] */ diff --git a/mesalib/src/mesa/main/multisample.c b/mesalib/src/mesa/main/multisample.c index 248494615..b0f45d933 100644 --- a/mesalib/src/mesa/main/multisample.c +++ b/mesalib/src/mesa/main/multisample.c @@ -29,6 +29,7 @@ #include "main/multisample.h" #include "main/mtypes.h" #include "main/fbobject.h" +#include "main/glformats.h" /** @@ -112,3 +113,79 @@ _mesa_SampleMaski(GLuint index, GLbitfield mask) FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE); ctx->Multisample.SampleMaskValue = mask; } + + +/* Helper for checking a requested sample count against the limit + * for a particular (target, internalFormat) pair. The limit imposed, + * and the error generated, both depend on which extensions are supported. + * + * Returns a GL error enum, or GL_NO_ERROR if the requested sample count is + * acceptable. + */ +GLenum +_mesa_check_sample_count(struct gl_context *ctx, GLenum target, + GLenum internalFormat, GLsizei samples) +{ + /* If ARB_internalformat_query is supported, then treat its highest returned sample + * count as the absolute maximum for this format; it is allowed to exceed MAX_SAMPLES. + * + * From the ARB_internalformat_query spec: + * + * "If <samples is greater than the maximum number of samples supported + * for <internalformat> then the error INVALID_OPERATION is generated." + */ + if (ctx->Extensions.ARB_internalformat_query) { + GLint buffer[16]; + int count = ctx->Driver.QuerySamplesForFormat(ctx, target, internalFormat, buffer); + int limit = count ? buffer[0] : -1; + + return samples > limit ? GL_INVALID_OPERATION : GL_NO_ERROR; + } + + /* If ARB_texture_multisample is supported, we have separate limits, + * which may be lower than MAX_SAMPLES: + * + * From the ARB_texture_multisample spec, when describing the operation + * of RenderbufferStorageMultisample: + * + * "If <internalformat> is a signed or unsigned integer format and + * <samples> is greater than the value of MAX_INTEGER_SAMPLES, then the + * error INVALID_OPERATION is generated" + * + * And when describing the operation of TexImage*Multisample: + * + * "The error INVALID_OPERATION may be generated if any of the following are true: + * + * * <internalformat> is a depth/stencil-renderable format and <samples> + * is greater than the value of MAX_DEPTH_TEXTURE_SAMPLES + * * <internalformat> is a color-renderable format and <samples> is + * grater than the value of MAX_COLOR_TEXTURE_SAMPLES + * * <internalformat> is a signed or unsigned integer format and + * <samples> is greater than the value of MAX_INTEGER_SAMPLES + */ + + if (ctx->Extensions.ARB_texture_multisample) { + if (_mesa_is_enum_format_integer(internalFormat)) + return samples > ctx->Const.MaxIntegerSamples ? GL_INVALID_OPERATION : GL_NO_ERROR; + + if (target == GL_TEXTURE_2D_MULTISAMPLE || + target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) { + + if (_mesa_is_depth_or_stencil_format(internalFormat)) + return samples > ctx->Const.MaxDepthTextureSamples + ? GL_INVALID_OPERATION : GL_NO_ERROR; + else + return samples > ctx->Const.MaxColorTextureSamples + ? GL_INVALID_OPERATION : GL_NO_ERROR; + } + } + + /* No more specific limit is available, so just use MAX_SAMPLES: + * + * On p205 of the GL3.1 spec: + * + * "... or if samples is greater than MAX_SAMPLES, then the error + * INVALID_VALUE is generated" + */ + return samples > ctx->Const.MaxSamples ? GL_INVALID_VALUE : GL_NO_ERROR; +} diff --git a/mesalib/src/mesa/main/multisample.h b/mesalib/src/mesa/main/multisample.h index 9e6b8e0d3..f2f01de5c 100644 --- a/mesalib/src/mesa/main/multisample.h +++ b/mesalib/src/mesa/main/multisample.h @@ -44,4 +44,9 @@ _mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat* val); extern void GLAPIENTRY _mesa_SampleMaski(GLuint index, GLbitfield mask); + +extern GLenum +_mesa_check_sample_count(struct gl_context *ctx, GLenum target, + GLenum internalFormat, GLsizei samples); + #endif diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c index 2f130ae9a..d3d09dea3 100644 --- a/mesalib/src/mesa/main/readpix.c +++ b/mesalib/src/mesa/main/readpix.c @@ -41,11 +41,212 @@ /** - * Tries to implement glReadPixels() of GL_DEPTH_COMPONENT using memcpy of the - * mapping. + * Return true if the conversion L=R+G+B is needed. */ static GLboolean -fast_read_depth_pixels( struct gl_context *ctx, +need_rgb_to_luminance_conversion(gl_format texFormat, GLenum format) +{ + GLenum baseTexFormat = _mesa_get_format_base_format(texFormat); + + return (baseTexFormat == GL_RG || + baseTexFormat == GL_RGB || + baseTexFormat == GL_RGBA) && + (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA); +} + + +/** + * Return transfer op flags for this ReadPixels operation. + */ +static GLbitfield +get_readpixels_transfer_ops(const struct gl_context *ctx, gl_format texFormat, + GLenum format, GLenum type, GLboolean uses_blit) +{ + GLbitfield transferOps = ctx->_ImageTransferState; + + if (format == GL_DEPTH_COMPONENT || + format == GL_DEPTH_STENCIL || + format == GL_STENCIL_INDEX) { + return 0; + } + + /* Pixel transfer ops (scale, bias, table lookup) do not apply + * to integer formats. + */ + if (_mesa_is_enum_format_integer(format)) { + return 0; + } + + if (uses_blit) { + /* For blit-based ReadPixels packing, the clamping is done automatically + * unless the type is float. */ + if (ctx->Color._ClampReadColor == GL_TRUE && + (type == GL_FLOAT || type == GL_HALF_FLOAT)) { + transferOps |= IMAGE_CLAMP_BIT; + } + } + else { + /* For CPU-based ReadPixels packing, the clamping must always be done + * for non-float types, */ + if (ctx->Color._ClampReadColor == GL_TRUE || + (type != GL_FLOAT && type != GL_HALF_FLOAT)) { + transferOps |= IMAGE_CLAMP_BIT; + } + } + + /* If the format is unsigned normalized, we can ignore clamping + * because the values are already in the range [0,1] so it won't + * have any effect anyway. + */ + if (_mesa_get_format_datatype(texFormat) == GL_UNSIGNED_NORMALIZED && + !need_rgb_to_luminance_conversion(texFormat, format)) { + transferOps &= ~IMAGE_CLAMP_BIT; + } + + return transferOps; +} + + +/** + * Return true if memcpy cannot be used for ReadPixels. + * + * If uses_blit is true, the function returns true if a simple 3D engine blit + * cannot be used for ReadPixels packing. + * + * NOTE: This doesn't take swizzling and format conversions between + * the readbuffer and the pixel pack buffer into account. + */ +GLboolean +_mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format, + GLenum type, GLboolean uses_blit) +{ + struct gl_renderbuffer *rb = + _mesa_get_read_renderbuffer_for_format(ctx, format); + GLenum srcType; + + ASSERT(rb); + + /* There are different rules depending on the base format. */ + switch (format) { + case GL_DEPTH_STENCIL: + return !_mesa_has_depthstencil_combined(ctx->ReadBuffer) || + ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f || + ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset || + ctx->Pixel.MapStencilFlag; + + case GL_DEPTH_COMPONENT: + return ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f; + + case GL_STENCIL_INDEX: + return ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset || + ctx->Pixel.MapStencilFlag; + + default: + /* Color formats. */ + if (need_rgb_to_luminance_conversion(rb->Format, format)) { + return GL_TRUE; + } + + /* Conversion between signed and unsigned integers needs masking + * (it isn't just memcpy). */ + srcType = _mesa_get_format_datatype(rb->Format); + + if ((srcType == GL_INT && + (type == GL_UNSIGNED_INT || + type == GL_UNSIGNED_SHORT || + type == GL_UNSIGNED_BYTE)) || + (srcType == GL_UNSIGNED_INT && + (type == GL_INT || + type == GL_SHORT || + type == GL_BYTE))) { + return GL_TRUE; + } + + /* And finally, see if there are any transfer ops. */ + return get_readpixels_transfer_ops(ctx, rb->Format, format, type, + uses_blit) != 0; + } + return GL_FALSE; +} + + +static GLboolean +readpixels_can_use_memcpy(const struct gl_context *ctx, GLenum format, GLenum type, + const struct gl_pixelstore_attrib *packing) +{ + struct gl_renderbuffer *rb = + _mesa_get_read_renderbuffer_for_format(ctx, format); + + ASSERT(rb); + + if (_mesa_readpixels_needs_slow_path(ctx, format, type, GL_FALSE)) { + return GL_FALSE; + } + + /* The base internal format and the base Mesa format must match. */ + if (rb->_BaseFormat != _mesa_get_format_base_format(rb->Format)) { + return GL_FALSE; + } + + /* The Mesa format must match the input format and type. */ + if (!_mesa_format_matches_format_and_type(rb->Format, format, type, + packing->SwapBytes)) { + return GL_FALSE; + } + + return GL_TRUE; +} + + +static GLboolean +readpixels_memcpy(struct gl_context *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + GLvoid *pixels, + const struct gl_pixelstore_attrib *packing) +{ + struct gl_renderbuffer *rb = + _mesa_get_read_renderbuffer_for_format(ctx, format); + GLubyte *dst, *map; + int dstStride, stride, j, texelBytes; + + /* Fail if memcpy cannot be used. */ + if (!readpixels_can_use_memcpy(ctx, format, type, packing)) { + return GL_FALSE; + } + + dstStride = _mesa_image_row_stride(packing, width, format, type); + dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, + format, type, 0, 0); + + ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, + &map, &stride); + if (!map) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); + return GL_TRUE; /* don't bother trying the slow path */ + } + + texelBytes = _mesa_get_format_bytes(rb->Format); + + /* memcpy*/ + for (j = 0; j < height; j++) { + memcpy(dst, map, width * texelBytes); + dst += dstStride; + map += stride; + } + + ctx->Driver.UnmapRenderbuffer(ctx, rb); + return GL_TRUE; +} + + +/** + * Optimized path for conversion of depth values to GL_DEPTH_COMPONENT, + * GL_UNSIGNED_INT. + */ +static GLboolean +read_uint_depth_pixels( struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum type, GLvoid *pixels, @@ -65,10 +266,6 @@ fast_read_depth_pixels( struct gl_context *ctx, if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED) return GL_FALSE; - if (!((type == GL_UNSIGNED_SHORT && rb->Format == MESA_FORMAT_Z16) || - type == GL_UNSIGNED_INT)) - return GL_FALSE; - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, &map, &stride); @@ -82,12 +279,7 @@ fast_read_depth_pixels( struct gl_context *ctx, GL_DEPTH_COMPONENT, type, 0, 0); for (j = 0; j < height; j++) { - if (type == GL_UNSIGNED_INT) { - _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst); - } else { - ASSERT(type == GL_UNSIGNED_SHORT && rb->Format == MESA_FORMAT_Z16); - memcpy(dst, map, width * 2); - } + _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst); map += stride; dst += dstStride; @@ -123,8 +315,10 @@ read_depth_pixels( struct gl_context *ctx, ASSERT(x + width <= (GLint) rb->Width); ASSERT(y + height <= (GLint) rb->Height); - if (fast_read_depth_pixels(ctx, x, y, width, height, type, pixels, packing)) + if (type == GL_UNSIGNED_INT && + read_uint_depth_pixels(ctx, x, y, width, height, type, pixels, packing)) { return; + } dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type); dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, @@ -212,21 +406,20 @@ read_stencil_pixels( struct gl_context *ctx, /** - * Try to do glReadPixels of RGBA data using a simple memcpy or swizzle. + * Try to do glReadPixels of RGBA data using swizzle. * \return GL_TRUE if successful, GL_FALSE otherwise (use the slow path) */ static GLboolean -fast_read_rgba_pixels_memcpy( struct gl_context *ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - GLbitfield transferOps ) +read_rgba_pixels_swizzle(struct gl_context *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + GLvoid *pixels, + const struct gl_pixelstore_attrib *packing) { struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; GLubyte *dst, *map; - int dstStride, stride, j, texelBytes; + int dstStride, stride, j; GLboolean swizzle_rb = GL_FALSE, copy_xrgb = GL_FALSE; /* XXX we could check for other swizzle/special cases here as needed */ @@ -242,19 +435,9 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx, !ctx->Pack.SwapBytes) { copy_xrgb = GL_TRUE; } - else if (!_mesa_format_matches_format_and_type(rb->Format, format, type, - ctx->Pack.SwapBytes)) - return GL_FALSE; - - /* If the format is unsigned normalized then we can ignore clamping - * because the values are already in the range [0,1] so it won't - * have any effect anyway. - */ - if (_mesa_get_format_datatype(rb->Format) == GL_UNSIGNED_NORMALIZED) - transferOps &= ~IMAGE_CLAMP_BIT; - - if (transferOps) + else { return GL_FALSE; + } dstStride = _mesa_image_row_stride(packing, width, format, type); dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, @@ -267,8 +450,6 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx, return GL_TRUE; /* don't bother trying the slow path */ } - texelBytes = _mesa_get_format_bytes(rb->Format); - if (swizzle_rb) { /* swap R/B */ for (j = 0; j < height; j++) { @@ -294,13 +475,6 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx, dst += dstStride; map += stride; } - } else { - /* just memcpy */ - for (j = 0; j < height; j++) { - memcpy(dst, map, width * texelBytes); - dst += dstStride; - map += stride; - } } ctx->Driver.UnmapRenderbuffer(ctx, rb); @@ -379,22 +553,20 @@ read_rgba_pixels( struct gl_context *ctx, GLenum format, GLenum type, GLvoid *pixels, const struct gl_pixelstore_attrib *packing ) { - GLbitfield transferOps = ctx->_ImageTransferState; + GLbitfield transferOps; struct gl_framebuffer *fb = ctx->ReadBuffer; struct gl_renderbuffer *rb = fb->_ColorReadBuffer; if (!rb) return; - if ((ctx->Color._ClampReadColor == GL_TRUE || type != GL_FLOAT) && - !_mesa_is_enum_format_integer(format)) { - transferOps |= IMAGE_CLAMP_BIT; - } + transferOps = get_readpixels_transfer_ops(ctx, rb->Format, format, type, + GL_FALSE); /* Try the optimized paths first. */ - if (fast_read_rgba_pixels_memcpy(ctx, x, y, width, height, - format, type, pixels, packing, - transferOps)) { + if (!transferOps && + read_rgba_pixels_swizzle(ctx, x, y, width, height, + format, type, pixels, packing)) { return; } @@ -649,6 +821,14 @@ _mesa_readpixels(struct gl_context *ctx, pixels = _mesa_map_pbo_dest(ctx, &clippedPacking, pixels); if (pixels) { + /* Try memcpy first. */ + if (readpixels_memcpy(ctx, x, y, width, height, format, type, + pixels, packing)) { + _mesa_unmap_pbo_dest(ctx, &clippedPacking); + return; + } + + /* Otherwise take the slow path. */ switch (format) { case GL_STENCIL_INDEX: read_stencil_pixels(ctx, x, y, width, height, type, pixels, diff --git a/mesalib/src/mesa/main/readpix.h b/mesalib/src/mesa/main/readpix.h index 5a5f73f52..7491c22ff 100644 --- a/mesalib/src/mesa/main/readpix.h +++ b/mesalib/src/mesa/main/readpix.h @@ -33,6 +33,10 @@ struct gl_context; struct gl_pixelstore_attrib; +extern GLboolean +_mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format, + GLenum type, GLboolean uses_blit); + extern void _mesa_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height, diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c index 7299a4b23..74b09ef2c 100644 --- a/mesalib/src/mesa/main/texgetimage.c +++ b/mesalib/src/mesa/main/texgetimage.c @@ -518,6 +518,7 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions, if (type_needs_clamping(type)) { /* the returned image type can't have negative values */ if (dataType == GL_FLOAT || + dataType == GL_HALF_FLOAT || dataType == GL_SIGNED_NORMALIZED || format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) { diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index 4042e7969..bc755ae79 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -40,6 +40,7 @@ #include "imports.h" #include "macros.h" #include "mfeatures.h" +#include "multisample.h" #include "state.h" #include "texcompress.h" #include "texcompress_cpal.h" @@ -4199,6 +4200,7 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, struct gl_texture_image *texImage; GLboolean sizeOK, dimensionsOK; gl_format texFormat; + GLenum sample_count_error; GET_CURRENT_CONTEXT(ctx); @@ -4225,35 +4227,13 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, return; } - if (_mesa_is_enum_format_integer(internalformat)) { - if (samples > ctx->Const.MaxIntegerSamples) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexImage%uDMultisample(samples>GL_MAX_INTEGER_SAMPLES)", - dims); - return; - } - } - else if (_mesa_is_depth_or_stencil_format(internalformat)) { - if (samples > ctx->Const.MaxDepthTextureSamples) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexImage%uDMultisample(samples>GL_MAX_DEPTH_TEXTURE_SAMPLES)", - dims); - return; - } - } - else { - if (samples > ctx->Const.MaxColorTextureSamples) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexImage%uDMultisample(samples>GL_MAX_COLOR_TEXTURE_SAMPLES)", - dims); - return; - } + sample_count_error = _mesa_check_sample_count(ctx, target, + internalformat, samples); + if (sample_count_error != GL_NO_ERROR) { + _mesa_error(ctx, sample_count_error, "glTexImage%uDMultisample(samples)", dims); + return; } - /* TODO: should ask the driver for the exact limit for this internalformat - * once IDR's internalformat_query bits land - */ - texObj = _mesa_get_current_tex_object(ctx, target); texImage = _mesa_get_tex_image(ctx, texObj, 0, 0); diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c index 120845b4a..bd2f75170 100644 --- a/mesalib/src/mesa/main/texparam.c +++ b/mesalib/src/mesa/main/texparam.c @@ -1460,6 +1460,12 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) *params = (GLfloat) obj->Immutable; break; + case GL_TEXTURE_IMMUTABLE_LEVELS: + if (!_mesa_is_gles3(ctx)) + goto invalid_pname; + *params = (GLfloat) obj->ImmutableLevels; + break; + case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external) goto invalid_pname; @@ -1637,6 +1643,12 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) *params = (GLint) obj->Immutable; break; + case GL_TEXTURE_IMMUTABLE_LEVELS: + if (!_mesa_is_gles3(ctx)) + goto invalid_pname; + *params = obj->ImmutableLevels; + break; + case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external) goto invalid_pname; diff --git a/mesalib/src/mesa/main/texstorage.c b/mesalib/src/mesa/main/texstorage.c index 00f19bae5..675fd745b 100644 --- a/mesalib/src/mesa/main/texstorage.c +++ b/mesalib/src/mesa/main/texstorage.c @@ -397,6 +397,7 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, } texObj->Immutable = GL_TRUE; + texObj->ImmutableLevels = levels; } } |