summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/bufferobj.c4
-rw-r--r--src/mesa/main/context.c4
-rw-r--r--src/mesa/main/extensions.c8
-rw-r--r--src/mesa/main/fbobject.c10
-rw-r--r--src/mesa/main/format_info.py12
-rw-r--r--src/mesa/main/format_utils.c2
-rw-r--r--src/mesa/main/formats.c258
-rw-r--r--src/mesa/main/formats.h10
-rw-r--r--src/mesa/main/get_hash_params.py2
-rw-r--r--src/mesa/main/mipmap.c2
-rw-r--r--src/mesa/main/mtypes.h17
-rw-r--r--src/mesa/main/multisample.c9
-rw-r--r--src/mesa/main/readpix.c2
-rw-r--r--src/mesa/main/shaderapi.c100
-rw-r--r--src/mesa/main/shaderimage.c150
-rw-r--r--src/mesa/main/shaderimage.h9
-rw-r--r--src/mesa/main/tests/Makefile.am1
-rw-r--r--src/mesa/main/tests/dispatch_sanity.cpp9
-rw-r--r--src/mesa/main/tests/mesa_formats.cpp139
-rw-r--r--src/mesa/main/texcompress.c30
-rw-r--r--src/mesa/main/texgetimage.c2
-rw-r--r--src/mesa/main/teximage.c190
-rw-r--r--src/mesa/main/teximage.h2
-rw-r--r--src/mesa/main/texobj.c15
-rw-r--r--src/mesa/main/texobj.h4
-rw-r--r--src/mesa/main/texparam.c38
-rw-r--r--src/mesa/main/texstorage.c37
-rw-r--r--src/mesa/main/texstorage.h21
-rw-r--r--src/mesa/main/texstore.c2
-rw-r--r--src/mesa/main/uniform_query.cpp25
-rw-r--r--src/mesa/main/uniforms.c9
31 files changed, 657 insertions, 466 deletions
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index 1cdea93..e17b41c 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -866,8 +866,8 @@ _mesa_init_buffer_objects( struct gl_context *ctx )
_mesa_reference_buffer_object(ctx,
&ctx->AtomicBufferBindings[i].BufferObject,
ctx->Shared->NullBufferObj);
- ctx->AtomicBufferBindings[i].Offset = -1;
- ctx->AtomicBufferBindings[i].Size = -1;
+ ctx->AtomicBufferBindings[i].Offset = 0;
+ ctx->AtomicBufferBindings[i].Size = 0;
}
}
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 888c461..be542dd 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -402,10 +402,6 @@ one_time_init( struct gl_context *ctx )
PACKAGE_VERSION, __DATE__, __TIME__);
}
#endif
-
-#ifdef DEBUG
- _mesa_test_formats();
-#endif
}
/* per-API one-time init */
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index d934d19..4a3c231 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -50,6 +50,7 @@ enum {
ES1 = 1 << API_OPENGLES,
ES2 = 1 << API_OPENGLES2,
ES3 = 1 << (API_OPENGL_LAST + 1),
+ ES31 = 1 << (API_OPENGL_LAST + 2),
};
/**
@@ -152,6 +153,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_shader_atomic_counters", o(ARB_shader_atomic_counters), GL, 2011 },
{ "GL_ARB_shader_bit_encoding", o(ARB_shader_bit_encoding), GL, 2010 },
{ "GL_ARB_shader_image_load_store", o(ARB_shader_image_load_store), GL, 2011 },
+ { "GL_ARB_shader_image_size", o(ARB_shader_image_size), GL, 2012 },
{ "GL_ARB_shader_objects", o(dummy_true), GL, 2002 },
{ "GL_ARB_shader_precision", o(ARB_shader_precision), GL, 2010 },
{ "GL_ARB_shader_stencil_export", o(ARB_shader_stencil_export), GL, 2009 },
@@ -773,6 +775,8 @@ _mesa_make_extension_string(struct gl_context *ctx)
unsigned api_set = (1 << ctx->API);
if (_mesa_is_gles3(ctx))
api_set |= ES3;
+ if (_mesa_is_gles31(ctx))
+ api_set |= ES31;
/* Check if the MESA_EXTENSION_MAX_YEAR env var is set */
{
@@ -854,6 +858,8 @@ _mesa_get_extension_count(struct gl_context *ctx)
unsigned api_set = (1 << ctx->API);
if (_mesa_is_gles3(ctx))
api_set |= ES3;
+ if (_mesa_is_gles31(ctx))
+ api_set |= ES31;
/* only count once */
if (ctx->Extensions.Count != 0)
@@ -880,6 +886,8 @@ _mesa_get_enabled_extension(struct gl_context *ctx, GLuint index)
unsigned api_set = (1 << ctx->API);
if (_mesa_is_gles3(ctx))
api_set |= ES3;
+ if (_mesa_is_gles31(ctx))
+ api_set |= ES31;
base = (GLboolean*) &ctx->Extensions;
n = 0;
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 8418340..07db195 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -2033,6 +2033,16 @@ renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
*/
sample_count_error = _mesa_check_sample_count(ctx, GL_RENDERBUFFER,
internalFormat, samples);
+
+ /* Section 2.5 (GL Errors) of OpenGL 3.0 specification, page 16:
+ *
+ * "If a negative number is provided where an argument of type sizei or
+ * sizeiptr is specified, the error INVALID VALUE is generated."
+ */
+ if (samples < 0) {
+ sample_count_error = GL_INVALID_VALUE;
+ }
+
if (sample_count_error != GL_NO_ERROR) {
_mesa_error(ctx, sample_count_error, "%s(samples)", func);
return;
diff --git a/src/mesa/main/format_info.py b/src/mesa/main/format_info.py
index 3bae57e..839d407 100644
--- a/src/mesa/main/format_info.py
+++ b/src/mesa/main/format_info.py
@@ -98,14 +98,6 @@ def get_gl_data_type(fmat):
else:
assert False
-def get_mesa_layout(fmat):
- if fmat.layout == 'array':
- return 'MESA_FORMAT_LAYOUT_ARRAY'
- elif fmat.layout == 'packed':
- return 'MESA_FORMAT_LAYOUT_PACKED'
- else:
- return 'MESA_FORMAT_LAYOUT_OTHER'
-
def get_channel_bits(fmat, chan_name):
if fmat.is_compressed():
# These values are pretty-much bogus, but OpenGL requires that we
@@ -179,7 +171,7 @@ for fmat in formats:
print ' {'
print ' {0},'.format(fmat.name)
print ' "{0}",'.format(fmat.name)
- print ' {0},'.format(get_mesa_layout(fmat))
+ print ' {0},'.format('MESA_FORMAT_LAYOUT_' + fmat.layout.upper())
print ' {0},'.format(get_gl_base_format(fmat))
print ' {0},'.format(get_gl_data_type(fmat))
@@ -188,6 +180,8 @@ for fmat in formats:
bits = [ get_channel_bits(fmat, name) for name in ['l', 'i', 'z', 's']]
print ' {0},'.format(', '.join(map(str, bits)))
+ print ' {0:d},'.format(fmat.colorspace == 'srgb')
+
print ' {0}, {1}, {2},'.format(fmat.block_width, fmat.block_height,
int(fmat.block_size() / 8))
diff --git a/src/mesa/main/format_utils.c b/src/mesa/main/format_utils.c
index 810bb16..5fdabd5 100644
--- a/src/mesa/main/format_utils.c
+++ b/src/mesa/main/format_utils.c
@@ -602,7 +602,7 @@ _mesa_format_to_array(mesa_format format, GLenum *type, int *num_components,
*normalized = !_mesa_is_format_integer(format);
- _mesa_format_to_type_and_comps(format, type, &format_components);
+ _mesa_uncompressed_format_to_type_and_comps(format, type, &format_components);
switch (_mesa_get_format_layout(format)) {
case MESA_FORMAT_LAYOUT_ARRAY:
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
index d7b2bae..8dd07d8 100644
--- a/src/mesa/main/formats.c
+++ b/src/mesa/main/formats.c
@@ -65,6 +65,8 @@ struct gl_format_info
GLubyte DepthBits;
GLubyte StencilBits;
+ bool IsSRGBFormat;
+
/**
* To describe compressed formats. If not compressed, Width=Height=1.
*/
@@ -81,6 +83,7 @@ static const struct gl_format_info *
_mesa_get_format_info(mesa_format format)
{
const struct gl_format_info *info = &format_info[format];
+ STATIC_ASSERT(ARRAY_SIZE(format_info) == MESA_FORMAT_COUNT);
assert(info->Name == format);
return info;
}
@@ -188,6 +191,12 @@ _mesa_get_format_max_bits(mesa_format format)
* The return value will be one of:
* MESA_FORMAT_LAYOUT_ARRAY
* MESA_FORMAT_LAYOUT_PACKED
+ * MESA_FORMAT_LAYOUT_S3TC
+ * MESA_FORMAT_LAYOUT_RGTC
+ * MESA_FORMAT_LAYOUT_FXT1
+ * MESA_FORMAT_LAYOUT_ETC1
+ * MESA_FORMAT_LAYOUT_ETC2
+ * MESA_FORMAT_LAYOUT_BPTC
* MESA_FORMAT_LAYOUT_OTHER
*/
extern enum mesa_format_layout
@@ -562,30 +571,8 @@ _mesa_is_format_color_format(mesa_format format)
GLenum
_mesa_get_format_color_encoding(mesa_format format)
{
- /* XXX this info should be encoded in gl_format_info */
- switch (format) {
- case MESA_FORMAT_BGR_SRGB8:
- case MESA_FORMAT_A8B8G8R8_SRGB:
- case MESA_FORMAT_B8G8R8A8_SRGB:
- case MESA_FORMAT_A8R8G8B8_SRGB:
- case MESA_FORMAT_R8G8B8A8_SRGB:
- case MESA_FORMAT_L_SRGB8:
- case MESA_FORMAT_L8A8_SRGB:
- case MESA_FORMAT_A8L8_SRGB:
- case MESA_FORMAT_SRGB_DXT1:
- case MESA_FORMAT_SRGBA_DXT1:
- case MESA_FORMAT_SRGBA_DXT3:
- case MESA_FORMAT_SRGBA_DXT5:
- case MESA_FORMAT_R8G8B8X8_SRGB:
- case MESA_FORMAT_ETC2_SRGB8:
- case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
- case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
- case MESA_FORMAT_B8G8R8X8_SRGB:
- case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM:
- return GL_SRGB;
- default:
- return GL_LINEAR;
- }
+ const struct gl_format_info *info = _mesa_get_format_info(format);
+ return info->IsSRGBFormat ? GL_SRGB : GL_LINEAR;
}
@@ -878,124 +865,13 @@ _mesa_format_row_stride(mesa_format format, GLsizei width)
}
-/**
- * Debug/test: check that all formats are handled in the
- * _mesa_format_to_type_and_comps() function. When new pixel formats
- * are added to Mesa, that function needs to be updated.
- * This is a no-op after the first call.
- */
-static void
-check_format_to_type_and_comps(void)
-{
- mesa_format f;
-
- for (f = MESA_FORMAT_NONE + 1; f < MESA_FORMAT_COUNT; f++) {
- GLenum datatype = 0;
- GLuint comps = 0;
- /* This function will emit a problem/warning if the format is
- * not handled.
- */
- _mesa_format_to_type_and_comps(f, &datatype, &comps);
- }
-}
/**
- * Do sanity checking of the format info table.
+ * Return datatype and number of components per texel for the given
+ * uncompressed mesa_format. Only used for mipmap generation code.
*/
void
-_mesa_test_formats(void)
-{
- GLuint i;
-
- STATIC_ASSERT(ARRAY_SIZE(format_info) == MESA_FORMAT_COUNT);
-
- for (i = 0; i < MESA_FORMAT_COUNT; i++) {
- const struct gl_format_info *info = _mesa_get_format_info(i);
- assert(info);
-
- assert(info->Name == i);
-
- if (info->Name == MESA_FORMAT_NONE)
- continue;
-
- if (info->BlockWidth == 1 && info->BlockHeight == 1) {
- if (info->RedBits > 0) {
- GLuint t = info->RedBits + info->GreenBits
- + info->BlueBits + info->AlphaBits;
- assert(t / 8 <= info->BytesPerBlock);
- (void) t;
- }
- }
-
- assert(info->DataType == GL_UNSIGNED_NORMALIZED ||
- info->DataType == GL_SIGNED_NORMALIZED ||
- info->DataType == GL_UNSIGNED_INT ||
- info->DataType == GL_INT ||
- info->DataType == GL_FLOAT ||
- /* Z32_FLOAT_X24S8 has DataType of GL_NONE */
- info->DataType == GL_NONE);
-
- if (info->BaseFormat == GL_RGB) {
- assert(info->RedBits > 0);
- assert(info->GreenBits > 0);
- assert(info->BlueBits > 0);
- assert(info->AlphaBits == 0);
- assert(info->LuminanceBits == 0);
- assert(info->IntensityBits == 0);
- }
- else if (info->BaseFormat == GL_RGBA) {
- assert(info->RedBits > 0);
- assert(info->GreenBits > 0);
- assert(info->BlueBits > 0);
- assert(info->AlphaBits > 0);
- assert(info->LuminanceBits == 0);
- assert(info->IntensityBits == 0);
- }
- else if (info->BaseFormat == GL_RG) {
- assert(info->RedBits > 0);
- assert(info->GreenBits > 0);
- assert(info->BlueBits == 0);
- assert(info->AlphaBits == 0);
- assert(info->LuminanceBits == 0);
- assert(info->IntensityBits == 0);
- }
- else if (info->BaseFormat == GL_RED) {
- assert(info->RedBits > 0);
- assert(info->GreenBits == 0);
- assert(info->BlueBits == 0);
- assert(info->AlphaBits == 0);
- assert(info->LuminanceBits == 0);
- assert(info->IntensityBits == 0);
- }
- else if (info->BaseFormat == GL_LUMINANCE) {
- assert(info->RedBits == 0);
- assert(info->GreenBits == 0);
- assert(info->BlueBits == 0);
- assert(info->AlphaBits == 0);
- assert(info->LuminanceBits > 0);
- assert(info->IntensityBits == 0);
- }
- else if (info->BaseFormat == GL_INTENSITY) {
- assert(info->RedBits == 0);
- assert(info->GreenBits == 0);
- assert(info->BlueBits == 0);
- assert(info->AlphaBits == 0);
- assert(info->LuminanceBits == 0);
- assert(info->IntensityBits > 0);
- }
- }
-
- check_format_to_type_and_comps();
-}
-
-
-
-/**
- * Return datatype and number of components per texel for the given mesa_format.
- * Only used for mipmap generation code.
- */
-void
-_mesa_format_to_type_and_comps(mesa_format format,
+_mesa_uncompressed_format_to_type_and_comps(mesa_format format,
GLenum *datatype, GLuint *comps)
{
switch (format) {
@@ -1229,44 +1105,6 @@ _mesa_format_to_type_and_comps(mesa_format format,
*comps = 2;
return;
- case MESA_FORMAT_RGB_FXT1:
- case MESA_FORMAT_RGBA_FXT1:
- case MESA_FORMAT_RGB_DXT1:
- case MESA_FORMAT_RGBA_DXT1:
- case MESA_FORMAT_RGBA_DXT3:
- case MESA_FORMAT_RGBA_DXT5:
- case MESA_FORMAT_SRGB_DXT1:
- case MESA_FORMAT_SRGBA_DXT1:
- case MESA_FORMAT_SRGBA_DXT3:
- case MESA_FORMAT_SRGBA_DXT5:
- case MESA_FORMAT_R_RGTC1_UNORM:
- case MESA_FORMAT_R_RGTC1_SNORM:
- case MESA_FORMAT_RG_RGTC2_UNORM:
- case MESA_FORMAT_RG_RGTC2_SNORM:
- case MESA_FORMAT_L_LATC1_UNORM:
- case MESA_FORMAT_L_LATC1_SNORM:
- case MESA_FORMAT_LA_LATC2_UNORM:
- case MESA_FORMAT_LA_LATC2_SNORM:
- case MESA_FORMAT_ETC1_RGB8:
- case MESA_FORMAT_ETC2_RGB8:
- case MESA_FORMAT_ETC2_SRGB8:
- case MESA_FORMAT_ETC2_RGBA8_EAC:
- case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
- case MESA_FORMAT_ETC2_R11_EAC:
- case MESA_FORMAT_ETC2_RG11_EAC:
- case MESA_FORMAT_ETC2_SIGNED_R11_EAC:
- case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
- case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
- case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
- case MESA_FORMAT_BPTC_RGBA_UNORM:
- case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM:
- case MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT:
- case MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT:
- /* XXX generate error instead? */
- *datatype = GL_UNSIGNED_BYTE;
- *comps = 0;
- return;
-
case MESA_FORMAT_RGBA_FLOAT32:
*datatype = GL_FLOAT;
*comps = 4;
@@ -1564,14 +1402,12 @@ _mesa_format_to_type_and_comps(mesa_format format,
case MESA_FORMAT_COUNT:
assert(0);
return;
-
- case MESA_FORMAT_NONE:
- /* For debug builds, warn if any formats are not handled */
-#ifdef DEBUG
default:
-#endif
- _mesa_problem(NULL, "bad format %s in _mesa_format_to_type_and_comps",
+ /* Warn if any formats are not handled */
+ _mesa_problem(NULL, "bad format %s in _mesa_uncompressed_format_to_type_and_comps",
_mesa_get_format_name(format));
+ assert(format == MESA_FORMAT_NONE ||
+ _mesa_is_format_compressed(format));
*datatype = 0;
*comps = 1;
}
@@ -1584,20 +1420,26 @@ _mesa_format_to_type_and_comps(mesa_format format,
* \param format the user-specified image format
* \param type the user-specified image datatype
* \param swapBytes typically the current pixel pack/unpack byteswap state
+ * \param[out] error GL_NO_ERROR if format is an expected input.
+ * GL_INVALID_ENUM if format is an unexpected input.
* \return GL_TRUE if the formats match, GL_FALSE otherwise.
*/
GLboolean
_mesa_format_matches_format_and_type(mesa_format mesa_format,
GLenum format, GLenum type,
- GLboolean swapBytes)
+ GLboolean swapBytes, GLenum *error)
{
const GLboolean littleEndian = _mesa_little_endian();
+ if (error)
+ *error = GL_NO_ERROR;
/* Note: When reading a GL format/type combination, the format lists channel
* assignments from most significant channel in the type to least
* significant. A type with _REV indicates that the assignments are
* swapped, so they are listed from least significant to most significant.
*
+ * Compressed formats will fall through and return GL_FALSE.
+ *
* For sanity, please keep this switch statement ordered the same as the
* enums in formats.h.
*/
@@ -1858,26 +1700,6 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format,
case MESA_FORMAT_S_UINT8:
return format == GL_STENCIL_INDEX && type == GL_UNSIGNED_BYTE;
- case MESA_FORMAT_SRGB_DXT1:
- case MESA_FORMAT_SRGBA_DXT1:
- case MESA_FORMAT_SRGBA_DXT3:
- case MESA_FORMAT_SRGBA_DXT5:
- return GL_FALSE;
-
- case MESA_FORMAT_RGB_FXT1:
- case MESA_FORMAT_RGBA_FXT1:
- case MESA_FORMAT_RGB_DXT1:
- case MESA_FORMAT_RGBA_DXT1:
- case MESA_FORMAT_RGBA_DXT3:
- case MESA_FORMAT_RGBA_DXT5:
- return GL_FALSE;
-
- case MESA_FORMAT_BPTC_RGBA_UNORM:
- case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM:
- case MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT:
- case MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT:
- return GL_FALSE;
-
case MESA_FORMAT_RGBA_FLOAT32:
return format == GL_RGBA && type == GL_FLOAT && !swapBytes;
case MESA_FORMAT_RGBA_FLOAT16:
@@ -2074,31 +1896,6 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format,
return format == GL_RGBA && type == GL_UNSIGNED_SHORT &&
!swapBytes;
- case MESA_FORMAT_R_RGTC1_UNORM:
- case MESA_FORMAT_R_RGTC1_SNORM:
- case MESA_FORMAT_RG_RGTC2_UNORM:
- case MESA_FORMAT_RG_RGTC2_SNORM:
- return GL_FALSE;
-
- case MESA_FORMAT_L_LATC1_UNORM:
- case MESA_FORMAT_L_LATC1_SNORM:
- case MESA_FORMAT_LA_LATC2_UNORM:
- case MESA_FORMAT_LA_LATC2_SNORM:
- return GL_FALSE;
-
- case MESA_FORMAT_ETC1_RGB8:
- case MESA_FORMAT_ETC2_RGB8:
- case MESA_FORMAT_ETC2_SRGB8:
- case MESA_FORMAT_ETC2_RGBA8_EAC:
- case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
- case MESA_FORMAT_ETC2_R11_EAC:
- case MESA_FORMAT_ETC2_RG11_EAC:
- case MESA_FORMAT_ETC2_SIGNED_R11_EAC:
- case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
- case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
- case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
- return GL_FALSE;
-
case MESA_FORMAT_A_SNORM8:
return format == GL_ALPHA && type == GL_BYTE;
case MESA_FORMAT_L_SNORM8:
@@ -2181,8 +1978,11 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format,
case MESA_FORMAT_B8G8R8X8_SRGB:
case MESA_FORMAT_X8R8G8B8_SRGB:
return GL_FALSE;
+ default:
+ assert(_mesa_is_format_compressed(format));
+ if (error)
+ *error = GL_INVALID_ENUM;
}
-
return GL_FALSE;
}
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
index d938e6a..4936fa0 100644
--- a/src/mesa/main/formats.h
+++ b/src/mesa/main/formats.h
@@ -64,6 +64,12 @@ extern "C" {
enum mesa_format_layout {
MESA_FORMAT_LAYOUT_ARRAY,
MESA_FORMAT_LAYOUT_PACKED,
+ MESA_FORMAT_LAYOUT_S3TC,
+ MESA_FORMAT_LAYOUT_RGTC,
+ MESA_FORMAT_LAYOUT_FXT1,
+ MESA_FORMAT_LAYOUT_ETC1,
+ MESA_FORMAT_LAYOUT_ETC2,
+ MESA_FORMAT_LAYOUT_BPTC,
MESA_FORMAT_LAYOUT_OTHER,
};
@@ -659,7 +665,7 @@ extern GLint
_mesa_format_row_stride(mesa_format format, GLsizei width);
extern void
-_mesa_format_to_type_and_comps(mesa_format format,
+_mesa_uncompressed_format_to_type_and_comps(mesa_format format,
GLenum *datatype, GLuint *comps);
extern void
@@ -680,7 +686,7 @@ _mesa_format_has_color_component(mesa_format format, int component);
GLboolean
_mesa_format_matches_format_and_type(mesa_format mesa_format,
GLenum format, GLenum type,
- GLboolean swapBytes);
+ GLboolean swapBytes, GLenum *error);
#ifdef __cplusplus
}
diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py
index 7dc92f1..517c391 100644
--- a/src/mesa/main/get_hash_params.py
+++ b/src/mesa/main/get_hash_params.py
@@ -806,7 +806,7 @@ descriptor=[
[ "MAX_VERTEX_ATTRIB_BINDINGS", "CONTEXT_ENUM(Const.MaxVertexAttribBindings), NO_EXTRA" ],
# GL_ARB_shader_image_load_store
- [ "MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS", "CONTEXT_INT(Const.MaxCombinedImageUnitsAndFragmentOutputs), extra_ARB_shader_image_load_store" ],
+ [ "MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS", "CONTEXT_INT(Const.MaxCombinedShaderOutputResources), extra_ARB_shader_image_load_store" ],
[ "MAX_IMAGE_SAMPLES", "CONTEXT_INT(Const.MaxImageSamples), extra_ARB_shader_image_load_store" ],
[ "MAX_GEOMETRY_IMAGE_UNIFORMS", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxImageUniforms), extra_ARB_shader_image_load_store_and_geometry_shader"],
diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c
index 1e22f93..2bf5902 100644
--- a/src/mesa/main/mipmap.c
+++ b/src/mesa/main/mipmap.c
@@ -1886,7 +1886,7 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
GLenum datatype;
GLuint comps;
- _mesa_format_to_type_and_comps(srcImage->TexFormat, &datatype, &comps);
+ _mesa_uncompressed_format_to_type_and_comps(srcImage->TexFormat, &datatype, &comps);
for (level = texObj->BaseLevel; level < maxLevel; level++) {
/* generate image[level+1] from image[level] */
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 83f3717..4883cbc 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -94,7 +94,10 @@ struct vbo_context;
#define PRIM_OUTSIDE_BEGIN_END (PRIM_MAX + 1)
#define PRIM_UNKNOWN (PRIM_MAX + 2)
-
+#define VARYING_SLOT_MAX (VARYING_SLOT_VAR0 + MAX_VARYING)
+#define VARYING_SLOT_PATCH0 (VARYING_SLOT_MAX)
+#define VARYING_SLOT_TESS_MAX (VARYING_SLOT_PATCH0 + MAX_VARYING)
+#define FRAG_RESULT_MAX (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS)
/**
* Determine if the given gl_varying_slot appears in the fragment shader.
@@ -117,7 +120,6 @@ _mesa_varying_slot_in_fs(gl_varying_slot slot)
}
}
-
/**
* Indexes for all renderbuffers
*/
@@ -3571,7 +3573,7 @@ struct gl_constants
/* GL_ARB_shader_image_load_store */
GLuint MaxImageUnits;
- GLuint MaxCombinedImageUnitsAndFragmentOutputs;
+ GLuint MaxCombinedShaderOutputResources;
GLuint MaxImageSamples;
GLuint MaxCombinedImageUniforms;
@@ -3656,6 +3658,7 @@ struct gl_extensions
GLboolean ARB_shader_atomic_counters;
GLboolean ARB_shader_bit_encoding;
GLboolean ARB_shader_image_load_store;
+ GLboolean ARB_shader_image_size;
GLboolean ARB_shader_precision;
GLboolean ARB_shader_stencil_export;
GLboolean ARB_shader_storage_buffer_object;
@@ -4073,10 +4076,16 @@ struct gl_image_unit
GLboolean _Valid;
/**
+ * Layer of the texture object bound to this unit as specified by the
+ * application.
+ */
+ GLuint Layer;
+
+ /**
* Layer of the texture object bound to this unit, or zero if the
* whole level is bound.
*/
- GLuint Layer;
+ GLuint _Layer;
/**
* Access allowed to this texture image. Either \c GL_READ_ONLY,
diff --git a/src/mesa/main/multisample.c b/src/mesa/main/multisample.c
index 09e6154..e7783ea 100644
--- a/src/mesa/main/multisample.c
+++ b/src/mesa/main/multisample.c
@@ -150,15 +150,6 @@ GLenum
_mesa_check_sample_count(struct gl_context *ctx, GLenum target,
GLenum internalFormat, GLsizei samples)
{
- /* Section 2.5 (GL Errors) of OpenGL 3.0 specification, page 16:
- *
- * "If a negative number is provided where an argument of type sizei or
- * sizeiptr is specified, the error INVALID VALUE is generated."
- */
- if (samples < 0) {
- return GL_INVALID_VALUE;
- }
-
/* Section 4.4 (Framebuffer objects), page 198 of the OpenGL ES 3.0.0
* specification says:
*
diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
index d826ecf..1277944 100644
--- a/src/mesa/main/readpix.c
+++ b/src/mesa/main/readpix.c
@@ -201,7 +201,7 @@ readpixels_can_use_memcpy(const struct gl_context *ctx, GLenum format, GLenum ty
/* The Mesa format must match the input format and type. */
if (!_mesa_format_matches_format_and_type(rb->Format, format, type,
- packing->SwapBytes)) {
+ packing->SwapBytes, NULL)) {
return GL_FALSE;
}
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index f9a7d13..b227c17 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -1995,55 +1995,6 @@ _mesa_use_shader_program(struct gl_context *ctx, GLenum type,
}
-static GLuint
-_mesa_create_shader_program(struct gl_context* ctx, GLboolean separate,
- GLenum type, GLsizei count,
- const GLchar* const *strings)
-{
- const GLuint shader = create_shader(ctx, type);
- GLuint program = 0;
-
- if (shader) {
- _mesa_ShaderSource(shader, count, strings, NULL);
-
- compile_shader(ctx, shader);
-
- program = create_shader_program(ctx);
- if (program) {
- struct gl_shader_program *shProg;
- struct gl_shader *sh;
- GLint compiled = GL_FALSE;
-
- shProg = _mesa_lookup_shader_program(ctx, program);
- sh = _mesa_lookup_shader(ctx, shader);
-
- shProg->SeparateShader = separate;
-
- get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
- if (compiled) {
- attach_shader(ctx, program, shader);
- link_program(ctx, program);
- detach_shader(ctx, program, shader);
-
-#if 0
- /* Possibly... */
- if (active-user-defined-varyings-in-linked-program) {
- append-error-to-info-log;
- shProg->LinkStatus = GL_FALSE;
- }
-#endif
- }
- if (sh->InfoLog)
- ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
- }
-
- delete_shader(ctx, shader);
- }
-
- return program;
-}
-
-
/**
* Copy program-specific data generated by linking from the gl_shader_program
* object to a specific gl_program object.
@@ -2111,7 +2062,56 @@ _mesa_CreateShaderProgramv(GLenum type, GLsizei count,
{
GET_CURRENT_CONTEXT(ctx);
- return _mesa_create_shader_program(ctx, GL_TRUE, type, count, strings);
+ const GLuint shader = create_shader(ctx, type);
+ GLuint program = 0;
+
+ /*
+ * According to OpenGL 4.5 and OpenGL ES 3.1 standards, section 7.3:
+ * GL_INVALID_VALUE should be generated if count < 0
+ */
+ if (count < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glCreateShaderProgram (count < 0)");
+ return program;
+ }
+
+ if (shader) {
+ _mesa_ShaderSource(shader, count, strings, NULL);
+
+ compile_shader(ctx, shader);
+
+ program = create_shader_program(ctx);
+ if (program) {
+ struct gl_shader_program *shProg;
+ struct gl_shader *sh;
+ GLint compiled = GL_FALSE;
+
+ shProg = _mesa_lookup_shader_program(ctx, program);
+ sh = _mesa_lookup_shader(ctx, shader);
+
+ shProg->SeparateShader = GL_TRUE;
+
+ get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
+ if (compiled) {
+ attach_shader(ctx, program, shader);
+ link_program(ctx, program);
+ detach_shader(ctx, program, shader);
+
+#if 0
+ /* Possibly... */
+ if (active-user-defined-varyings-in-linked-program) {
+ append-error-to-info-log;
+ shProg->LinkStatus = GL_FALSE;
+ }
+#endif
+ }
+ if (sh->InfoLog)
+ ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
+ }
+
+ delete_shader(ctx, shader);
+ }
+
+ return program;
}
diff --git a/src/mesa/main/shaderimage.c b/src/mesa/main/shaderimage.c
index a348cdb..c4bba84 100644
--- a/src/mesa/main/shaderimage.c
+++ b/src/mesa/main/shaderimage.c
@@ -331,17 +331,88 @@ get_image_format_class(mesa_format format)
}
}
+/**
+ * Return whether an image format should be supported based on the current API
+ * version of the context.
+ */
+static bool
+is_image_format_supported(const struct gl_context *ctx, GLenum format)
+{
+ switch (format) {
+ /* Formats supported on both desktop and ES GL, c.f. table 8.27 of the
+ * OpenGL ES 3.1 specification.
+ */
+ case GL_RGBA32F:
+ case GL_RGBA16F:
+ case GL_R32F:
+ case GL_RGBA32UI:
+ case GL_RGBA16UI:
+ case GL_RGBA8UI:
+ case GL_R32UI:
+ case GL_RGBA32I:
+ case GL_RGBA16I:
+ case GL_RGBA8I:
+ case GL_R32I:
+ case GL_RGBA8:
+ case GL_RGBA8_SNORM:
+ return true;
+
+ /* Formats supported on unextended desktop GL and the original
+ * ARB_shader_image_load_store extension, c.f. table 3.21 of the OpenGL 4.2
+ * specification.
+ */
+ case GL_RG32F:
+ case GL_RG16F:
+ case GL_R11F_G11F_B10F:
+ case GL_R16F:
+ case GL_RGB10_A2UI:
+ case GL_RG32UI:
+ case GL_RG16UI:
+ case GL_RG8UI:
+ case GL_R16UI:
+ case GL_R8UI:
+ case GL_RG32I:
+ case GL_RG16I:
+ case GL_RG8I:
+ case GL_R16I:
+ case GL_R8I:
+ case GL_RGBA16:
+ case GL_RGB10_A2:
+ case GL_RG16:
+ case GL_RG8:
+ case GL_R16:
+ case GL_R8:
+ case GL_RGBA16_SNORM:
+ case GL_RG16_SNORM:
+ case GL_RG8_SNORM:
+ case GL_R16_SNORM:
+ case GL_R8_SNORM:
+ return _mesa_is_desktop_gl(ctx);
+
+ default:
+ return false;
+ }
+}
+
+struct gl_image_unit
+_mesa_default_image_unit(struct gl_context *ctx)
+{
+ const GLenum format = _mesa_is_desktop_gl(ctx) ? GL_R8 : GL_R32UI;
+ const struct gl_image_unit u = {
+ .Access = GL_READ_ONLY,
+ .Format = format,
+ ._ActualFormat = _mesa_get_shader_image_format(format)
+ };
+ return u;
+}
+
void
_mesa_init_image_units(struct gl_context *ctx)
{
unsigned i;
- for (i = 0; i < ARRAY_SIZE(ctx->ImageUnits); ++i) {
- struct gl_image_unit *u = &ctx->ImageUnits[i];
- u->Access = GL_READ_ONLY;
- u->Format = GL_R8;
- u->_ActualFormat = _mesa_get_shader_image_format(u->Format);
- }
+ for (i = 0; i < ARRAY_SIZE(ctx->ImageUnits); ++i)
+ ctx->ImageUnits[i] = _mesa_default_image_unit(ctx);
}
static GLboolean
@@ -362,7 +433,7 @@ validate_image_unit(struct gl_context *ctx, struct gl_image_unit *u)
return GL_FALSE;
if (_mesa_tex_target_is_layered(t->Target) &&
- u->Layer >= _mesa_get_texture_layers(t, u->Level))
+ u->_Layer >= _mesa_get_texture_layers(t, u->Level))
return GL_FALSE;
if (t->Target == GL_TEXTURE_BUFFER) {
@@ -370,7 +441,7 @@ validate_image_unit(struct gl_context *ctx, struct gl_image_unit *u)
} else {
struct gl_texture_image *img = (t->Target == GL_TEXTURE_CUBE_MAP ?
- t->Image[u->Layer][u->Level] :
+ t->Image[u->_Layer][u->Level] :
t->Image[0][u->Level]);
if (!img || img->Border || img->NumSamples > ctx->Const.MaxImageSamples)
@@ -442,7 +513,7 @@ validate_bind_image_texture(struct gl_context *ctx, GLuint unit,
return GL_FALSE;
}
- if (!_mesa_get_shader_image_format(format)) {
+ if (!is_image_format_supported(ctx, format)) {
_mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(format)");
return GL_FALSE;
}
@@ -475,6 +546,18 @@ _mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level,
return;
}
+ /* From section 8.22 "Texture Image Loads and Stores" of the OpenGL ES
+ * 3.1 spec:
+ *
+ * "An INVALID_OPERATION error is generated if texture is not the name
+ * of an immutable texture object."
+ */
+ if (_mesa_is_gles(ctx) && !t->Immutable) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBindImageTexture(!immutable)");
+ return;
+ }
+
_mesa_reference_texobj(&u->TexObj, t);
} else {
_mesa_reference_texobj(&u->TexObj, NULL);
@@ -488,7 +571,8 @@ _mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level,
if (u->TexObj && _mesa_tex_target_is_layered(u->TexObj->Target)) {
u->Layered = layered;
- u->Layer = (layered ? 0 : layer);
+ u->Layer = layer;
+ u->_Layer = (u->Layered ? 0 : u->Layer);
} else {
u->Layered = GL_FALSE;
u->Layer = 0;
@@ -599,7 +683,7 @@ _mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures)
tex_format = image->InternalFormat;
}
- if (_mesa_get_shader_image_format(tex_format) == MESA_FORMAT_NONE) {
+ if (!is_image_format_supported(ctx, tex_format)) {
/* The ARB_multi_bind spec says:
*
* "An INVALID_OPERATION error is generated if the internal
@@ -619,7 +703,7 @@ _mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures)
_mesa_reference_texobj(&u->TexObj, texObj);
u->Level = 0;
u->Layered = _mesa_tex_target_is_layered(texObj->Target);
- u->Layer = 0;
+ u->_Layer = u->Layer = 0;
u->Access = GL_READ_WRITE;
u->Format = tex_format;
u->_ActualFormat = _mesa_get_shader_image_format(tex_format);
@@ -629,7 +713,7 @@ _mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures)
_mesa_reference_texobj(&u->TexObj, NULL);
u->Level = 0;
u->Layered = GL_FALSE;
- u->Layer = 0;
+ u->_Layer = u->Layer = 0;
u->Access = GL_READ_ONLY;
u->Format = GL_R8;
u->_ActualFormat = MESA_FORMAT_R_UNORM8;
@@ -653,3 +737,43 @@ _mesa_MemoryBarrier(GLbitfield barriers)
if (ctx->Driver.MemoryBarrier)
ctx->Driver.MemoryBarrier(ctx, barriers);
}
+
+void GLAPIENTRY
+_mesa_MemoryBarrierByRegion(GLbitfield barriers)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ GLbitfield all_allowed_bits = GL_ATOMIC_COUNTER_BARRIER_BIT |
+ GL_FRAMEBUFFER_BARRIER_BIT |
+ GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
+ GL_SHADER_STORAGE_BARRIER_BIT |
+ GL_TEXTURE_FETCH_BARRIER_BIT |
+ GL_UNIFORM_BARRIER_BIT;
+
+ if (ctx->Driver.MemoryBarrier) {
+ /* From section 7.11.2 of the OpenGL ES 3.1 specification:
+ *
+ * "When barriers is ALL_BARRIER_BITS, shader memory accesses will be
+ * synchronized relative to all these barrier bits, but not to other
+ * barrier bits specific to MemoryBarrier."
+ *
+ * That is, if barriers is the special value GL_ALL_BARRIER_BITS, then all
+ * barriers allowed by glMemoryBarrierByRegion should be activated."
+ */
+ if (barriers == GL_ALL_BARRIER_BITS)
+ return ctx->Driver.MemoryBarrier(ctx, all_allowed_bits);
+
+ /* From section 7.11.2 of the OpenGL ES 3.1 specification:
+ *
+ * "An INVALID_VALUE error is generated if barriers is not the special
+ * value ALL_BARRIER_BITS, and has any bits set other than those
+ * described above."
+ */
+ if ((barriers & ~all_allowed_bits) != 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glMemoryBarrierByRegion(unsupported barrier bit");
+ }
+
+ ctx->Driver.MemoryBarrier(ctx, barriers);
+ }
+}
diff --git a/src/mesa/main/shaderimage.h b/src/mesa/main/shaderimage.h
index 33d8a1e..bbe088a 100644
--- a/src/mesa/main/shaderimage.h
+++ b/src/mesa/main/shaderimage.h
@@ -43,6 +43,12 @@ mesa_format
_mesa_get_shader_image_format(GLenum format);
/**
+ * Get a single image unit struct with the default state.
+ */
+struct gl_image_unit
+_mesa_default_image_unit(struct gl_context *ctx);
+
+/**
* Initialize a context's shader image units to the default state.
*/
void
@@ -68,6 +74,9 @@ _mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures);
void GLAPIENTRY
_mesa_MemoryBarrier(GLbitfield barriers);
+void GLAPIENTRY
+_mesa_MemoryBarrierByRegion(GLbitfield barriers);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/mesa/main/tests/Makefile.am b/src/mesa/main/tests/Makefile.am
index 251474d..9467f3b 100644
--- a/src/mesa/main/tests/Makefile.am
+++ b/src/mesa/main/tests/Makefile.am
@@ -27,6 +27,7 @@ AM_CPPFLAGS += -DHAVE_SHARED_GLAPI
main_test_SOURCES += \
dispatch_sanity.cpp \
+ mesa_formats.cpp \
program_state_string.cpp
main_test_LDADD += \
diff --git a/src/mesa/main/tests/dispatch_sanity.cpp b/src/mesa/main/tests/dispatch_sanity.cpp
index af89d2c..59107eb 100644
--- a/src/mesa/main/tests/dispatch_sanity.cpp
+++ b/src/mesa/main/tests/dispatch_sanity.cpp
@@ -851,6 +851,9 @@ const struct function common_desktop_functions_possible[] = {
// { "glTextureStorage2DMultisampleEXT", 43, -1 }, // XXX: Add to xml
// { "glTextureStorage3DMultisampleEXT", 43, -1 }, // XXX: Add to xml
+/* GL 4.5 */
+ { "glMemoryBarrierByRegion", 45, -1 },
+
/* GL_ARB_internalformat_query */
{ "glGetInternalformativ", 30, -1 },
@@ -1739,6 +1742,9 @@ const struct function gl_core_functions_possible[] = {
// { "glTextureStorage2DMultisampleEXT", 43, -1 }, // XXX: Add to xml
// { "glTextureStorage3DMultisampleEXT", 43, -1 }, // XXX: Add to xml
+/* GL 4.5 */
+ { "glMemoryBarrierByRegion", 45, -1 },
+
/* GL_ARB_direct_state_access */
{ "glCreateTransformFeedbacks", 45, -1 },
{ "glTransformFeedbackBufferBase", 45, -1 },
@@ -2461,8 +2467,7 @@ const struct function gles31_functions_possible[] = {
{ "glGetBooleani_v", 31, -1 },
{ "glMemoryBarrier", 31, -1 },
- // FINISHME: This function has not been implemented yet.
- // { "glMemoryBarrierByRegion", 31, -1 },
+ { "glMemoryBarrierByRegion", 31, -1 },
{ "glTexStorage2DMultisample", 31, -1 },
{ "glGetMultisamplefv", 31, -1 },
diff --git a/src/mesa/main/tests/mesa_formats.cpp b/src/mesa/main/tests/mesa_formats.cpp
new file mode 100644
index 0000000..5356cd9
--- /dev/null
+++ b/src/mesa/main/tests/mesa_formats.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \name mesa_formats.cpp
+ *
+ * Verify that all mesa formats are handled in certain functions and that
+ * the format info table is sane.
+ *
+ */
+
+#include <gtest/gtest.h>
+
+#include "main/formats.h"
+#include "main/glformats.h"
+
+/**
+ * Debug/test: check that all uncompressed formats are handled in the
+ * _mesa_uncompressed_format_to_type_and_comps() function. When new pixel
+ * formats are added to Mesa, that function needs to be updated.
+ */
+TEST(MesaFormatsTest, FormatTypeAndComps)
+{
+ for (int fi = MESA_FORMAT_NONE + 1; fi < MESA_FORMAT_COUNT; ++fi) {
+ mesa_format f = (mesa_format) fi;
+ SCOPED_TRACE(_mesa_get_format_name(f));
+
+ /* This function will emit a problem/warning if the format is
+ * not handled.
+ */
+ if (!_mesa_is_format_compressed(f)) {
+ GLenum datatype = 0;
+ GLenum error = 0;
+ GLuint comps = 0;
+
+ /* If the datatype is zero, the format was not handled */
+ _mesa_uncompressed_format_to_type_and_comps(f, &datatype, &comps);
+ EXPECT_NE(datatype, (GLenum)0);
+
+ /* If the error isn't NO_ERROR, the format was not handled.
+ * Use an arbitrary GLenum format. */
+ _mesa_format_matches_format_and_type(f, GL_RG, datatype,
+ GL_FALSE, &error);
+ EXPECT_EQ((GLenum)GL_NO_ERROR, error);
+ }
+
+ }
+}
+
+/**
+ * Do sanity checking of the format info table.
+ */
+TEST(MesaFormatsTest, FormatSanity)
+{
+ for (int fi = 0; fi < MESA_FORMAT_COUNT; ++fi) {
+ mesa_format f = (mesa_format) fi;
+ SCOPED_TRACE(_mesa_get_format_name(f));
+ GLenum datatype = _mesa_get_format_datatype(f);
+ GLint r = _mesa_get_format_bits(f, GL_RED_BITS);
+ GLint g = _mesa_get_format_bits(f, GL_GREEN_BITS);
+ GLint b = _mesa_get_format_bits(f, GL_BLUE_BITS);
+ GLint a = _mesa_get_format_bits(f, GL_ALPHA_BITS);
+ GLint l = _mesa_get_format_bits(f, GL_TEXTURE_LUMINANCE_SIZE);
+ GLint i = _mesa_get_format_bits(f, GL_TEXTURE_INTENSITY_SIZE);
+
+ /* Note: Z32_FLOAT_X24S8 has datatype of GL_NONE */
+ EXPECT_TRUE(datatype == GL_NONE ||
+ datatype == GL_UNSIGNED_NORMALIZED ||
+ datatype == GL_SIGNED_NORMALIZED ||
+ datatype == GL_UNSIGNED_INT ||
+ datatype == GL_INT ||
+ datatype == GL_FLOAT);
+
+ if (r > 0 && !_mesa_is_format_compressed(f)) {
+ GLint bytes = _mesa_get_format_bytes(f);
+ EXPECT_LE((r+g+b+a) / 8, bytes);
+ }
+
+ /* Determines if the base format has a channel [rgba] or property [li].
+ * > indicates existance
+ * == indicates non-existance
+ */
+ #define HAS_PROP(rop,gop,bop,aop,lop,iop) \
+ do { \
+ EXPECT_TRUE(r rop 0); \
+ EXPECT_TRUE(g gop 0); \
+ EXPECT_TRUE(b bop 0); \
+ EXPECT_TRUE(a aop 0); \
+ EXPECT_TRUE(l lop 0); \
+ EXPECT_TRUE(i iop 0); \
+ } while(0)
+
+ switch (_mesa_get_format_base_format(f)) {
+ case GL_RGBA:
+ HAS_PROP(>,>,>,>,==,==);
+ break;
+ case GL_RGB:
+ HAS_PROP(>,>,>,==,==,==);
+ break;
+ case GL_RG:
+ HAS_PROP(>,>,==,==,==,==);
+ break;
+ case GL_RED:
+ HAS_PROP(>,==,==,==,==,==);
+ break;
+ case GL_LUMINANCE:
+ HAS_PROP(==,==,==,==,>,==);
+ break;
+ case GL_INTENSITY:
+ HAS_PROP(==,==,==,==,==,>);
+ break;
+ default:
+ break;
+ }
+
+ #undef HAS_PROP
+
+ }
+}
diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c
index 0fd1a36..edfb036 100644
--- a/src/mesa/main/texcompress.c
+++ b/src/mesa/main/texcompress.c
@@ -586,34 +586,16 @@ _mesa_compressed_image_address(GLint col, GLint row, GLint img,
compressed_fetch_func
_mesa_get_compressed_fetch_func(mesa_format format)
{
- switch (format) {
- case MESA_FORMAT_RGB_DXT1:
- case MESA_FORMAT_RGBA_DXT1:
- case MESA_FORMAT_RGBA_DXT3:
- case MESA_FORMAT_RGBA_DXT5:
- case MESA_FORMAT_SRGB_DXT1:
- case MESA_FORMAT_SRGBA_DXT1:
- case MESA_FORMAT_SRGBA_DXT3:
- case MESA_FORMAT_SRGBA_DXT5:
+ switch (_mesa_get_format_layout(format)) {
+ case MESA_FORMAT_LAYOUT_S3TC:
return _mesa_get_dxt_fetch_func(format);
- case MESA_FORMAT_RGB_FXT1:
- case MESA_FORMAT_RGBA_FXT1:
+ case MESA_FORMAT_LAYOUT_FXT1:
return _mesa_get_fxt_fetch_func(format);
- case MESA_FORMAT_R_RGTC1_UNORM:
- case MESA_FORMAT_L_LATC1_UNORM:
- case MESA_FORMAT_R_RGTC1_SNORM:
- case MESA_FORMAT_L_LATC1_SNORM:
- case MESA_FORMAT_RG_RGTC2_UNORM:
- case MESA_FORMAT_LA_LATC2_UNORM:
- case MESA_FORMAT_RG_RGTC2_SNORM:
- case MESA_FORMAT_LA_LATC2_SNORM:
+ case MESA_FORMAT_LAYOUT_RGTC:
return _mesa_get_compressed_rgtc_func(format);
- case MESA_FORMAT_ETC1_RGB8:
+ case MESA_FORMAT_LAYOUT_ETC1:
return _mesa_get_etc_fetch_func(format);
- case MESA_FORMAT_BPTC_RGBA_UNORM:
- case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM:
- case MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT:
- case MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT:
+ case MESA_FORMAT_LAYOUT_BPTC:
return _mesa_get_bptc_fetch_func(format);
default:
return NULL;
diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c
index c0ccce3..3c1e166 100644
--- a/src/mesa/main/texgetimage.c
+++ b/src/mesa/main/texgetimage.c
@@ -651,7 +651,7 @@ get_tex_memcpy(struct gl_context *ctx,
texBaseFormat == texImage->_BaseFormat) {
memCopy = _mesa_format_matches_format_and_type(texImage->TexFormat,
format, type,
- ctx->Pack.SwapBytes);
+ ctx->Pack.SwapBytes, NULL);
}
if (depth > 1) {
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 3a556a6..274ecad 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -1785,18 +1785,36 @@ compressedteximage_only_format(const struct gl_context *ctx, GLenum format)
}
+/* Writes to an GL error pointer if non-null and returns whether or not the
+ * error is GL_NO_ERROR */
+static bool
+write_error(GLenum *err_ptr, GLenum error)
+{
+ if (err_ptr)
+ *err_ptr = error;
+
+ return error == GL_NO_ERROR;
+}
+
/**
* Helper function to determine whether a target and specific compression
- * format are supported.
+ * format are supported. The error parameter returns GL_NO_ERROR if the
+ * target can be compressed. Otherwise it returns either GL_INVALID_OPERATION
+ * or GL_INVALID_ENUM, whichever is more appropriate.
*/
GLboolean
_mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target,
- GLenum intFormat)
+ GLenum intFormat, GLenum *error)
{
+ GLboolean target_can_be_compresed = GL_FALSE;
+ mesa_format format = _mesa_glenum_to_compressed_format(intFormat);
+ enum mesa_format_layout layout = _mesa_get_format_layout(format);
+
switch (target) {
case GL_TEXTURE_2D:
case GL_PROXY_TEXTURE_2D:
- return GL_TRUE; /* true for any compressed format so far */
+ target_can_be_compresed = GL_TRUE; /* true for any compressed format so far */
+ break;
case GL_PROXY_TEXTURE_CUBE_MAP:
case GL_TEXTURE_CUBE_MAP:
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
@@ -1805,26 +1823,46 @@ _mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target,
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- return ctx->Extensions.ARB_texture_cube_map;
+ target_can_be_compresed = ctx->Extensions.ARB_texture_cube_map;
+ break;
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
case GL_TEXTURE_2D_ARRAY_EXT:
- return ctx->Extensions.EXT_texture_array;
+ target_can_be_compresed = ctx->Extensions.EXT_texture_array;
+ break;
case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
case GL_TEXTURE_CUBE_MAP_ARRAY:
- return ctx->Extensions.ARB_texture_cube_map_array;
+ /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec:
+ *
+ * "The ETC2/EAC texture compression algorithm supports only
+ * two-dimensional images. If internalformat is an ETC2/EAC format,
+ * glCompressedTexImage3D will generate an INVALID_OPERATION error if
+ * target is not TEXTURE_2D_ARRAY."
+ *
+ * This should also be applicable for glTexStorage3D(). Other available
+ * targets for these functions are: TEXTURE_3D and TEXTURE_CUBE_MAP_ARRAY.
+ */
+ if (layout == MESA_FORMAT_LAYOUT_ETC2 && _mesa_is_gles3(ctx))
+ return write_error(error, GL_INVALID_OPERATION);
+
+ target_can_be_compresed = ctx->Extensions.ARB_texture_cube_map_array;
+ break;
case GL_TEXTURE_3D:
- switch (intFormat) {
- case GL_COMPRESSED_RGBA_BPTC_UNORM:
- case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
- case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
- case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
- return ctx->Extensions.ARB_texture_compression_bptc;
- default:
- return GL_FALSE;
+
+ /* See ETC2/EAC comment in switch case GL_TEXTURE_CUBE_MAP_ARRAY. */
+ if (layout == MESA_FORMAT_LAYOUT_ETC2 && _mesa_is_gles3(ctx))
+ return write_error(error, GL_INVALID_OPERATION);
+
+ if (layout == MESA_FORMAT_LAYOUT_BPTC) {
+ target_can_be_compresed = ctx->Extensions.ARB_texture_compression_bptc;
+ break;
}
+
+ break;
default:
- return GL_FALSE;
+ break;
}
+ return write_error(error,
+ target_can_be_compresed ? GL_NO_ERROR : GL_INVALID_ENUM);
}
@@ -2284,8 +2322,9 @@ texture_error_check( struct gl_context *ctx,
/* additional checks for compressed textures */
if (_mesa_is_compressed_format(ctx, internalFormat)) {
- if (!_mesa_target_can_be_compressed(ctx, target, internalFormat)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
+ GLenum err;
+ if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &err)) {
+ _mesa_error(ctx, err,
"glTexImage%dD(target can't be compressed)", dimensions);
return GL_TRUE;
}
@@ -2340,16 +2379,8 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
GLenum error = GL_NO_ERROR;
char *reason = ""; /* no error */
- if (!_mesa_target_can_be_compressed(ctx, target, internalFormat)) {
+ if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &error)) {
reason = "target";
- /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec:
- *
- * "The ETC2/EAC texture compression algorithm supports only
- * two-dimensional images. If internalformat is an ETC2/EAC format,
- * CompressedTexImage3D will generate an INVALID_OPERATION error if
- * target is not TEXTURE_2D_ARRAY."
- */
- error = _mesa_is_desktop_gl(ctx) ? GL_INVALID_ENUM : GL_INVALID_OPERATION;
goto error;
}
@@ -2813,9 +2844,10 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
}
if (_mesa_is_compressed_format(ctx, internalFormat)) {
- if (!_mesa_target_can_be_compressed(ctx, target, internalFormat)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glCopyTexImage%dD(target)", dimensions);
+ GLenum err;
+ if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &err)) {
+ _mesa_error(ctx, err,
+ "glCopyTexImage%dD(target can't be compressed)", dimensions);
return GL_TRUE;
}
if (compressedteximage_only_format(ctx, internalFormat)) {
@@ -5569,10 +5601,13 @@ static GLboolean
is_renderable_texture_format(struct gl_context *ctx, GLenum internalformat)
{
/* Everything that is allowed for renderbuffers,
- * except for a base format of GL_STENCIL_INDEX.
+ * except for a base format of GL_STENCIL_INDEX, unless supported.
*/
GLenum baseFormat = _mesa_base_fbo_format(ctx, internalformat);
- return baseFormat != 0 && baseFormat != GL_STENCIL_INDEX;
+ if (ctx->Extensions.ARB_texture_stencil8)
+ return baseFormat != 0;
+ else
+ return baseFormat != 0 && baseFormat != GL_STENCIL_INDEX;
}
@@ -5596,13 +5631,13 @@ check_multisample_target(GLuint dims, GLenum target, bool dsa)
static void
-_mesa_texture_image_multisample(struct gl_context *ctx, GLuint dims,
- struct gl_texture_object *texObj,
- GLenum target, GLsizei samples,
- GLint internalformat, GLsizei width,
- GLsizei height, GLsizei depth,
- GLboolean fixedsamplelocations,
- GLboolean immutable, const char *func)
+texture_image_multisample(struct gl_context *ctx, GLuint dims,
+ struct gl_texture_object *texObj,
+ GLenum target, GLsizei samples,
+ GLint internalformat, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLboolean fixedsamplelocations,
+ GLboolean immutable, const char *func)
{
struct gl_texture_image *texImage;
GLboolean sizeOK, dimensionsOK, samplesOK;
@@ -5616,6 +5651,11 @@ _mesa_texture_image_multisample(struct gl_context *ctx, GLuint dims,
return;
}
+ if (samples < 1) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples < 1)", func);
+ return;
+ }
+
if (!check_multisample_target(dims, target, dsa)) {
if (dsa) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(target)", func);
@@ -5763,10 +5803,10 @@ _mesa_TexImage2DMultisample(GLenum target, GLsizei samples,
if (!texObj)
return;
- _mesa_texture_image_multisample(ctx, 2, texObj, target, samples,
- internalformat, width, height, 1,
- fixedsamplelocations, GL_FALSE,
- "glTexImage2DMultisample");
+ texture_image_multisample(ctx, 2, texObj, target, samples,
+ internalformat, width, height, 1,
+ fixedsamplelocations, GL_FALSE,
+ "glTexImage2DMultisample");
}
@@ -5783,12 +5823,26 @@ _mesa_TexImage3DMultisample(GLenum target, GLsizei samples,
if (!texObj)
return;
- _mesa_texture_image_multisample(ctx, 3, texObj, target, samples,
- internalformat, width, height, depth,
- fixedsamplelocations, GL_FALSE,
- "glTexImage3DMultisample");
+ texture_image_multisample(ctx, 3, texObj, target, samples,
+ internalformat, width, height, depth,
+ fixedsamplelocations, GL_FALSE,
+ "glTexImage3DMultisample");
}
+static bool
+valid_texstorage_ms_parameters(GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei samples, unsigned dims)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!_mesa_valid_tex_storage_dim(width, height, depth)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexStorage%uDMultisample(width=%d,height=%d,depth=%d)",
+ dims, width, height, depth);
+ return false;
+ }
+ return true;
+}
void GLAPIENTRY
_mesa_TexStorage2DMultisample(GLenum target, GLsizei samples,
@@ -5802,10 +5856,13 @@ _mesa_TexStorage2DMultisample(GLenum target, GLsizei samples,
if (!texObj)
return;
- _mesa_texture_image_multisample(ctx, 2, texObj, target, samples,
- internalformat, width, height, 1,
- fixedsamplelocations, GL_TRUE,
- "glTexStorage2DMultisample");
+ if (!valid_texstorage_ms_parameters(width, height, 1, samples, 2))
+ return;
+
+ texture_image_multisample(ctx, 2, texObj, target, samples,
+ internalformat, width, height, 1,
+ fixedsamplelocations, GL_TRUE,
+ "glTexStorage2DMultisample");
}
void GLAPIENTRY
@@ -5821,10 +5878,13 @@ _mesa_TexStorage3DMultisample(GLenum target, GLsizei samples,
if (!texObj)
return;
- _mesa_texture_image_multisample(ctx, 3, texObj, target, samples,
- internalformat, width, height, depth,
- fixedsamplelocations, GL_TRUE,
- "glTexStorage3DMultisample");
+ if (!valid_texstorage_ms_parameters(width, height, depth, samples, 3))
+ return;
+
+ texture_image_multisample(ctx, 3, texObj, target, samples,
+ internalformat, width, height, depth,
+ fixedsamplelocations, GL_TRUE,
+ "glTexStorage3DMultisample");
}
void GLAPIENTRY
@@ -5841,10 +5901,13 @@ _mesa_TextureStorage2DMultisample(GLuint texture, GLsizei samples,
if (!texObj)
return;
- _mesa_texture_image_multisample(ctx, 2, texObj, texObj->Target, samples,
- internalformat, width, height, 1,
- fixedsamplelocations, GL_TRUE,
- "glTextureStorage2DMultisample");
+ if (!valid_texstorage_ms_parameters(width, height, 1, samples, 2))
+ return;
+
+ texture_image_multisample(ctx, 2, texObj, texObj->Target, samples,
+ internalformat, width, height, 1,
+ fixedsamplelocations, GL_TRUE,
+ "glTextureStorage2DMultisample");
}
void GLAPIENTRY
@@ -5862,8 +5925,11 @@ _mesa_TextureStorage3DMultisample(GLuint texture, GLsizei samples,
if (!texObj)
return;
- _mesa_texture_image_multisample(ctx, 3, texObj, texObj->Target, samples,
- internalformat, width, height, depth,
- fixedsamplelocations, GL_TRUE,
- "glTextureStorage3DMultisample");
+ if (!valid_texstorage_ms_parameters(width, height, depth, samples, 3))
+ return;
+
+ texture_image_multisample(ctx, 3, texObj, texObj->Target, samples,
+ internalformat, width, height, depth,
+ fixedsamplelocations, GL_TRUE,
+ "glTextureStorage3DMultisample");
}
diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h
index bf729da..a4736b5 100644
--- a/src/mesa/main/teximage.h
+++ b/src/mesa/main/teximage.h
@@ -133,7 +133,7 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
extern GLboolean
_mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target,
- GLenum intFormat);
+ GLenum intFormat, GLenum *error);
extern GLuint
_mesa_tex_target_to_face(GLenum target);
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index cd7cfd6..c5d83e1 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -37,6 +37,7 @@
#include "hash.h"
#include "imports.h"
#include "macros.h"
+#include "shaderimage.h"
#include "teximage.h"
#include "texobj.h"
#include "texstate.h"
@@ -1411,8 +1412,10 @@ unbind_texobj_from_image_units(struct gl_context *ctx,
for (i = 0; i < ctx->Const.MaxImageUnits; i++) {
struct gl_image_unit *unit = &ctx->ImageUnits[i];
- if (texObj == unit->TexObj)
+ if (texObj == unit->TexObj) {
_mesa_reference_texobj(&unit->TexObj, NULL);
+ *unit = _mesa_default_image_unit(ctx);
+ }
}
}
@@ -1742,10 +1745,10 @@ _mesa_BindTexture( GLenum target, GLuint texName )
* texture object will be decremented. It'll be deleted if the
* count hits zero.
*/
-void
-_mesa_bind_texture_unit(struct gl_context *ctx,
- GLuint unit,
- struct gl_texture_object *texObj)
+static void
+bind_texture_unit(struct gl_context *ctx,
+ GLuint unit,
+ struct gl_texture_object *texObj)
{
struct gl_texture_unit *texUnit;
@@ -1834,7 +1837,7 @@ _mesa_BindTextureUnit(GLuint unit, GLuint texture)
}
assert(valid_texture_object(texObj));
- _mesa_bind_texture_unit(ctx, unit, texObj);
+ bind_texture_unit(ctx, unit, texObj);
}
diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
index ec5ccb2..690878c 100644
--- a/src/mesa/main/texobj.h
+++ b/src/mesa/main/texobj.h
@@ -209,10 +209,6 @@ extern void
_mesa_delete_nameless_texture(struct gl_context *ctx,
struct gl_texture_object *texObj);
-extern void
-_mesa_bind_texture_unit(struct gl_context *ctx,
- GLuint unit,
- struct gl_texture_object *texObj);
/*@}*/
diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c
index c0611c3..16739f1 100644
--- a/src/mesa/main/texparam.c
+++ b/src/mesa/main/texparam.c
@@ -1562,6 +1562,19 @@ invalid_pname:
_mesa_enum_to_string(pname));
}
+static bool
+valid_tex_level_parameteriv_target(struct gl_context *ctx, GLenum target,
+ bool dsa)
+{
+ const char *suffix = dsa ? "ture" : "";
+ if (!legal_get_tex_level_parameter_target(ctx, target, dsa)) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTex%sLevelParameter[if]v(target=%s)", suffix,
+ _mesa_enum_to_string(target));
+ return false;
+ }
+ return true;
+}
/**
* This isn't exposed to the rest of the driver because it is a part of the
@@ -1585,13 +1598,6 @@ get_tex_level_parameteriv(struct gl_context *ctx,
return;
}
- if (!legal_get_tex_level_parameter_target(ctx, target, dsa)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetTex%sLevelParameter[if]v(target=%s)", suffix,
- _mesa_enum_to_string(target));
- return;
- }
-
maxLevels = _mesa_max_texture_levels(ctx, target);
assert(maxLevels != 0);
@@ -1619,6 +1625,9 @@ _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
GLint iparam;
GET_CURRENT_CONTEXT(ctx);
+ if (!valid_tex_level_parameteriv_target(ctx, target, false))
+ return;
+
texObj = _mesa_get_current_tex_object(ctx, target);
if (!texObj)
return;
@@ -1636,6 +1645,9 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
struct gl_texture_object *texObj;
GET_CURRENT_CONTEXT(ctx);
+ if (!valid_tex_level_parameteriv_target(ctx, target, false))
+ return;
+
texObj = _mesa_get_current_tex_object(ctx, target);
if (!texObj)
return;
@@ -1657,6 +1669,9 @@ _mesa_GetTextureLevelParameterfv(GLuint texture, GLint level,
if (!texObj)
return;
+ if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true))
+ return;
+
get_tex_level_parameteriv(ctx, texObj, texObj->Target, level,
pname, &iparam, true);
@@ -1675,6 +1690,9 @@ _mesa_GetTextureLevelParameteriv(GLuint texture, GLint level,
if (!texObj)
return;
+ if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true))
+ return;
+
get_tex_level_parameteriv(ctx, texObj, texObj->Target, level,
pname, params, true);
}
@@ -1890,6 +1908,12 @@ get_tex_parameterfv(struct gl_context *ctx,
*params = (GLfloat) obj->Sampler.sRGBDecode;
break;
+ case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
+ if (!ctx->Extensions.ARB_shader_image_load_store)
+ goto invalid_pname;
+ *params = (GLfloat) obj->ImageFormatCompatibilityType;
+ break;
+
default:
goto invalid_pname;
}
diff --git a/src/mesa/main/texstorage.c b/src/mesa/main/texstorage.c
index 4a2cc60..c53bb29 100644
--- a/src/mesa/main/texstorage.c
+++ b/src/mesa/main/texstorage.c
@@ -189,6 +189,20 @@ clear_texture_fields(struct gl_context *ctx,
}
+/**
+ * Update/re-validate framebuffer object.
+ */
+static void
+update_fbo_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
+{
+ const unsigned numFaces = _mesa_num_tex_faces(texObj->Target);
+ for (int level = 0; level < ARRAY_SIZE(texObj->Image[0]); level++) {
+ for (unsigned face = 0; face < numFaces; face++)
+ _mesa_update_fbo_texture(ctx, texObj, face, level);
+ }
+}
+
+
GLboolean
_mesa_is_legal_tex_storage_format(struct gl_context *ctx, GLenum internalformat)
{
@@ -287,29 +301,21 @@ tex_storage_error_check(struct gl_context *ctx,
* order to allow meta functions to use legacy formats. */
/* size check */
- if (width < 1 || height < 1 || depth < 1) {
+ if (!_mesa_valid_tex_storage_dim(width, height, depth)) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glTex%sStorage%uD(width, height or depth < 1)",
suffix, dims);
return GL_TRUE;
}
- /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec:
- *
- * "The ETC2/EAC texture compression algorithm supports only
- * two-dimensional images. If internalformat is an ETC2/EAC format,
- * CompressedTexImage3D will generate an INVALID_OPERATION error if
- * target is not TEXTURE_2D_ARRAY."
- *
- * This should also be applicable for glTexStorage3D().
- */
- if (_mesa_is_compressed_format(ctx, internalformat)
- && !_mesa_target_can_be_compressed(ctx, target, internalformat)) {
- _mesa_error(ctx, _mesa_is_desktop_gl(ctx)?
- GL_INVALID_ENUM : GL_INVALID_OPERATION,
+ if (_mesa_is_compressed_format(ctx, internalformat)) {
+ GLenum err;
+ if (!_mesa_target_can_be_compressed(ctx, target, internalformat, &err)) {
+ _mesa_error(ctx, err,
"glTex%sStorage%dD(internalformat = %s)", suffix, dims,
_mesa_enum_to_string(internalformat));
- return GL_TRUE;
+ return GL_TRUE;
+ }
}
/* levels check */
@@ -446,6 +452,7 @@ _mesa_texture_storage(struct gl_context *ctx, GLuint dims,
_mesa_set_texture_view_state(ctx, texObj, target, levels);
+ update_fbo_texture(ctx, texObj);
}
}
diff --git a/src/mesa/main/texstorage.h b/src/mesa/main/texstorage.h
index 6f5495f..033ecb7 100644
--- a/src/mesa/main/texstorage.h
+++ b/src/mesa/main/texstorage.h
@@ -38,6 +38,27 @@ _mesa_texture_storage(struct gl_context *ctx, GLuint dims,
GLenum internalformat, GLsizei width,
GLsizei height, GLsizei depth, bool dsa);
+/**
+ * Texture width, height and depth check shared with the
+ * multisample variants of TexStorage functions.
+ *
+ * From OpenGL 4.5 Core spec, page 260 (section 8.19)
+ *
+ * "An INVALID_VALUE error is generated if width, height, depth
+ * or levels are less than 1, for commands with the corresponding
+ * parameters."
+ *
+ * (referring to TextureStorage* commands, these also match values
+ * specified for OpenGL ES 3.1.)
+ */
+static inline bool
+_mesa_valid_tex_storage_dim(GLsizei width, GLsizei height, GLsizei depth)
+{
+ if (width < 1 || height < 1 || depth < 1)
+ return false;
+ return true;
+}
+
/*@}*/
/**
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index 37c0569..fc83310 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -863,7 +863,7 @@ _mesa_texstore_can_use_memcpy(struct gl_context *ctx,
/* The Mesa format must match the input format and type. */
if (!_mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
+ srcPacking->SwapBytes, NULL)) {
return GL_FALSE;
}
diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index 036530e..1026618 100644
--- a/src/mesa/main/uniform_query.cpp
+++ b/src/mesa/main/uniform_query.cpp
@@ -319,24 +319,31 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
return;
}
+ if ((uni->type->base_type == GLSL_TYPE_DOUBLE &&
+ returnType != GLSL_TYPE_DOUBLE) ||
+ (uni->type->base_type != GLSL_TYPE_DOUBLE &&
+ returnType == GLSL_TYPE_DOUBLE)) {
+ _mesa_error( ctx, GL_INVALID_OPERATION,
+ "glGetnUniform*vARB(incompatible uniform types)");
+ return;
+ }
{
unsigned elements = (uni->type->is_sampler())
? 1 : uni->type->components();
+ const int dmul = uni->type->base_type == GLSL_TYPE_DOUBLE ? 2 : 1;
/* Calculate the source base address *BEFORE* modifying elements to
* account for the size of the user's buffer.
*/
const union gl_constant_value *const src =
- &uni->storage[offset * elements];
+ &uni->storage[offset * elements * dmul];
assert(returnType == GLSL_TYPE_FLOAT || returnType == GLSL_TYPE_INT ||
- returnType == GLSL_TYPE_UINT);
- /* The three (currently) supported types all have the same size,
- * which is of course the same as their union. That'll change
- * with glGetUniformdv()...
- */
- unsigned bytes = sizeof(src[0]) * elements;
+ returnType == GLSL_TYPE_UINT || returnType == GLSL_TYPE_DOUBLE);
+
+ /* doubles have a different size than the other 3 types */
+ unsigned bytes = sizeof(src[0]) * elements * dmul;
if (bufSize < 0 || bytes > (unsigned) bufSize) {
_mesa_error( ctx, GL_INVALID_OPERATION,
"glGetnUniform*vARB(out of bounds: bufSize is %d,"
@@ -677,9 +684,11 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
match = (basicType != GLSL_TYPE_DOUBLE);
break;
case GLSL_TYPE_SAMPLER:
- case GLSL_TYPE_IMAGE:
match = (basicType == GLSL_TYPE_INT);
break;
+ case GLSL_TYPE_IMAGE:
+ match = (basicType == GLSL_TYPE_INT && _mesa_is_desktop_gl(ctx));
+ break;
default:
match = (basicType == uni->type->base_type);
break;
diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
index ff1df72..10819e2 100644
--- a/src/mesa/main/uniforms.c
+++ b/src/mesa/main/uniforms.c
@@ -888,16 +888,7 @@ _mesa_GetnUniformdvARB(GLuint program, GLint location,
{
GET_CURRENT_CONTEXT(ctx);
- (void) program;
- (void) location;
- (void) bufSize;
- (void) params;
-
- /*
_mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_DOUBLE, params);
- */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformdvARB"
- "(GL_ARB_gpu_shader_fp64 not implemented)");
}
void GLAPIENTRY