diff options
Diffstat (limited to 'mesalib/src/mesa')
-rw-r--r-- | mesalib/src/mesa/drivers/common/driverfuncs.c | 1 | ||||
-rw-r--r-- | mesalib/src/mesa/drivers/common/meta.c | 197 | ||||
-rw-r--r-- | mesalib/src/mesa/drivers/common/meta.h | 11 | ||||
-rw-r--r-- | mesalib/src/mesa/main/config.h | 11 | ||||
-rw-r--r-- | mesalib/src/mesa/main/dd.h | 14 | ||||
-rw-r--r-- | mesalib/src/mesa/main/extensions.c | 1 | ||||
-rw-r--r-- | mesalib/src/mesa/main/get_hash_params.py | 7 | ||||
-rw-r--r-- | mesalib/src/mesa/main/imports.h | 6 | ||||
-rw-r--r-- | mesalib/src/mesa/main/mtypes.h | 1 | ||||
-rw-r--r-- | mesalib/src/mesa/main/teximage.c | 321 | ||||
-rw-r--r-- | mesalib/src/mesa/main/teximage.h | 10 | ||||
-rw-r--r-- | mesalib/src/mesa/main/texstore.c | 87 | ||||
-rw-r--r-- | mesalib/src/mesa/main/texstore.h | 7 | ||||
-rw-r--r-- | mesalib/src/mesa/main/uniform_query.cpp | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 12 |
15 files changed, 661 insertions, 27 deletions
diff --git a/mesalib/src/mesa/drivers/common/driverfuncs.c b/mesalib/src/mesa/drivers/common/driverfuncs.c index 6ece5d80e..4f0f7a686 100644 --- a/mesalib/src/mesa/drivers/common/driverfuncs.c +++ b/mesalib/src/mesa/drivers/common/driverfuncs.c @@ -95,6 +95,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver) driver->TexImage = _mesa_store_teximage; driver->TexSubImage = _mesa_store_texsubimage; driver->GetTexImage = _mesa_meta_GetTexImage; + driver->ClearTexSubImage = _mesa_meta_ClearTexSubImage; driver->CopyTexSubImage = _mesa_meta_CopyTexSubImage; driver->GenerateMipmap = _mesa_meta_GenerateMipmap; driver->TestProxyTexImage = _mesa_test_proxy_teximage; diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index 89d7a157c..b12898f26 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -40,6 +40,7 @@ #include "main/blit.h" #include "main/bufferobj.h" #include "main/buffers.h" +#include "main/clear.h" #include "main/colortab.h" #include "main/condrender.h" #include "main/depth.h" @@ -47,6 +48,7 @@ #include "main/fbobject.h" #include "main/feedback.h" #include "main/formats.h" +#include "main/format_unpack.h" #include "main/glformats.h" #include "main/image.h" #include "main/macros.h" @@ -71,6 +73,7 @@ #include "main/teximage.h" #include "main/texparam.h" #include "main/texstate.h" +#include "main/texstore.h" #include "main/transformfeedback.h" #include "main/uniforms.h" #include "main/varray.h" @@ -505,6 +508,11 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state) _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE); } + if (state & MESA_META_DITHER) { + save->DitherFlag = ctx->Color.DitherFlag; + _mesa_set_enable(ctx, GL_DITHER, GL_TRUE); + } + if (state & MESA_META_COLOR_MASK) { memcpy(save->ColorMask, ctx->Color.ColorMask, sizeof(ctx->Color.ColorMask)); @@ -875,6 +883,9 @@ _mesa_meta_end(struct gl_context *ctx) _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled); } + if (state & MESA_META_DITHER) + _mesa_set_enable(ctx, GL_DITHER, save->DitherFlag); + if (state & MESA_META_COLOR_MASK) { GLuint i; for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { @@ -3339,3 +3350,189 @@ _mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, _mesa_meta_end(ctx); } + +static bool +cleartexsubimage_color(struct gl_context *ctx, + struct gl_texture_image *texImage, + const GLvoid *clearValue, + GLint zoffset) +{ + mesa_format format; + union gl_color_union colorValue; + GLenum datatype; + GLenum status; + + _mesa_meta_bind_fbo_image(GL_COLOR_ATTACHMENT0, texImage, zoffset); + + status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + return false; + + /* We don't want to apply an sRGB conversion so override the format */ + format = _mesa_get_srgb_format_linear(texImage->TexFormat); + datatype = _mesa_get_format_datatype(format); + + switch (datatype) { + case GL_UNSIGNED_INT: + case GL_INT: + if (clearValue) + _mesa_unpack_uint_rgba_row(format, 1, clearValue, + (GLuint (*)[4]) colorValue.ui); + else + memset(&colorValue, 0, sizeof colorValue); + if (datatype == GL_INT) + _mesa_ClearBufferiv(GL_COLOR, 0, colorValue.i); + else + _mesa_ClearBufferuiv(GL_COLOR, 0, colorValue.ui); + break; + default: + if (clearValue) + _mesa_unpack_rgba_row(format, 1, clearValue, + (GLfloat (*)[4]) colorValue.f); + else + memset(&colorValue, 0, sizeof colorValue); + _mesa_ClearBufferfv(GL_COLOR, 0, colorValue.f); + break; + } + + return true; +} + +static bool +cleartexsubimage_depth_stencil(struct gl_context *ctx, + struct gl_texture_image *texImage, + const GLvoid *clearValue, + GLint zoffset) +{ + GLint stencilValue; + GLfloat depthValue; + GLenum status; + + _mesa_meta_bind_fbo_image(GL_DEPTH_ATTACHMENT, texImage, zoffset); + + if (texImage->_BaseFormat == GL_DEPTH_STENCIL) + _mesa_meta_bind_fbo_image(GL_STENCIL_ATTACHMENT, texImage, zoffset); + + status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + return false; + + if (clearValue) { + GLuint depthStencilValue[2]; + + /* Convert the clearValue from whatever format it's in to a floating + * point value for the depth and an integer value for the stencil index + */ + _mesa_unpack_float_32_uint_24_8_depth_stencil_row(texImage->TexFormat, + 1, /* n */ + clearValue, + depthStencilValue); + /* We need a memcpy here instead of a cast because we need to + * reinterpret the bytes as a float rather than converting it + */ + memcpy(&depthValue, depthStencilValue, sizeof depthValue); + stencilValue = depthStencilValue[1] & 0xff; + } else { + depthValue = 0.0f; + stencilValue = 0; + } + + if (texImage->_BaseFormat == GL_DEPTH_STENCIL) + _mesa_ClearBufferfi(GL_DEPTH_STENCIL, 0, depthValue, stencilValue); + else + _mesa_ClearBufferfv(GL_DEPTH, 0, &depthValue); + + return true; +} + +static bool +cleartexsubimage_for_zoffset(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLint zoffset, + const GLvoid *clearValue) +{ + GLuint fbo; + bool success; + + _mesa_GenFramebuffers(1, &fbo); + _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); + + switch(texImage->_BaseFormat) { + case GL_DEPTH_STENCIL: + case GL_DEPTH_COMPONENT: + success = cleartexsubimage_depth_stencil(ctx, texImage, + clearValue, zoffset); + break; + default: + success = cleartexsubimage_color(ctx, texImage, clearValue, zoffset); + break; + } + + _mesa_DeleteFramebuffers(1, &fbo); + + return success; +} + +static bool +cleartexsubimage_using_fbo(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + const GLvoid *clearValue) +{ + bool success = true; + GLint z; + + _mesa_meta_begin(ctx, + MESA_META_SCISSOR | + MESA_META_COLOR_MASK | + MESA_META_DITHER | + MESA_META_FRAMEBUFFER_SRGB); + + _mesa_set_enable(ctx, GL_DITHER, GL_FALSE); + + _mesa_set_enable(ctx, GL_SCISSOR_TEST, GL_TRUE); + _mesa_Scissor(xoffset, yoffset, width, height); + + for (z = zoffset; z < zoffset + depth; z++) { + if (!cleartexsubimage_for_zoffset(ctx, texImage, z, clearValue)) { + success = false; + break; + } + } + + _mesa_meta_end(ctx); + + return success; +} + +extern void +_mesa_meta_ClearTexSubImage(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + const GLvoid *clearValue) +{ + bool res; + + _mesa_unlock_texture(ctx, texImage->TexObject); + + res = cleartexsubimage_using_fbo(ctx, texImage, + xoffset, yoffset, zoffset, + width, height, depth, + clearValue); + + _mesa_lock_texture(ctx, texImage->TexObject); + + if (res) + return; + + _mesa_warning(ctx, + "Falling back to mapping the texture in " + "glClearTexSubImage\n"); + + _mesa_store_cleartexsubimage(ctx, texImage, + xoffset, yoffset, zoffset, + width, height, depth, + clearValue); +} diff --git a/mesalib/src/mesa/drivers/common/meta.h b/mesalib/src/mesa/drivers/common/meta.h index 765f8dfe4..b269dceed 100644 --- a/mesalib/src/mesa/drivers/common/meta.h +++ b/mesalib/src/mesa/drivers/common/meta.h @@ -59,6 +59,7 @@ #define MESA_META_FRAMEBUFFER_SRGB 0x200000 #define MESA_META_OCCLUSION_QUERY 0x400000 #define MESA_META_DRAW_BUFFERS 0x800000 +#define MESA_META_DITHER 0x1000000 /**\}*/ /** @@ -84,6 +85,9 @@ struct save_state GLbitfield BlendEnabled; GLboolean ColorLogicOpEnabled; + /** MESA_META_DITHER */ + GLboolean DitherFlag; + /** MESA_META_COLOR_MASK */ GLubyte ColorMask[MAX_DRAW_BUFFERS][4]; @@ -473,6 +477,13 @@ _mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims, GLsizei width, GLsizei height); extern void +_mesa_meta_ClearTexSubImage(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + const GLvoid *clearValue); + +extern void _mesa_meta_GetTexImage(struct gl_context *ctx, GLenum format, GLenum type, GLvoid *pixels, struct gl_texture_image *texImage); diff --git a/mesalib/src/mesa/main/config.h b/mesalib/src/mesa/main/config.h index c96502a7f..4ec4b7502 100644 --- a/mesalib/src/mesa/main/config.h +++ b/mesalib/src/mesa/main/config.h @@ -289,6 +289,17 @@ #define PERFQUERY_HAVE_GPA_EXTENDED_COUNTERS 0 /*@}*/ +/** For GL_ARB_compute_shader */ +/*@{*/ +#define MAX_COMPUTE_UNIFORM_BLOCKS 12 +#define MAX_COMPUTE_TEXTURE_IMAGE_UNITS 16 +#define MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 8 +#define MAX_COMPUTE_ATOMIC_COUNTERS 8 +#define MAX_COMPUTE_SHARED_MEMORY_SIZE 32768 +#define MAX_COMPUTE_UNIFORM_COMPONENTS 512 +#define MAX_COMPUTE_IMAGE_UNIFORMS 8 +/*@}*/ + /* * Color channel component order * diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h index 633ea2c3a..89765351e 100644 --- a/mesalib/src/mesa/main/dd.h +++ b/mesalib/src/mesa/main/dd.h @@ -239,6 +239,20 @@ struct dd_function_table { struct gl_texture_image *texImage ); /** + * Called by glClearTex[Sub]Image + * + * Clears a rectangular region of the image to a given value. The + * clearValue argument is either NULL or points to a single texel to use as + * the clear value in the same internal format as the texture image. If it + * is NULL then the texture should be cleared to zeroes. + */ + void (*ClearTexSubImage)(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + const GLvoid *clearValue); + + /** * Called by glCopyTex[Sub]Image[123]D(). * * This function should copy a rectangular region in the rb to a single diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index 92e3f0d68..9ac8377a4 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -90,6 +90,7 @@ static const struct extension extension_table[] = { { "GL_ARB_blend_func_extended", o(ARB_blend_func_extended), GL, 2009 }, { "GL_ARB_buffer_storage", o(ARB_buffer_storage), GL, 2013 }, { "GL_ARB_clear_buffer_object", o(dummy_true), GL, 2012 }, + { "GL_ARB_clear_texture", o(ARB_clear_texture), GL, 2013 }, { "GL_ARB_color_buffer_float", o(ARB_color_buffer_float), GL, 2004 }, { "GL_ARB_compressed_texture_pixel_storage", o(dummy_true), GL, 2011 }, { "GL_ARB_compute_shader", o(ARB_compute_shader), GL, 2012 }, diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py index d45962d95..35d6172a3 100644 --- a/mesalib/src/mesa/main/get_hash_params.py +++ b/mesalib/src/mesa/main/get_hash_params.py @@ -774,6 +774,13 @@ descriptor=[ # GL_ARB_compute_shader [ "MAX_COMPUTE_WORK_GROUP_INVOCATIONS", "CONTEXT_INT(Const.MaxComputeWorkGroupInvocations), extra_ARB_compute_shader" ], + [ "MAX_COMPUTE_UNIFORM_BLOCKS", "CONST(MAX_COMPUTE_UNIFORM_BLOCKS), extra_ARB_compute_shader" ], + [ "MAX_COMPUTE_TEXTURE_IMAGE_UNITS", "CONST(MAX_COMPUTE_TEXTURE_IMAGE_UNITS), extra_ARB_compute_shader" ], + [ "MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS", "CONST(MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS), extra_ARB_compute_shader" ], + [ "MAX_COMPUTE_ATOMIC_COUNTERS", "CONST(MAX_COMPUTE_ATOMIC_COUNTERS), extra_ARB_compute_shader" ], + [ "MAX_COMPUTE_SHARED_MEMORY_SIZE", "CONST(MAX_COMPUTE_SHARED_MEMORY_SIZE), extra_ARB_compute_shader" ], + [ "MAX_COMPUTE_UNIFORM_COMPONENTS", "CONST(MAX_COMPUTE_UNIFORM_COMPONENTS), extra_ARB_compute_shader" ], + [ "MAX_COMPUTE_IMAGE_UNIFORMS", "CONST(MAX_COMPUTE_IMAGE_UNIFORMS), extra_ARB_compute_shader" ], # GL_ARB_gpu_shader5 [ "MAX_GEOMETRY_SHADER_INVOCATIONS", "CONST(MAX_GEOMETRY_SHADER_INVOCATIONS), extra_ARB_gpu_shader5" ], diff --git a/mesalib/src/mesa/main/imports.h b/mesalib/src/mesa/main/imports.h index af780b249..09e55ebf0 100644 --- a/mesalib/src/mesa/main/imports.h +++ b/mesalib/src/mesa/main/imports.h @@ -274,10 +274,12 @@ static inline int IROUND_POS(float f) return (int) (f + 0.5F); } +#ifdef __x86_64__ +# include <xmmintrin.h> +#endif /** * Convert float to int using a fast method. The rounding mode may vary. - * XXX We could use an x86-64/SSE2 version here. */ static inline int F_TO_I(float f) { @@ -292,6 +294,8 @@ static inline int F_TO_I(float f) fistp r } return r; +#elif defined(__x86_64__) + return _mm_cvt_ss2si(_mm_load_ss(&f)); #else return IROUND(f); #endif diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 91d9172f9..3f60a5530 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -3527,6 +3527,7 @@ struct gl_extensions GLboolean ARB_base_instance; GLboolean ARB_blend_func_extended; GLboolean ARB_buffer_storage; + GLboolean ARB_clear_texture; GLboolean ARB_color_buffer_float; GLboolean ARB_compute_shader; GLboolean ARB_conservative_depth; diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index a06959463..fb2dee7d8 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -51,6 +51,7 @@ #include "textureview.h" #include "mtypes.h" #include "glformats.h" +#include "texstore.h" /** @@ -2010,6 +2011,43 @@ _mesa_legal_texture_base_format_for_target(struct gl_context *ctx, return true; } +static bool +texture_formats_agree(GLenum internalFormat, + GLenum format) +{ + GLboolean colorFormat; + GLboolean is_format_depth_or_depthstencil; + GLboolean is_internalFormat_depth_or_depthstencil; + + /* Even though there are no color-index textures, we still have to support + * uploading color-index data and remapping it to RGB via the + * GL_PIXEL_MAP_I_TO_[RGBA] tables. + */ + const GLboolean indexFormat = (format == GL_COLOR_INDEX); + + is_internalFormat_depth_or_depthstencil = + _mesa_is_depth_format(internalFormat) || + _mesa_is_depthstencil_format(internalFormat); + + is_format_depth_or_depthstencil = + _mesa_is_depth_format(format) || + _mesa_is_depthstencil_format(format); + + colorFormat = _mesa_is_color_format(format); + + if (_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) + return false; + + if (is_internalFormat_depth_or_depthstencil != + is_format_depth_or_depthstencil) + return false; + + if (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) + return false; + + return true; +} + /** * Test the glTexImage[123]D() parameters for errors. * @@ -2043,17 +2081,8 @@ texture_error_check( struct gl_context *ctx, GLint width, GLint height, GLint depth, GLint border ) { - GLboolean colorFormat; - GLboolean is_format_depth_or_depthstencil; - GLboolean is_internalFormat_depth_or_depthstencil; GLenum err; - /* Even though there are no color-index textures, we still have to support - * uploading color-index data and remapping it to RGB via the - * GL_PIXEL_MAP_I_TO_[RGBA] tables. - */ - const GLboolean indexFormat = (format == GL_COLOR_INDEX); - /* Note: for proxy textures, some error conditions immediately generate * a GL error in the usual way. But others do not generate a GL error. * Instead, they cause the width, height, depth, format fields of the @@ -2136,18 +2165,7 @@ texture_error_check( struct gl_context *ctx, } /* make sure internal format and format basically agree */ - is_internalFormat_depth_or_depthstencil = - _mesa_is_depth_format(internalFormat) || - _mesa_is_depthstencil_format(internalFormat); - - is_format_depth_or_depthstencil = - _mesa_is_depth_format(format) || - _mesa_is_depthstencil_format(format); - - colorFormat = _mesa_is_color_format(format); - if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) || - (is_internalFormat_depth_or_depthstencil != is_format_depth_or_depthstencil) || - (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format))) { + if (!texture_formats_agree(internalFormat, format)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexImage%dD(incompatible internalFormat = %s, format = %s)", dimensions, _mesa_lookup_enum_by_nr(internalFormat), @@ -3818,6 +3836,266 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, x, y, width, height); } +static bool +check_clear_tex_image(struct gl_context *ctx, + const char *function, + struct gl_texture_image *texImage, + GLenum format, GLenum type, + const void *data, + GLubyte *clearValue) +{ + struct gl_texture_object *texObj = texImage->TexObject; + static const GLubyte zeroData[MAX_PIXEL_BYTES]; + GLenum internalFormat = texImage->InternalFormat; + GLenum err; + + if (texObj->Target == GL_TEXTURE_BUFFER) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(buffer texture)", function); + return false; + } + + if (_mesa_is_compressed_format(ctx, internalFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(compressed texture)", function); + return false; + } + + err = _mesa_error_check_format_and_type(ctx, format, type); + if (err != GL_NO_ERROR) { + _mesa_error(ctx, err, + "%s(incompatible format = %s, type = %s)", + function, + _mesa_lookup_enum_by_nr(format), + _mesa_lookup_enum_by_nr(type)); + return false; + } + + /* make sure internal format and format basically agree */ + if (!texture_formats_agree(internalFormat, format)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(incompatible internalFormat = %s, format = %s)", + function, + _mesa_lookup_enum_by_nr(internalFormat), + _mesa_lookup_enum_by_nr(format)); + return false; + } + + if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) { + /* both source and dest must be integer-valued, or neither */ + if (_mesa_is_format_integer_color(texImage->TexFormat) != + _mesa_is_enum_format_integer(format)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(integer/non-integer format mismatch)", + function); + return false; + } + } + + if (!_mesa_texstore(ctx, + 1, /* dims */ + texImage->_BaseFormat, + texImage->TexFormat, + 0, /* dstRowStride */ + &clearValue, + 1, 1, 1, /* srcWidth/Height/Depth */ + format, type, + data ? data : zeroData, + &ctx->DefaultPacking)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid format)", function); + return false; + } + + return true; +} + +static struct gl_texture_object * +get_tex_obj_for_clear(struct gl_context *ctx, + const char *function, + GLuint texture) +{ + struct gl_texture_object *texObj; + + if (texture == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(zero texture)", function); + return NULL; + } + + texObj = _mesa_lookup_texture(ctx, texture); + + if (texObj == NULL) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", function); + return NULL; + } + + if (texObj->Target == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unbound tex)", function); + return NULL; + } + + return texObj; +} + +static int +get_tex_images_for_clear(struct gl_context *ctx, + const char *function, + struct gl_texture_object *texObj, + GLint level, + struct gl_texture_image **texImages) +{ + GLenum target; + int i; + + if (level < 0 || level >= MAX_TEXTURE_LEVELS) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function); + return 0; + } + + if (texObj->Target == GL_TEXTURE_CUBE_MAP) { + for (i = 0; i < MAX_FACES; i++) { + target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i; + + texImages[i] = _mesa_select_tex_image(ctx, texObj, target, level); + if (texImages[i] == NULL) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(invalid level)", function); + return 0; + } + } + + return MAX_FACES; + } + + texImages[0] = _mesa_select_tex_image(ctx, texObj, texObj->Target, level); + + if (texImages[0] == NULL) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function); + return 0; + } + + return 1; +} + +void GLAPIENTRY +_mesa_ClearTexSubImage( GLuint texture, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const void *data ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_object *texObj; + struct gl_texture_image *texImages[MAX_FACES]; + GLubyte clearValue[MAX_FACES][MAX_PIXEL_BYTES]; + int i, numImages; + int minDepth, maxDepth; + + texObj = get_tex_obj_for_clear(ctx, "glClearTexSubImage", texture); + + if (texObj == NULL) + return; + + _mesa_lock_texture(ctx, texObj); + + numImages = get_tex_images_for_clear(ctx, "glClearTexSubImage", + texObj, level, texImages); + if (numImages == 0) + goto out; + + if (numImages == 1) { + minDepth = -(int) texImages[0]->Border; + maxDepth = texImages[0]->Depth; + } else { + minDepth = 0; + maxDepth = numImages; + } + + if (xoffset < -(GLint) texImages[0]->Border || + yoffset < -(GLint) texImages[0]->Border || + zoffset < minDepth || + width < 0 || + height < 0 || + depth < 0 || + xoffset + width > texImages[0]->Width || + yoffset + height > texImages[0]->Height || + zoffset + depth > maxDepth) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glClearSubTexImage(invalid dimensions)"); + goto out; + } + + if (numImages == 1) { + if (check_clear_tex_image(ctx, "glClearTexSubImage", + texImages[0], + format, type, data, clearValue[0])) { + ctx->Driver.ClearTexSubImage(ctx, + texImages[0], + xoffset, yoffset, zoffset, + width, height, depth, + data ? clearValue[0] : NULL); + } + } else { + for (i = zoffset; i < zoffset + depth; i++) { + if (!check_clear_tex_image(ctx, "glClearTexSubImage", + texImages[i], + format, type, data, clearValue[i])) + goto out; + } + for (i = zoffset; i < zoffset + depth; i++) { + ctx->Driver.ClearTexSubImage(ctx, + texImages[i], + xoffset, yoffset, 0, + width, height, 1, + data ? clearValue[i] : NULL); + } + } + + out: + _mesa_unlock_texture(ctx, texObj); +} + +void GLAPIENTRY +_mesa_ClearTexImage( GLuint texture, GLint level, + GLenum format, GLenum type, const void *data ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_object *texObj; + struct gl_texture_image *texImages[MAX_FACES]; + GLubyte clearValue[MAX_FACES][MAX_PIXEL_BYTES]; + int i, numImages; + + texObj = get_tex_obj_for_clear(ctx, "glClearTexImage", texture); + + if (texObj == NULL) + return; + + _mesa_lock_texture(ctx, texObj); + + numImages = get_tex_images_for_clear(ctx, "glClearTexImage", + texObj, level, texImages); + + for (i = 0; i < numImages; i++) { + if (!check_clear_tex_image(ctx, "glClearTexImage", + texImages[i], + format, type, data, + clearValue[i])) + goto out; + } + + for (i = 0; i < numImages; i++) { + ctx->Driver.ClearTexSubImage(ctx, texImages[i], + -(GLint) texImages[i]->Border, /* xoffset */ + -(GLint) texImages[i]->Border, /* yoffset */ + -(GLint) texImages[i]->Border, /* zoffset */ + texImages[i]->Width, + texImages[i]->Height, + texImages[i]->Depth, + data ? clearValue[i] : NULL); + } + +out: + _mesa_unlock_texture(ctx, texObj); +} + @@ -4578,7 +4856,6 @@ _mesa_TexStorage2DMultisample(GLenum target, GLsizei samples, "glTexStorage2DMultisample"); } - void GLAPIENTRY _mesa_TexStorage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h index dd1504b40..42305f44f 100644 --- a/mesalib/src/mesa/main/teximage.h +++ b/mesalib/src/mesa/main/teximage.h @@ -261,6 +261,16 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, extern void GLAPIENTRY +_mesa_ClearTexSubImage( GLuint texture, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const void *data ); + +extern void GLAPIENTRY +_mesa_ClearTexImage( GLuint texture, GLint level, + GLenum format, GLenum type, const void *data ); + +extern void GLAPIENTRY _mesa_CompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index d363f9faa..aea53f8d1 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -3830,6 +3830,21 @@ _mesa_texstore_can_use_memcpy(struct gl_context *ctx, return GL_FALSE; } + /* Depth texture data needs clamping in following cases: + * - Floating point dstFormat with signed srcType: clamp to [0.0, 1.0]. + * - Fixed point dstFormat with signed srcType: clamp to [0, 2^n -1]. + * + * All the cases except one (float dstFormat with float srcType) are ruled + * out by _mesa_format_matches_format_and_type() check above. Handle the + * remaining case here. + */ + if ((baseInternalFormat == GL_DEPTH_COMPONENT || + baseInternalFormat == GL_DEPTH_STENCIL) && + (srcType == GL_FLOAT || + srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV)) { + return GL_FALSE; + } + return GL_TRUE; } @@ -4079,6 +4094,78 @@ _mesa_store_texsubimage(struct gl_context *ctx, GLuint dims, format, type, pixels, packing, "glTexSubImage"); } +static void +clear_image_to_zero(GLubyte *dstMap, GLint dstRowStride, + GLsizei width, GLsizei height, + GLsizei clearValueSize) +{ + GLsizei y; + + for (y = 0; y < height; y++) { + memset(dstMap, 0, clearValueSize * width); + dstMap += dstRowStride; + } +} + +static void +clear_image_to_value(GLubyte *dstMap, GLint dstRowStride, + GLsizei width, GLsizei height, + const GLvoid *clearValue, + GLsizei clearValueSize) +{ + GLsizei y, x; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + memcpy(dstMap, clearValue, clearValueSize); + dstMap += clearValueSize; + } + dstMap += dstRowStride - clearValueSize * width; + } +} + +/* + * Fallback for Driver.ClearTexSubImage(). + */ +void +_mesa_store_cleartexsubimage(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + const GLvoid *clearValue) +{ + GLubyte *dstMap; + GLint dstRowStride; + GLsizeiptr clearValueSize; + GLsizei z; + + clearValueSize = _mesa_get_format_bytes(texImage->TexFormat); + + for (z = 0; z < depth; z++) { + ctx->Driver.MapTextureImage(ctx, texImage, + z + zoffset, xoffset, yoffset, + width, height, + GL_MAP_WRITE_BIT, + &dstMap, &dstRowStride); + if (dstMap == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearTex*Image"); + return; + } + + if (clearValue) { + clear_image_to_value(dstMap, dstRowStride, + width, height, + clearValue, + clearValueSize); + } else { + clear_image_to_zero(dstMap, dstRowStride, + width, height, + clearValueSize); + } + + ctx->Driver.UnmapTextureImage(ctx, texImage, z + zoffset); + } +} /** * Fallback for Driver.CompressedTexImage() diff --git a/mesalib/src/mesa/main/texstore.h b/mesalib/src/mesa/main/texstore.h index c4cfffde6..dd1e1d015 100644 --- a/mesalib/src/mesa/main/texstore.h +++ b/mesalib/src/mesa/main/texstore.h @@ -118,6 +118,13 @@ _mesa_store_texsubimage(struct gl_context *ctx, GLuint dims, extern void +_mesa_store_cleartexsubimage(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + const GLvoid *clearValue); + +extern void _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage, GLsizei imageSize, const GLvoid *data); diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp index 480bc6f16..609d94bd7 100644 --- a/mesalib/src/mesa/main/uniform_query.cpp +++ b/mesalib/src/mesa/main/uniform_query.cpp @@ -91,7 +91,7 @@ _mesa_GetActiveUniformsiv(GLuint program, if (uniformCount < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "glGetUniformIndices(uniformCount < 0)"); + "glGetActiveUniformsiv(uniformCount < 0)"); return; } diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 5c51e63d9..5ea146547 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -2028,6 +2028,15 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) */ emit(ir, TGSI_OPCODE_MAD, result_dst, op[0], op[1], op[2]); break; + case ir_unop_interpolate_at_centroid: + emit(ir, TGSI_OPCODE_INTERP_CENTROID, result_dst, op[0]); + break; + case ir_binop_interpolate_at_offset: + emit(ir, TGSI_OPCODE_INTERP_OFFSET, result_dst, op[0], op[1]); + break; + case ir_binop_interpolate_at_sample: + emit(ir, TGSI_OPCODE_INTERP_SAMPLE, result_dst, op[0], op[1]); + break; case ir_unop_pack_snorm_2x16: case ir_unop_pack_unorm_2x16: case ir_unop_pack_half_2x16: @@ -2049,9 +2058,6 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) case ir_binop_ldexp: case ir_binop_carry: case ir_binop_borrow: - case ir_unop_interpolate_at_centroid: - case ir_binop_interpolate_at_offset: - case ir_binop_interpolate_at_sample: /* This operation is not supported, or should have already been handled. */ assert(!"Invalid ir opcode in glsl_to_tgsi_visitor::visit()"); |