aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa')
-rw-r--r--mesalib/src/mesa/drivers/common/driverfuncs.c1
-rw-r--r--mesalib/src/mesa/drivers/common/meta.c197
-rw-r--r--mesalib/src/mesa/drivers/common/meta.h11
-rw-r--r--mesalib/src/mesa/main/config.h11
-rw-r--r--mesalib/src/mesa/main/dd.h14
-rw-r--r--mesalib/src/mesa/main/extensions.c1
-rw-r--r--mesalib/src/mesa/main/get_hash_params.py7
-rw-r--r--mesalib/src/mesa/main/imports.h6
-rw-r--r--mesalib/src/mesa/main/mtypes.h1
-rw-r--r--mesalib/src/mesa/main/teximage.c321
-rw-r--r--mesalib/src/mesa/main/teximage.h10
-rw-r--r--mesalib/src/mesa/main/texstore.c87
-rw-r--r--mesalib/src/mesa/main/texstore.h7
-rw-r--r--mesalib/src/mesa/main/uniform_query.cpp2
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp12
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()");