summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2015-08-14 17:25:04 -0700
committerJason Ekstrand <[email protected]>2015-08-17 11:25:03 -0700
commit6a7ca4ef2cd3f39d3b5e77051cb3f3175e9e60df (patch)
treed5413781ac9e9ecfc22cf403fa7465d6a7cadb34 /src/mesa/main
parentb4c02253c4e1a7bc5a7a6369045210932f5de605 (diff)
parentd3e23f1ff915c01541f8df375b50b93b3da565a8 (diff)
Merge remote-tracking branch 'mesa-public/master' into vulkan
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/api_validate.c88
-rw-r--r--src/mesa/main/atifragshader.c30
-rw-r--r--src/mesa/main/attrib.c2
-rw-r--r--src/mesa/main/blend.c50
-rw-r--r--src/mesa/main/blit.c34
-rw-r--r--src/mesa/main/blit.h6
-rw-r--r--src/mesa/main/bufferobj.c401
-rw-r--r--src/mesa/main/buffers.c22
-rw-r--r--src/mesa/main/clear.c20
-rw-r--r--src/mesa/main/condrender.c4
-rw-r--r--src/mesa/main/config.h16
-rw-r--r--src/mesa/main/context.c80
-rw-r--r--src/mesa/main/context.h20
-rw-r--r--src/mesa/main/copyimage.c8
-rw-r--r--src/mesa/main/dd.h21
-rw-r--r--src/mesa/main/debug.c6
-rw-r--r--src/mesa/main/depth.c2
-rw-r--r--src/mesa/main/dlist.c14
-rw-r--r--src/mesa/main/drawpix.c18
-rw-r--r--src/mesa/main/enable.c16
-rw-r--r--src/mesa/main/enums.h2
-rw-r--r--src/mesa/main/errors.c4
-rw-r--r--src/mesa/main/errors.h1
-rw-r--r--src/mesa/main/extensions.c6
-rw-r--r--src/mesa/main/fbobject.c81
-rw-r--r--src/mesa/main/feedback.c2
-rw-r--r--src/mesa/main/ffvertex_prog.c10
-rw-r--r--src/mesa/main/fog.c2
-rwxr-xr-xsrc/mesa/main/format_parser.py7
-rw-r--r--src/mesa/main/format_utils.h9
-rw-r--r--src/mesa/main/formatquery.c12
-rw-r--r--src/mesa/main/formats.c23
-rw-r--r--src/mesa/main/formats.h5
-rw-r--r--src/mesa/main/framebuffer.c2
-rw-r--r--src/mesa/main/genmipmap.c2
-rw-r--r--src/mesa/main/get.c75
-rw-r--r--src/mesa/main/get_hash_generator.py12
-rw-r--r--src/mesa/main/get_hash_params.py117
-rw-r--r--src/mesa/main/getstring.c4
-rw-r--r--src/mesa/main/glformats.c66
-rw-r--r--src/mesa/main/glformats.h3
-rw-r--r--src/mesa/main/hint.c4
-rw-r--r--src/mesa/main/imports.c4
-rw-r--r--src/mesa/main/imports.h28
-rw-r--r--src/mesa/main/light.c42
-rw-r--r--src/mesa/main/lines.c4
-rw-r--r--src/mesa/main/macros.h22
-rw-r--r--src/mesa/main/matrix.c8
-rw-r--r--src/mesa/main/mipmap.c9
-rw-r--r--src/mesa/main/mtypes.h222
-rw-r--r--src/mesa/main/multisample.c9
-rw-r--r--src/mesa/main/objectlabel.c2
-rw-r--r--src/mesa/main/pack.c18
-rw-r--r--src/mesa/main/pipelineobj.c34
-rw-r--r--src/mesa/main/pixel.c4
-rw-r--r--src/mesa/main/pixeltransfer.c19
-rw-r--r--src/mesa/main/points.c8
-rw-r--r--src/mesa/main/polygon.c14
-rw-r--r--src/mesa/main/program_resource.c189
-rw-r--r--src/mesa/main/queryobj.c30
-rw-r--r--src/mesa/main/readpix.c142
-rw-r--r--src/mesa/main/readpix.h13
-rw-r--r--src/mesa/main/samplerobj.c22
-rw-r--r--src/mesa/main/shader_query.cpp348
-rw-r--r--src/mesa/main/shaderapi.c732
-rw-r--r--src/mesa/main/shaderapi.h48
-rw-r--r--src/mesa/main/shaderimage.c2
-rw-r--r--src/mesa/main/shaderobj.h105
-rw-r--r--src/mesa/main/state.c54
-rw-r--r--src/mesa/main/tests/dispatch_sanity.cpp27
-rw-r--r--src/mesa/main/tests/enum_strings.cpp13
-rw-r--r--src/mesa/main/texenv.c10
-rw-r--r--src/mesa/main/texformat.c2
-rw-r--r--src/mesa/main/texgen.c6
-rw-r--r--src/mesa/main/texgetimage.c1191
-rw-r--r--src/mesa/main/texgetimage.h40
-rw-r--r--src/mesa/main/teximage.c417
-rw-r--r--src/mesa/main/teximage.h9
-rw-r--r--src/mesa/main/texobj.c10
-rw-r--r--src/mesa/main/texparam.c30
-rw-r--r--src/mesa/main/texstate.c54
-rw-r--r--src/mesa/main/texstate.h2
-rw-r--r--src/mesa/main/texstorage.c17
-rw-r--r--src/mesa/main/texstore.c1
-rw-r--r--src/mesa/main/textureview.c10
-rw-r--r--src/mesa/main/uniform_query.cpp95
-rw-r--r--src/mesa/main/uniforms.c28
-rw-r--r--src/mesa/main/uniforms.h4
-rw-r--r--src/mesa/main/varray.c6
-rw-r--r--src/mesa/main/version.c2
-rw-r--r--src/mesa/main/viewport.c18
-rw-r--r--src/mesa/main/viewport.h2
92 files changed, 3872 insertions, 1561 deletions
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index 9c2e29e6472..53c8fb893b5 100644
--- a/src/mesa/main/api_validate.c
+++ b/src/mesa/main/api_validate.c
@@ -69,6 +69,25 @@ check_valid_to_render(struct gl_context *ctx, const char *function)
return false;
}
+ /* The spec argues that this is allowed because a tess ctrl shader
+ * without a tess eval shader can be used with transform feedback.
+ * However, glBeginTransformFeedback doesn't allow GL_PATCHES and
+ * therefore doesn't allow tessellation.
+ *
+ * Further investigation showed that this is indeed a spec bug and
+ * a tess ctrl shader without a tess eval shader shouldn't have been
+ * allowed, because there is no API in GL 4.0 that can make use this
+ * to produce something useful.
+ *
+ * Also, all vendors except one don't support a tess ctrl shader without
+ * a tess eval shader anyway.
+ */
+ if (ctx->TessCtrlProgram._Current && !ctx->TessEvalProgram._Current) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(tess eval shader is missing)", function);
+ return false;
+ }
+
/* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec
* says:
*
@@ -127,6 +146,9 @@ _mesa_is_valid_prim_mode(struct gl_context *ctx, GLenum mode)
if (mode <= GL_TRIANGLE_STRIP_ADJACENCY)
return _mesa_has_geometry_shaders(ctx);
+ if (mode == GL_PATCHES)
+ return _mesa_has_tessellation(ctx);
+
return false;
}
@@ -136,6 +158,7 @@ _mesa_is_valid_prim_mode(struct gl_context *ctx, GLenum mode)
* etc? Also, do additional checking related to transformation feedback.
* Note: this function cannot be called during glNewList(GL_COMPILE) because
* this code depends on current transform feedback state.
+ * Also, do additional checking related to tessellation shaders.
*/
GLboolean
_mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name)
@@ -170,11 +193,29 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name)
* TRIANGLES_ADJACENCY_ARB and <mode> is not
* TRIANGLES_ADJACENCY_ARB or TRIANGLE_STRIP_ADJACENCY_ARB.
*
+ * The GL spec doesn't mention any interaction with tessellation, which
+ * is clearly a spec bug. The same rule should apply, but instead of
+ * the draw primitive mode, the tessellation evaluation shader primitive
+ * mode should be used for the checking.
*/
if (ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]) {
const GLenum geom_mode =
ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]->Geom.InputType;
- switch (mode) {
+ struct gl_shader_program *tes =
+ ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
+ GLenum mode_before_gs = mode;
+
+ if (tes) {
+ if (tes->TessEval.PointMode)
+ mode_before_gs = GL_POINTS;
+ else if (tes->TessEval.PrimitiveMode == GL_ISOLINES)
+ mode_before_gs = GL_LINES;
+ else
+ /* the GL_QUADS mode generates triangles too */
+ mode_before_gs = GL_TRIANGLES;
+ }
+
+ switch (mode_before_gs) {
case GL_POINTS:
valid_enum = (geom_mode == GL_POINTS);
break;
@@ -209,12 +250,42 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name)
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(mode=%s vs geometry shader input %s)",
name,
- _mesa_lookup_prim_by_nr(mode),
+ _mesa_lookup_prim_by_nr(mode_before_gs),
_mesa_lookup_prim_by_nr(geom_mode));
return GL_FALSE;
}
}
+ /* From the OpenGL 4.0 (Core Profile) spec (section 2.12):
+ *
+ * "Tessellation operates only on patch primitives. If tessellation is
+ * active, any command that transfers vertices to the GL will
+ * generate an INVALID_OPERATION error if the primitive mode is not
+ * PATCHES.
+ * Patch primitives are not supported by pipeline stages below the
+ * tessellation evaluation shader. If there is no active program
+ * object or the active program object does not contain a tessellation
+ * evaluation shader, the error INVALID_OPERATION is generated by any
+ * command that transfers vertices to the GL if the primitive mode is
+ * PATCHES."
+ *
+ */
+ if (ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL] ||
+ ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]) {
+ if (mode != GL_PATCHES) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "only GL_PATCHES valid with tessellation");
+ return GL_FALSE;
+ }
+ }
+ else {
+ if (mode == GL_PATCHES) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "GL_PATCHES only valid with tessellation");
+ return GL_FALSE;
+ }
+ }
+
/* From the GL_EXT_transform_feedback spec:
*
* "The error INVALID_OPERATION is generated if Begin, or any command
@@ -247,6 +318,17 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name)
pass = GL_FALSE;
}
}
+ else if (ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]) {
+ struct gl_shader_program *tes =
+ ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
+
+ if (tes->TessEval.PointMode)
+ pass = ctx->TransformFeedback.Mode == GL_POINTS;
+ else if (tes->TessEval.PrimitiveMode == GL_ISOLINES)
+ pass = ctx->TransformFeedback.Mode == GL_LINES;
+ else
+ pass = ctx->TransformFeedback.Mode == GL_TRIANGLES;
+ }
else {
switch (mode) {
case GL_POINTS:
@@ -291,7 +373,7 @@ valid_elements_type(struct gl_context *ctx, GLenum type, const char *name)
default:
_mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)", name,
- _mesa_lookup_enum_by_nr(type));
+ _mesa_enum_to_string(type));
return false;
}
}
diff --git a/src/mesa/main/atifragshader.c b/src/mesa/main/atifragshader.c
index 9fc35520a38..935ba05b7cc 100644
--- a/src/mesa/main/atifragshader.c
+++ b/src/mesa/main/atifragshader.c
@@ -132,21 +132,21 @@ static void debug_op(GLint optype, GLuint arg_count, GLenum op, GLuint dst,
op_name = atifs_ops[(arg_count-1)+(optype?3:0)];
- fprintf(stderr, "%s(%s, %s", op_name, _mesa_lookup_enum_by_nr(op),
- _mesa_lookup_enum_by_nr(dst));
+ fprintf(stderr, "%s(%s, %s", op_name, _mesa_enum_to_string(op),
+ _mesa_enum_to_string(dst));
if (!optype)
fprintf(stderr, ", %d", dstMask);
fprintf(stderr, ", %s", create_dst_mod_str(dstMod));
- fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg1),
- _mesa_lookup_enum_by_nr(arg1Rep), arg1Mod);
+ fprintf(stderr, ", %s, %s, %d", _mesa_enum_to_string(arg1),
+ _mesa_enum_to_string(arg1Rep), arg1Mod);
if (arg_count>1)
- fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg2),
- _mesa_lookup_enum_by_nr(arg2Rep), arg2Mod);
+ fprintf(stderr, ", %s, %s, %d", _mesa_enum_to_string(arg2),
+ _mesa_enum_to_string(arg2Rep), arg2Mod);
if (arg_count>2)
- fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg3),
- _mesa_lookup_enum_by_nr(arg3Rep), arg3Mod);
+ fprintf(stderr, ", %s, %s, %d", _mesa_enum_to_string(arg3),
+ _mesa_enum_to_string(arg3Rep), arg3Mod);
fprintf(stderr,")\n");
@@ -383,7 +383,7 @@ _mesa_EndFragmentShaderATI(void)
for (j = 0; j < MAX_NUM_PASSES_ATI; j++) {
for (i = 0; i < MAX_NUM_FRAGMENT_REGISTERS_ATI; i++) {
GLuint op = curProg->SetupInst[j][i].Opcode;
- const char *op_enum = op > 5 ? _mesa_lookup_enum_by_nr(op) : "0";
+ const char *op_enum = op > 5 ? _mesa_enum_to_string(op) : "0";
GLuint src = curProg->SetupInst[j][i].src;
GLuint swizzle = curProg->SetupInst[j][i].swizzle;
fprintf(stderr, "%2d %04X %s %d %04X\n", i, op, op_enum, src,
@@ -392,8 +392,8 @@ _mesa_EndFragmentShaderATI(void)
for (i = 0; i < curProg->numArithInstr[j]; i++) {
GLuint op0 = curProg->Instructions[j][i].Opcode[0];
GLuint op1 = curProg->Instructions[j][i].Opcode[1];
- const char *op0_enum = op0 > 5 ? _mesa_lookup_enum_by_nr(op0) : "0";
- const char *op1_enum = op1 > 5 ? _mesa_lookup_enum_by_nr(op1) : "0";
+ const char *op0_enum = op0 > 5 ? _mesa_enum_to_string(op0) : "0";
+ const char *op1_enum = op1 > 5 ? _mesa_enum_to_string(op1) : "0";
GLuint count0 = curProg->Instructions[j][i].ArgCount[0];
GLuint count1 = curProg->Instructions[j][i].ArgCount[1];
fprintf(stderr, "%2d %04X %s %d %04X %s %d\n", i, op0, op0_enum, count0,
@@ -477,8 +477,8 @@ _mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle)
#if MESA_DEBUG_ATI_FS
_mesa_debug(ctx, "%s(%s, %s, %s)\n", __func__,
- _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(coord),
- _mesa_lookup_enum_by_nr(swizzle));
+ _mesa_enum_to_string(dst), _mesa_enum_to_string(coord),
+ _mesa_enum_to_string(swizzle));
#endif
}
@@ -550,8 +550,8 @@ _mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle)
#if MESA_DEBUG_ATI_FS
_mesa_debug(ctx, "%s(%s, %s, %s)\n", __func__,
- _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(interp),
- _mesa_lookup_enum_by_nr(swizzle));
+ _mesa_enum_to_string(dst), _mesa_enum_to_string(interp),
+ _mesa_enum_to_string(swizzle));
#endif
}
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index 53626e38be9..08f13178f84 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -937,7 +937,7 @@ _mesa_PopAttrib(void)
if (MESA_VERBOSE & VERBOSE_API) {
_mesa_debug(ctx, "glPopAttrib %s\n",
- _mesa_lookup_enum_by_nr(attr->kind));
+ _mesa_enum_to_string(attr->kind));
}
switch (attr->kind) {
diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c
index d869fa2aa09..4fc32962425 100644
--- a/src/mesa/main/blend.c
+++ b/src/mesa/main/blend.c
@@ -128,28 +128,28 @@ validate_blend_factors(struct gl_context *ctx, const char *func,
if (!legal_src_factor(ctx, sfactorRGB)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"%s(sfactorRGB = %s)", func,
- _mesa_lookup_enum_by_nr(sfactorRGB));
+ _mesa_enum_to_string(sfactorRGB));
return GL_FALSE;
}
if (!legal_dst_factor(ctx, dfactorRGB)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"%s(dfactorRGB = %s)", func,
- _mesa_lookup_enum_by_nr(dfactorRGB));
+ _mesa_enum_to_string(dfactorRGB));
return GL_FALSE;
}
if (sfactorA != sfactorRGB && !legal_src_factor(ctx, sfactorA)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"%s(sfactorA = %s)", func,
- _mesa_lookup_enum_by_nr(sfactorA));
+ _mesa_enum_to_string(sfactorA));
return GL_FALSE;
}
if (dfactorA != dfactorRGB && !legal_dst_factor(ctx, dfactorA)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"%s(dfactorA = %s)", func,
- _mesa_lookup_enum_by_nr(dfactorA));
+ _mesa_enum_to_string(dfactorA));
return GL_FALSE;
}
@@ -208,10 +208,10 @@ _mesa_BlendFuncSeparate( GLenum sfactorRGB, GLenum dfactorRGB,
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glBlendFuncSeparate %s %s %s %s\n",
- _mesa_lookup_enum_by_nr(sfactorRGB),
- _mesa_lookup_enum_by_nr(dfactorRGB),
- _mesa_lookup_enum_by_nr(sfactorA),
- _mesa_lookup_enum_by_nr(dfactorA));
+ _mesa_enum_to_string(sfactorRGB),
+ _mesa_enum_to_string(dfactorRGB),
+ _mesa_enum_to_string(sfactorA),
+ _mesa_enum_to_string(dfactorA));
if (!validate_blend_factors(ctx, "glBlendFuncSeparate",
sfactorRGB, dfactorRGB,
@@ -342,7 +342,7 @@ _mesa_BlendEquation( GLenum mode )
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glBlendEquation(%s)\n",
- _mesa_lookup_enum_by_nr(mode));
+ _mesa_enum_to_string(mode));
if (!legal_blend_equation(ctx, mode)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation");
@@ -385,7 +385,7 @@ _mesa_BlendEquationiARB(GLuint buf, GLenum mode)
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glBlendEquationi(%u, %s)\n",
- buf, _mesa_lookup_enum_by_nr(mode));
+ buf, _mesa_enum_to_string(mode));
if (buf >= ctx->Const.MaxDrawBuffers) {
_mesa_error(ctx, GL_INVALID_VALUE, "glBlendFuncSeparatei(buffer=%u)",
@@ -421,8 +421,8 @@ _mesa_BlendEquationSeparate( GLenum modeRGB, GLenum modeA )
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glBlendEquationSeparateEXT(%s %s)\n",
- _mesa_lookup_enum_by_nr(modeRGB),
- _mesa_lookup_enum_by_nr(modeA));
+ _mesa_enum_to_string(modeRGB),
+ _mesa_enum_to_string(modeA));
if ( (modeRGB != modeA) && !ctx->Extensions.EXT_blend_equation_separate ) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -476,8 +476,8 @@ _mesa_BlendEquationSeparateiARB(GLuint buf, GLenum modeRGB, GLenum modeA)
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glBlendEquationSeparatei(%u, %s %s)\n", buf,
- _mesa_lookup_enum_by_nr(modeRGB),
- _mesa_lookup_enum_by_nr(modeA));
+ _mesa_enum_to_string(modeRGB),
+ _mesa_enum_to_string(modeA));
if (buf >= ctx->Const.MaxDrawBuffers) {
_mesa_error(ctx, GL_INVALID_VALUE, "glBlendEquationSeparatei(buffer=%u)",
@@ -567,7 +567,10 @@ _mesa_AlphaFunc( GLenum func, GLclampf ref )
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glAlphaFunc(%s, %f)\n",
- _mesa_lookup_enum_by_nr(func), ref);
+ _mesa_enum_to_string(func), ref);
+
+ if (ctx->Color.AlphaFunc == func && ctx->Color.AlphaRefUnclamped == ref)
+ return; /* no change */
switch (func) {
case GL_NEVER:
@@ -578,9 +581,6 @@ _mesa_AlphaFunc( GLenum func, GLclampf ref )
case GL_NOTEQUAL:
case GL_GEQUAL:
case GL_ALWAYS:
- if (ctx->Color.AlphaFunc == func && ctx->Color.AlphaRefUnclamped == ref)
- return; /* no change */
-
FLUSH_VERTICES(ctx, _NEW_COLOR);
ctx->Color.AlphaFunc = func;
ctx->Color.AlphaRefUnclamped = ref;
@@ -613,7 +613,7 @@ _mesa_LogicOp( GLenum opcode )
GET_CURRENT_CONTEXT(ctx);
if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glLogicOp(%s)\n", _mesa_lookup_enum_by_nr(opcode));
+ _mesa_debug(ctx, "glLogicOp(%s)\n", _mesa_enum_to_string(opcode));
switch (opcode) {
case GL_CLEAR:
@@ -790,7 +790,7 @@ _mesa_ClampColor(GLenum target, GLenum clamp)
invalid_enum:
_mesa_error(ctx, GL_INVALID_ENUM, "glClampColor(%s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
}
static GLboolean
@@ -930,12 +930,10 @@ void _mesa_init_color( struct gl_context * ctx )
ctx->Color._ClampFragmentColor = GL_FALSE;
ctx->Color.ClampReadColor = GL_FIXED_ONLY_ARB;
- if (ctx->API == API_OPENGLES2) {
- /* GLES 3 behaves as though GL_FRAMEBUFFER_SRGB is always enabled. */
- ctx->Color.sRGBEnabled = GL_TRUE;
- } else {
- ctx->Color.sRGBEnabled = GL_FALSE;
- }
+ /* GLES 1/2/3 behaves as though GL_FRAMEBUFFER_SRGB is always enabled
+ * if EGL_KHR_gl_colorspace has been used to request sRGB.
+ */
+ ctx->Color.sRGBEnabled = _mesa_is_gles(ctx);
}
/*@}*/
diff --git a/src/mesa/main/blit.c b/src/mesa/main/blit.c
index db8fee5a414..a32f1a42aea 100644
--- a/src/mesa/main/blit.c
+++ b/src/mesa/main/blit.c
@@ -37,6 +37,7 @@
#include "framebuffer.h"
#include "glformats.h"
#include "mtypes.h"
+#include "macros.h"
#include "state.h"
@@ -59,6 +60,31 @@ find_attachment(const struct gl_framebuffer *fb,
/**
+ * \return true if two regions overlap, false otherwise
+ */
+bool
+_mesa_regions_overlap(int srcX0, int srcY0,
+ int srcX1, int srcY1,
+ int dstX0, int dstY0,
+ int dstX1, int dstY1)
+{
+ if (MAX2(srcX0, srcX1) < MIN2(dstX0, dstX1))
+ return false; /* dst completely right of src */
+
+ if (MAX2(dstX0, dstX1) < MIN2(srcX0, srcX1))
+ return false; /* dst completely left of src */
+
+ if (MAX2(srcY0, srcY1) < MIN2(dstY0, dstY1))
+ return false; /* dst completely above src */
+
+ if (MAX2(dstY0, dstY1) < MIN2(srcY0, srcY1))
+ return false; /* dst completely below src */
+
+ return true; /* some overlap */
+}
+
+
+/**
* Helper function for checking if the datatypes of color buffers are
* compatible for glBlitFramebuffer. From the 3.1 spec, page 198:
*
@@ -186,7 +212,7 @@ _mesa_blit_framebuffer(struct gl_context *ctx,
if (!is_valid_blit_filter(ctx, filter)) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid filter %s)", func,
- _mesa_lookup_enum_by_nr(filter));
+ _mesa_enum_to_string(filter));
return;
}
@@ -194,7 +220,7 @@ _mesa_blit_framebuffer(struct gl_context *ctx,
filter == GL_SCALED_RESOLVE_NICEST_EXT) &&
(readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s: invalid samples)", func,
- _mesa_lookup_enum_by_nr(filter));
+ _mesa_enum_to_string(filter));
return;
}
@@ -522,7 +548,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
" %d, %d, %d, %d, 0x%x, %s)\n",
srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1,
- mask, _mesa_lookup_enum_by_nr(filter));
+ mask, _mesa_enum_to_string(filter));
_mesa_blit_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
srcX0, srcY0, srcX1, srcY1,
@@ -547,7 +573,7 @@ _mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer,
readFramebuffer, drawFramebuffer,
srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1,
- mask, _mesa_lookup_enum_by_nr(filter));
+ mask, _mesa_enum_to_string(filter));
/*
* According to PDF page 533 of the OpenGL 4.5 core spec (30.10.2014,
diff --git a/src/mesa/main/blit.h b/src/mesa/main/blit.h
index 54b946e3192..88dd4a9ec8d 100644
--- a/src/mesa/main/blit.h
+++ b/src/mesa/main/blit.h
@@ -28,6 +28,12 @@
#include "glheader.h"
+extern bool
+_mesa_regions_overlap(int srcX0, int srcY0,
+ int srcX1, int srcY1,
+ int dstX0, int dstY0,
+ int dstX1, int dstY1);
+
extern void
_mesa_blit_framebuffer(struct gl_context *ctx,
struct gl_framebuffer *readFb,
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index 66dee680258..1cdea937f91 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -91,8 +91,9 @@ get_buffer_target(struct gl_context *ctx, GLenum target)
case GL_COPY_WRITE_BUFFER:
return &ctx->CopyWriteBuffer;
case GL_DRAW_INDIRECT_BUFFER:
- if (ctx->API == API_OPENGL_CORE &&
- ctx->Extensions.ARB_draw_indirect) {
+ if ((ctx->API == API_OPENGL_CORE &&
+ ctx->Extensions.ARB_draw_indirect) ||
+ _mesa_is_gles31(ctx)) {
return &ctx->DrawIndirectBuffer;
}
break;
@@ -112,6 +113,11 @@ get_buffer_target(struct gl_context *ctx, GLenum target)
return &ctx->UniformBuffer;
}
break;
+ case GL_SHADER_STORAGE_BUFFER:
+ if (ctx->Extensions.ARB_shader_storage_buffer_object) {
+ return &ctx->ShaderStorageBuffer;
+ }
+ break;
case GL_ATOMIC_COUNTER_BUFFER:
if (ctx->Extensions.ARB_shader_atomic_counters) {
return &ctx->AtomicBuffer;
@@ -831,6 +837,9 @@ _mesa_init_buffer_objects( struct gl_context *ctx )
_mesa_reference_buffer_object(ctx, &ctx->UniformBuffer,
ctx->Shared->NullBufferObj);
+ _mesa_reference_buffer_object(ctx, &ctx->ShaderStorageBuffer,
+ ctx->Shared->NullBufferObj);
+
_mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer,
ctx->Shared->NullBufferObj);
@@ -845,6 +854,14 @@ _mesa_init_buffer_objects( struct gl_context *ctx )
ctx->UniformBufferBindings[i].Size = -1;
}
+ for (i = 0; i < MAX_COMBINED_SHADER_STORAGE_BUFFERS; i++) {
+ _mesa_reference_buffer_object(ctx,
+ &ctx->ShaderStorageBufferBindings[i].BufferObject,
+ ctx->Shared->NullBufferObj);
+ ctx->ShaderStorageBufferBindings[i].Offset = -1;
+ ctx->ShaderStorageBufferBindings[i].Size = -1;
+ }
+
for (i = 0; i < MAX_COMBINED_ATOMIC_BUFFERS; i++) {
_mesa_reference_buffer_object(ctx,
&ctx->AtomicBufferBindings[i].BufferObject,
@@ -867,6 +884,8 @@ _mesa_free_buffer_objects( struct gl_context *ctx )
_mesa_reference_buffer_object(ctx, &ctx->UniformBuffer, NULL);
+ _mesa_reference_buffer_object(ctx, &ctx->ShaderStorageBuffer, NULL);
+
_mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, NULL);
_mesa_reference_buffer_object(ctx, &ctx->DrawIndirectBuffer, NULL);
@@ -877,6 +896,12 @@ _mesa_free_buffer_objects( struct gl_context *ctx )
NULL);
}
+ for (i = 0; i < MAX_COMBINED_SHADER_STORAGE_BUFFERS; i++) {
+ _mesa_reference_buffer_object(ctx,
+ &ctx->ShaderStorageBufferBindings[i].BufferObject,
+ NULL);
+ }
+
for (i = 0; i < MAX_COMBINED_ATOMIC_BUFFERS; i++) {
_mesa_reference_buffer_object(ctx,
&ctx->AtomicBufferBindings[i].BufferObject,
@@ -1158,7 +1183,7 @@ _mesa_BindBuffer(GLenum target, GLuint buffer)
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glBindBuffer(%s, %u)\n",
- _mesa_lookup_enum_by_nr(target), buffer);
+ _mesa_enum_to_string(target), buffer);
bind_buffer_object(ctx, target, buffer);
}
@@ -1240,6 +1265,17 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids)
_mesa_BindBuffer( GL_UNIFORM_BUFFER, 0 );
}
+ /* unbind SSBO binding points */
+ for (j = 0; j < ctx->Const.MaxShaderStorageBufferBindings; j++) {
+ if (ctx->ShaderStorageBufferBindings[j].BufferObject == bufObj) {
+ _mesa_BindBufferBase(GL_SHADER_STORAGE_BUFFER, j, 0);
+ }
+ }
+
+ if (ctx->ShaderStorageBuffer == bufObj) {
+ _mesa_BindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
+ }
+
/* unbind Atomci Buffer binding points */
for (j = 0; j < ctx->Const.MaxAtomicBufferBindings; j++) {
if (ctx->AtomicBufferBindings[j].BufferObject == bufObj) {
@@ -1500,9 +1536,9 @@ _mesa_buffer_data(struct gl_context *ctx, struct gl_buffer_object *bufObj,
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "%s(%s, %ld, %p, %s)\n",
func,
- _mesa_lookup_enum_by_nr(target),
+ _mesa_enum_to_string(target),
(long int) size, data,
- _mesa_lookup_enum_by_nr(usage));
+ _mesa_enum_to_string(usage));
if (size < 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "%s(size < 0)", func);
@@ -1535,7 +1571,7 @@ _mesa_buffer_data(struct gl_context *ctx, struct gl_buffer_object *bufObj,
if (!valid_usage) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid usage: %s)", func,
- _mesa_lookup_enum_by_nr(usage));
+ _mesa_enum_to_string(usage));
return;
}
@@ -1990,7 +2026,7 @@ get_buffer_parameter(struct gl_context *ctx,
invalid_pname:
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid pname: %s)", func,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
return false;
}
@@ -2337,7 +2373,7 @@ _mesa_map_buffer_range(struct gl_context *ctx,
if (offset + length > bufObj->Size) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "%s(offset %ld + length %ld > buffer_size %ld)", func,
+ "%s(offset %td + length %td > buffer_size %td)", func,
offset, length, bufObj->Size);
return NULL;
}
@@ -2999,6 +3035,33 @@ set_ubo_binding(struct gl_context *ctx,
}
/**
+ * Binds a buffer object to a shader storage buffer binding point.
+ *
+ * The caller is responsible for flushing vertices and updating
+ * NewDriverState.
+ */
+static void
+set_ssbo_binding(struct gl_context *ctx,
+ struct gl_shader_storage_buffer_binding *binding,
+ struct gl_buffer_object *bufObj,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLboolean autoSize)
+{
+ _mesa_reference_buffer_object(ctx, &binding->BufferObject, bufObj);
+
+ binding->Offset = offset;
+ binding->Size = size;
+ binding->AutomaticSize = autoSize;
+
+ /* If this is a real buffer object, mark it has having been used
+ * at some point as a SSBO.
+ */
+ if (size >= 0)
+ bufObj->UsageHistory |= USAGE_SHADER_STORAGE_BUFFER;
+}
+
+/**
* Binds a buffer object to a uniform buffer binding point.
*
* Unlike set_ubo_binding(), this function also flushes vertices
@@ -3030,6 +3093,37 @@ bind_uniform_buffer(struct gl_context *ctx,
}
/**
+ * Binds a buffer object to a shader storage buffer binding point.
+ *
+ * Unlike set_ssbo_binding(), this function also flushes vertices
+ * and updates NewDriverState. It also checks if the binding
+ * has actually changed before updating it.
+ */
+static void
+bind_shader_storage_buffer(struct gl_context *ctx,
+ GLuint index,
+ struct gl_buffer_object *bufObj,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLboolean autoSize)
+{
+ struct gl_shader_storage_buffer_binding *binding =
+ &ctx->ShaderStorageBufferBindings[index];
+
+ if (binding->BufferObject == bufObj &&
+ binding->Offset == offset &&
+ binding->Size == size &&
+ binding->AutomaticSize == autoSize) {
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, 0);
+ ctx->NewDriverState |= ctx->DriverFlags.NewShaderStorageBuffer;
+
+ set_ssbo_binding(ctx, binding, bufObj, offset, size, autoSize);
+}
+
+/**
* Bind a region of a buffer object to a uniform block binding point.
* \param index the uniform buffer binding point index
* \param bufObj the buffer object
@@ -3064,6 +3158,40 @@ bind_buffer_range_uniform_buffer(struct gl_context *ctx,
bind_uniform_buffer(ctx, index, bufObj, offset, size, GL_FALSE);
}
+/**
+ * Bind a region of a buffer object to a shader storage block binding point.
+ * \param index the shader storage buffer binding point index
+ * \param bufObj the buffer object
+ * \param offset offset to the start of buffer object region
+ * \param size size of the buffer object region
+ */
+static void
+bind_buffer_range_shader_storage_buffer(struct gl_context *ctx,
+ GLuint index,
+ struct gl_buffer_object *bufObj,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ if (index >= ctx->Const.MaxShaderStorageBufferBindings) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index);
+ return;
+ }
+
+ if (offset & (ctx->Const.ShaderStorageBufferOffsetAlignment - 1)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glBindBufferRange(offset misaligned %d/%d)", (int) offset,
+ ctx->Const.ShaderStorageBufferOffsetAlignment);
+ return;
+ }
+
+ if (bufObj == ctx->Shared->NullBufferObj) {
+ offset = -1;
+ size = -1;
+ }
+
+ _mesa_reference_buffer_object(ctx, &ctx->ShaderStorageBuffer, bufObj);
+ bind_shader_storage_buffer(ctx, index, bufObj, offset, size, GL_FALSE);
+}
/**
* Bind a buffer object to a uniform block binding point.
@@ -3088,6 +3216,28 @@ bind_buffer_base_uniform_buffer(struct gl_context *ctx,
}
/**
+ * Bind a buffer object to a shader storage block binding point.
+ * As above, but offset = 0.
+ */
+static void
+bind_buffer_base_shader_storage_buffer(struct gl_context *ctx,
+ GLuint index,
+ struct gl_buffer_object *bufObj)
+{
+ if (index >= ctx->Const.MaxShaderStorageBufferBindings) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index);
+ return;
+ }
+
+ _mesa_reference_buffer_object(ctx, &ctx->ShaderStorageBuffer, bufObj);
+
+ if (bufObj == ctx->Shared->NullBufferObj)
+ bind_shader_storage_buffer(ctx, index, bufObj, -1, -1, GL_TRUE);
+ else
+ bind_shader_storage_buffer(ctx, index, bufObj, 0, 0, GL_TRUE);
+}
+
+/**
* Binds a buffer object to an atomic buffer binding point.
*
* The caller is responsible for validating the offset,
@@ -3219,6 +3369,35 @@ error_check_bind_uniform_buffers(struct gl_context *ctx,
return true;
}
+static bool
+error_check_bind_shader_storage_buffers(struct gl_context *ctx,
+ GLuint first, GLsizei count,
+ const char *caller)
+{
+ if (!ctx->Extensions.ARB_shader_storage_buffer_object) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "%s(target=GL_SHADER_STORAGE_BUFFER)", caller);
+ return false;
+ }
+
+ /* The ARB_multi_bind_spec says:
+ *
+ * "An INVALID_OPERATION error is generated if <first> + <count> is
+ * greater than the number of target-specific indexed binding points,
+ * as described in section 6.7.1."
+ */
+ if (first + count > ctx->Const.MaxShaderStorageBufferBindings) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(first=%u + count=%d > the value of "
+ "GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS=%u)",
+ caller, first, count,
+ ctx->Const.MaxShaderStorageBufferBindings);
+ return false;
+ }
+
+ return true;
+}
+
/**
* Unbind all uniform buffers in the range
* <first> through <first>+<count>-1
@@ -3234,6 +3413,22 @@ unbind_uniform_buffers(struct gl_context *ctx, GLuint first, GLsizei count)
bufObj, -1, -1, GL_TRUE);
}
+/**
+ * Unbind all shader storage buffers in the range
+ * <first> through <first>+<count>-1
+ */
+static void
+unbind_shader_storage_buffers(struct gl_context *ctx, GLuint first,
+ GLsizei count)
+{
+ struct gl_buffer_object *bufObj = ctx->Shared->NullBufferObj;
+ GLint i;
+
+ for (i = 0; i < count; i++)
+ set_ssbo_binding(ctx, &ctx->ShaderStorageBufferBindings[first + i],
+ bufObj, -1, -1, GL_TRUE);
+}
+
static void
bind_uniform_buffers_base(struct gl_context *ctx, GLuint first, GLsizei count,
const GLuint *buffers)
@@ -3301,6 +3496,73 @@ bind_uniform_buffers_base(struct gl_context *ctx, GLuint first, GLsizei count,
}
static void
+bind_shader_storage_buffers_base(struct gl_context *ctx, GLuint first,
+ GLsizei count, const GLuint *buffers)
+{
+ GLint i;
+
+ if (!error_check_bind_shader_storage_buffers(ctx, first, count,
+ "glBindBuffersBase"))
+ return;
+
+ /* Assume that at least one binding will be changed */
+ FLUSH_VERTICES(ctx, 0);
+ ctx->NewDriverState |= ctx->DriverFlags.NewShaderStorageBuffer;
+
+ if (!buffers) {
+ /* The ARB_multi_bind spec says:
+ *
+ * "If <buffers> is NULL, all bindings from <first> through
+ * <first>+<count>-1 are reset to their unbound (zero) state."
+ */
+ unbind_shader_storage_buffers(ctx, first, count);
+ return;
+ }
+
+ /* Note that the error semantics for multi-bind commands differ from
+ * those of other GL commands.
+ *
+ * The Issues section in the ARB_multi_bind spec says:
+ *
+ * "(11) Typically, OpenGL specifies that if an error is generated by a
+ * command, that command has no effect. This is somewhat
+ * unfortunate for multi-bind commands, because it would require a
+ * first pass to scan the entire list of bound objects for errors
+ * and then a second pass to actually perform the bindings.
+ * Should we have different error semantics?
+ *
+ * RESOLVED: Yes. In this specification, when the parameters for
+ * one of the <count> binding points are invalid, that binding point
+ * is not updated and an error will be generated. However, other
+ * binding points in the same command will be updated if their
+ * parameters are valid and no other error occurs."
+ */
+
+ _mesa_begin_bufferobj_lookups(ctx);
+
+ for (i = 0; i < count; i++) {
+ struct gl_shader_storage_buffer_binding *binding =
+ &ctx->ShaderStorageBufferBindings[first + i];
+ struct gl_buffer_object *bufObj;
+
+ if (binding->BufferObject && binding->BufferObject->Name == buffers[i])
+ bufObj = binding->BufferObject;
+ else
+ bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i,
+ "glBindBuffersBase");
+
+ if (bufObj) {
+ if (bufObj == ctx->Shared->NullBufferObj)
+ set_ssbo_binding(ctx, binding, bufObj, -1, -1, GL_TRUE);
+ else
+ set_ssbo_binding(ctx, binding, bufObj, 0, 0, GL_TRUE);
+ }
+ }
+
+ _mesa_end_bufferobj_lookups(ctx);
+}
+
+static void
bind_uniform_buffers_range(struct gl_context *ctx, GLuint first, GLsizei count,
const GLuint *buffers,
const GLintptr *offsets, const GLsizeiptr *sizes)
@@ -3405,6 +3667,112 @@ bind_uniform_buffers_range(struct gl_context *ctx, GLuint first, GLsizei count,
_mesa_end_bufferobj_lookups(ctx);
}
+static void
+bind_shader_storage_buffers_range(struct gl_context *ctx, GLuint first,
+ GLsizei count, const GLuint *buffers,
+ const GLintptr *offsets,
+ const GLsizeiptr *sizes)
+{
+ GLint i;
+
+ if (!error_check_bind_shader_storage_buffers(ctx, first, count,
+ "glBindBuffersRange"))
+ return;
+
+ /* Assume that at least one binding will be changed */
+ FLUSH_VERTICES(ctx, 0);
+ ctx->NewDriverState |= ctx->DriverFlags.NewShaderStorageBuffer;
+
+ if (!buffers) {
+ /* The ARB_multi_bind spec says:
+ *
+ * "If <buffers> is NULL, all bindings from <first> through
+ * <first>+<count>-1 are reset to their unbound (zero) state.
+ * In this case, the offsets and sizes associated with the
+ * binding points are set to default values, ignoring
+ * <offsets> and <sizes>."
+ */
+ unbind_shader_storage_buffers(ctx, first, count);
+ return;
+ }
+
+ /* Note that the error semantics for multi-bind commands differ from
+ * those of other GL commands.
+ *
+ * The Issues section in the ARB_multi_bind spec says:
+ *
+ * "(11) Typically, OpenGL specifies that if an error is generated by a
+ * command, that command has no effect. This is somewhat
+ * unfortunate for multi-bind commands, because it would require a
+ * first pass to scan the entire list of bound objects for errors
+ * and then a second pass to actually perform the bindings.
+ * Should we have different error semantics?
+ *
+ * RESOLVED: Yes. In this specification, when the parameters for
+ * one of the <count> binding points are invalid, that binding point
+ * is not updated and an error will be generated. However, other
+ * binding points in the same command will be updated if their
+ * parameters are valid and no other error occurs."
+ */
+
+ _mesa_begin_bufferobj_lookups(ctx);
+
+ for (i = 0; i < count; i++) {
+ struct gl_shader_storage_buffer_binding *binding =
+ &ctx->ShaderStorageBufferBindings[first + i];
+ struct gl_buffer_object *bufObj;
+
+ if (!bind_buffers_check_offset_and_size(ctx, i, offsets, sizes))
+ continue;
+
+ /* The ARB_multi_bind spec says:
+ *
+ * "An INVALID_VALUE error is generated by BindBuffersRange if any
+ * pair of values in <offsets> and <sizes> does not respectively
+ * satisfy the constraints described for those parameters for the
+ * specified target, as described in section 6.7.1 (per binding)."
+ *
+ * Section 6.7.1 refers to table 6.5, which says:
+ *
+ * "┌───────────────────────────────────────────────────────────────┐
+ * │ Shader storage buffer array bindings (see sec. 7.8) │
+ * ├─────────────────────┬─────────────────────────────────────────┤
+ * │ ... │ ... │
+ * │ offset restriction │ multiple of value of SHADER_STORAGE_- │
+ * │ │ BUFFER_OFFSET_ALIGNMENT │
+ * │ ... │ ... │
+ * │ size restriction │ none │
+ * └─────────────────────┴─────────────────────────────────────────┘"
+ */
+ if (offsets[i] & (ctx->Const.ShaderStorageBufferOffsetAlignment - 1)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glBindBuffersRange(offsets[%u]=%" PRId64
+ " is misaligned; it must be a multiple of the value of "
+ "GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT=%u when "
+ "target=GL_SHADER_STORAGE_BUFFER)",
+ i, (int64_t) offsets[i],
+ ctx->Const.ShaderStorageBufferOffsetAlignment);
+ continue;
+ }
+
+ if (binding->BufferObject && binding->BufferObject->Name == buffers[i])
+ bufObj = binding->BufferObject;
+ else
+ bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i,
+ "glBindBuffersRange");
+
+ if (bufObj) {
+ if (bufObj == ctx->Shared->NullBufferObj)
+ set_ssbo_binding(ctx, binding, bufObj, -1, -1, GL_FALSE);
+ else
+ set_ssbo_binding(ctx, binding, bufObj,
+ offsets[i], sizes[i], GL_FALSE);
+ }
+ }
+
+ _mesa_end_bufferobj_lookups(ctx);
+}
+
static bool
error_check_bind_xfb_buffers(struct gl_context *ctx,
struct gl_transform_feedback_object *tfObj,
@@ -3894,6 +4262,9 @@ _mesa_BindBufferRange(GLenum target, GLuint index,
case GL_UNIFORM_BUFFER:
bind_buffer_range_uniform_buffer(ctx, index, bufObj, offset, size);
return;
+ case GL_SHADER_STORAGE_BUFFER:
+ bind_buffer_range_shader_storage_buffer(ctx, index, bufObj, offset, size);
+ return;
case GL_ATOMIC_COUNTER_BUFFER:
bind_atomic_buffer(ctx, index, bufObj, offset, size,
"glBindBufferRange");
@@ -3960,6 +4331,9 @@ _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
case GL_UNIFORM_BUFFER:
bind_buffer_base_uniform_buffer(ctx, index, bufObj);
return;
+ case GL_SHADER_STORAGE_BUFFER:
+ bind_buffer_base_shader_storage_buffer(ctx, index, bufObj);
+ return;
case GL_ATOMIC_COUNTER_BUFFER:
bind_atomic_buffer(ctx, index, bufObj, 0, 0,
"glBindBufferBase");
@@ -3984,13 +4358,17 @@ _mesa_BindBuffersRange(GLenum target, GLuint first, GLsizei count,
case GL_UNIFORM_BUFFER:
bind_uniform_buffers_range(ctx, first, count, buffers, offsets, sizes);
return;
+ case GL_SHADER_STORAGE_BUFFER:
+ bind_shader_storage_buffers_range(ctx, first, count, buffers, offsets,
+ sizes);
+ return;
case GL_ATOMIC_COUNTER_BUFFER:
bind_atomic_buffers_range(ctx, first, count, buffers,
offsets, sizes);
return;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glBindBuffersRange(target=%s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
break;
}
}
@@ -4008,12 +4386,15 @@ _mesa_BindBuffersBase(GLenum target, GLuint first, GLsizei count,
case GL_UNIFORM_BUFFER:
bind_uniform_buffers_base(ctx, first, count, buffers);
return;
+ case GL_SHADER_STORAGE_BUFFER:
+ bind_shader_storage_buffers_base(ctx, first, count, buffers);
+ return;
case GL_ATOMIC_COUNTER_BUFFER:
bind_atomic_buffers_base(ctx, first, count, buffers);
return;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glBindBuffersBase(target=%s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
break;
}
}
diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c
index 0536266d756..93588a2ee18 100644
--- a/src/mesa/main/buffers.c
+++ b/src/mesa/main/buffers.c
@@ -251,7 +251,7 @@ _mesa_draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb,
FLUSH_VERTICES(ctx, 0);
if (MESA_VERBOSE & VERBOSE_API) {
- _mesa_debug(ctx, "%s %s\n", caller, _mesa_lookup_enum_by_nr(buffer));
+ _mesa_debug(ctx, "%s %s\n", caller, _mesa_enum_to_string(buffer));
}
if (buffer == GL_NONE) {
@@ -264,14 +264,14 @@ _mesa_draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb,
if (destMask == BAD_MASK) {
/* totally bogus buffer */
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)", caller,
- _mesa_lookup_enum_by_nr(buffer));
+ _mesa_enum_to_string(buffer));
return;
}
destMask &= supportedMask;
if (destMask == 0x0) {
/* none of the named color buffers exist! */
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid buffer %s)",
- caller, _mesa_lookup_enum_by_nr(buffer));
+ caller, _mesa_enum_to_string(buffer));
return;
}
}
@@ -411,7 +411,7 @@ _mesa_draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
*/
if (destMask[output] == BAD_MASK) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)",
- caller, _mesa_lookup_enum_by_nr(buffers[output]));
+ caller, _mesa_enum_to_string(buffers[output]));
return;
}
@@ -427,7 +427,7 @@ _mesa_draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
*/
if (_mesa_bitcount(destMask[output]) > 1) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)",
- caller, _mesa_lookup_enum_by_nr(buffers[output]));
+ caller, _mesa_enum_to_string(buffers[output]));
return;
}
@@ -445,7 +445,7 @@ _mesa_draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
if (destMask[output] == 0) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(unsupported buffer %s)",
- caller, _mesa_lookup_enum_by_nr(buffers[output]));
+ caller, _mesa_enum_to_string(buffers[output]));
return;
}
@@ -459,7 +459,7 @@ _mesa_draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
buffers[output] != GL_COLOR_ATTACHMENT0 + output) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(unsupported buffer %s)",
- caller, _mesa_lookup_enum_by_nr(buffers[output]));
+ caller, _mesa_enum_to_string(buffers[output]));
return;
}
@@ -471,7 +471,7 @@ _mesa_draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
if (destMask[output] & usedBufferMask) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(duplicated buffer %s)",
- caller, _mesa_lookup_enum_by_nr(buffers[output]));
+ caller, _mesa_enum_to_string(buffers[output]));
return;
}
@@ -700,7 +700,7 @@ _mesa_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb,
FLUSH_VERTICES(ctx, 0);
if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "%s %s\n", caller, _mesa_lookup_enum_by_nr(buffer));
+ _mesa_debug(ctx, "%s %s\n", caller, _mesa_enum_to_string(buffer));
if (buffer == GL_NONE) {
/* This is legal--it means that no buffer should be bound for reading. */
@@ -712,14 +712,14 @@ _mesa_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb,
if (srcBuffer == -1) {
_mesa_error(ctx, GL_INVALID_ENUM,
"%s(invalid buffer %s)", caller,
- _mesa_lookup_enum_by_nr(buffer));
+ _mesa_enum_to_string(buffer));
return;
}
supportedMask = supported_buffer_bitmask(ctx, fb);
if (((1 << srcBuffer) & supportedMask) == 0) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(invalid buffer %s)", caller,
- _mesa_lookup_enum_by_nr(buffer));
+ _mesa_enum_to_string(buffer));
return;
}
}
diff --git a/src/mesa/main/clear.c b/src/mesa/main/clear.c
index 426caea4709..3bfcc5c0e39 100644
--- a/src/mesa/main/clear.c
+++ b/src/mesa/main/clear.c
@@ -325,6 +325,18 @@ _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
_mesa_update_state( ctx );
}
+ /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
+ * of the OpenGL 4.5 spec states:
+ *
+ * "An INVALID_ENUM error is generated by ClearBufferiv and
+ * ClearNamedFramebufferiv if buffer is not COLOR or STENCIL."
+ */
+ if (buffer == GL_DEPTH || buffer == GL_DEPTH_STENCIL) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glClearBufferiv(buffer=GL_DEPTH || GL_DEPTH_STENCIL)");
+ return;
+ }
+
switch (buffer) {
case GL_STENCIL:
/* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
@@ -395,7 +407,7 @@ _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
return;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)",
- _mesa_lookup_enum_by_nr(buffer));
+ _mesa_enum_to_string(buffer));
return;
}
}
@@ -485,7 +497,7 @@ _mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
return;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)",
- _mesa_lookup_enum_by_nr(buffer));
+ _mesa_enum_to_string(buffer));
return;
}
}
@@ -596,7 +608,7 @@ _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
return;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)",
- _mesa_lookup_enum_by_nr(buffer));
+ _mesa_enum_to_string(buffer));
return;
}
}
@@ -636,7 +648,7 @@ _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
if (buffer != GL_DEPTH_STENCIL) {
_mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)",
- _mesa_lookup_enum_by_nr(buffer));
+ _mesa_enum_to_string(buffer));
return;
}
diff --git a/src/mesa/main/condrender.c b/src/mesa/main/condrender.c
index 77e4b95ee8f..46c6036d2a5 100644
--- a/src/mesa/main/condrender.c
+++ b/src/mesa/main/condrender.c
@@ -87,7 +87,7 @@ _mesa_BeginConditionalRender(GLuint queryId, GLenum mode)
/* fallthrough - invalid */
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glBeginConditionalRender(mode=%s)",
- _mesa_lookup_enum_by_nr(mode));
+ _mesa_enum_to_string(mode));
return;
}
@@ -184,7 +184,7 @@ _mesa_check_conditional_render(struct gl_context *ctx)
default:
_mesa_problem(ctx, "Bad cond render mode %s in "
" _mesa_check_conditional_render()",
- _mesa_lookup_enum_by_nr(ctx->Query.CondRenderMode));
+ _mesa_enum_to_string(ctx->Query.CondRenderMode));
return GL_TRUE;
}
}
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index 9c3baf4c6aa..b35031db3c9 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -171,8 +171,10 @@
#define MAX_PROGRAM_LOCAL_PARAMS 4096
#define MAX_UNIFORMS 4096
#define MAX_UNIFORM_BUFFERS 15 /* + 1 default uniform buffer */
+#define MAX_SHADER_STORAGE_BUFFERS 7 /* + 1 default shader storage buffer */
/* 6 is for vertex, hull, domain, geometry, fragment, and compute shader. */
#define MAX_COMBINED_UNIFORM_BUFFERS (MAX_UNIFORM_BUFFERS * 6)
+#define MAX_COMBINED_SHADER_STORAGE_BUFFERS (MAX_SHADER_STORAGE_BUFFERS * 6)
#define MAX_ATOMIC_COUNTERS 4096
/* 6 is for vertex, hull, domain, geometry, fragment, and compute shader. */
#define MAX_COMBINED_ATOMIC_BUFFERS (MAX_UNIFORM_BUFFERS * 6)
@@ -272,6 +274,12 @@
#define MAX_VERTEX_STREAMS 4
/*@}*/
+/** For GL_ARB_shader_subroutine */
+/*@{*/
+#define MAX_SUBROUTINES 256
+#define MAX_SUBROUTINE_UNIFORM_LOCATIONS 1024
+/*@}*/
+
/** For GL_INTEL_performance_query */
/*@{*/
#define MAX_PERFQUERY_QUERY_NAME_LENGTH 256
@@ -294,6 +302,14 @@
/** For GL_ARB_pipeline_statistics_query */
#define MAX_PIPELINE_STATISTICS 11
+/** For GL_ARB_tessellation_shader */
+/*@{*/
+#define MAX_TESS_GEN_LEVEL 64
+#define MAX_PATCH_VERTICES 32
+#define MAX_TESS_PATCH_COMPONENTS 120
+#define MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 4096
+/*@}*/
+
/*
* Color channel component order
*
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 79fa01849e0..888c461d1c2 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -120,6 +120,7 @@
#include "shaderobj.h"
#include "shaderimage.h"
#include "util/simple_list.h"
+#include "util/strtod.h"
#include "state.h"
#include "stencil.h"
#include "texcompress_s3tc.h"
@@ -338,31 +339,6 @@ _mesa_destroy_visual( struct gl_config *vis )
/**
- * This is lame. gdb only seems to recognize enum types that are
- * actually used somewhere. We want to be able to print/use enum
- * values such as TEXTURE_2D_INDEX in gdb. But we don't actually use
- * the gl_texture_index type anywhere. Thus, this lame function.
- */
-static void
-dummy_enum_func(void)
-{
- gl_buffer_index bi = BUFFER_FRONT_LEFT;
- gl_face_index fi = FACE_POS_X;
- gl_frag_result fr = FRAG_RESULT_DEPTH;
- gl_texture_index ti = TEXTURE_2D_ARRAY_INDEX;
- gl_vert_attrib va = VERT_ATTRIB_POS;
- gl_varying_slot vs = VARYING_SLOT_POS;
-
- (void) bi;
- (void) fi;
- (void) fr;
- (void) ti;
- (void) va;
- (void) vs;
-}
-
-
-/**
* One-time initialization mutex lock.
*
* \sa Used by one_time_init().
@@ -370,6 +346,16 @@ dummy_enum_func(void)
mtx_t OneTimeLock = _MTX_INITIALIZER_NP;
+/**
+ * Calls all the various one-time-fini functions in Mesa
+ */
+
+static void
+one_time_fini(void)
+{
+ _mesa_destroy_shader_compiler();
+ _mesa_locale_fini();
+}
/**
* Calls all the various one-time-init functions in Mesa.
@@ -391,13 +377,14 @@ one_time_init( struct gl_context *ctx )
if (!api_init_mask) {
GLuint i;
- /* do some implementation tests */
- assert( sizeof(GLbyte) == 1 );
- assert( sizeof(GLubyte) == 1 );
- assert( sizeof(GLshort) == 2 );
- assert( sizeof(GLushort) == 2 );
- assert( sizeof(GLint) == 4 );
- assert( sizeof(GLuint) == 4 );
+ STATIC_ASSERT(sizeof(GLbyte) == 1);
+ STATIC_ASSERT(sizeof(GLubyte) == 1);
+ STATIC_ASSERT(sizeof(GLshort) == 2);
+ STATIC_ASSERT(sizeof(GLushort) == 2);
+ STATIC_ASSERT(sizeof(GLint) == 4);
+ STATIC_ASSERT(sizeof(GLuint) == 4);
+
+ _mesa_locale_init();
_mesa_one_time_init_extension_overrides();
@@ -407,6 +394,8 @@ one_time_init( struct gl_context *ctx )
_mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
}
+ atexit(one_time_fini);
+
#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
if (MESA_VERBOSE != 0) {
_mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n",
@@ -429,13 +418,6 @@ one_time_init( struct gl_context *ctx )
api_init_mask |= 1 << ctx->API;
mtx_unlock(&OneTimeLock);
-
- /* Hopefully atexit() is widely available. If not, we may need some
- * #ifdef tests here.
- */
- atexit(_mesa_destroy_shader_compiler);
-
- dummy_enum_func();
}
@@ -496,6 +478,8 @@ init_program_limits(struct gl_constants *consts, gl_shader_stage stage,
prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */
prog->MaxOutputComponents = 0; /* value not used */
break;
+ case MESA_SHADER_TESS_CTRL:
+ case MESA_SHADER_TESS_EVAL:
case MESA_SHADER_GEOMETRY:
prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS;
@@ -554,6 +538,8 @@ init_program_limits(struct gl_constants *consts, gl_shader_stage stage,
prog->MaxAtomicBuffers = 0;
prog->MaxAtomicCounters = 0;
+
+ prog->MaxShaderStorageBlocks = 8;
}
@@ -615,6 +601,12 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api)
consts->MaxUniformBlockSize = 16384;
consts->UniformBufferOffsetAlignment = 1;
+ /** GL_ARB_shader_storage_buffer_object */
+ consts->MaxCombinedShaderStorageBlocks = 8;
+ consts->MaxShaderStorageBufferBindings = 8;
+ consts->MaxShaderStorageBlockSize = 128 * 1024 * 1024; /* 2^27 */
+ consts->ShaderStorageBufferOffsetAlignment = 256;
+
/* GL_ARB_explicit_uniform_location, GL_MAX_UNIFORM_LOCATIONS */
consts->MaxUserAssignableUniformLocations =
4 * MESA_SHADER_STAGES * MAX_UNIFORMS;
@@ -724,6 +716,14 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api)
/** GL_KHR_context_flush_control */
consts->ContextReleaseBehavior = GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH;
+
+ /** GL_ARB_tessellation_shader */
+ consts->MaxTessGenLevel = MAX_TESS_GEN_LEVEL;
+ consts->MaxPatchVertices = MAX_PATCH_VERTICES;
+ consts->Program[MESA_SHADER_TESS_CTRL].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
+ consts->Program[MESA_SHADER_TESS_EVAL].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
+ consts->MaxTessPatchComponents = MAX_TESS_PATCH_COMPONENTS;
+ consts->MaxTessControlTotalOutputComponents = MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS;
}
@@ -1331,6 +1331,8 @@ _mesa_free_context_data( struct gl_context *ctx )
_mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
_mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
+ _mesa_reference_tesscprog(ctx, &ctx->TessCtrlProgram._Current, NULL);
+ _mesa_reference_tesseprog(ctx, &ctx->TessEvalProgram._Current, NULL);
_mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL);
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h
index 6f3c941016f..0f7529ad975 100644
--- a/src/mesa/main/context.h
+++ b/src/mesa/main/context.h
@@ -343,6 +343,26 @@ _mesa_has_compute_shaders(const struct gl_context *ctx)
(ctx->API == API_OPENGLES2 && ctx->Version >= 31);
}
+/**
+ * Checks if the context supports shader subroutines.
+ */
+static inline bool
+_mesa_has_shader_subroutine(const struct gl_context *ctx)
+{
+ return ctx->API == API_OPENGL_CORE &&
+ (ctx->Version >= 40 || ctx->Extensions.ARB_shader_subroutine);
+}
+
+/**
+ * Checks if the context supports tessellation.
+ */
+static inline GLboolean
+_mesa_has_tessellation(const struct gl_context *ctx)
+{
+ return ctx->API == API_OPENGL_CORE &&
+ ctx->Extensions.ARB_tessellation_shader;
+}
+
#ifdef __cplusplus
}
diff --git a/src/mesa/main/copyimage.c b/src/mesa/main/copyimage.c
index e8732c6175b..05bc50dd2c6 100644
--- a/src/mesa/main/copyimage.c
+++ b/src/mesa/main/copyimage.c
@@ -93,7 +93,7 @@ prepare_target(struct gl_context *ctx, GLuint name, GLenum *target, int level,
default:
_mesa_error(ctx, GL_INVALID_ENUM,
"glCopyImageSubData(%sTarget = %s)", dbg_prefix,
- _mesa_lookup_enum_by_nr(*target));
+ _mesa_enum_to_string(*target));
return false;
}
@@ -159,7 +159,7 @@ prepare_target(struct gl_context *ctx, GLuint name, GLenum *target, int level,
if ((*tex_obj)->Target != *target) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glCopyImageSubData(%sTarget = %s)", dbg_prefix,
- _mesa_lookup_enum_by_nr(*target));
+ _mesa_enum_to_string(*target));
return false;
}
@@ -416,9 +416,9 @@ _mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel,
_mesa_debug(ctx, "glCopyImageSubData(%u, %s, %d, %d, %d, %d, "
"%u, %s, %d, %d, %d, %d, "
"%d, %d, %d)\n",
- srcName, _mesa_lookup_enum_by_nr(srcTarget), srcLevel,
+ srcName, _mesa_enum_to_string(srcTarget), srcLevel,
srcX, srcY, srcZ,
- dstName, _mesa_lookup_enum_by_nr(dstTarget), dstLevel,
+ dstName, _mesa_enum_to_string(dstTarget), dstLevel,
dstX, dstY, dstZ,
srcWidth, srcHeight, srcWidth);
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index d783e34222f..87eb63ea374 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -232,11 +232,13 @@ struct dd_function_table {
/**
- * Called by glGetTexImage().
+ * Called by glGetTexImage(), glGetTextureSubImage().
*/
- void (*GetTexImage)( struct gl_context *ctx,
- GLenum format, GLenum type, GLvoid *pixels,
- struct gl_texture_image *texImage );
+ void (*GetTexSubImage)(struct gl_context *ctx,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, GLvoid *pixels,
+ struct gl_texture_image *texImage);
/**
* Called by glClearTex[Sub]Image
@@ -326,16 +328,19 @@ struct dd_function_table {
void (*CompressedTexSubImage)(struct gl_context *ctx, GLuint dims,
struct gl_texture_image *texImage,
GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLint height, GLint depth,
+ GLsizei width, GLsizei height, GLsizei depth,
GLenum format,
GLsizei imageSize, const GLvoid *data);
/**
* Called by glGetCompressedTexImage.
*/
- void (*GetCompressedTexImage)(struct gl_context *ctx,
- struct gl_texture_image *texImage,
- GLvoid *data);
+ void (*GetCompressedTexSubImage)(struct gl_context *ctx,
+ struct gl_texture_image *texImage,
+ GLint xoffset, GLint yoffset,
+ GLint zoffset, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLvoid *data);
/*@}*/
/**
diff --git a/src/mesa/main/debug.c b/src/mesa/main/debug.c
index c93e84a04d0..5ca7d5ce500 100644
--- a/src/mesa/main/debug.c
+++ b/src/mesa/main/debug.c
@@ -272,7 +272,9 @@ write_texture_image(struct gl_texture_object *texObj,
store = ctx->Pack; /* save */
ctx->Pack = ctx->DefaultPacking;
- ctx->Driver.GetTexImage(ctx, GL_RGBA, GL_UNSIGNED_BYTE, buffer, img);
+ ctx->Driver.GetTexSubImage(ctx,
+ 0, 0, 0, img->Width, img->Height, img->Depth,
+ GL_RGBA, GL_UNSIGNED_BYTE, buffer, img);
/* make filename */
_mesa_snprintf(s, sizeof(s), "/tmp/tex%u.l%u.f%u.ppm", texObj->Name, level, face);
@@ -411,7 +413,7 @@ dump_renderbuffer(const struct gl_renderbuffer *rb, GLboolean writeImage)
{
printf("Renderbuffer %u: %u x %u IntFormat = %s\n",
rb->Name, rb->Width, rb->Height,
- _mesa_lookup_enum_by_nr(rb->InternalFormat));
+ _mesa_enum_to_string(rb->InternalFormat));
if (writeImage) {
_mesa_write_renderbuffer_image(rb);
}
diff --git a/src/mesa/main/depth.c b/src/mesa/main/depth.c
index bb4591cf152..c3534407599 100644
--- a/src/mesa/main/depth.c
+++ b/src/mesa/main/depth.c
@@ -63,7 +63,7 @@ _mesa_DepthFunc( GLenum func )
GET_CURRENT_CONTEXT(ctx);
if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glDepthFunc %s\n", _mesa_lookup_enum_by_nr(func));
+ _mesa_debug(ctx, "glDepthFunc %s\n", _mesa_enum_to_string(func));
if (ctx->Depth.Func == func)
return;
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index aafe486fb60..5554738d1a3 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -9000,7 +9000,7 @@ _mesa_NewList(GLuint name, GLenum mode)
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glNewList %u %s\n", name,
- _mesa_lookup_enum_by_nr(mode));
+ _mesa_enum_to_string(mode));
if (name == 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glNewList");
@@ -9688,7 +9688,7 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
static const char *
enum_string(GLenum k)
{
- return _mesa_lookup_enum_by_nr(k);
+ return _mesa_enum_to_string(k);
}
@@ -9827,19 +9827,19 @@ print_list(struct gl_context *ctx, GLuint list, const char *fname)
break;
case OPCODE_BIND_TEXTURE:
fprintf(f, "BindTexture %s %d\n",
- _mesa_lookup_enum_by_nr(n[1].ui), n[2].ui);
+ _mesa_enum_to_string(n[1].ui), n[2].ui);
break;
case OPCODE_SHADE_MODEL:
- fprintf(f, "ShadeModel %s\n", _mesa_lookup_enum_by_nr(n[1].ui));
+ fprintf(f, "ShadeModel %s\n", _mesa_enum_to_string(n[1].ui));
break;
case OPCODE_MAP1:
fprintf(f, "Map1 %s %.3f %.3f %d %d\n",
- _mesa_lookup_enum_by_nr(n[1].ui),
+ _mesa_enum_to_string(n[1].ui),
n[2].f, n[3].f, n[4].i, n[5].i);
break;
case OPCODE_MAP2:
fprintf(f, "Map2 %s %.3f %.3f %.3f %.3f %d %d %d %d\n",
- _mesa_lookup_enum_by_nr(n[1].ui),
+ _mesa_enum_to_string(n[1].ui),
n[2].f, n[3].f, n[4].f, n[5].f,
n[6].i, n[7].i, n[8].i, n[9].i);
break;
@@ -9918,7 +9918,7 @@ print_list(struct gl_context *ctx, GLuint list, const char *fname)
case OPCODE_PROVOKING_VERTEX:
fprintf(f, "ProvokingVertex %s\n",
- _mesa_lookup_enum_by_nr(n[1].ui));
+ _mesa_enum_to_string(n[1].ui));
break;
/*
diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c
index 55035f214b3..720a082ce6d 100644
--- a/src/mesa/main/drawpix.c
+++ b/src/mesa/main/drawpix.c
@@ -53,10 +53,10 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glDrawPixels(%d, %d, %s, %s, %p) // to %s at %d, %d\n",
width, height,
- _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type),
+ _mesa_enum_to_string(format),
+ _mesa_enum_to_string(type),
pixels,
- _mesa_lookup_enum_by_nr(ctx->DrawBuffer->ColorDrawBuffer[0]),
+ _mesa_enum_to_string(ctx->DrawBuffer->ColorDrawBuffer[0]),
IROUND(ctx->Current.RasterPos[0]),
IROUND(ctx->Current.RasterPos[1]));
@@ -96,8 +96,8 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
err = _mesa_error_check_format_and_type(ctx, format, type);
if (err != GL_NO_ERROR) {
_mesa_error(ctx, err, "glDrawPixels(invalid format %s and/or type %s)",
- _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type));
+ _mesa_enum_to_string(format),
+ _mesa_enum_to_string(type));
goto end;
}
@@ -198,9 +198,9 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
_mesa_debug(ctx,
"glCopyPixels(%d, %d, %d, %d, %s) // from %s to %s at %d, %d\n",
srcx, srcy, width, height,
- _mesa_lookup_enum_by_nr(type),
- _mesa_lookup_enum_by_nr(ctx->ReadBuffer->ColorReadBuffer),
- _mesa_lookup_enum_by_nr(ctx->DrawBuffer->ColorDrawBuffer[0]),
+ _mesa_enum_to_string(type),
+ _mesa_enum_to_string(ctx->ReadBuffer->ColorReadBuffer),
+ _mesa_enum_to_string(ctx->DrawBuffer->ColorDrawBuffer[0]),
IROUND(ctx->Current.RasterPos[0]),
IROUND(ctx->Current.RasterPos[1]));
@@ -218,7 +218,7 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
type != GL_STENCIL &&
type != GL_DEPTH_STENCIL) {
_mesa_error(ctx, GL_INVALID_ENUM, "glCopyPixels(type=%s)",
- _mesa_lookup_enum_by_nr(type));
+ _mesa_enum_to_string(type));
return;
}
diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c
index 9008a386343..42f67990784 100644
--- a/src/mesa/main/enable.c
+++ b/src/mesa/main/enable.c
@@ -146,7 +146,7 @@ client_state(struct gl_context *ctx, GLenum cap, GLboolean state)
invalid_enum_error:
_mesa_error(ctx, GL_INVALID_ENUM, "gl%sClientState(%s)",
- state ? "Enable" : "Disable", _mesa_lookup_enum_by_nr(cap));
+ state ? "Enable" : "Disable", _mesa_enum_to_string(cap));
}
@@ -283,7 +283,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "%s %s (newstate is %x)\n",
state ? "glEnable" : "glDisable",
- _mesa_lookup_enum_by_nr(cap),
+ _mesa_enum_to_string(cap),
ctx->NewState);
switch (cap) {
@@ -1001,7 +1001,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
/* ARB_texture_multisample */
case GL_SAMPLE_MASK:
- if (!_mesa_is_desktop_gl(ctx))
+ if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles31(ctx))
goto invalid_enum_error;
CHECK_EXTENSION(ARB_texture_multisample, cap);
if (ctx->Multisample.SampleMask == state)
@@ -1022,7 +1022,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
invalid_enum_error:
_mesa_error(ctx, GL_INVALID_ENUM, "gl%s(%s)",
- state ? "Enable" : "Disable", _mesa_lookup_enum_by_nr(cap));
+ state ? "Enable" : "Disable", _mesa_enum_to_string(cap));
}
@@ -1101,7 +1101,7 @@ _mesa_set_enablei(struct gl_context *ctx, GLenum cap,
invalid_enum_error:
_mesa_error(ctx, GL_INVALID_ENUM, "%s(cap=%s)",
state ? "glEnablei" : "glDisablei",
- _mesa_lookup_enum_by_nr(cap));
+ _mesa_enum_to_string(cap));
}
@@ -1143,7 +1143,7 @@ _mesa_IsEnabledi( GLenum cap, GLuint index )
return (ctx->Scissor.EnableFlags >> index) & 1;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabledIndexed(cap=%s)",
- _mesa_lookup_enum_by_nr(cap));
+ _mesa_enum_to_string(cap));
return GL_FALSE;
}
}
@@ -1603,7 +1603,7 @@ _mesa_IsEnabled( GLenum cap )
/* ARB_texture_multisample */
case GL_SAMPLE_MASK:
- if (!_mesa_is_desktop_gl(ctx))
+ if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles31(ctx))
goto invalid_enum_error;
CHECK_EXTENSION(ARB_texture_multisample);
return ctx->Multisample.SampleMask;
@@ -1623,6 +1623,6 @@ _mesa_IsEnabled( GLenum cap )
invalid_enum_error:
_mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled(%s)",
- _mesa_lookup_enum_by_nr(cap));
+ _mesa_enum_to_string(cap));
return GL_FALSE;
}
diff --git a/src/mesa/main/enums.h b/src/mesa/main/enums.h
index 66bdd53bbab..0e18cd407e9 100644
--- a/src/mesa/main/enums.h
+++ b/src/mesa/main/enums.h
@@ -42,7 +42,7 @@ extern "C" {
#endif
-extern const char *_mesa_lookup_enum_by_nr( int nr );
+extern const char *_mesa_enum_to_string( int nr );
/* Get the name of an enum given that it is a primitive type. Avoids
* GL_FALSE/GL_POINTS ambiguity and others.
diff --git a/src/mesa/main/errors.c b/src/mesa/main/errors.c
index b3406665d94..f720de316e4 100644
--- a/src/mesa/main/errors.c
+++ b/src/mesa/main/errors.c
@@ -1314,7 +1314,7 @@ flush_delayed_errors( struct gl_context *ctx )
if (ctx->ErrorDebugCount) {
_mesa_snprintf(s, MAX_DEBUG_MESSAGE_LENGTH, "%d similar %s errors",
ctx->ErrorDebugCount,
- _mesa_lookup_enum_by_nr(ctx->ErrorValue));
+ _mesa_enum_to_string(ctx->ErrorValue));
output_if_debug("Mesa", s, GL_TRUE);
@@ -1503,7 +1503,7 @@ _mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... )
}
len = _mesa_snprintf(s2, MAX_DEBUG_MESSAGE_LENGTH, "%s in %s",
- _mesa_lookup_enum_by_nr(error), s);
+ _mesa_enum_to_string(error), s);
if (len >= MAX_DEBUG_MESSAGE_LENGTH) {
/* Same as above. */
assert(0);
diff --git a/src/mesa/main/errors.h b/src/mesa/main/errors.h
index 24f234f7f10..81e47a8b8c1 100644
--- a/src/mesa/main/errors.h
+++ b/src/mesa/main/errors.h
@@ -37,6 +37,7 @@
#include <stdio.h>
+#include <stdarg.h>
#include "compiler.h"
#include "glheader.h"
#include "mtypes.h"
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 4176a69ed7c..d934d19c3e7 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -121,6 +121,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_framebuffer_object", o(ARB_framebuffer_object), GL, 2005 },
{ "GL_ARB_framebuffer_sRGB", o(EXT_framebuffer_sRGB), GL, 1998 },
{ "GL_ARB_get_program_binary", o(dummy_true), GL, 2010 },
+ { "GL_ARB_get_texture_sub_image", o(dummy_true), GL, 2014 },
{ "GL_ARB_gpu_shader5", o(ARB_gpu_shader5), GLC, 2010 },
{ "GL_ARB_gpu_shader_fp64", o(ARB_gpu_shader_fp64), GLC, 2010 },
{ "GL_ARB_half_float_pixel", o(dummy_true), GL, 2003 },
@@ -154,6 +155,8 @@ static const struct extension extension_table[] = {
{ "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 },
+ { "GL_ARB_shader_storage_buffer_object", o(ARB_shader_storage_buffer_object), GL, 2012 },
+ { "GL_ARB_shader_subroutine", o(ARB_shader_subroutine), GLC, 2010 },
{ "GL_ARB_shader_texture_lod", o(ARB_shader_texture_lod), GL, 2009 },
{ "GL_ARB_shading_language_100", o(dummy_true), GLL, 2003 },
{ "GL_ARB_shading_language_packing", o(ARB_shading_language_packing), GL, 2011 },
@@ -382,6 +385,9 @@ static const struct extension extension_table[] = {
{ "GL_NV_point_sprite", o(NV_point_sprite), GL, 2001 },
{ "GL_NV_primitive_restart", o(NV_primitive_restart), GLL, 2002 },
{ "GL_NV_read_buffer", o(dummy_true), ES2, 2011 },
+ { "GL_NV_read_depth", o(dummy_true), ES2, 2011 },
+ { "GL_NV_read_depth_stencil", o(dummy_true), ES2, 2011 },
+ { "GL_NV_read_stencil", o(dummy_true), ES2, 2011 },
{ "GL_NV_texgen_reflection", o(dummy_true), GLL, 1999 },
{ "GL_NV_texture_barrier", o(NV_texture_barrier), GL, 2009 },
{ "GL_NV_texture_env_combine4", o(NV_texture_env_combine4), GLL, 1999 },
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index f8dcf122d99..841834030df 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -2007,7 +2007,7 @@ renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
baseFormat = _mesa_base_fbo_format(ctx, internalFormat);
if (baseFormat == 0) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat=%s)",
- func, _mesa_lookup_enum_by_nr(internalFormat));
+ func, _mesa_enum_to_string(internalFormat));
return;
}
@@ -2095,12 +2095,12 @@ renderbuffer_storage_named(GLuint renderbuffer, GLenum internalFormat,
if (samples == NO_SAMPLES)
_mesa_debug(ctx, "%s(%u, %s, %d, %d)\n",
func, renderbuffer,
- _mesa_lookup_enum_by_nr(internalFormat),
+ _mesa_enum_to_string(internalFormat),
width, height);
else
_mesa_debug(ctx, "%s(%u, %s, %d, %d, %d)\n",
func, renderbuffer,
- _mesa_lookup_enum_by_nr(internalFormat),
+ _mesa_enum_to_string(internalFormat),
width, height, samples);
}
@@ -2131,14 +2131,14 @@ renderbuffer_storage_target(GLenum target, GLenum internalFormat,
if (samples == NO_SAMPLES)
_mesa_debug(ctx, "%s(%s, %s, %d, %d)\n",
func,
- _mesa_lookup_enum_by_nr(target),
- _mesa_lookup_enum_by_nr(internalFormat),
+ _mesa_enum_to_string(target),
+ _mesa_enum_to_string(internalFormat),
width, height);
else
_mesa_debug(ctx, "%s(%s, %s, %d, %d, %d)\n",
func,
- _mesa_lookup_enum_by_nr(target),
- _mesa_lookup_enum_by_nr(internalFormat),
+ _mesa_enum_to_string(target),
+ _mesa_enum_to_string(internalFormat),
width, height, samples);
}
@@ -2311,7 +2311,7 @@ get_render_buffer_parameteriv(struct gl_context *ctx,
/* fallthrough */
default:
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid pname=%s)", func,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
return;
}
}
@@ -2694,13 +2694,13 @@ _mesa_CheckFramebufferStatus(GLenum target)
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glCheckFramebufferStatus(%s)\n",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
fb = get_framebuffer_target(ctx, target);
if (!fb) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glCheckFramebufferStatus(invalid target %s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return 0;
}
@@ -2732,7 +2732,7 @@ _mesa_CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target)
default:
_mesa_error(ctx, GL_INVALID_ENUM,
"glCheckNamedFramebufferStatus(invalid target %s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return 0;
}
@@ -2851,7 +2851,7 @@ check_layered_texture_target(struct gl_context *ctx, GLenum target,
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(invalid texture target %s)", caller,
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return false;
}
@@ -2893,7 +2893,7 @@ check_texture_target(struct gl_context *ctx, GLenum target,
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(invalid texture target %s)", caller,
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return false;
}
@@ -2944,8 +2944,9 @@ check_textarget(struct gl_context *ctx, int dims, GLenum target,
break;
case GL_TEXTURE_2D_MULTISAMPLE:
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
- err = _mesa_is_gles(ctx)
- || !ctx->Extensions.ARB_texture_multisample;
+ err = (_mesa_is_gles(ctx) ||
+ !ctx->Extensions.ARB_texture_multisample) &&
+ !_mesa_is_gles31(ctx);
break;
default:
err = true;
@@ -2962,7 +2963,7 @@ check_textarget(struct gl_context *ctx, int dims, GLenum target,
if (err) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(invalid textarget %s)",
- caller, _mesa_lookup_enum_by_nr(textarget));
+ caller, _mesa_enum_to_string(textarget));
return false;
}
@@ -3074,7 +3075,7 @@ _mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
att = get_attachment(ctx, fb, attachment);
if (att == NULL) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid attachment %s)", caller,
- _mesa_lookup_enum_by_nr(attachment));
+ _mesa_enum_to_string(attachment));
return;
}
@@ -3157,7 +3158,7 @@ framebuffer_texture_with_dims(int dims, GLenum target,
fb = get_framebuffer_target(ctx, target);
if (!fb) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", caller,
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
@@ -3225,7 +3226,7 @@ _mesa_FramebufferTextureLayer(GLenum target, GLenum attachment,
if (!fb) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glFramebufferTextureLayer(invalid target %s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
@@ -3304,7 +3305,7 @@ _mesa_FramebufferTexture(GLenum target, GLenum attachment,
GET_CURRENT_CONTEXT(ctx);
struct gl_framebuffer *fb;
struct gl_texture_object *texObj;
- GLboolean layered;
+ GLboolean layered = GL_FALSE;
const char *func = "FramebufferTexture";
@@ -3319,7 +3320,7 @@ _mesa_FramebufferTexture(GLenum target, GLenum attachment,
if (!fb) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glFramebufferTexture(invalid target %s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
@@ -3347,7 +3348,7 @@ _mesa_NamedFramebufferTexture(GLuint framebuffer, GLenum attachment,
GET_CURRENT_CONTEXT(ctx);
struct gl_framebuffer *fb;
struct gl_texture_object *texObj;
- GLboolean layered;
+ GLboolean layered = GL_FALSE;
const char *func = "glNamedFramebufferTexture";
@@ -3400,7 +3401,7 @@ _mesa_framebuffer_renderbuffer(struct gl_context *ctx,
if (att == NULL) {
_mesa_error(ctx, GL_INVALID_ENUM,
"%s(invalid attachment %s)", func,
- _mesa_lookup_enum_by_nr(attachment));
+ _mesa_enum_to_string(attachment));
return;
}
@@ -3440,7 +3441,7 @@ _mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment,
if (!fb) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glFramebufferRenderbuffer(invalid target %s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
@@ -3539,7 +3540,7 @@ _mesa_get_framebuffer_attachment_parameter(struct gl_context *ctx,
attachment != GL_DEPTH && attachment != GL_STENCIL) {
_mesa_error(ctx, GL_INVALID_ENUM,
"%s(invalid attachment %s)", caller,
- _mesa_lookup_enum_by_nr(attachment));
+ _mesa_enum_to_string(attachment));
return;
}
/* the default / window-system FBO */
@@ -3552,7 +3553,7 @@ _mesa_get_framebuffer_attachment_parameter(struct gl_context *ctx,
if (att == NULL) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid attachment %s)", caller,
- _mesa_lookup_enum_by_nr(attachment));
+ _mesa_enum_to_string(attachment));
return;
}
@@ -3609,7 +3610,7 @@ _mesa_get_framebuffer_attachment_parameter(struct gl_context *ctx,
}
else if (att->Type == GL_NONE) {
_mesa_error(ctx, err, "%s(invalid pname %s)", caller,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
}
else {
goto invalid_pname_enum;
@@ -3626,7 +3627,7 @@ _mesa_get_framebuffer_attachment_parameter(struct gl_context *ctx,
}
else if (att->Type == GL_NONE) {
_mesa_error(ctx, err, "%s(invalid pname %s)", caller,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
}
else {
goto invalid_pname_enum;
@@ -3637,7 +3638,7 @@ _mesa_get_framebuffer_attachment_parameter(struct gl_context *ctx,
goto invalid_pname_enum;
} else if (att->Type == GL_NONE) {
_mesa_error(ctx, err, "%s(invalid pname %s)", caller,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
} else if (att->Type == GL_TEXTURE) {
if (att->Texture && (att->Texture->Target == GL_TEXTURE_3D ||
att->Texture->Target == GL_TEXTURE_2D_ARRAY)) {
@@ -3659,7 +3660,7 @@ _mesa_get_framebuffer_attachment_parameter(struct gl_context *ctx,
}
else if (att->Type == GL_NONE) {
_mesa_error(ctx, err, "%s(invalid pname %s)", caller,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
}
else {
if (ctx->Extensions.EXT_framebuffer_sRGB) {
@@ -3682,7 +3683,7 @@ _mesa_get_framebuffer_attachment_parameter(struct gl_context *ctx,
}
else if (att->Type == GL_NONE) {
_mesa_error(ctx, err, "%s(invalid pname %s)", caller,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
}
else {
mesa_format format = att->Renderbuffer->Format;
@@ -3734,7 +3735,7 @@ _mesa_get_framebuffer_attachment_parameter(struct gl_context *ctx,
}
else if (att->Type == GL_NONE) {
_mesa_error(ctx, err, "%s(invalid pname %s)", caller,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
}
else if (att->Texture) {
const struct gl_texture_image *texImage =
@@ -3763,7 +3764,7 @@ _mesa_get_framebuffer_attachment_parameter(struct gl_context *ctx,
*params = att->Layered;
} else if (att->Type == GL_NONE) {
_mesa_error(ctx, err, "%s(invalid pname %s)", caller,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
} else {
goto invalid_pname_enum;
}
@@ -3776,7 +3777,7 @@ _mesa_get_framebuffer_attachment_parameter(struct gl_context *ctx,
invalid_pname_enum:
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid pname %s)", caller,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
return;
}
@@ -3792,7 +3793,7 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
if (!buffer) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetFramebufferAttachmentParameteriv(invalid target %s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
@@ -4009,7 +4010,7 @@ invalidate_framebuffer_storage(struct gl_context *ctx,
invalid_enum:
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid attachment %s)", name,
- _mesa_lookup_enum_by_nr(attachments[i]));
+ _mesa_enum_to_string(attachments[i]));
return;
}
@@ -4026,7 +4027,7 @@ _mesa_InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments,
if (!fb) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glInvalidateSubFramebuffer(invalid target %s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
@@ -4076,7 +4077,7 @@ _mesa_InvalidateFramebuffer(GLenum target, GLsizei numAttachments,
if (!fb) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glInvalidateFramebuffer(invalid target %s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
@@ -4152,7 +4153,7 @@ _mesa_DiscardFramebufferEXT(GLenum target, GLsizei numAttachments,
if (!fb) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glDiscardFramebufferEXT(target %s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
@@ -4189,5 +4190,5 @@ _mesa_DiscardFramebufferEXT(GLenum target, GLsizei numAttachments,
invalid_enum:
_mesa_error(ctx, GL_INVALID_ENUM,
"glDiscardFramebufferEXT(attachment %s)",
- _mesa_lookup_enum_by_nr(attachments[i]));
+ _mesa_enum_to_string(attachments[i]));
}
diff --git a/src/mesa/main/feedback.c b/src/mesa/main/feedback.c
index 6bc4294f9c7..699e2a855a3 100644
--- a/src/mesa/main/feedback.c
+++ b/src/mesa/main/feedback.c
@@ -415,7 +415,7 @@ _mesa_RenderMode( GLenum mode )
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glRenderMode %s\n", _mesa_lookup_enum_by_nr(mode));
+ _mesa_debug(ctx, "glRenderMode %s\n", _mesa_enum_to_string(mode));
FLUSH_VERTICES(ctx, _NEW_RENDERMODE);
diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c
index 70adaf88551..95b428dca3e 100644
--- a/src/mesa/main/ffvertex_prog.c
+++ b/src/mesa/main/ffvertex_prog.c
@@ -189,15 +189,15 @@ static void make_state_key( struct gl_context *ctx, struct state_key *key )
if (light->Enabled) {
key->unit[i].light_enabled = 1;
- if (light->EyePosition[3] == 0.0)
+ if (light->EyePosition[3] == 0.0F)
key->unit[i].light_eyepos3_is_zero = 1;
- if (light->SpotCutoff == 180.0)
+ if (light->SpotCutoff == 180.0F)
key->unit[i].light_spotcutoff_is_180 = 1;
- if (light->ConstantAttenuation != 1.0 ||
- light->LinearAttenuation != 0.0 ||
- light->QuadraticAttenuation != 0.0)
+ if (light->ConstantAttenuation != 1.0F ||
+ light->LinearAttenuation != 0.0F ||
+ light->QuadraticAttenuation != 0.0F)
key->unit[i].light_attenuated = 1;
}
}
diff --git a/src/mesa/main/fog.c b/src/mesa/main/fog.c
index 3bce289e785..45f343d61c8 100644
--- a/src/mesa/main/fog.c
+++ b/src/mesa/main/fog.c
@@ -115,7 +115,7 @@ _mesa_Fogfv( GLenum pname, const GLfloat *params )
ctx->Fog.Mode = m;
break;
case GL_FOG_DENSITY:
- if (*params<0.0) {
+ if (*params<0.0F) {
_mesa_error( ctx, GL_INVALID_VALUE, "glFog" );
return;
}
diff --git a/src/mesa/main/format_parser.py b/src/mesa/main/format_parser.py
index 11184f78e2c..799b14f0b1c 100755
--- a/src/mesa/main/format_parser.py
+++ b/src/mesa/main/format_parser.py
@@ -40,9 +40,6 @@ SRGB = 'srgb'
YUV = 'yuv'
ZS = 'zs'
-def is_power_of_two(x):
- return not bool(x & (x - 1))
-
VERY_LARGE = 99999999999999999999999
class Channel:
@@ -100,10 +97,6 @@ class Channel:
else:
return 1
- def is_power_of_two(self):
- """Returns true if the size of this channel is a power of two."""
- return is_power_of_two(self.size)
-
def datatype(self):
"""Returns the datatype corresponding to a channel type and size"""
return _get_datatype(self.type, self.size)
diff --git a/src/mesa/main/format_utils.h b/src/mesa/main/format_utils.h
index 7f500ec78da..618f43d0aaa 100644
--- a/src/mesa/main/format_utils.h
+++ b/src/mesa/main/format_utils.h
@@ -33,6 +33,7 @@
#include "imports.h"
#include "macros.h"
+#include "util/rounding.h"
extern const mesa_array_format RGBA32_FLOAT;
extern const mesa_array_format RGBA8_UBYTE;
@@ -84,7 +85,7 @@ _mesa_float_to_unorm(float x, unsigned dst_bits)
else if (x > 1.0f)
return MAX_UINT(dst_bits);
else
- return F_TO_I(x * MAX_UINT(dst_bits));
+ return _mesa_lroundevenf(x * MAX_UINT(dst_bits));
}
static inline unsigned
@@ -98,7 +99,7 @@ _mesa_unorm_to_unorm(unsigned x, unsigned src_bits, unsigned dst_bits)
{
if (src_bits < dst_bits) {
return EXTEND_NORMALIZED_INT(x, src_bits, dst_bits);
- } else {
+ } else if (src_bits > dst_bits) {
unsigned src_half = (1 << (src_bits - 1)) - 1;
if (src_bits + dst_bits > sizeof(x) * 8) {
@@ -108,6 +109,8 @@ _mesa_unorm_to_unorm(unsigned x, unsigned src_bits, unsigned dst_bits)
} else {
return (x * MAX_UINT(dst_bits) + src_half) / MAX_UINT(src_bits);
}
+ } else {
+ return x;
}
}
@@ -128,7 +131,7 @@ _mesa_float_to_snorm(float x, unsigned dst_bits)
else if (x > 1.0f)
return MAX_INT(dst_bits);
else
- return F_TO_I(x * MAX_INT(dst_bits));
+ return _mesa_lroundevenf(x * MAX_INT(dst_bits));
}
static inline int
diff --git a/src/mesa/main/formatquery.c b/src/mesa/main/formatquery.c
index 7741cabada1..85f7b6b5664 100644
--- a/src/mesa/main/formatquery.c
+++ b/src/mesa/main/formatquery.c
@@ -74,13 +74,15 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
case GL_TEXTURE_2D_MULTISAMPLE:
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
/* These enums are only valid if ARB_texture_multisample is supported */
- if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample)
+ if ((_mesa_is_desktop_gl(ctx) &&
+ ctx->Extensions.ARB_texture_multisample) ||
+ _mesa_is_gles31(ctx))
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetInternalformativ(target=%s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
@@ -107,7 +109,7 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
_mesa_base_fbo_format(ctx, internalformat) == 0) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetInternalformativ(internalformat=%s)",
- _mesa_lookup_enum_by_nr(internalformat));
+ _mesa_enum_to_string(internalformat));
return;
}
@@ -119,7 +121,7 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
if (bufSize < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetInternalformativ(target=%s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
@@ -168,7 +170,7 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
default:
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetInternalformativ(pname=%s)",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
return;
}
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
index baeb1bfe5de..d7b2bae59e7 100644
--- a/src/mesa/main/formats.c
+++ b/src/mesa/main/formats.c
@@ -354,14 +354,22 @@ _mesa_array_format_flip_channels(mesa_array_format format)
return format;
if (num_channels == 2) {
- _mesa_array_format_set_swizzle(&format, swizzle[1], swizzle[0],
- swizzle[2], swizzle[3]);
+ /* Assert that the swizzle makes sense for 2 channels */
+ for (unsigned i = 0; i < 4; i++)
+ assert(swizzle[i] != 2 && swizzle[i] != 3);
+
+ static const uint8_t flip_xy[6] = { 1, 0, 2, 3, 4, 5 };
+ _mesa_array_format_set_swizzle(&format,
+ flip_xy[swizzle[0]], flip_xy[swizzle[1]],
+ flip_xy[swizzle[2]], flip_xy[swizzle[3]]);
return format;
}
if (num_channels == 4) {
- _mesa_array_format_set_swizzle(&format, swizzle[3], swizzle[2],
- swizzle[1], swizzle[0]);
+ static const uint8_t flip[6] = { 3, 2, 1, 0, 4, 5 };
+ _mesa_array_format_set_swizzle(&format,
+ flip[swizzle[0]], flip[swizzle[1]],
+ flip[swizzle[2]], flip[swizzle[3]]);
return format;
}
@@ -372,10 +380,11 @@ uint32_t
_mesa_format_to_array_format(mesa_format format)
{
const struct gl_format_info *info = _mesa_get_format_info(format);
- if (_mesa_little_endian())
- return info->ArrayFormat;
- else
+ if (info->ArrayFormat && !_mesa_little_endian() &&
+ info->Layout == MESA_FORMAT_LAYOUT_PACKED)
return _mesa_array_format_flip_channels(info->ArrayFormat);
+ else
+ return info->ArrayFormat;
}
static struct hash_table *format_array_format_table;
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
index 7e451caf0ff..d938e6ad513 100644
--- a/src/mesa/main/formats.h
+++ b/src/mesa/main/formats.h
@@ -191,6 +191,11 @@ static inline void
_mesa_array_format_set_swizzle(mesa_array_format *f,
int32_t x, int32_t y, int32_t z, int32_t w)
{
+ *f &= ~(MESA_ARRAY_FORMAT_SWIZZLE_X_MASK |
+ MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK |
+ MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK |
+ MESA_ARRAY_FORMAT_SWIZZLE_W_MASK);
+
*f |= ((x << 8 ) & MESA_ARRAY_FORMAT_SWIZZLE_X_MASK) |
((y << 11) & MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK) |
((z << 14) & MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK) |
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index 77c04b8dab8..37e2c29c89c 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -938,7 +938,7 @@ _mesa_print_framebuffer(const struct gl_framebuffer *fb)
fprintf(stderr, "Mesa Framebuffer %u at %p\n", fb->Name, (void *) fb);
fprintf(stderr, " Size: %u x %u Status: %s\n", fb->Width, fb->Height,
- _mesa_lookup_enum_by_nr(fb->_Status));
+ _mesa_enum_to_string(fb->_Status));
fprintf(stderr, " Attachments:\n");
for (i = 0; i < BUFFER_COUNT; i++) {
diff --git a/src/mesa/main/genmipmap.c b/src/mesa/main/genmipmap.c
index 9aef090194e..c18f9d5223f 100644
--- a/src/mesa/main/genmipmap.c
+++ b/src/mesa/main/genmipmap.c
@@ -83,7 +83,7 @@ _mesa_generate_texture_mipmap(struct gl_context *ctx,
if (error) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGenerate%sMipmap(target=%s)",
- suffix, _mesa_lookup_enum_by_nr(target));
+ suffix, _mesa_enum_to_string(target));
return;
}
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 3d6d63916b3..307a5ffbd1c 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -149,6 +149,8 @@ enum value_extra {
EXTRA_EXT_UBO_GS4,
EXTRA_EXT_ATOMICS_GS4,
EXTRA_EXT_SHADER_IMAGE_GS4,
+ EXTRA_EXT_ATOMICS_TESS,
+ EXTRA_EXT_SHADER_IMAGE_TESS,
};
#define NO_EXTRA NULL
@@ -349,12 +351,58 @@ static const int extra_ARB_shader_image_load_store_and_geometry_shader[] = {
EXTRA_END
};
+static const int extra_ARB_shader_atomic_counters_and_tessellation[] = {
+ EXTRA_EXT_ATOMICS_TESS,
+ EXTRA_END
+};
+
+static const int extra_ARB_shader_image_load_store_and_tessellation[] = {
+ EXTRA_EXT_SHADER_IMAGE_TESS,
+ EXTRA_END
+};
+
static const int extra_ARB_draw_indirect_es31[] = {
EXT(ARB_draw_indirect),
EXTRA_API_ES31,
EXTRA_END
};
+static const int extra_ARB_shader_image_load_store_es31[] = {
+ EXT(ARB_shader_image_load_store),
+ EXTRA_API_ES31,
+ EXTRA_END
+};
+
+static const int extra_ARB_shader_atomic_counters_es31[] = {
+ EXT(ARB_shader_atomic_counters),
+ EXTRA_API_ES31,
+ EXTRA_END
+};
+
+static const int extra_ARB_texture_multisample_es31[] = {
+ EXT(ARB_texture_multisample),
+ EXTRA_API_ES31,
+ EXTRA_END
+};
+
+static const int extra_ARB_texture_gather_es31[] = {
+ EXT(ARB_texture_gather),
+ EXTRA_API_ES31,
+ EXTRA_END
+};
+
+static const int extra_ARB_compute_shader_es31[] = {
+ EXT(ARB_compute_shader),
+ EXTRA_API_ES31,
+ EXTRA_END
+};
+
+static const int extra_ARB_explicit_uniform_location_es31[] = {
+ EXT(ARB_explicit_uniform_location),
+ EXTRA_API_ES31,
+ EXTRA_END
+};
+
EXTRA_EXT(ARB_texture_cube_map);
EXTRA_EXT(EXT_texture_array);
EXTRA_EXT(NV_fog_distance);
@@ -401,6 +449,8 @@ EXTRA_EXT(ARB_explicit_uniform_location);
EXTRA_EXT(ARB_clip_control);
EXTRA_EXT(EXT_polygon_offset_clamp);
EXTRA_EXT(ARB_framebuffer_no_attachments);
+EXTRA_EXT(ARB_tessellation_shader);
+EXTRA_EXT(ARB_shader_subroutine);
static const int
extra_ARB_color_buffer_float_or_glcore[] = {
@@ -626,7 +676,7 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
break;
case GL_EDGE_FLAG:
- v->value_bool = ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0;
+ v->value_bool = ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0F;
break;
case GL_READ_BUFFER:
@@ -1149,6 +1199,16 @@ check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d
api_found = (ctx->Extensions.ARB_shader_image_load_store &&
_mesa_has_geometry_shaders(ctx));
break;
+ case EXTRA_EXT_ATOMICS_TESS:
+ api_check = GL_TRUE;
+ api_found = ctx->Extensions.ARB_shader_atomic_counters &&
+ _mesa_has_tessellation(ctx);
+ break;
+ case EXTRA_EXT_SHADER_IMAGE_TESS:
+ api_check = GL_TRUE;
+ api_found = ctx->Extensions.ARB_shader_image_load_store &&
+ _mesa_has_tessellation(ctx);
+ break;
case EXTRA_END:
break;
default: /* *e is a offset into the extension struct */
@@ -1161,7 +1221,7 @@ check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d
if (api_check && !api_found) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func,
- _mesa_lookup_enum_by_nr(d->pname));
+ _mesa_enum_to_string(d->pname));
return GL_FALSE;
}
@@ -1208,10 +1268,13 @@ find_value(const char *func, GLenum pname, void **p, union value *v)
* value since it's compatible with GLES2 its entry in table_set[] is at the
* end.
*/
- STATIC_ASSERT(ARRAY_SIZE(table_set) == API_OPENGL_LAST + 2);
+ STATIC_ASSERT(ARRAY_SIZE(table_set) == API_OPENGL_LAST + 3);
if (_mesa_is_gles3(ctx)) {
api = API_OPENGL_LAST + 1;
}
+ if (_mesa_is_gles31(ctx)) {
+ api = API_OPENGL_LAST + 2;
+ }
mask = ARRAY_SIZE(table(api)) - 1;
hash = (pname * prime_factor);
while (1) {
@@ -1222,7 +1285,7 @@ find_value(const char *func, GLenum pname, void **p, union value *v)
* any valid enum. */
if (unlikely(idx == 0)) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
return &error_value;
}
@@ -2004,11 +2067,11 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v)
invalid_enum:
_mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
return TYPE_INVALID;
invalid_value:
_mesa_error(ctx, GL_INVALID_VALUE, "%s(pname=%s)", func,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
return TYPE_INVALID;
}
diff --git a/src/mesa/main/get_hash_generator.py b/src/mesa/main/get_hash_generator.py
index b200d197341..c777b782442 100644
--- a/src/mesa/main/get_hash_generator.py
+++ b/src/mesa/main/get_hash_generator.py
@@ -44,7 +44,7 @@ prime_factor = 89
prime_step = 281
hash_table_size = 1024
-gl_apis=set(["GL", "GL_CORE", "GLES", "GLES2", "GLES3"])
+gl_apis=set(["GL", "GL_CORE", "GLES", "GLES2", "GLES3", "GLES31"])
def print_header():
print "typedef const unsigned short table_t[%d];\n" % (hash_table_size)
@@ -68,6 +68,7 @@ api_enum = [
'GLES2',
'GL_CORE',
'GLES3', # Not in gl_api enum in mtypes.h
+ 'GLES31', # Not in gl_api enum in mtypes.h
]
def api_index(api):
@@ -167,10 +168,13 @@ def generate_hash_tables(enum_list, enabled_apis, param_descriptors):
for api in valid_apis:
add_to_hash_table(tables[api], hash_val, len(params))
- # Also add GLES2 items to the GLES3 hash table
+ # Also add GLES2 items to the GLES3 and GLES31 hash table
if api == "GLES2":
add_to_hash_table(tables["GLES3"], hash_val, len(params))
-
+ add_to_hash_table(tables["GLES31"], hash_val, len(params))
+ # Also add GLES3 items to the GLES31 hash table
+ if api == "GLES3":
+ add_to_hash_table(tables["GLES31"], hash_val, len(params))
params.append(["GL_" + enum_name, param[1]])
sorted_tables={}
@@ -206,7 +210,7 @@ if __name__ == '__main__':
die("missing descriptor file (-f)\n")
# generate the code for all APIs
- enabled_apis = set(["GLES", "GLES2", "GLES3", "GL", "GL_CORE"])
+ enabled_apis = set(["GLES", "GLES2", "GLES3", "GLES31", "GL", "GL_CORE"])
try:
api_desc = gl_XML.parse_GL_API(api_desc_file)
diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py
index 74ff3ba6619..7dc92f10100 100644
--- a/src/mesa/main/get_hash_params.py
+++ b/src/mesa/main/get_hash_params.py
@@ -351,6 +351,9 @@ descriptor=[
# GL_ARB_framebuffer_object
[ "MAX_SAMPLES", "CONTEXT_INT(Const.MaxSamples), extra_ARB_framebuffer_object_EXT_framebuffer_multisample" ],
+# GL_ARB_sampler_objects / GL 3.3 / GLES 3.0
+ [ "SAMPLER_BINDING", "LOC_CUSTOM, TYPE_INT, GL_SAMPLER_BINDING, NO_EXTRA" ],
+
# GL_ARB_sync
[ "MAX_SERVER_WAIT_TIMEOUT", "CONTEXT_INT64(Const.MaxServerWaitTimeout), extra_ARB_sync" ],
@@ -404,9 +407,49 @@ descriptor=[
[ "TEXTURE_EXTERNAL_OES", "LOC_CUSTOM, TYPE_BOOLEAN, 0, extra_OES_EGL_image_external" ],
]},
-{ "apis": ["GL", "GL_CORE", "GLES3"], "params": [
-# GL_ARB_sampler_objects / GL 3.3 / GLES 3.0
- [ "SAMPLER_BINDING", "LOC_CUSTOM, TYPE_INT, GL_SAMPLER_BINDING, NO_EXTRA" ],
+# Enums in OpenGL and ES 3.1
+{ "apis": ["GL", "GL_CORE", "GLES31"], "params": [
+# GL_ARB_shader_image_load_store / GLES 3.1
+ [ "MAX_IMAGE_UNITS", "CONTEXT_INT(Const.MaxImageUnits), extra_ARB_shader_image_load_store_es31" ],
+ [ "MAX_VERTEX_IMAGE_UNIFORMS", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxImageUniforms), extra_ARB_shader_image_load_store_es31" ],
+ [ "MAX_FRAGMENT_IMAGE_UNIFORMS", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxImageUniforms), extra_ARB_shader_image_load_store_es31" ],
+ [ "MAX_COMBINED_IMAGE_UNIFORMS", "CONTEXT_INT(Const.MaxCombinedImageUniforms), extra_ARB_shader_image_load_store_es31" ],
+
+# GL_ARB_shader_atomic_counters / GLES 3.1
+ [ "ATOMIC_COUNTER_BUFFER_BINDING", "LOC_CUSTOM, TYPE_INT, 0, extra_ARB_shader_atomic_counters_es31" ],
+ [ "MAX_ATOMIC_COUNTER_BUFFER_BINDINGS", "CONTEXT_INT(Const.MaxAtomicBufferBindings), extra_ARB_shader_atomic_counters_es31" ],
+ [ "MAX_ATOMIC_COUNTER_BUFFER_SIZE", "CONTEXT_INT(Const.MaxAtomicBufferSize), extra_ARB_shader_atomic_counters_es31" ],
+ [ "MAX_VERTEX_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxAtomicBuffers), extra_ARB_shader_atomic_counters_es31" ],
+ [ "MAX_VERTEX_ATOMIC_COUNTERS", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxAtomicCounters), extra_ARB_shader_atomic_counters_es31" ],
+ [ "MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicBuffers), extra_ARB_shader_atomic_counters_es31" ],
+ [ "MAX_FRAGMENT_ATOMIC_COUNTERS", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicCounters), extra_ARB_shader_atomic_counters_es31" ],
+ [ "MAX_COMBINED_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.MaxCombinedAtomicBuffers), extra_ARB_shader_atomic_counters_es31" ],
+ [ "MAX_COMBINED_ATOMIC_COUNTERS", "CONTEXT_INT(Const.MaxCombinedAtomicCounters), extra_ARB_shader_atomic_counters_es31" ],
+
+# GL_ARB_texture_multisample / GLES 3.1
+ [ "TEXTURE_BINDING_2D_MULTISAMPLE", "LOC_CUSTOM, TYPE_INT, TEXTURE_2D_MULTISAMPLE_INDEX, extra_ARB_texture_multisample_es31" ],
+ [ "MAX_COLOR_TEXTURE_SAMPLES", "CONTEXT_INT(Const.MaxColorTextureSamples), extra_ARB_texture_multisample_es31" ],
+ [ "MAX_DEPTH_TEXTURE_SAMPLES", "CONTEXT_INT(Const.MaxDepthTextureSamples), extra_ARB_texture_multisample_es31" ],
+ [ "MAX_INTEGER_SAMPLES", "CONTEXT_INT(Const.MaxIntegerSamples), extra_ARB_texture_multisample_es31" ],
+ [ "SAMPLE_MASK", "CONTEXT_BOOL(Multisample.SampleMask), extra_ARB_texture_multisample_es31" ],
+ [ "MAX_SAMPLE_MASK_WORDS", "CONST(1), extra_ARB_texture_multisample_es31" ],
+
+# GL_ARB_texture_gather / GLES 3.1
+ [ "MIN_PROGRAM_TEXTURE_GATHER_OFFSET", "CONTEXT_INT(Const.MinProgramTextureGatherOffset), extra_ARB_texture_gather_es31"],
+ [ "MAX_PROGRAM_TEXTURE_GATHER_OFFSET", "CONTEXT_INT(Const.MaxProgramTextureGatherOffset), extra_ARB_texture_gather_es31"],
+
+# GL_ARB_compute_shader / GLES 3.1
+ [ "MAX_COMPUTE_WORK_GROUP_INVOCATIONS", "CONTEXT_INT(Const.MaxComputeWorkGroupInvocations), extra_ARB_compute_shader_es31" ],
+ [ "MAX_COMPUTE_UNIFORM_BLOCKS", "CONST(MAX_COMPUTE_UNIFORM_BLOCKS), extra_ARB_compute_shader_es31" ],
+ [ "MAX_COMPUTE_TEXTURE_IMAGE_UNITS", "CONST(MAX_COMPUTE_TEXTURE_IMAGE_UNITS), extra_ARB_compute_shader_es31" ],
+ [ "MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS", "CONST(MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS), extra_ARB_compute_shader_es31" ],
+ [ "MAX_COMPUTE_ATOMIC_COUNTERS", "CONST(MAX_COMPUTE_ATOMIC_COUNTERS), extra_ARB_compute_shader_es31" ],
+ [ "MAX_COMPUTE_SHARED_MEMORY_SIZE", "CONST(MAX_COMPUTE_SHARED_MEMORY_SIZE), extra_ARB_compute_shader_es31" ],
+ [ "MAX_COMPUTE_UNIFORM_COMPONENTS", "CONST(MAX_COMPUTE_UNIFORM_COMPONENTS), extra_ARB_compute_shader_es31" ],
+ [ "MAX_COMPUTE_IMAGE_UNIFORMS", "CONST(MAX_COMPUTE_IMAGE_UNIFORMS), extra_ARB_compute_shader_es31" ],
+
+# GL_ARB_explicit_uniform_location / GLES 3.1
+ [ "MAX_UNIFORM_LOCATIONS", "CONTEXT_INT(Const.MaxUserAssignableUniformLocations), extra_ARB_explicit_uniform_location_es31" ],
]},
# Enums in OpenGL Core profile and ES 3.1
@@ -498,7 +541,6 @@ descriptor=[
[ "MAX_LIST_NESTING", "CONST(MAX_LIST_NESTING), NO_EXTRA" ],
[ "MAX_NAME_STACK_DEPTH", "CONST(MAX_NAME_STACK_DEPTH), NO_EXTRA" ],
[ "MAX_PIXEL_MAP_TABLE", "CONST(MAX_PIXEL_MAP_TABLE), NO_EXTRA" ],
- [ "MAX_UNIFORM_LOCATIONS", "CONTEXT_INT(Const.MaxUserAssignableUniformLocations), extra_ARB_explicit_uniform_location" ],
[ "NAME_STACK_DEPTH", "CONTEXT_INT(Select.NameStackDepth), NO_EXTRA" ],
[ "PACK_LSB_FIRST", "CONTEXT_BOOL(Pack.LsbFirst), NO_EXTRA" ],
[ "PACK_SWAP_BYTES", "CONTEXT_BOOL(Pack.SwapBytes), NO_EXTRA" ],
@@ -699,13 +741,7 @@ descriptor=[
[ "TEXTURE_BUFFER_ARB", "LOC_CUSTOM, TYPE_INT, 0, extra_texture_buffer_object" ],
# GL_ARB_texture_multisample / GL 3.2
- [ "TEXTURE_BINDING_2D_MULTISAMPLE", "LOC_CUSTOM, TYPE_INT, TEXTURE_2D_MULTISAMPLE_INDEX, extra_ARB_texture_multisample" ],
[ "TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY", "LOC_CUSTOM, TYPE_INT, TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX, extra_ARB_texture_multisample" ],
- [ "MAX_COLOR_TEXTURE_SAMPLES", "CONTEXT_INT(Const.MaxColorTextureSamples), extra_ARB_texture_multisample" ],
- [ "MAX_DEPTH_TEXTURE_SAMPLES", "CONTEXT_INT(Const.MaxDepthTextureSamples), extra_ARB_texture_multisample" ],
- [ "MAX_INTEGER_SAMPLES", "CONTEXT_INT(Const.MaxIntegerSamples), extra_ARB_texture_multisample" ],
- [ "SAMPLE_MASK", "CONTEXT_BOOL(Multisample.SampleMask), extra_ARB_texture_multisample" ],
- [ "MAX_SAMPLE_MASK_WORDS", "CONST(1), extra_ARB_texture_multisample" ],
# GL 3.0
[ "CONTEXT_FLAGS", "CONTEXT_INT(Const.ContextFlags), extra_version_30" ],
@@ -756,48 +792,23 @@ descriptor=[
[ "TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB", "LOC_CUSTOM, TYPE_INT, TEXTURE_CUBE_ARRAY_INDEX, extra_ARB_texture_cube_map_array" ],
# GL_ARB_texture_gather
- [ "MIN_PROGRAM_TEXTURE_GATHER_OFFSET", "CONTEXT_INT(Const.MinProgramTextureGatherOffset), extra_ARB_texture_gather"],
- [ "MAX_PROGRAM_TEXTURE_GATHER_OFFSET", "CONTEXT_INT(Const.MaxProgramTextureGatherOffset), extra_ARB_texture_gather"],
[ "MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB", "CONTEXT_INT(Const.MaxProgramTextureGatherComponents), extra_ARB_texture_gather"],
# GL_ARB_separate_shader_objects
[ "PROGRAM_PIPELINE_BINDING", "LOC_CUSTOM, TYPE_INT, GL_PROGRAM_PIPELINE_BINDING, NO_EXTRA" ],
# GL_ARB_shader_atomic_counters
- [ "ATOMIC_COUNTER_BUFFER_BINDING", "LOC_CUSTOM, TYPE_INT, 0, extra_ARB_shader_atomic_counters" ],
- [ "MAX_ATOMIC_COUNTER_BUFFER_BINDINGS", "CONTEXT_INT(Const.MaxAtomicBufferBindings), extra_ARB_shader_atomic_counters" ],
- [ "MAX_ATOMIC_COUNTER_BUFFER_SIZE", "CONTEXT_INT(Const.MaxAtomicBufferSize), extra_ARB_shader_atomic_counters" ],
- [ "MAX_VERTEX_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxAtomicBuffers), extra_ARB_shader_atomic_counters" ],
- [ "MAX_VERTEX_ATOMIC_COUNTERS", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxAtomicCounters), extra_ARB_shader_atomic_counters" ],
- [ "MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicBuffers), extra_ARB_shader_atomic_counters" ],
- [ "MAX_FRAGMENT_ATOMIC_COUNTERS", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicCounters), extra_ARB_shader_atomic_counters" ],
[ "MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicBuffers), extra_ARB_shader_atomic_counters_and_geometry_shader" ],
[ "MAX_GEOMETRY_ATOMIC_COUNTERS", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicCounters), extra_ARB_shader_atomic_counters_and_geometry_shader" ],
- [ "MAX_COMBINED_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.MaxCombinedAtomicBuffers), extra_ARB_shader_atomic_counters" ],
- [ "MAX_COMBINED_ATOMIC_COUNTERS", "CONTEXT_INT(Const.MaxCombinedAtomicCounters), extra_ARB_shader_atomic_counters" ],
# GL_ARB_vertex_attrib_binding
[ "MAX_VERTEX_ATTRIB_RELATIVE_OFFSET", "CONTEXT_ENUM(Const.MaxVertexAttribRelativeOffset), NO_EXTRA" ],
[ "MAX_VERTEX_ATTRIB_BINDINGS", "CONTEXT_ENUM(Const.MaxVertexAttribBindings), NO_EXTRA" ],
# GL_ARB_shader_image_load_store
- [ "MAX_IMAGE_UNITS", "CONTEXT_INT(Const.MaxImageUnits), extra_ARB_shader_image_load_store"],
- [ "MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS", "CONTEXT_INT(Const.MaxCombinedImageUnitsAndFragmentOutputs), extra_ARB_shader_image_load_store"],
- [ "MAX_IMAGE_SAMPLES", "CONTEXT_INT(Const.MaxImageSamples), extra_ARB_shader_image_load_store"],
- [ "MAX_VERTEX_IMAGE_UNIFORMS", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxImageUniforms), extra_ARB_shader_image_load_store"],
+ [ "MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS", "CONTEXT_INT(Const.MaxCombinedImageUnitsAndFragmentOutputs), 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"],
- [ "MAX_FRAGMENT_IMAGE_UNIFORMS", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxImageUniforms), extra_ARB_shader_image_load_store"],
- [ "MAX_COMBINED_IMAGE_UNIFORMS", "CONTEXT_INT(Const.MaxCombinedImageUniforms), extra_ARB_shader_image_load_store"],
-
-# 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_framebuffer_no_attachments
["MAX_FRAMEBUFFER_WIDTH", "CONTEXT_INT(Const.MaxFramebufferWidth), extra_ARB_framebuffer_no_attachments"],
@@ -826,6 +837,38 @@ descriptor=[
[ "MIN_FRAGMENT_INTERPOLATION_OFFSET", "CONTEXT_FLOAT(Const.MinFragmentInterpolationOffset), extra_ARB_gpu_shader5" ],
[ "MAX_FRAGMENT_INTERPOLATION_OFFSET", "CONTEXT_FLOAT(Const.MaxFragmentInterpolationOffset), extra_ARB_gpu_shader5" ],
[ "FRAGMENT_INTERPOLATION_OFFSET_BITS", "CONST(FRAGMENT_INTERPOLATION_OFFSET_BITS), extra_ARB_gpu_shader5" ],
+
+# GL_ARB_tessellation_shader
+ [ "PATCH_VERTICES", "CONTEXT_INT(TessCtrlProgram.patch_vertices), extra_ARB_tessellation_shader" ],
+ [ "PATCH_DEFAULT_OUTER_LEVEL", "CONTEXT_FLOAT4(TessCtrlProgram.patch_default_outer_level), extra_ARB_tessellation_shader" ],
+ [ "PATCH_DEFAULT_INNER_LEVEL", "CONTEXT_FLOAT2(TessCtrlProgram.patch_default_inner_level), extra_ARB_tessellation_shader" ],
+ [ "MAX_TESS_GEN_LEVEL", "CONTEXT_INT(Const.MaxTessGenLevel), extra_ARB_tessellation_shader" ],
+ [ "MAX_PATCH_VERTICES", "CONTEXT_INT(Const.MaxPatchVertices), extra_ARB_tessellation_shader" ],
+ [ "MAX_TESS_CONTROL_UNIFORM_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_CTRL].MaxUniformComponents), extra_ARB_tessellation_shader" ],
+ [ "MAX_TESS_EVALUATION_UNIFORM_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_EVAL].MaxUniformComponents), extra_ARB_tessellation_shader" ],
+ [ "MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_CTRL].MaxTextureImageUnits), extra_ARB_tessellation_shader" ],
+ [ "MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_EVAL].MaxTextureImageUnits), extra_ARB_tessellation_shader" ],
+ [ "MAX_TESS_CONTROL_OUTPUT_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_CTRL].MaxOutputComponents), extra_ARB_tessellation_shader" ],
+ [ "MAX_TESS_PATCH_COMPONENTS", "CONTEXT_INT(Const.MaxTessPatchComponents), extra_ARB_tessellation_shader" ],
+ [ "MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS", "CONTEXT_INT(Const.MaxTessControlTotalOutputComponents), extra_ARB_tessellation_shader" ],
+ [ "MAX_TESS_EVALUATION_OUTPUT_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_EVAL].MaxOutputComponents), extra_ARB_tessellation_shader" ],
+ [ "MAX_TESS_CONTROL_INPUT_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_CTRL].MaxInputComponents), extra_ARB_tessellation_shader" ],
+ [ "MAX_TESS_EVALUATION_INPUT_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_EVAL].MaxInputComponents), extra_ARB_tessellation_shader" ],
+ [ "MAX_TESS_CONTROL_UNIFORM_BLOCKS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_CTRL].MaxUniformBlocks), extra_ARB_tessellation_shader" ],
+ [ "MAX_TESS_EVALUATION_UNIFORM_BLOCKS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_EVAL].MaxUniformBlocks), extra_ARB_tessellation_shader" ],
+ [ "MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_CTRL].MaxCombinedUniformComponents), extra_ARB_tessellation_shader" ],
+ [ "MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_EVAL].MaxCombinedUniformComponents), extra_ARB_tessellation_shader" ],
+# Dependencies on GL_ARB_tessellation_shader
+ [ "MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_CTRL].MaxAtomicBuffers), extra_ARB_shader_atomic_counters_and_tessellation" ],
+ [ "MAX_TESS_CONTROL_ATOMIC_COUNTERS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_CTRL].MaxAtomicCounters), extra_ARB_shader_atomic_counters_and_tessellation" ],
+ [ "MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_EVAL].MaxAtomicBuffers), extra_ARB_shader_atomic_counters_and_tessellation" ],
+ [ "MAX_TESS_EVALUATION_ATOMIC_COUNTERS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_EVAL].MaxAtomicCounters), extra_ARB_shader_atomic_counters_and_tessellation" ],
+ [ "MAX_TESS_CONTROL_IMAGE_UNIFORMS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_CTRL].MaxImageUniforms), extra_ARB_shader_image_load_store_and_tessellation"],
+ [ "MAX_TESS_EVALUATION_IMAGE_UNIFORMS", "CONTEXT_INT(Const.Program[MESA_SHADER_TESS_EVAL].MaxImageUniforms), extra_ARB_shader_image_load_store_and_tessellation"],
+
+# GL_ARB_shader_subroutine
+ [ "MAX_SUBROUTINES", "CONST(MAX_SUBROUTINES), extra_ARB_shader_subroutine" ],
+ [ "MAX_SUBROUTINE_UNIFORM_LOCATIONS", "CONST(MAX_SUBROUTINE_UNIFORM_LOCATIONS), extra_ARB_shader_subroutine" ],
]}
]
diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c
index 72d99ca4e22..9873fdbf1a4 100644
--- a/src/mesa/main/getstring.c
+++ b/src/mesa/main/getstring.c
@@ -208,7 +208,7 @@ _mesa_GetPointerv( GLenum pname, GLvoid **params )
return;
if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glGetPointerv %s\n", _mesa_lookup_enum_by_nr(pname));
+ _mesa_debug(ctx, "glGetPointerv %s\n", _mesa_enum_to_string(pname));
switch (pname) {
case GL_VERTEX_ARRAY_POINTER:
@@ -299,7 +299,7 @@ _mesa_GetError( void )
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glGetError <-- %s\n", _mesa_lookup_enum_by_nr(e));
+ _mesa_debug(ctx, "glGetError <-- %s\n", _mesa_enum_to_string(e));
ctx->ErrorValue = (GLenum) GL_NO_ERROR;
ctx->ErrorDebugCount = 0;
diff --git a/src/mesa/main/glformats.c b/src/mesa/main/glformats.c
index ac69fabccaa..3eb66dab7f8 100644
--- a/src/mesa/main/glformats.c
+++ b/src/mesa/main/glformats.c
@@ -186,7 +186,7 @@ get_map_idx(GLenum value)
return IDX_RG;
default:
_mesa_problem(NULL, "Unexpected inFormat %s",
- _mesa_lookup_enum_by_nr(value));
+ _mesa_enum_to_string(value));
return 0;
}
}
@@ -216,8 +216,8 @@ _mesa_compute_component_mapping(GLenum inFormat, GLenum outFormat, GLubyte *map)
#if 0
printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
- inFormat, _mesa_lookup_enum_by_nr(inFormat),
- outFormat, _mesa_lookup_enum_by_nr(outFormat),
+ inFormat, _mesa_enum_to_string(inFormat),
+ outFormat, _mesa_enum_to_string(outFormat),
map[0],
map[1],
map[2],
@@ -1278,9 +1278,53 @@ _mesa_is_compressed_format(const struct gl_context *ctx, GLenum format)
}
}
+/**
+ * Convert various unpack formats to the corresponding base format.
+ */
+GLenum
+_mesa_unpack_format_to_base_format(GLenum format)
+{
+ switch(format) {
+ case GL_RED_INTEGER:
+ return GL_RED;
+ case GL_GREEN_INTEGER:
+ return GL_GREEN;
+ case GL_BLUE_INTEGER:
+ return GL_BLUE;
+ case GL_ALPHA_INTEGER:
+ return GL_ALPHA;
+ case GL_RG_INTEGER:
+ return GL_RG;
+ case GL_RGB_INTEGER:
+ return GL_RGB;
+ case GL_RGBA_INTEGER:
+ return GL_RGBA;
+ case GL_BGR_INTEGER:
+ return GL_BGR;
+ case GL_BGRA_INTEGER:
+ return GL_BGRA;
+ case GL_LUMINANCE_INTEGER_EXT:
+ return GL_LUMINANCE;
+ case GL_LUMINANCE_ALPHA_INTEGER_EXT:
+ return GL_LUMINANCE_ALPHA;
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_RG:
+ case GL_RGB:
+ case GL_RGBA:
+ case GL_BGR:
+ case GL_BGRA:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ default:
+ return format;
+ }
+}
/**
- * Convert various base formats to the cooresponding integer format.
+ * Convert various base formats to the corresponding integer format.
*/
GLenum
_mesa_base_format_to_integer_format(GLenum format)
@@ -2605,8 +2649,6 @@ get_swizzle_from_gl_format(GLenum format, uint8_t *swizzle)
uint32_t
_mesa_format_from_format_and_type(GLenum format, GLenum type)
{
- mesa_array_format array_format;
-
bool is_array_format = true;
uint8_t swizzle[4];
bool normalized = false, is_float = false, is_signed = false;
@@ -2662,15 +2704,9 @@ _mesa_format_from_format_and_type(GLenum format, GLenum type)
normalized = !_mesa_is_enum_format_integer(format);
num_channels = _mesa_components_in_format(format);
- array_format =
- MESA_ARRAY_FORMAT(type_size, is_signed, is_float,
- normalized, num_channels,
- swizzle[0], swizzle[1], swizzle[2], swizzle[3]);
-
- if (!_mesa_little_endian())
- array_format = _mesa_array_format_flip_channels(array_format);
-
- return array_format;
+ return MESA_ARRAY_FORMAT(type_size, is_signed, is_float,
+ normalized, num_channels,
+ swizzle[0], swizzle[1], swizzle[2], swizzle[3]);
}
/* Otherwise this is not an array format, so return the mesa_format
diff --git a/src/mesa/main/glformats.h b/src/mesa/main/glformats.h
index 8881cb7d86b..419955a6033 100644
--- a/src/mesa/main/glformats.h
+++ b/src/mesa/main/glformats.h
@@ -101,6 +101,9 @@ _mesa_is_compressed_format(const struct gl_context *ctx, GLenum format);
extern GLenum
_mesa_base_format_to_integer_format(GLenum format);
+extern GLenum
+_mesa_unpack_format_to_base_format(GLenum format);
+
extern GLboolean
_mesa_base_format_has_channel(GLenum base_format, GLenum pname);
diff --git a/src/mesa/main/hint.c b/src/mesa/main/hint.c
index 3e056ebaf13..984239a7276 100644
--- a/src/mesa/main/hint.c
+++ b/src/mesa/main/hint.c
@@ -40,8 +40,8 @@ _mesa_Hint( GLenum target, GLenum mode )
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glHint %s %s\n",
- _mesa_lookup_enum_by_nr(target),
- _mesa_lookup_enum_by_nr(mode));
+ _mesa_enum_to_string(target),
+ _mesa_enum_to_string(mode));
if (mode != GL_NICEST && mode != GL_FASTEST && mode != GL_DONT_CARE) {
_mesa_error(ctx, GL_INVALID_ENUM, "glHint(mode)");
diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c
index 68c7316575c..350e6752c8b 100644
--- a/src/mesa/main/imports.c
+++ b/src/mesa/main/imports.c
@@ -369,7 +369,7 @@ _mesa_float_to_half(float val)
* or normal.
*/
e = 0;
- m = (int) _mesa_roundevenf((1 << 24) * fabsf(fi.f));
+ m = _mesa_lroundevenf((1 << 24) * fabsf(fi.f));
}
else if (new_exp > 15) {
/* map this value to infinity */
@@ -383,7 +383,7 @@ _mesa_float_to_half(float val)
* either normal or infinite.
*/
e = new_exp + 15;
- m = (int) _mesa_roundevenf(flt_m / (float) (1 << 13));
+ m = _mesa_lroundevenf(flt_m / (float) (1 << 13));
}
}
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index 9ffe3decd0f..d61279ac4e5 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -170,34 +170,6 @@ 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.
- */
-static inline int F_TO_I(float f)
-{
-#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
- int r;
- __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
- return r;
-#elif defined(USE_X86_ASM) && defined(_MSC_VER)
- int r;
- _asm {
- fld f
- fistp r
- }
- return r;
-#elif defined(__x86_64__)
- return _mm_cvt_ss2si(_mm_load_ss(&f));
-#else
- return IROUND(f);
-#endif
-}
-
-
/** Return (as an integer) floor of float */
static inline int IFLOOR(float f)
{
diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c
index 4021dbef922..14b4b04162b 100644
--- a/src/mesa/main/light.c
+++ b/src/mesa/main/light.c
@@ -42,16 +42,16 @@ _mesa_ShadeModel( GLenum mode )
GET_CURRENT_CONTEXT(ctx);
if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glShadeModel %s\n", _mesa_lookup_enum_by_nr(mode));
+ _mesa_debug(ctx, "glShadeModel %s\n", _mesa_enum_to_string(mode));
+
+ if (ctx->Light.ShadeModel == mode)
+ return;
if (mode != GL_FLAT && mode != GL_SMOOTH) {
_mesa_error(ctx, GL_INVALID_ENUM, "glShadeModel");
return;
}
- if (ctx->Light.ShadeModel == mode)
- return;
-
FLUSH_VERTICES(ctx, _NEW_LIGHT);
ctx->Light.ShadeModel = mode;
@@ -143,7 +143,7 @@ _mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *pa
COPY_3V(light->SpotDirection, params);
break;
case GL_SPOT_EXPONENT:
- assert(params[0] >= 0.0);
+ assert(params[0] >= 0.0F);
assert(params[0] <= ctx->Const.MaxSpotExponent);
if (light->SpotExponent == params[0])
return;
@@ -151,12 +151,12 @@ _mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *pa
light->SpotExponent = params[0];
break;
case GL_SPOT_CUTOFF:
- assert(params[0] == 180.0 || (params[0] >= 0.0 && params[0] <= 90.0));
+ assert(params[0] == 180.0F || (params[0] >= 0.0F && params[0] <= 90.0F));
if (light->SpotCutoff == params[0])
return;
FLUSH_VERTICES(ctx, _NEW_LIGHT);
light->SpotCutoff = params[0];
- light->_CosCutoff = (GLfloat) (cos(light->SpotCutoff * M_PI / 180.0));
+ light->_CosCutoff = (cosf(light->SpotCutoff * M_PI / 180.0));
if (light->_CosCutoff < 0)
light->_CosCutoff = 0;
if (light->SpotCutoff != 180.0F)
@@ -165,21 +165,21 @@ _mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *pa
light->_Flags &= ~LIGHT_SPOT;
break;
case GL_CONSTANT_ATTENUATION:
- assert(params[0] >= 0.0);
+ assert(params[0] >= 0.0F);
if (light->ConstantAttenuation == params[0])
return;
FLUSH_VERTICES(ctx, _NEW_LIGHT);
light->ConstantAttenuation = params[0];
break;
case GL_LINEAR_ATTENUATION:
- assert(params[0] >= 0.0);
+ assert(params[0] >= 0.0F);
if (light->LinearAttenuation == params[0])
return;
FLUSH_VERTICES(ctx, _NEW_LIGHT);
light->LinearAttenuation = params[0];
break;
case GL_QUADRATIC_ATTENUATION:
- assert(params[0] >= 0.0);
+ assert(params[0] >= 0.0F);
if (light->QuadraticAttenuation == params[0])
return;
FLUSH_VERTICES(ctx, _NEW_LIGHT);
@@ -238,31 +238,31 @@ _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params )
params = temp;
break;
case GL_SPOT_EXPONENT:
- if (params[0] < 0.0 || params[0] > ctx->Const.MaxSpotExponent) {
+ if (params[0] < 0.0F || params[0] > ctx->Const.MaxSpotExponent) {
_mesa_error(ctx, GL_INVALID_VALUE, "glLight");
return;
}
break;
case GL_SPOT_CUTOFF:
- if ((params[0] < 0.0 || params[0] > 90.0) && params[0] != 180.0) {
+ if ((params[0] < 0.0F || params[0] > 90.0F) && params[0] != 180.0F) {
_mesa_error(ctx, GL_INVALID_VALUE, "glLight");
return;
}
break;
case GL_CONSTANT_ATTENUATION:
- if (params[0] < 0.0) {
+ if (params[0] < 0.0F) {
_mesa_error(ctx, GL_INVALID_VALUE, "glLight");
return;
}
break;
case GL_LINEAR_ATTENUATION:
- if (params[0] < 0.0) {
+ if (params[0] < 0.0F) {
_mesa_error(ctx, GL_INVALID_VALUE, "glLight");
return;
}
break;
case GL_QUADRATIC_ATTENUATION:
- if (params[0] < 0.0) {
+ if (params[0] < 0.0F) {
_mesa_error(ctx, GL_INVALID_VALUE, "glLight");
return;
}
@@ -463,14 +463,14 @@ _mesa_LightModelfv( GLenum pname, const GLfloat *params )
case GL_LIGHT_MODEL_LOCAL_VIEWER:
if (ctx->API != API_OPENGL_COMPAT)
goto invalid_pname;
- newbool = (params[0]!=0.0);
+ newbool = (params[0] != 0.0F);
if (ctx->Light.Model.LocalViewer == newbool)
return;
FLUSH_VERTICES(ctx, _NEW_LIGHT);
ctx->Light.Model.LocalViewer = newbool;
break;
case GL_LIGHT_MODEL_TWO_SIDE:
- newbool = (params[0]!=0.0);
+ newbool = (params[0] != 0.0F);
if (ctx->Light.Model.TwoSide == newbool)
return;
FLUSH_VERTICES(ctx, _NEW_LIGHT);
@@ -723,8 +723,8 @@ _mesa_ColorMaterial( GLenum face, GLenum mode )
if (MESA_VERBOSE&VERBOSE_API)
_mesa_debug(ctx, "glColorMaterial %s %s\n",
- _mesa_lookup_enum_by_nr(face),
- _mesa_lookup_enum_by_nr(mode));
+ _mesa_enum_to_string(face),
+ _mesa_enum_to_string(mode));
bitmask = _mesa_material_bitmask(ctx, face, mode, legal, "glColorMaterial");
if (bitmask == 0)
@@ -975,7 +975,7 @@ compute_light_positions( struct gl_context *ctx )
}
else {
/* positional light w/ homogeneous coordinate, divide by W */
- GLfloat wInv = (GLfloat)1.0 / light->_Position[3];
+ GLfloat wInv = 1.0F / light->_Position[3];
light->_Position[0] *= wInv;
light->_Position[1] *= wInv;
light->_Position[2] *= wInv;
@@ -1024,7 +1024,7 @@ update_modelview_scale( struct gl_context *ctx )
if (!_math_matrix_is_length_preserving(ctx->ModelviewMatrixStack.Top)) {
const GLfloat *m = ctx->ModelviewMatrixStack.Top->inv;
GLfloat f = m[2] * m[2] + m[6] * m[6] + m[10] * m[10];
- if (f < 1e-12) f = 1.0;
+ if (f < 1e-12f) f = 1.0f;
if (ctx->_NeedEyeCoords)
ctx->_ModelViewInvScale = 1.0f / sqrtf(f);
else
diff --git a/src/mesa/main/lines.c b/src/mesa/main/lines.c
index 3c08ed2e713..c020fb3eb9e 100644
--- a/src/mesa/main/lines.c
+++ b/src/mesa/main/lines.c
@@ -45,7 +45,7 @@ _mesa_LineWidth( GLfloat width )
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glLineWidth %f\n", width);
- if (width<=0.0) {
+ if (width <= 0.0F) {
_mesa_error( ctx, GL_INVALID_VALUE, "glLineWidth" );
return;
}
@@ -63,7 +63,7 @@ _mesa_LineWidth( GLfloat width )
if (ctx->API == API_OPENGL_CORE
&& ((ctx->Const.ContextFlags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
!= 0)
- && width > 1.0) {
+ && width > 1.0F) {
_mesa_error( ctx, GL_INVALID_VALUE, "glLineWidth" );
return;
}
diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h
index 0608650aeb4..54df50c9cfe 100644
--- a/src/mesa/main/macros.h
+++ b/src/mesa/main/macros.h
@@ -33,6 +33,7 @@
#include "util/macros.h"
#include "util/u_math.h"
+#include "util/rounding.h"
#include "imports.h"
@@ -131,12 +132,12 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
#define INT_TO_USHORT(i) ((i) < 0 ? 0 : ((GLushort) ((i) >> 15)))
#define UINT_TO_USHORT(i) ((i) < 0 ? 0 : ((GLushort) ((i) >> 16)))
#define UNCLAMPED_FLOAT_TO_USHORT(us, f) \
- us = ( (GLushort) F_TO_I( CLAMP((f), 0.0F, 1.0F) * 65535.0F) )
+ us = ( (GLushort) _mesa_lroundevenf( CLAMP((f), 0.0F, 1.0F) * 65535.0F) )
#define CLAMPED_FLOAT_TO_USHORT(us, f) \
- us = ( (GLushort) F_TO_I( (f) * 65535.0F) )
+ us = ( (GLushort) _mesa_lroundevenf( (f) * 65535.0F) )
#define UNCLAMPED_FLOAT_TO_SHORT(s, f) \
- s = ( (GLshort) F_TO_I( CLAMP((f), -1.0F, 1.0F) * 32767.0F) )
+ s = ( (GLshort) _mesa_lroundevenf( CLAMP((f), -1.0F, 1.0F) * 32767.0F) )
/***
*** UNCLAMPED_FLOAT_TO_UBYTE: clamp float to [0,1] and map to ubyte in [0,255]
@@ -167,9 +168,9 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
} while (0)
#else
#define UNCLAMPED_FLOAT_TO_UBYTE(ub, f) \
- ub = ((GLubyte) F_TO_I(CLAMP((f), 0.0F, 1.0F) * 255.0F))
+ ub = ((GLubyte) _mesa_lroundevenf(CLAMP((f), 0.0F, 1.0F) * 255.0F))
#define CLAMPED_FLOAT_TO_UBYTE(ub, f) \
- ub = ((GLubyte) F_TO_I((f) * 255.0F))
+ ub = ((GLubyte) _mesa_lroundevenf((f) * 255.0F))
#endif
static fi_type UINT_AS_UNION(GLuint u)
@@ -679,17 +680,6 @@ minify(unsigned value, unsigned levels)
}
/**
- * Return true if the given value is a power of two.
- *
- * Note that this considers 0 a power of two.
- */
-static inline bool
-is_power_of_two(unsigned value)
-{
- return (value & (value - 1)) == 0;
-}
-
-/**
* Align a value up to an alignment value
*
* If \c value is not already aligned to the requested alignment value, it
diff --git a/src/mesa/main/matrix.c b/src/mesa/main/matrix.c
index 80c8a248ce4..2b8016a4a72 100644
--- a/src/mesa/main/matrix.c
+++ b/src/mesa/main/matrix.c
@@ -229,7 +229,7 @@ _mesa_PushMatrix( void )
if (MESA_VERBOSE&VERBOSE_API)
_mesa_debug(ctx, "glPushMatrix %s\n",
- _mesa_lookup_enum_by_nr(ctx->Transform.MatrixMode));
+ _mesa_enum_to_string(ctx->Transform.MatrixMode));
if (stack->Depth + 1 >= stack->MaxDepth) {
if (ctx->Transform.MatrixMode == GL_TEXTURE) {
@@ -239,7 +239,7 @@ _mesa_PushMatrix( void )
}
else {
_mesa_error(ctx, GL_STACK_OVERFLOW, "glPushMatrix(mode=%s)",
- _mesa_lookup_enum_by_nr(ctx->Transform.MatrixMode));
+ _mesa_enum_to_string(ctx->Transform.MatrixMode));
}
return;
}
@@ -270,7 +270,7 @@ _mesa_PopMatrix( void )
if (MESA_VERBOSE&VERBOSE_API)
_mesa_debug(ctx, "glPopMatrix %s\n",
- _mesa_lookup_enum_by_nr(ctx->Transform.MatrixMode));
+ _mesa_enum_to_string(ctx->Transform.MatrixMode));
if (stack->Depth == 0) {
if (ctx->Transform.MatrixMode == GL_TEXTURE) {
@@ -280,7 +280,7 @@ _mesa_PopMatrix( void )
}
else {
_mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopMatrix(mode=%s)",
- _mesa_lookup_enum_by_nr(ctx->Transform.MatrixMode));
+ _mesa_enum_to_string(ctx->Transform.MatrixMode));
}
return;
}
diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c
index 7732d09b2ec..1e22f930092 100644
--- a/src/mesa/main/mipmap.c
+++ b/src/mesa/main/mipmap.c
@@ -2077,9 +2077,12 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
/* Get the uncompressed image */
assert(srcImage->Level == texObj->BaseLevel);
- ctx->Driver.GetTexImage(ctx,
- temp_base_format, temp_datatype,
- temp_src, srcImage);
+ ctx->Driver.GetTexSubImage(ctx,
+ 0, 0, 0,
+ srcImage->Width, srcImage->Height,
+ srcImage->Depth,
+ temp_base_format, temp_datatype,
+ temp_src, srcImage);
/* restore packing mode */
ctx->Pack = save;
}
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 2d285b87a78..83f3717754d 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -90,7 +90,7 @@ struct vbo_context;
/** Extra draw modes beyond GL_POINTS, GL_TRIANGLE_FAN, etc */
-#define PRIM_MAX GL_TRIANGLE_STRIP_ADJACENCY
+#define PRIM_MAX GL_PATCHES
#define PRIM_OUTSIDE_BEGIN_END (PRIM_MAX + 1)
#define PRIM_UNKNOWN (PRIM_MAX + 2)
@@ -109,6 +109,8 @@ _mesa_varying_slot_in_fs(gl_varying_slot slot)
case VARYING_SLOT_EDGE:
case VARYING_SLOT_CLIP_VERTEX:
case VARYING_SLOT_LAYER:
+ case VARYING_SLOT_TESS_LEVEL_OUTER:
+ case VARYING_SLOT_TESS_LEVEL_INNER:
return GL_FALSE;
default:
return GL_TRUE;
@@ -1254,6 +1256,7 @@ typedef enum {
USAGE_UNIFORM_BUFFER = 0x1,
USAGE_TEXTURE_BUFFER = 0x2,
USAGE_ATOMIC_COUNTER_BUFFER = 0x4,
+ USAGE_SHADER_STORAGE_BUFFER = 0x8,
} gl_buffer_usage;
@@ -1654,6 +1657,11 @@ struct gl_transform_feedback_info
* multiple transform feedback outputs in the same buffer.
*/
unsigned BufferStride[MAX_FEEDBACK_BUFFERS];
+
+ /**
+ * Which transform feedback stream this buffer binding is associated with.
+ */
+ unsigned BufferStream[MAX_FEEDBACK_BUFFERS];
};
@@ -1891,6 +1899,8 @@ struct gl_program
GLbitfield64 InputsRead; /**< Bitmask of which input regs are read */
GLbitfield64 DoubleInputsRead; /**< Bitmask of which input regs are read and are doubles */
GLbitfield64 OutputsWritten; /**< Bitmask of which output regs are written */
+ GLbitfield PatchInputsRead; /**< VAR[0..31] usage for patch inputs (user-defined only) */
+ GLbitfield PatchOutputsWritten; /**< VAR[0..31] usage for patch outputs (user-defined only) */
GLbitfield SystemValuesRead; /**< Bitmask of SYSTEM_VALUE_x inputs used */
GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */
GLbitfield SamplersUsed; /**< Bitfield of which samplers are used */
@@ -1958,6 +1968,29 @@ struct gl_vertex_program
};
+/** Tessellation control program object */
+struct gl_tess_ctrl_program
+{
+ struct gl_program Base; /**< base class */
+
+ /* output layout */
+ GLint VerticesOut;
+};
+
+
+/** Tessellation evaluation program object */
+struct gl_tess_eval_program
+{
+ struct gl_program Base; /**< base class */
+
+ /* input layout */
+ GLenum PrimitiveMode; /* GL_TRIANGLES, GL_QUADS or GL_ISOLINES */
+ GLenum Spacing; /* GL_EQUAL, GL_FRACTIONAL_EVEN, GL_FRACTIONAL_ODD */
+ GLenum VertexOrder; /* GL_CW or GL_CCW */
+ bool PointMode;
+};
+
+
/** Geometry program object */
struct gl_geometry_program
{
@@ -2060,6 +2093,27 @@ struct gl_vertex_program_state
GLboolean _Overriden;
};
+/**
+ * Context state for tessellation control programs.
+ */
+struct gl_tess_ctrl_program_state
+{
+ /** Currently bound and valid shader. */
+ struct gl_tess_ctrl_program *_Current;
+
+ GLint patch_vertices;
+ GLfloat patch_default_outer_level[4];
+ GLfloat patch_default_inner_level[2];
+};
+
+/**
+ * Context state for tessellation evaluation programs.
+ */
+struct gl_tess_eval_program_state
+{
+ /** Currently bound and valid shader. */
+ struct gl_tess_eval_program *_Current;
+};
/**
* Context state for geometry programs.
@@ -2154,13 +2208,23 @@ struct gl_ati_fragment_shader_state
struct ati_fragment_shader *Current;
};
+/**
+ * Shader subroutine function definition
+ */
+struct gl_subroutine_function
+{
+ char *name;
+ int num_compat_types;
+ const struct glsl_type **types;
+};
/**
* A GLSL vertex or fragment shader object.
*/
struct gl_shader
{
- /** GL_FRAGMENT_SHADER || GL_VERTEX_SHADER || GL_GEOMETRY_SHADER_ARB.
+ /** GL_FRAGMENT_SHADER || GL_VERTEX_SHADER || GL_GEOMETRY_SHADER_ARB ||
+ * GL_TESS_CONTROL_SHADER || GL_TESS_EVALUATION_SHADER.
* Must be the first field.
*/
GLenum Type;
@@ -2240,6 +2304,41 @@ struct gl_shader
bool pixel_center_integer;
/**
+ * Tessellation Control shader state from layout qualifiers.
+ */
+ struct {
+ /**
+ * 0 - vertices not declared in shader, or
+ * 1 .. GL_MAX_PATCH_VERTICES
+ */
+ GLint VerticesOut;
+ } TessCtrl;
+
+ /**
+ * Tessellation Evaluation shader state from layout qualifiers.
+ */
+ struct {
+ /**
+ * GL_TRIANGLES, GL_QUADS, GL_ISOLINES or PRIM_UNKNOWN if it's not set
+ * in this shader.
+ */
+ GLenum PrimitiveMode;
+ /**
+ * GL_EQUAL, GL_FRACTIONAL_ODD, GL_FRACTIONAL_EVEN, or 0 if it's not set
+ * in this shader.
+ */
+ GLenum Spacing;
+ /**
+ * GL_CW, GL_CCW, or 0 if it's not set in this shader.
+ */
+ GLenum VertexOrder;
+ /**
+ * 1, 0, or -1 if it's not set in this shader.
+ */
+ int PointMode;
+ } TessEval;
+
+ /**
* Geometry shader state from GLSL 1.50 layout qualifiers.
*/
struct {
@@ -2304,6 +2403,25 @@ struct gl_shader
*/
unsigned LocalSize[3];
} Comp;
+
+ /**
+ * Number of types for subroutine uniforms.
+ */
+ GLuint NumSubroutineUniformTypes;
+
+ /**
+ * Subroutine uniform remap table
+ * based on the program level uniform remap table.
+ */
+ GLuint NumSubroutineUniformRemapTable;
+ struct gl_uniform_storage **SubroutineUniformRemapTable;
+
+ /**
+ * Num of subroutine functions for this stage
+ * and storage for them.
+ */
+ GLuint NumSubroutineFunctions;
+ struct gl_subroutine_function *SubroutineFunctions;
};
@@ -2365,6 +2483,11 @@ struct gl_uniform_block
GLuint UniformBufferSize;
/**
+ * Is this actually an interface block for a shader storage buffer?
+ */
+ bool IsShaderStorage;
+
+ /**
* Layout specified in the shader
*
* This isn't accessible through the API, but it is used while
@@ -2468,6 +2591,37 @@ struct gl_shader_program
enum gl_frag_depth_layout FragDepthLayout;
/**
+ * Tessellation Control shader state from layout qualifiers.
+ */
+ struct {
+ /**
+ * 0 - vertices not declared in shader, or
+ * 1 .. GL_MAX_PATCH_VERTICES
+ */
+ GLint VerticesOut;
+ } TessCtrl;
+
+ /**
+ * Tessellation Evaluation shader state from layout qualifiers.
+ */
+ struct {
+ /** GL_TRIANGLES, GL_QUADS or GL_ISOLINES */
+ GLenum PrimitiveMode;
+ /** GL_EQUAL, GL_FRACTIONAL_ODD or GL_FRACTIONAL_EVEN */
+ GLenum Spacing;
+ /** GL_CW or GL_CCW */
+ GLenum VertexOrder;
+ bool PointMode;
+ /**
+ * True if gl_ClipDistance is written to. Copied into
+ * gl_tess_eval_program by _mesa_copy_linked_program_data().
+ */
+ GLboolean UsesClipDistance;
+ GLuint ClipDistanceArraySize; /**< Size of the gl_ClipDistance array, or
+ 0 if not present. */
+ } TessEval;
+
+ /**
* Geometry shader state - copied into gl_geometry_program by
* _mesa_copy_linked_program_data().
*/
@@ -2681,6 +2835,7 @@ struct gl_shader_compiler_options
GLboolean EmitNoIndirectOutput; /**< No indirect addressing of outputs */
GLboolean EmitNoIndirectTemp; /**< No indirect addressing of temps */
GLboolean EmitNoIndirectUniform; /**< No indirect addressing of constants */
+ GLboolean EmitNoIndirectSampler; /**< No indirect addressing of samplers */
/*@}*/
GLuint MaxIfDepth; /**< Maximum nested IF blocks */
@@ -3100,6 +3255,9 @@ struct gl_program_constants
/* GL_ARB_shader_image_load_store */
GLuint MaxImageUniforms;
+
+ /* GL_ARB_shader_storage_buffer_object */
+ GLuint MaxShaderStorageBlocks;
};
@@ -3197,6 +3355,15 @@ struct gl_constants
GLuint UniformBufferOffsetAlignment;
/** @} */
+ /** @{
+ * GL_ARB_shader_storage_buffer_object
+ */
+ GLuint MaxCombinedShaderStorageBlocks;
+ GLuint MaxShaderStorageBufferBindings;
+ GLuint MaxShaderStorageBlockSize;
+ GLuint ShaderStorageBufferOffsetAlignment;
+ /** @} */
+
/**
* GL_ARB_explicit_uniform_location
*/
@@ -3423,6 +3590,13 @@ struct gl_constants
GLenum ContextReleaseBehavior;
struct gl_shader_compiler_options ShaderCompilerOptions[MESA_SHADER_STAGES];
+
+ /** GL_ARB_tessellation_shader */
+ GLuint MaxPatchVertices;
+ GLuint MaxTessGenLevel;
+ GLuint MaxTessPatchComponents;
+ GLuint MaxTessControlTotalOutputComponents;
+ bool LowerTessLevel; /**< Lower gl_TessLevel* from float[n] to vecn? */
};
@@ -3484,6 +3658,8 @@ struct gl_extensions
GLboolean ARB_shader_image_load_store;
GLboolean ARB_shader_precision;
GLboolean ARB_shader_stencil_export;
+ GLboolean ARB_shader_storage_buffer_object;
+ GLboolean ARB_shader_subroutine;
GLboolean ARB_shader_texture_lod;
GLboolean ARB_shading_language_packing;
GLboolean ARB_shading_language_420pack;
@@ -3815,6 +3991,12 @@ struct gl_driver_flags
*/
uint64_t NewUniformBuffer;
+ /**
+ * gl_context::ShaderStorageBufferBindings
+ * gl_shader_program::ShaderStorageBlocks
+ */
+ uint64_t NewShaderStorageBuffer;
+
uint64_t NewTextureBuffer;
/**
@@ -3826,6 +4008,11 @@ struct gl_driver_flags
* gl_context::ImageUnits
*/
uint64_t NewImageUnits;
+
+ /**
+ * gl_context::TessCtrlProgram::patch_default_*
+ */
+ uint64_t NewDefaultTessLevels;
};
struct gl_uniform_buffer_binding
@@ -3842,6 +4029,20 @@ struct gl_uniform_buffer_binding
GLboolean AutomaticSize;
};
+struct gl_shader_storage_buffer_binding
+{
+ struct gl_buffer_object *BufferObject;
+ /** Start of shader storage block data in the buffer */
+ GLintptr Offset;
+ /** Size of data allowed to be referenced from the buffer (in bytes) */
+ GLsizeiptr Size;
+ /**
+ * glBindBufferBase() indicates that the Size should be ignored and only
+ * limited by the current size of the BufferObject.
+ */
+ GLboolean AutomaticSize;
+};
+
/**
* ARB_shader_image_load_store image unit.
*/
@@ -4047,6 +4248,8 @@ struct gl_context
struct gl_fragment_program_state FragmentProgram;
struct gl_geometry_program_state GeometryProgram;
struct gl_compute_program_state ComputeProgram;
+ struct gl_tess_ctrl_program_state TessCtrlProgram;
+ struct gl_tess_eval_program_state TessEvalProgram;
struct gl_ati_fragment_shader_state ATIFragmentShader;
struct gl_pipeline_shader_state Pipeline; /**< GLSL pipeline shader object state */
@@ -4089,6 +4292,12 @@ struct gl_context
struct gl_buffer_object *UniformBuffer;
/**
+ * Current GL_ARB_shader_storage_buffer_object binding referenced by
+ * GL_SHADER_STORAGE_BUFFER target for glBufferData, glMapBuffer, etc.
+ */
+ struct gl_buffer_object *ShaderStorageBuffer;
+
+ /**
* Array of uniform buffers for GL_ARB_uniform_buffer_object and GL 3.1.
* This is set up using glBindBufferRange() or glBindBufferBase(). They are
* associated with uniform blocks by glUniformBlockBinding()'s state in the
@@ -4098,6 +4307,15 @@ struct gl_context
UniformBufferBindings[MAX_COMBINED_UNIFORM_BUFFERS];
/**
+ * Array of shader storage buffers for ARB_shader_storage_buffer_object
+ * and GL 4.3. This is set up using glBindBufferRange() or
+ * glBindBufferBase(). They are associated with shader storage blocks by
+ * glShaderStorageBlockBinding()'s state in the shader program.
+ */
+ struct gl_shader_storage_buffer_binding
+ ShaderStorageBufferBindings[MAX_COMBINED_SHADER_STORAGE_BUFFERS];
+
+ /**
* Object currently associated with the GL_ATOMIC_COUNTER_BUFFER
* target.
*/
diff --git a/src/mesa/main/multisample.c b/src/mesa/main/multisample.c
index 816837b95bd..09e6154f7ec 100644
--- a/src/mesa/main/multisample.c
+++ b/src/mesa/main/multisample.c
@@ -43,7 +43,7 @@ _mesa_SampleCoverage(GLclampf value, GLboolean invert)
FLUSH_VERTICES(ctx, 0);
- ctx->Multisample.SampleCoverageValue = (GLfloat) CLAMP(value, 0.0, 1.0);
+ ctx->Multisample.SampleCoverageValue = CLAMP(value, 0.0f, 1.0f);
ctx->Multisample.SampleCoverageInvert = invert;
ctx->NewState |= _NEW_MULTISAMPLE;
}
@@ -134,7 +134,7 @@ _mesa_MinSampleShading(GLclampf value)
FLUSH_VERTICES(ctx, 0);
- ctx->Multisample.MinSampleShadingValue = CLAMP(value, 0.0, 1.0);
+ ctx->Multisample.MinSampleShadingValue = CLAMP(value, 0.0f, 1.0f);
ctx->NewState |= _NEW_MULTISAMPLE;
}
@@ -164,8 +164,11 @@ _mesa_check_sample_count(struct gl_context *ctx, GLenum target,
*
* "If internalformat is a signed or unsigned integer format and samples
* is greater than zero, then the error INVALID_OPERATION is generated."
+ *
+ * This restriction is relaxed for OpenGL ES 3.1.
*/
- if (_mesa_is_gles3(ctx) && _mesa_is_enum_format_integer(internalFormat)
+ if ((ctx->API == API_OPENGLES2 && ctx->Version == 30) &&
+ _mesa_is_enum_format_integer(internalFormat)
&& samples > 0) {
return GL_INVALID_OPERATION;
}
diff --git a/src/mesa/main/objectlabel.c b/src/mesa/main/objectlabel.c
index 5626054687b..1019f893ba8 100644
--- a/src/mesa/main/objectlabel.c
+++ b/src/mesa/main/objectlabel.c
@@ -234,7 +234,7 @@ get_label_pointer(struct gl_context *ctx, GLenum identifier, GLuint name,
invalid_enum:
_mesa_error(ctx, GL_INVALID_ENUM, "%s(identifier = %s)",
- caller, _mesa_lookup_enum_by_nr(identifier));
+ caller, _mesa_enum_to_string(identifier));
return NULL;
}
diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c
index f72360817e9..7147fd6e4fe 100644
--- a/src/mesa/main/pack.c
+++ b/src/mesa/main/pack.c
@@ -470,7 +470,7 @@ extract_uint_indexes(GLuint n, GLuint indexes[],
static inline GLuint
clamp_float_to_uint(GLfloat f)
{
- return f < 0.0F ? 0 : F_TO_I(f);
+ return f < 0.0F ? 0 : _mesa_lroundevenf(f);
}
@@ -478,7 +478,7 @@ static inline GLuint
clamp_half_to_uint(GLhalfARB h)
{
GLfloat f = _mesa_half_to_float(h);
- return f < 0.0F ? 0 : F_TO_I(f);
+ return f < 0.0F ? 0 : _mesa_lroundevenf(f);
}
@@ -796,7 +796,7 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
* back to an int type can introduce errors that will show up as
* artifacts in things like depth peeling which uses glCopyTexImage.
*/
- if (ctx->Pixel.DepthScale == 1.0 && ctx->Pixel.DepthBias == 0.0) {
+ if (ctx->Pixel.DepthScale == 1.0F && ctx->Pixel.DepthBias == 0.0F) {
if (srcType == GL_UNSIGNED_INT && dstType == GL_UNSIGNED_SHORT) {
const GLuint *src = (const GLuint *) source;
GLushort *dst = (GLushort *) dest;
@@ -874,8 +874,8 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
case GL_UNSIGNED_INT_24_8_EXT: /* GL_EXT_packed_depth_stencil */
if (dstType == GL_UNSIGNED_INT_24_8_EXT &&
depthMax == 0xffffff &&
- ctx->Pixel.DepthScale == 1.0 &&
- ctx->Pixel.DepthBias == 0.0) {
+ ctx->Pixel.DepthScale == 1.0F &&
+ ctx->Pixel.DepthBias == 0.0F) {
const GLuint *src = (const GLuint *) source;
GLuint *zValues = (GLuint *) dest;
GLuint i;
@@ -945,7 +945,7 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
{
const GLfloat scale = ctx->Pixel.DepthScale;
const GLfloat bias = ctx->Pixel.DepthBias;
- if (scale != 1.0 || bias != 0.0) {
+ if (scale != 1.0F || bias != 0.0F) {
GLuint i;
for (i = 0; i < n; i++) {
depthValues[i] = depthValues[i] * scale + bias;
@@ -958,7 +958,7 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
if (needClamp) {
GLuint i;
for (i = 0; i < n; i++) {
- depthValues[i] = (GLfloat)CLAMP(depthValues[i], 0.0, 1.0);
+ depthValues[i] = CLAMP(depthValues[i], 0.0F, 1.0F);
}
}
@@ -1025,7 +1025,7 @@ _mesa_pack_depth_span( struct gl_context *ctx, GLuint n, GLvoid *dest,
return;
}
- if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
+ if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F) {
memcpy(depthCopy, depthSpan, n * sizeof(GLfloat));
_mesa_scale_and_bias_depth(ctx, n, depthCopy);
depthSpan = depthCopy;
@@ -1153,7 +1153,7 @@ _mesa_pack_depth_stencil_span(struct gl_context *ctx,GLuint n,
return;
}
- if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
+ if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F) {
memcpy(depthCopy, depthVals, n * sizeof(GLfloat));
_mesa_scale_and_bias_depth(ctx, n, depthCopy);
depthVals = depthCopy;
diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
index 279ae2078fe..07acbf10c1d 100644
--- a/src/mesa/main/pipelineobj.c
+++ b/src/mesa/main/pipelineobj.c
@@ -244,14 +244,13 @@ _mesa_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
*
* "If stages is not the special value ALL_SHADER_BITS, and has a bit
* set that is not recognized, the error INVALID_VALUE is generated."
- *
- * NOT YET SUPPORTED:
- * GL_TESS_CONTROL_SHADER_BIT
- * GL_TESS_EVALUATION_SHADER_BIT
*/
any_valid_stages = GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT;
if (_mesa_has_geometry_shaders(ctx))
any_valid_stages |= GL_GEOMETRY_SHADER_BIT;
+ if (_mesa_has_tessellation(ctx))
+ any_valid_stages |= GL_TESS_CONTROL_SHADER_BIT |
+ GL_TESS_EVALUATION_SHADER_BIT;
if (stages != GL_ALL_SHADER_BITS && (stages & ~any_valid_stages) != 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glUseProgramStages(Stages)");
@@ -327,6 +326,12 @@ _mesa_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
if ((stages & GL_GEOMETRY_SHADER_BIT) != 0)
_mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER, shProg, pipe);
+
+ if ((stages & GL_TESS_CONTROL_SHADER_BIT) != 0)
+ _mesa_use_shader_program(ctx, GL_TESS_CONTROL_SHADER, shProg, pipe);
+
+ if ((stages & GL_TESS_EVALUATION_SHADER_BIT) != 0)
+ _mesa_use_shader_program(ctx, GL_TESS_EVALUATION_SHADER, shProg, pipe);
}
/**
@@ -588,6 +593,7 @@ _mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
/* Are geometry shaders available in this context?
*/
const bool has_gs = _mesa_has_geometry_shaders(ctx);
+ const bool has_tess = _mesa_has_tessellation(ctx);;
if (!pipe) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -615,11 +621,17 @@ _mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
? pipe->CurrentProgram[MESA_SHADER_VERTEX]->Name : 0;
return;
case GL_TESS_EVALUATION_SHADER:
- /* NOT YET SUPPORTED */
- break;
+ if (!has_tess)
+ break;
+ *params = pipe->CurrentProgram[MESA_SHADER_TESS_EVAL]
+ ? pipe->CurrentProgram[MESA_SHADER_TESS_EVAL]->Name : 0;
+ return;
case GL_TESS_CONTROL_SHADER:
- /* NOT YET SUPPORTED */
- break;
+ if (!has_tess)
+ break;
+ *params = pipe->CurrentProgram[MESA_SHADER_TESS_CTRL]
+ ? pipe->CurrentProgram[MESA_SHADER_TESS_CTRL]->Name : 0;
+ return;
case GL_GEOMETRY_SHADER:
if (!has_gs)
break;
@@ -635,7 +647,7 @@ _mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
}
_mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramPipelineiv(pname=%s)",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
}
/**
@@ -777,7 +789,9 @@ _mesa_validate_program_pipeline(struct gl_context* ctx,
* executable vertex shader."
*/
if (!pipe->CurrentProgram[MESA_SHADER_VERTEX]
- && pipe->CurrentProgram[MESA_SHADER_GEOMETRY]) {
+ && (pipe->CurrentProgram[MESA_SHADER_GEOMETRY] ||
+ pipe->CurrentProgram[MESA_SHADER_TESS_CTRL] ||
+ pipe->CurrentProgram[MESA_SHADER_TESS_EVAL])) {
pipe->InfoLog = ralloc_strdup(pipe, "Program lacks a vertex shader");
goto err;
}
diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c
index ecda2694fc8..608a5454702 100644
--- a/src/mesa/main/pixel.c
+++ b/src/mesa/main/pixel.c
@@ -455,12 +455,12 @@ _mesa_GetnPixelMapusvARB( GLenum map, GLsizei bufSize, GLushort *values )
/* special cases */
case GL_PIXEL_MAP_I_TO_I:
for (i = 0; i < mapsize; i++) {
- values[i] = (GLushort) CLAMP(ctx->PixelMaps.ItoI.Map[i], 0.0, 65535.);
+ values[i] = (GLushort) CLAMP(ctx->PixelMaps.ItoI.Map[i], 0.0F, 65535.0F);
}
break;
case GL_PIXEL_MAP_S_TO_S:
for (i = 0; i < mapsize; i++) {
- values[i] = (GLushort) CLAMP(ctx->PixelMaps.StoS.Map[i], 0.0, 65535.);
+ values[i] = (GLushort) CLAMP(ctx->PixelMaps.StoS.Map[i], 0.0F, 65535.0F);
}
break;
default:
diff --git a/src/mesa/main/pixeltransfer.c b/src/mesa/main/pixeltransfer.c
index 94464ea6709..22eac00a7df 100644
--- a/src/mesa/main/pixeltransfer.c
+++ b/src/mesa/main/pixeltransfer.c
@@ -35,6 +35,7 @@
#include "pixeltransfer.h"
#include "imports.h"
#include "mtypes.h"
+#include "util/rounding.h"
/*
@@ -47,25 +48,25 @@ _mesa_scale_and_bias_rgba(GLuint n, GLfloat rgba[][4],
GLfloat rBias, GLfloat gBias,
GLfloat bBias, GLfloat aBias)
{
- if (rScale != 1.0 || rBias != 0.0) {
+ if (rScale != 1.0F || rBias != 0.0F) {
GLuint i;
for (i = 0; i < n; i++) {
rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias;
}
}
- if (gScale != 1.0 || gBias != 0.0) {
+ if (gScale != 1.0F || gBias != 0.0F) {
GLuint i;
for (i = 0; i < n; i++) {
rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias;
}
}
- if (bScale != 1.0 || bBias != 0.0) {
+ if (bScale != 1.0F || bBias != 0.0F) {
GLuint i;
for (i = 0; i < n; i++) {
rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias;
}
}
- if (aScale != 1.0 || aBias != 0.0) {
+ if (aScale != 1.0F || aBias != 0.0F) {
GLuint i;
for (i = 0; i < n; i++) {
rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias;
@@ -94,10 +95,10 @@ _mesa_map_rgba( const struct gl_context *ctx, GLuint n, GLfloat rgba[][4] )
GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
- rgba[i][RCOMP] = rMap[F_TO_I(r * rscale)];
- rgba[i][GCOMP] = gMap[F_TO_I(g * gscale)];
- rgba[i][BCOMP] = bMap[F_TO_I(b * bscale)];
- rgba[i][ACOMP] = aMap[F_TO_I(a * ascale)];
+ rgba[i][RCOMP] = rMap[(int)_mesa_lroundevenf(r * rscale)];
+ rgba[i][GCOMP] = gMap[(int)_mesa_lroundevenf(g * gscale)];
+ rgba[i][BCOMP] = bMap[(int)_mesa_lroundevenf(b * bscale)];
+ rgba[i][ACOMP] = aMap[(int)_mesa_lroundevenf(a * ascale)];
}
}
@@ -236,7 +237,7 @@ _mesa_apply_ci_transfer_ops(const struct gl_context *ctx,
GLuint i;
for (i = 0; i < n; i++) {
const GLuint j = indexes[i] & mask;
- indexes[i] = F_TO_I(ctx->PixelMaps.ItoI.Map[j]);
+ indexes[i] = _mesa_lroundevenf(ctx->PixelMaps.ItoI.Map[j]);
}
}
}
diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c
index 5ad1f38f366..863e3c1af32 100644
--- a/src/mesa/main/points.c
+++ b/src/mesa/main/points.c
@@ -45,7 +45,7 @@ _mesa_PointSize( GLfloat size )
{
GET_CURRENT_CONTEXT(ctx);
- if (size <= 0.0) {
+ if (size <= 0.0F) {
_mesa_error( ctx, GL_INVALID_VALUE, "glPointSize" );
return;
}
@@ -119,9 +119,9 @@ _mesa_PointParameterfv( GLenum pname, const GLfloat *params)
return;
FLUSH_VERTICES(ctx, _NEW_POINT);
COPY_3V(ctx->Point.Params, params);
- ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0 ||
- ctx->Point.Params[1] != 0.0 ||
- ctx->Point.Params[2] != 0.0);
+ ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0F ||
+ ctx->Point.Params[1] != 0.0F ||
+ ctx->Point.Params[2] != 0.0F);
break;
case GL_POINT_SIZE_MIN_EXT:
if (params[0] < 0.0F) {
diff --git a/src/mesa/main/polygon.c b/src/mesa/main/polygon.c
index a1f0aa02da1..60af88f9857 100644
--- a/src/mesa/main/polygon.c
+++ b/src/mesa/main/polygon.c
@@ -56,7 +56,7 @@ _mesa_CullFace( GLenum mode )
GET_CURRENT_CONTEXT(ctx);
if (MESA_VERBOSE&VERBOSE_API)
- _mesa_debug(ctx, "glCullFace %s\n", _mesa_lookup_enum_by_nr(mode));
+ _mesa_debug(ctx, "glCullFace %s\n", _mesa_enum_to_string(mode));
if (mode!=GL_FRONT && mode!=GL_BACK && mode!=GL_FRONT_AND_BACK) {
_mesa_error( ctx, GL_INVALID_ENUM, "glCullFace" );
@@ -91,16 +91,16 @@ _mesa_FrontFace( GLenum mode )
GET_CURRENT_CONTEXT(ctx);
if (MESA_VERBOSE&VERBOSE_API)
- _mesa_debug(ctx, "glFrontFace %s\n", _mesa_lookup_enum_by_nr(mode));
+ _mesa_debug(ctx, "glFrontFace %s\n", _mesa_enum_to_string(mode));
+
+ if (ctx->Polygon.FrontFace == mode)
+ return;
if (mode!=GL_CW && mode!=GL_CCW) {
_mesa_error( ctx, GL_INVALID_ENUM, "glFrontFace" );
return;
}
- if (ctx->Polygon.FrontFace == mode)
- return;
-
FLUSH_VERTICES(ctx, _NEW_POLYGON);
ctx->Polygon.FrontFace = mode;
@@ -128,8 +128,8 @@ _mesa_PolygonMode( GLenum face, GLenum mode )
if (MESA_VERBOSE&VERBOSE_API)
_mesa_debug(ctx, "glPolygonMode %s %s\n",
- _mesa_lookup_enum_by_nr(face),
- _mesa_lookup_enum_by_nr(mode));
+ _mesa_enum_to_string(face),
+ _mesa_enum_to_string(mode));
if (mode!=GL_POINT && mode!=GL_LINE && mode!=GL_FILL) {
_mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(mode)" );
diff --git a/src/mesa/main/program_resource.c b/src/mesa/main/program_resource.c
index d857b84e60d..23d2b4d2da0 100644
--- a/src/mesa/main/program_resource.c
+++ b/src/mesa/main/program_resource.c
@@ -28,10 +28,11 @@
#include "main/mtypes.h"
#include "main/shaderapi.h"
#include "main/shaderobj.h"
+#include "main/context.h"
#include "program_resource.h"
-
+#include "ir_uniform.h"
static bool
-supported_interface_enum(GLenum iface)
+supported_interface_enum(struct gl_context *ctx, GLenum iface)
{
switch (iface) {
case GL_UNIFORM:
@@ -42,17 +43,21 @@ supported_interface_enum(GLenum iface)
case GL_ATOMIC_COUNTER_BUFFER:
return true;
case GL_VERTEX_SUBROUTINE:
- case GL_TESS_CONTROL_SUBROUTINE:
- case GL_TESS_EVALUATION_SUBROUTINE:
- case GL_GEOMETRY_SUBROUTINE:
case GL_FRAGMENT_SUBROUTINE:
- case GL_COMPUTE_SUBROUTINE:
case GL_VERTEX_SUBROUTINE_UNIFORM:
- case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
- case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
- case GL_GEOMETRY_SUBROUTINE_UNIFORM:
case GL_FRAGMENT_SUBROUTINE_UNIFORM:
+ return _mesa_has_shader_subroutine(ctx);
+ case GL_GEOMETRY_SUBROUTINE:
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ return _mesa_has_geometry_shaders(ctx) && _mesa_has_shader_subroutine(ctx);
+ case GL_COMPUTE_SUBROUTINE:
case GL_COMPUTE_SUBROUTINE_UNIFORM:
+ return _mesa_has_compute_shaders(ctx) && _mesa_has_shader_subroutine(ctx);
+ case GL_TESS_CONTROL_SUBROUTINE:
+ case GL_TESS_EVALUATION_SUBROUTINE:
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
+ return _mesa_has_tessellation(ctx) && _mesa_has_shader_subroutine(ctx);
case GL_BUFFER_VARIABLE:
case GL_SHADER_STORAGE_BLOCK:
default:
@@ -79,9 +84,9 @@ _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface,
}
/* Validate interface. */
- if (!supported_interface_enum(programInterface)) {
+ if (!supported_interface_enum(ctx, programInterface)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramInterfaceiv(%s)",
- _mesa_lookup_enum_by_nr(programInterface));
+ _mesa_enum_to_string(programInterface));
return;
}
@@ -96,8 +101,8 @@ _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface,
if (programInterface == GL_ATOMIC_COUNTER_BUFFER) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetProgramInterfaceiv(%s pname %s)",
- _mesa_lookup_enum_by_nr(programInterface),
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(programInterface),
+ _mesa_enum_to_string(pname));
return;
}
/* Name length consists of base name, 3 additional chars '[0]' if
@@ -138,15 +143,40 @@ _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface,
default:
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetProgramInterfaceiv(%s pname %s)",
- _mesa_lookup_enum_by_nr(programInterface),
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(programInterface),
+ _mesa_enum_to_string(pname));
};
break;
case GL_MAX_NUM_COMPATIBLE_SUBROUTINES:
+ switch (programInterface) {
+ case GL_VERTEX_SUBROUTINE_UNIFORM:
+ case GL_FRAGMENT_SUBROUTINE_UNIFORM:
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ case GL_COMPUTE_SUBROUTINE_UNIFORM:
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: {
+ for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) {
+ if (shProg->ProgramResourceList[i].Type == programInterface) {
+ struct gl_uniform_storage *uni =
+ (struct gl_uniform_storage *)
+ shProg->ProgramResourceList[i].Data;
+ *params = MAX2(*params, uni->num_compatible_subroutines);
+ }
+ }
+ break;
+ }
+
+ default:
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetProgramInterfaceiv(%s pname %s)",
+ _mesa_enum_to_string(programInterface),
+ _mesa_enum_to_string(pname));
+ }
+ break;
default:
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetProgramInterfaceiv(pname %s)",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
}
}
@@ -173,32 +203,12 @@ is_xfb_marker(const char *str)
return false;
}
-/**
- * Checks if given name index is legal for GetProgramResourceIndex,
- * check is written to be compatible with GL_ARB_array_of_arrays.
- */
-static bool
-valid_program_resource_index_name(const GLchar *name)
-{
- const char *array = strstr(name, "[");
- const char *close = strrchr(name, ']');
-
- /* Not array, no need for the check. */
- if (!array)
- return true;
-
- /* Last array index has to be zero. */
- if (!close || *--close != '0')
- return false;
-
- return true;
-}
-
GLuint GLAPIENTRY
_mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface,
const GLchar *name)
{
GET_CURRENT_CONTEXT(ctx);
+ unsigned array_index = 0;
struct gl_program_resource *res;
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
@@ -206,6 +216,11 @@ _mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface,
if (!shProg || !name)
return GL_INVALID_INDEX;
+ if (!supported_interface_enum(ctx, programInterface)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceIndex(%s)",
+ _mesa_enum_to_string(programInterface));
+ return GL_INVALID_INDEX;
+ }
/*
* For the interface TRANSFORM_FEEDBACK_VARYING, the value INVALID_INDEX
* should be returned when querying the index assigned to the special names
@@ -217,24 +232,33 @@ _mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface,
return GL_INVALID_INDEX;
switch (programInterface) {
+ case GL_TESS_CONTROL_SUBROUTINE:
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ case GL_TESS_EVALUATION_SUBROUTINE:
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
+ case GL_COMPUTE_SUBROUTINE:
+ case GL_COMPUTE_SUBROUTINE_UNIFORM:
+ case GL_GEOMETRY_SUBROUTINE:
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ case GL_VERTEX_SUBROUTINE:
+ case GL_FRAGMENT_SUBROUTINE:
+ case GL_VERTEX_SUBROUTINE_UNIFORM:
+ case GL_FRAGMENT_SUBROUTINE_UNIFORM:
case GL_PROGRAM_INPUT:
case GL_PROGRAM_OUTPUT:
case GL_UNIFORM:
case GL_TRANSFORM_FEEDBACK_VARYING:
- /* Validate name syntax for array variables */
- if (!valid_program_resource_index_name(name))
- return GL_INVALID_INDEX;
- /* fall-through */
case GL_UNIFORM_BLOCK:
- res = _mesa_program_resource_find_name(shProg, programInterface, name);
- if (!res)
+ res = _mesa_program_resource_find_name(shProg, programInterface, name,
+ &array_index);
+ if (!res || array_index > 0)
return GL_INVALID_INDEX;
return _mesa_program_resource_index(shProg, res);
case GL_ATOMIC_COUNTER_BUFFER:
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceIndex(%s)",
- _mesa_lookup_enum_by_nr(programInterface));
+ _mesa_enum_to_string(programInterface));
}
return GL_INVALID_INDEX;
@@ -250,19 +274,13 @@ _mesa_GetProgramResourceName(GLuint program, GLenum programInterface,
_mesa_lookup_shader_program_err(ctx, program,
"glGetProgramResourceName");
- /* Set user friendly return values in case of errors. */
- if (name)
- *name = '\0';
- if (length)
- *length = 0;
-
if (!shProg || !name)
return;
if (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
- !supported_interface_enum(programInterface)) {
+ !supported_interface_enum(ctx, programInterface)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceName(%s)",
- _mesa_lookup_enum_by_nr(programInterface));
+ _mesa_enum_to_string(programInterface));
return;
}
@@ -300,36 +318,6 @@ _mesa_GetProgramResourceiv(GLuint program, GLenum programInterface,
propCount, props, bufSize, length, params);
}
-/**
- * Function verifies syntax of given name for GetProgramResourceLocation
- * and GetProgramResourceLocationIndex for the following cases:
- *
- * "array element portion of a string passed to GetProgramResourceLocation
- * or GetProgramResourceLocationIndex must not have, a "+" sign, extra
- * leading zeroes, or whitespace".
- *
- * Check is written to be compatible with GL_ARB_array_of_arrays.
- */
-static bool
-invalid_array_element_syntax(const GLchar *name)
-{
- char *first = strchr(name, '[');
- char *last = strrchr(name, '[');
-
- if (!first)
- return false;
-
- /* No '+' or ' ' allowed anywhere. */
- if (strchr(first, '+') || strchr(first, ' '))
- return true;
-
- /* Check that last array index is 0. */
- if (last[1] == '0' && last[2] != ']')
- return true;
-
- return false;
-}
-
static struct gl_shader_program *
lookup_linked_program(GLuint program, const char *caller)
{
@@ -356,7 +344,7 @@ _mesa_GetProgramResourceLocation(GLuint program, GLenum programInterface,
struct gl_shader_program *shProg =
lookup_linked_program(program, "glGetProgramResourceLocation");
- if (!shProg || !name || invalid_array_element_syntax(name))
+ if (!shProg || !name)
return -1;
/* Validate programInterface. */
@@ -366,24 +354,33 @@ _mesa_GetProgramResourceLocation(GLuint program, GLenum programInterface,
case GL_PROGRAM_OUTPUT:
break;
- /* For reference valid cases requiring additional extension support:
- * GL_ARB_shader_subroutine
- * GL_ARB_tessellation_shader
- * GL_ARB_compute_shader
- */
case GL_VERTEX_SUBROUTINE_UNIFORM:
- case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
- case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
- case GL_GEOMETRY_SUBROUTINE_UNIFORM:
case GL_FRAGMENT_SUBROUTINE_UNIFORM:
+ if (!_mesa_has_shader_subroutine(ctx))
+ goto fail;
+ break;
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ if (!_mesa_has_geometry_shaders(ctx) || !_mesa_has_shader_subroutine(ctx))
+ goto fail;
+ break;
case GL_COMPUTE_SUBROUTINE_UNIFORM:
-
+ if (!_mesa_has_compute_shaders(ctx) || !_mesa_has_shader_subroutine(ctx))
+ goto fail;
+ break;
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
+ if (!_mesa_has_tessellation(ctx) || !_mesa_has_shader_subroutine(ctx))
+ goto fail;
+ break;
default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceLocation(%s %s)",
- _mesa_lookup_enum_by_nr(programInterface), name);
+ goto fail;
}
return _mesa_program_resource_location(shProg, programInterface, name);
+fail:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceLocation(%s %s)",
+ _mesa_enum_to_string(programInterface), name);
+ return -1;
}
/**
@@ -397,7 +394,7 @@ _mesa_GetProgramResourceLocationIndex(GLuint program, GLenum programInterface,
struct gl_shader_program *shProg =
lookup_linked_program(program, "glGetProgramResourceLocationIndex");
- if (!shProg || !name || invalid_array_element_syntax(name))
+ if (!shProg || !name)
return -1;
/* From the GL_ARB_program_interface_query spec:
@@ -408,7 +405,7 @@ _mesa_GetProgramResourceLocationIndex(GLuint program, GLenum programInterface,
if (programInterface != GL_PROGRAM_OUTPUT) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetProgramResourceLocationIndex(%s)",
- _mesa_lookup_enum_by_nr(programInterface));
+ _mesa_enum_to_string(programInterface));
return -1;
}
diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c
index 5ff1b953231..98366857f62 100644
--- a/src/mesa/main/queryobj.c
+++ b/src/mesa/main/queryobj.c
@@ -217,7 +217,7 @@ get_query_binding_point(struct gl_context *ctx, GLenum target, GLuint index)
case GL_TESS_CONTROL_SHADER_PATCHES_ARB:
case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB:
- if (ctx->Extensions.ARB_tessellation_shader)
+ if (_mesa_has_tessellation(ctx))
return get_pipe_stats_binding_point(ctx, target);
else
return NULL;
@@ -295,7 +295,7 @@ _mesa_CreateQueries(GLenum target, GLsizei n, GLuint *ids)
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glCreateQueries(invalid target = %s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
@@ -390,7 +390,7 @@ _mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id)
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glBeginQueryIndexed(%s, %u, %u)\n",
- _mesa_lookup_enum_by_nr(target), index, id);
+ _mesa_enum_to_string(target), index, id);
if (!query_error_check_index(ctx, target, index))
return;
@@ -412,7 +412,7 @@ _mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id)
if (*bindpt) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBeginQuery{Indexed}(target=%s is active)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
@@ -496,7 +496,7 @@ _mesa_EndQueryIndexed(GLenum target, GLuint index)
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glEndQueryIndexed(%s, %u)\n",
- _mesa_lookup_enum_by_nr(target), index);
+ _mesa_enum_to_string(target), index);
if (!query_error_check_index(ctx, target, index))
return;
@@ -516,8 +516,8 @@ _mesa_EndQueryIndexed(GLenum target, GLuint index)
if (q && q->Target != target) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glEndQuery(target=%s with active query of target %s)",
- _mesa_lookup_enum_by_nr(target),
- _mesa_lookup_enum_by_nr(q->Target));
+ _mesa_enum_to_string(target),
+ _mesa_enum_to_string(q->Target));
return;
}
@@ -553,7 +553,7 @@ _mesa_QueryCounter(GLuint id, GLenum target)
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glQueryCounter(%u, %s)\n", id,
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
/* error checking */
if (target != GL_TIMESTAMP) {
@@ -628,9 +628,9 @@ _mesa_GetQueryIndexediv(GLenum target, GLuint index, GLenum pname,
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glGetQueryIndexediv(%s, %u, %s)\n",
- _mesa_lookup_enum_by_nr(target),
+ _mesa_enum_to_string(target),
index,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
if (!query_error_check_index(ctx, target, index))
return;
@@ -712,7 +712,7 @@ _mesa_GetQueryIndexediv(GLenum target, GLuint index, GLenum pname,
default:
_mesa_problem(ctx,
"Unknown target in glGetQueryIndexediv(target = %s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
*params = 0;
break;
}
@@ -740,7 +740,7 @@ _mesa_GetQueryObjectiv(GLuint id, GLenum pname, GLint *params)
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glGetQueryObjectiv(%u, %s)\n", id,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
if (id)
q = _mesa_lookup_query_object(ctx, id);
@@ -794,7 +794,7 @@ _mesa_GetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glGetQueryObjectuiv(%u, %s)\n", id,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
if (id)
q = _mesa_lookup_query_object(ctx, id);
@@ -851,7 +851,7 @@ _mesa_GetQueryObjecti64v(GLuint id, GLenum pname, GLint64EXT *params)
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glGetQueryObjecti64v(%u, %s)\n", id,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
if (id)
q = _mesa_lookup_query_object(ctx, id);
@@ -894,7 +894,7 @@ _mesa_GetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params)
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glGetQueryObjectui64v(%u, %s)\n", id,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
if (id)
q = _mesa_lookup_query_object(ctx, id);
diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
index a3357cd6419..d826ecfc3d5 100644
--- a/src/mesa/main/readpix.c
+++ b/src/mesa/main/readpix.c
@@ -47,28 +47,47 @@
* Return true if the conversion L=R+G+B is needed.
*/
GLboolean
-_mesa_need_rgb_to_luminance_conversion(mesa_format texFormat, GLenum format)
+_mesa_need_rgb_to_luminance_conversion(GLenum srcBaseFormat,
+ GLenum dstBaseFormat)
{
- GLenum baseTexFormat = _mesa_get_format_base_format(texFormat);
-
- return (baseTexFormat == GL_RG ||
- baseTexFormat == GL_RGB ||
- baseTexFormat == GL_RGBA) &&
- (format == GL_LUMINANCE ||
- format == GL_LUMINANCE_ALPHA ||
- format == GL_LUMINANCE_INTEGER_EXT ||
- format == GL_LUMINANCE_ALPHA_INTEGER_EXT);
+ return (srcBaseFormat == GL_RG ||
+ srcBaseFormat == GL_RGB ||
+ srcBaseFormat == GL_RGBA) &&
+ (dstBaseFormat == GL_LUMINANCE ||
+ dstBaseFormat == GL_LUMINANCE_ALPHA);
}
+/**
+ * Return true if the conversion L,I to RGB conversion is needed.
+ */
+GLboolean
+_mesa_need_luminance_to_rgb_conversion(GLenum srcBaseFormat,
+ GLenum dstBaseFormat)
+{
+ return (srcBaseFormat == GL_LUMINANCE ||
+ srcBaseFormat == GL_LUMINANCE_ALPHA ||
+ srcBaseFormat == GL_INTENSITY) &&
+ (dstBaseFormat == GL_GREEN ||
+ dstBaseFormat == GL_BLUE ||
+ dstBaseFormat == GL_RG ||
+ dstBaseFormat == GL_RGB ||
+ dstBaseFormat == GL_BGR ||
+ dstBaseFormat == GL_RGBA ||
+ dstBaseFormat == GL_BGRA);
+}
/**
* Return transfer op flags for this ReadPixels operation.
*/
-static GLbitfield
-get_readpixels_transfer_ops(const struct gl_context *ctx, mesa_format texFormat,
- GLenum format, GLenum type, GLboolean uses_blit)
+GLbitfield
+_mesa_get_readpixels_transfer_ops(const struct gl_context *ctx,
+ mesa_format texFormat,
+ GLenum format, GLenum type,
+ GLboolean uses_blit)
{
GLbitfield transferOps = ctx->_ImageTransferState;
+ GLenum srcBaseFormat = _mesa_get_format_base_format(texFormat);
+ GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
if (format == GL_DEPTH_COMPONENT ||
format == GL_DEPTH_STENCIL ||
@@ -105,7 +124,7 @@ get_readpixels_transfer_ops(const struct gl_context *ctx, mesa_format texFormat,
* have any effect anyway.
*/
if (_mesa_get_format_datatype(texFormat) == GL_UNSIGNED_NORMALIZED &&
- !_mesa_need_rgb_to_luminance_conversion(texFormat, format)) {
+ !_mesa_need_rgb_to_luminance_conversion(srcBaseFormat, dstBaseFormat)) {
transferOps &= ~IMAGE_CLAMP_BIT;
}
@@ -128,7 +147,7 @@ _mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format,
{
struct gl_renderbuffer *rb =
_mesa_get_read_renderbuffer_for_format(ctx, format);
- GLenum srcType;
+ GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
assert(rb);
@@ -149,28 +168,14 @@ _mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format,
default:
/* Color formats. */
- if (_mesa_need_rgb_to_luminance_conversion(rb->Format, format)) {
- return GL_TRUE;
- }
-
- /* Conversion between signed and unsigned integers needs masking
- * (it isn't just memcpy). */
- srcType = _mesa_get_format_datatype(rb->Format);
-
- if ((srcType == GL_INT &&
- (type == GL_UNSIGNED_INT ||
- type == GL_UNSIGNED_SHORT ||
- type == GL_UNSIGNED_BYTE)) ||
- (srcType == GL_UNSIGNED_INT &&
- (type == GL_INT ||
- type == GL_SHORT ||
- type == GL_BYTE))) {
+ if (_mesa_need_rgb_to_luminance_conversion(rb->_BaseFormat,
+ dstBaseFormat)) {
return GL_TRUE;
}
/* And finally, see if there are any transfer ops. */
- return get_readpixels_transfer_ops(ctx, rb->Format, format, type,
- uses_blit) != 0;
+ return _mesa_get_readpixels_transfer_ops(ctx, rb->Format, format, type,
+ uses_blit) != 0;
}
return GL_FALSE;
}
@@ -263,7 +268,7 @@ read_uint_depth_pixels( struct gl_context *ctx,
GLubyte *map, *dst;
int stride, dstStride, j;
- if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0)
+ if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F)
return GL_FALSE;
if (packing->SwapBytes)
@@ -432,18 +437,19 @@ read_rgba_pixels( struct gl_context *ctx,
uint8_t rebase_swizzle[4];
struct gl_framebuffer *fb = ctx->ReadBuffer;
struct gl_renderbuffer *rb = fb->_ColorReadBuffer;
+ GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
if (!rb)
return;
- transferOps = get_readpixels_transfer_ops(ctx, rb->Format, format, type,
- GL_FALSE);
+ transferOps = _mesa_get_readpixels_transfer_ops(ctx, rb->Format, format,
+ type, GL_FALSE);
/* Describe the dst format */
dst_is_integer = _mesa_is_enum_format_integer(format);
dst_stride = _mesa_image_row_stride(packing, width, format, type);
dst_format = _mesa_format_from_format_and_type(format, type);
convert_rgb_to_lum =
- _mesa_need_rgb_to_luminance_conversion(rb->Format, format);
+ _mesa_need_rgb_to_luminance_conversion(rb->_BaseFormat, dstBaseFormat);
dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
format, type, 0, 0);
@@ -815,7 +821,7 @@ read_depth_stencil_pixels(struct gl_context *ctx,
const struct gl_pixelstore_attrib *packing )
{
const GLboolean scaleOrBias
- = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
+ = ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F;
const GLboolean stencilTransfer = ctx->Pixel.IndexShift
|| ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag;
GLubyte *dst;
@@ -910,10 +916,8 @@ read_pixels_es3_error_check(GLenum format, GLenum type,
const GLenum data_type = _mesa_get_format_datatype(rb->Format);
GLboolean is_unsigned_int = GL_FALSE;
GLboolean is_signed_int = GL_FALSE;
-
- if (!_mesa_is_color_format(internalFormat)) {
- return GL_INVALID_OPERATION;
- }
+ GLboolean is_float_depth = (internalFormat == GL_DEPTH_COMPONENT32F) ||
+ (internalFormat == GL_DEPTH32F_STENCIL8);
is_unsigned_int = _mesa_is_enum_format_unsigned_int(internalFormat);
if (!is_unsigned_int) {
@@ -944,6 +948,43 @@ read_pixels_es3_error_check(GLenum format, GLenum type,
(is_unsigned_int && type == GL_UNSIGNED_INT))
return GL_NO_ERROR;
break;
+ case GL_DEPTH_STENCIL:
+ switch (type) {
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ if (is_float_depth)
+ return GL_NO_ERROR;
+ break;
+ case GL_UNSIGNED_INT_24_8:
+ if (!is_float_depth)
+ return GL_NO_ERROR;
+ break;
+ default:
+ return GL_INVALID_ENUM;
+ }
+ break;
+ case GL_DEPTH_COMPONENT:
+ switch (type) {
+ case GL_FLOAT:
+ if (is_float_depth)
+ return GL_NO_ERROR;
+ break;
+ case GL_UNSIGNED_SHORT:
+ case GL_UNSIGNED_INT_24_8:
+ if (!is_float_depth)
+ return GL_NO_ERROR;
+ break;
+ default:
+ return GL_INVALID_ENUM;
+ }
+ break;
+ case GL_STENCIL_INDEX:
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ return GL_NO_ERROR;
+ default:
+ return GL_INVALID_ENUM;
+ }
+ break;
}
return GL_INVALID_OPERATION;
@@ -966,8 +1007,8 @@ _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glReadPixels(%d, %d, %s, %s, %p)\n",
width, height,
- _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type),
+ _mesa_enum_to_string(format),
+ _mesa_enum_to_string(type),
pixels);
if (width < 0 || height < 0) {
@@ -1017,15 +1058,10 @@ _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
err = read_pixels_es3_error_check(format, type, rb);
}
- if (err == GL_NO_ERROR && (format == GL_DEPTH_COMPONENT
- || format == GL_DEPTH_STENCIL)) {
- err = GL_INVALID_ENUM;
- }
-
if (err != GL_NO_ERROR) {
_mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
- _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type));
+ _mesa_enum_to_string(format),
+ _mesa_enum_to_string(type));
return;
}
}
@@ -1033,8 +1069,8 @@ _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
err = _mesa_error_check_format_and_type(ctx, format, type);
if (err != GL_NO_ERROR) {
_mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
- _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type));
+ _mesa_enum_to_string(format),
+ _mesa_enum_to_string(type));
return;
}
diff --git a/src/mesa/main/readpix.h b/src/mesa/main/readpix.h
index 1636dd9ce3e..481ad9d9c37 100644
--- a/src/mesa/main/readpix.h
+++ b/src/mesa/main/readpix.h
@@ -38,7 +38,18 @@ _mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format,
GLenum type, GLboolean uses_blit);
extern GLboolean
-_mesa_need_rgb_to_luminance_conversion(mesa_format texFormat, GLenum format);
+_mesa_need_rgb_to_luminance_conversion(GLenum srcBaseFormat,
+ GLenum dstBaseFormat);
+
+extern GLboolean
+_mesa_need_luminance_to_rgb_conversion(GLenum srcBaseFormat,
+ GLenum dstBaseFormat);
+
+extern GLbitfield
+_mesa_get_readpixels_transfer_ops(const struct gl_context *ctx,
+ mesa_format texFormat,
+ GLenum format, GLenum type,
+ GLboolean uses_blit);
extern void
_mesa_readpixels(struct gl_context *ctx,
diff --git a/src/mesa/main/samplerobj.c b/src/mesa/main/samplerobj.c
index a3aacc66aa3..32180fb1ba2 100644
--- a/src/mesa/main/samplerobj.c
+++ b/src/mesa/main/samplerobj.c
@@ -689,7 +689,7 @@ set_sampler_max_anisotropy(struct gl_context *ctx,
if (samp->MaxAnisotropy == param)
return GL_FALSE;
- if (param < 1.0)
+ if (param < 1.0F)
return INVALID_VALUE;
flush(ctx);
@@ -813,7 +813,7 @@ _mesa_SamplerParameteri(GLuint sampler, GLenum pname, GLint param)
break;
case INVALID_PNAME:
_mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(pname=%s)\n",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
break;
case INVALID_PARAM:
_mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(param=%d)\n",
@@ -906,7 +906,7 @@ _mesa_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
break;
case INVALID_PNAME:
_mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(pname=%s)\n",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
break;
case INVALID_PARAM:
_mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(param=%f)\n",
@@ -1006,7 +1006,7 @@ _mesa_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params)
break;
case INVALID_PNAME:
_mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(pname=%s)\n",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
break;
case INVALID_PARAM:
_mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(param=%d)\n",
@@ -1099,7 +1099,7 @@ _mesa_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params)
break;
case INVALID_PNAME:
_mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(pname=%s)\n",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
break;
case INVALID_PARAM:
_mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(param=%f)\n",
@@ -1184,7 +1184,7 @@ _mesa_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params)
break;
case INVALID_PNAME:
_mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(pname=%s)\n",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
break;
case INVALID_PARAM:
_mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(param=%d)\n",
@@ -1270,7 +1270,7 @@ _mesa_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params)
break;
case INVALID_PNAME:
_mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(pname=%s)\n",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
break;
case INVALID_PARAM:
_mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(param=%u)\n",
@@ -1380,7 +1380,7 @@ _mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
invalid_pname:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameteriv(pname=%s)",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
}
@@ -1466,7 +1466,7 @@ _mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
invalid_pname:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterfv(pname=%s)",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
}
@@ -1545,7 +1545,7 @@ _mesa_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params)
invalid_pname:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIiv(pname=%s)",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
}
@@ -1624,7 +1624,7 @@ _mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params)
invalid_pname:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIuiv(pname=%s)",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
}
diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp
index a6246a39aad..ee7320221e2 100644
--- a/src/mesa/main/shader_query.cpp
+++ b/src/mesa/main/shader_query.cpp
@@ -44,7 +44,8 @@ extern "C" {
static GLint
program_resource_location(struct gl_shader_program *shProg,
- struct gl_program_resource *res, const char *name);
+ struct gl_program_resource *res, const char *name,
+ unsigned array_index);
/**
* Declare convenience functions to return resource data in a given type.
@@ -61,6 +62,7 @@ DECL_RESOURCE_FUNC(UBO, gl_uniform_block);
DECL_RESOURCE_FUNC(UNI, gl_uniform_storage);
DECL_RESOURCE_FUNC(ATC, gl_active_atomic_buffer);
DECL_RESOURCE_FUNC(XFB, gl_transform_feedback_varying_info);
+DECL_RESOURCE_FUNC(SUB, gl_subroutine_function);
void GLAPIENTRY
_mesa_BindAttribLocation(GLhandleARB program, GLuint index,
@@ -189,63 +191,6 @@ _mesa_GetActiveAttrib(GLhandleARB program, GLuint desired_index,
(GLint *) type, "glGetActiveAttrib");
}
-/* Locations associated with shader variables (array or non-array) can be
- * queried using its base name or using the base name appended with the
- * valid array index. For example, in case of below vertex shader, valid
- * queries can be made to know the location of "xyz", "array", "array[0]",
- * "array[1]", "array[2]" and "array[3]". In this example index reurned
- * will be 0, 0, 0, 1, 2, 3 respectively.
- *
- * [Vertex Shader]
- * layout(location=0) in vec4 xyz;
- * layout(location=1) in vec4[4] array;
- * void main()
- * { }
- *
- * This requirement came up with the addition of ARB_program_interface_query
- * to OpenGL 4.3 specification. See page 101 (page 122 of the PDF) for details.
- *
- * This utility function is used by:
- * _mesa_GetAttribLocation
- * _mesa_GetFragDataLocation
- * _mesa_GetFragDataIndex
- *
- * Returns 0:
- * if the 'name' string matches var->name.
- * Returns 'matched index':
- * if the 'name' string matches var->name appended with valid array index.
- */
-int static inline
-get_matching_index(const ir_variable *const var, const char *name) {
- unsigned idx = 0;
- const char *const paren = strchr(name, '[');
- const unsigned len = (paren != NULL) ? paren - name : strlen(name);
-
- if (paren != NULL) {
- if (!var->type->is_array())
- return -1;
-
- char *endptr;
- idx = (unsigned) strtol(paren + 1, &endptr, 10);
- const unsigned idx_len = endptr != (paren + 1) ? endptr - paren - 1 : 0;
-
- /* Validate the sub string representing index in 'name' string */
- if ((idx > 0 && paren[1] == '0') /* leading zeroes */
- || (idx == 0 && idx_len > 1) /* all zeroes */
- || paren[1] == ' ' /* whitespace */
- || endptr[0] != ']' /* closing brace */
- || endptr[1] != '\0' /* null char */
- || idx_len == 0 /* missing index */
- || idx >= var->type->length) /* exceeding array bound */
- return -1;
- }
-
- if (strncmp(var->name, name, len) == 0 && var->name[len] == '\0')
- return idx;
-
- return -1;
-}
-
GLint GLAPIENTRY
_mesa_GetAttribLocation(GLhandleARB program, const GLcharARB * name)
{
@@ -271,13 +216,15 @@ _mesa_GetAttribLocation(GLhandleARB program, const GLcharARB * name)
if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL)
return -1;
+ unsigned array_index = 0;
struct gl_program_resource *res =
- _mesa_program_resource_find_name(shProg, GL_PROGRAM_INPUT, name);
+ _mesa_program_resource_find_name(shProg, GL_PROGRAM_INPUT, name,
+ &array_index);
if (!res)
return -1;
- GLint loc = program_resource_location(shProg, res, name);
+ GLint loc = program_resource_location(shProg, res, name, array_index);
/* The extra check against against 0 is made because of builtin-attribute
* locations that have offset applied. Function program_resource_location
@@ -455,13 +402,15 @@ _mesa_GetFragDataLocation(GLuint program, const GLchar *name)
if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)
return -1;
+ unsigned array_index = 0;
struct gl_program_resource *res =
- _mesa_program_resource_find_name(shProg, GL_PROGRAM_OUTPUT, name);
+ _mesa_program_resource_find_name(shProg, GL_PROGRAM_OUTPUT, name,
+ &array_index);
if (!res)
return -1;
- GLint loc = program_resource_location(shProg, res, name);
+ GLint loc = program_resource_location(shProg, res, name, array_index);
/* The extra check against against 0 is made because of builtin-attribute
* locations that have offset applied. Function program_resource_location
@@ -497,6 +446,20 @@ _mesa_program_resource_name(struct gl_program_resource *res)
return RESOURCE_VAR(res)->name;
case GL_UNIFORM:
return RESOURCE_UNI(res)->name;
+ case GL_VERTEX_SUBROUTINE_UNIFORM:
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ case GL_FRAGMENT_SUBROUTINE_UNIFORM:
+ case GL_COMPUTE_SUBROUTINE_UNIFORM:
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
+ return RESOURCE_UNI(res)->name + MESA_SUBROUTINE_PREFIX_LEN;
+ case GL_VERTEX_SUBROUTINE:
+ case GL_GEOMETRY_SUBROUTINE:
+ case GL_FRAGMENT_SUBROUTINE:
+ case GL_COMPUTE_SUBROUTINE:
+ case GL_TESS_CONTROL_SUBROUTINE:
+ case GL_TESS_EVALUATION_SUBROUTINE:
+ return RESOURCE_SUB(res)->name;
default:
assert(!"support for resource type not implemented");
}
@@ -515,7 +478,19 @@ _mesa_program_resource_array_size(struct gl_program_resource *res)
case GL_PROGRAM_OUTPUT:
return RESOURCE_VAR(res)->data.max_array_access;
case GL_UNIFORM:
+ case GL_VERTEX_SUBROUTINE_UNIFORM:
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ case GL_FRAGMENT_SUBROUTINE_UNIFORM:
+ case GL_COMPUTE_SUBROUTINE_UNIFORM:
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
return RESOURCE_UNI(res)->array_elements;
+ case GL_VERTEX_SUBROUTINE:
+ case GL_GEOMETRY_SUBROUTINE:
+ case GL_FRAGMENT_SUBROUTINE:
+ case GL_COMPUTE_SUBROUTINE:
+ case GL_TESS_CONTROL_SUBROUTINE:
+ case GL_TESS_EVALUATION_SUBROUTINE:
case GL_ATOMIC_COUNTER_BUFFER:
case GL_UNIFORM_BLOCK:
return 0;
@@ -525,39 +500,32 @@ _mesa_program_resource_array_size(struct gl_program_resource *res)
return 0;
}
-static int
-array_index_of_resource(struct gl_program_resource *res,
- const char *name)
+/**
+ * Checks if array subscript is valid and if so sets array_index.
+ */
+static bool
+valid_array_index(const GLchar *name, unsigned *array_index)
{
- assert(res->Data);
+ long idx = 0;
+ const GLchar *out_base_name_end;
- switch (res->Type) {
- case GL_PROGRAM_INPUT:
- case GL_PROGRAM_OUTPUT:
- return get_matching_index(RESOURCE_VAR(res), name);
- default:
- assert(!"support for resource type not implemented");
- return -1;
- }
+ idx = parse_program_resource_name(name, &out_base_name_end);
+ if (idx < 0)
+ return false;
+
+ if (array_index)
+ *array_index = idx;
+
+ return true;
}
/* Find a program resource with specific name in given interface.
*/
struct gl_program_resource *
_mesa_program_resource_find_name(struct gl_shader_program *shProg,
- GLenum programInterface, const char *name)
+ GLenum programInterface, const char *name,
+ unsigned *array_index)
{
- GET_CURRENT_CONTEXT(ctx);
- const char *full_name = name;
-
- /* When context has 'VertexID_is_zero_based' set, gl_VertexID has been
- * lowered to gl_VertexIDMESA.
- */
- if (name && ctx->Const.VertexID_is_zero_based) {
- if (strcmp(name, "gl_VertexID") == 0)
- full_name = "gl_VertexIDMESA";
- }
-
struct gl_program_resource *res = shProg->ProgramResourceList;
for (unsigned i = 0; i < shProg->NumProgramResourceList; i++, res++) {
if (res->Type != programInterface)
@@ -567,26 +535,46 @@ _mesa_program_resource_find_name(struct gl_shader_program *shProg,
const char *rname = _mesa_program_resource_name(res);
unsigned baselen = strlen(rname);
- switch (programInterface) {
- case GL_TRANSFORM_FEEDBACK_VARYING:
- case GL_UNIFORM_BLOCK:
- case GL_UNIFORM:
- if (strncmp(rname, name, baselen) == 0) {
+ if (strncmp(rname, name, baselen) == 0) {
+ switch (programInterface) {
+ case GL_UNIFORM_BLOCK:
/* Basename match, check if array or struct. */
if (name[baselen] == '\0' ||
name[baselen] == '[' ||
name[baselen] == '.') {
return res;
}
+ break;
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ case GL_UNIFORM:
+ case GL_VERTEX_SUBROUTINE_UNIFORM:
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ case GL_FRAGMENT_SUBROUTINE_UNIFORM:
+ case GL_COMPUTE_SUBROUTINE_UNIFORM:
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
+ case GL_VERTEX_SUBROUTINE:
+ case GL_GEOMETRY_SUBROUTINE:
+ case GL_FRAGMENT_SUBROUTINE:
+ case GL_COMPUTE_SUBROUTINE:
+ case GL_TESS_CONTROL_SUBROUTINE:
+ case GL_TESS_EVALUATION_SUBROUTINE:
+ if (name[baselen] == '.') {
+ return res;
+ }
+ /* fall-through */
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ if (name[baselen] == '\0') {
+ return res;
+ } else if (name[baselen] == '[' &&
+ valid_array_index(name, array_index)) {
+ return res;
+ }
+ break;
+ default:
+ assert(!"not implemented for given interface");
}
- break;
- case GL_PROGRAM_INPUT:
- case GL_PROGRAM_OUTPUT:
- if (array_index_of_resource(res, full_name) >= 0)
- return res;
- break;
- default:
- assert(!"not implemented for given interface");
}
}
return NULL;
@@ -651,6 +639,18 @@ _mesa_program_resource_find_index(struct gl_shader_program *shProg,
case GL_PROGRAM_INPUT:
case GL_PROGRAM_OUTPUT:
case GL_UNIFORM:
+ case GL_VERTEX_SUBROUTINE_UNIFORM:
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ case GL_FRAGMENT_SUBROUTINE_UNIFORM:
+ case GL_COMPUTE_SUBROUTINE_UNIFORM:
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
+ case GL_VERTEX_SUBROUTINE:
+ case GL_GEOMETRY_SUBROUTINE:
+ case GL_FRAGMENT_SUBROUTINE:
+ case GL_COMPUTE_SUBROUTINE:
+ case GL_TESS_CONTROL_SUBROUTINE:
+ case GL_TESS_EVALUATION_SUBROUTINE:
if (++idx == (int) index)
return res;
break;
@@ -719,6 +719,12 @@ _mesa_get_program_resource_name(struct gl_shader_program *shProg,
bool add_index = !(((programInterface == GL_PROGRAM_INPUT) &&
res->StageReferences & (1 << MESA_SHADER_GEOMETRY)));
+ /* Transform feedback varyings have array index already appended
+ * in their names.
+ */
+ if (programInterface == GL_TRANSFORM_FEEDBACK_VARYING)
+ add_index = false;
+
if (add_index && _mesa_program_resource_array_size(res)) {
int i;
@@ -736,17 +742,9 @@ _mesa_get_program_resource_name(struct gl_shader_program *shProg,
static GLint
program_resource_location(struct gl_shader_program *shProg,
- struct gl_program_resource *res, const char *name)
+ struct gl_program_resource *res, const char *name,
+ unsigned array_index)
{
- unsigned index, offset;
- int array_index = -1;
-
- if (res->Type == GL_PROGRAM_INPUT || res->Type == GL_PROGRAM_OUTPUT) {
- array_index = array_index_of_resource(res, name);
- if (array_index < 0)
- return -1;
- }
-
/* Built-in locations should report GL_INVALID_INDEX. */
if (is_gl_identifier(name))
return GL_INVALID_INDEX;
@@ -757,13 +755,22 @@ program_resource_location(struct gl_shader_program *shProg,
*/
switch (res->Type) {
case GL_PROGRAM_INPUT:
+ /* If the input is an array, fail if the index is out of bounds. */
+ if (array_index > 0
+ && array_index >= RESOURCE_VAR(res)->type->length) {
+ return -1;
+ }
return RESOURCE_VAR(res)->data.location + array_index - VERT_ATTRIB_GENERIC0;
case GL_PROGRAM_OUTPUT:
+ /* If the output is an array, fail if the index is out of bounds. */
+ if (array_index > 0
+ && array_index >= RESOURCE_VAR(res)->type->length) {
+ return -1;
+ }
return RESOURCE_VAR(res)->data.location + array_index - FRAG_RESULT_DATA0;
case GL_UNIFORM:
- index = _mesa_get_uniform_location(shProg, name, &offset);
-
- if (index == GL_INVALID_INDEX)
+ /* If the uniform is built-in, fail. */
+ if (RESOURCE_UNI(res)->builtin)
return -1;
/* From the GL_ARB_uniform_buffer_object spec:
@@ -777,9 +784,21 @@ program_resource_location(struct gl_shader_program *shProg,
RESOURCE_UNI(res)->atomic_buffer_index != -1)
return -1;
- /* location in remap table + array element offset */
- return RESOURCE_UNI(res)->remap_location + offset;
+ /* fallthrough */
+ case GL_VERTEX_SUBROUTINE_UNIFORM:
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ case GL_FRAGMENT_SUBROUTINE_UNIFORM:
+ case GL_COMPUTE_SUBROUTINE_UNIFORM:
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
+ /* If the uniform is an array, fail if the index is out of bounds. */
+ if (array_index > 0
+ && array_index >= RESOURCE_UNI(res)->array_elements) {
+ return -1;
+ }
+ /* location in remap table + array element offset */
+ return RESOURCE_UNI(res)->remap_location + array_index;
default:
return -1;
}
@@ -787,22 +806,22 @@ program_resource_location(struct gl_shader_program *shProg,
/**
* Function implements following location queries:
- * glGetAttribLocation
- * glGetFragDataLocation
* glGetUniformLocation
*/
GLint
_mesa_program_resource_location(struct gl_shader_program *shProg,
GLenum programInterface, const char *name)
{
+ unsigned array_index = 0;
struct gl_program_resource *res =
- _mesa_program_resource_find_name(shProg, programInterface, name);
+ _mesa_program_resource_find_name(shProg, programInterface, name,
+ &array_index);
/* Resource not found. */
if (!res)
return -1;
- return program_resource_location(shProg, res, name);
+ return program_resource_location(shProg, res, name, array_index);
}
/**
@@ -814,7 +833,7 @@ _mesa_program_resource_location_index(struct gl_shader_program *shProg,
GLenum programInterface, const char *name)
{
struct gl_program_resource *res =
- _mesa_program_resource_find_name(shProg, programInterface, name);
+ _mesa_program_resource_find_name(shProg, programInterface, name, NULL);
/* Non-existent variable or resource is not referenced by fragment stage. */
if (!res || !(res->StageReferences & (1 << MESA_SHADER_FRAGMENT)))
@@ -829,6 +848,10 @@ stage_from_enum(GLenum ref)
switch (ref) {
case GL_REFERENCED_BY_VERTEX_SHADER:
return MESA_SHADER_VERTEX;
+ case GL_REFERENCED_BY_TESS_CONTROL_SHADER:
+ return MESA_SHADER_TESS_CTRL;
+ case GL_REFERENCED_BY_TESS_EVALUATION_SHADER:
+ return MESA_SHADER_TESS_EVAL;
case GL_REFERENCED_BY_GEOMETRY_SHADER:
return MESA_SHADER_GEOMETRY;
case GL_REFERENCED_BY_FRAGMENT_SHADER:
@@ -886,7 +909,8 @@ get_buffer_property(struct gl_shader_program *shProg,
for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) {
const char *iname = RESOURCE_UBO(res)->Uniforms[i].IndexName;
struct gl_program_resource *uni =
- _mesa_program_resource_find_name(shProg, GL_UNIFORM, iname);
+ _mesa_program_resource_find_name(shProg, GL_UNIFORM, iname,
+ NULL);
if (!uni)
continue;
(*val)++;
@@ -896,7 +920,8 @@ get_buffer_property(struct gl_shader_program *shProg,
for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) {
const char *iname = RESOURCE_UBO(res)->Uniforms[i].IndexName;
struct gl_program_resource *uni =
- _mesa_program_resource_find_name(shProg, GL_UNIFORM, iname);
+ _mesa_program_resource_find_name(shProg, GL_UNIFORM, iname,
+ NULL);
if (!uni)
continue;
*val++ =
@@ -925,8 +950,8 @@ get_buffer_property(struct gl_shader_program *shProg,
invalid_operation:
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s prop %s)", caller,
- _mesa_lookup_enum_by_nr(res->Type),
- _mesa_lookup_enum_by_nr(prop));
+ _mesa_enum_to_string(res->Type),
+ _mesa_enum_to_string(prop));
return 0;
}
@@ -944,11 +969,17 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
switch(prop) {
case GL_NAME_LENGTH:
- if (res->Type == GL_ATOMIC_COUNTER_BUFFER)
+ switch (res->Type) {
+ case GL_ATOMIC_COUNTER_BUFFER:
goto invalid_operation;
- /* Base name +3 if array '[0]' + terminator. */
- *val = strlen(_mesa_program_resource_name(res)) +
- (_mesa_program_resource_array_size(res) > 0 ? 3 : 0) + 1;
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ *val = strlen(_mesa_program_resource_name(res)) + 1;
+ break;
+ default:
+ /* Base name +3 if array '[0]' + terminator. */
+ *val = strlen(_mesa_program_resource_name(res)) +
+ (_mesa_program_resource_array_size(res) > 0 ? 3 : 0) + 1;
+ }
return 1;
case GL_TYPE:
switch (res->Type) {
@@ -1014,6 +1045,8 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
goto invalid_enum;
/* fallthrough */
case GL_REFERENCED_BY_VERTEX_SHADER:
+ case GL_REFERENCED_BY_TESS_CONTROL_SHADER:
+ case GL_REFERENCED_BY_TESS_EVALUATION_SHADER:
case GL_REFERENCED_BY_GEOMETRY_SHADER:
case GL_REFERENCED_BY_FRAGMENT_SHADER:
switch (res->Type) {
@@ -1034,7 +1067,8 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
case GL_PROGRAM_INPUT:
case GL_PROGRAM_OUTPUT:
*val = program_resource_location(shProg, res,
- _mesa_program_resource_name(res));
+ _mesa_program_resource_name(res),
+ 0);
return 1;
default:
goto invalid_operation;
@@ -1045,10 +1079,54 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
*val = RESOURCE_VAR(res)->data.index;
return 1;
+ case GL_NUM_COMPATIBLE_SUBROUTINES:
+ if (res->Type != GL_VERTEX_SUBROUTINE_UNIFORM &&
+ res->Type != GL_FRAGMENT_SUBROUTINE_UNIFORM &&
+ res->Type != GL_GEOMETRY_SUBROUTINE_UNIFORM &&
+ res->Type != GL_COMPUTE_SUBROUTINE_UNIFORM &&
+ res->Type != GL_TESS_CONTROL_SUBROUTINE_UNIFORM &&
+ res->Type != GL_TESS_EVALUATION_SUBROUTINE_UNIFORM)
+ goto invalid_operation;
+ *val = RESOURCE_UNI(res)->num_compatible_subroutines;
+ return 1;
+ case GL_COMPATIBLE_SUBROUTINES: {
+ const struct gl_uniform_storage *uni;
+ struct gl_shader *sh;
+ unsigned count, i;
+ int j;
+
+ if (res->Type != GL_VERTEX_SUBROUTINE_UNIFORM &&
+ res->Type != GL_FRAGMENT_SUBROUTINE_UNIFORM &&
+ res->Type != GL_GEOMETRY_SUBROUTINE_UNIFORM &&
+ res->Type != GL_COMPUTE_SUBROUTINE_UNIFORM &&
+ res->Type != GL_TESS_CONTROL_SUBROUTINE_UNIFORM &&
+ res->Type != GL_TESS_EVALUATION_SUBROUTINE_UNIFORM)
+ goto invalid_operation;
+ uni = RESOURCE_UNI(res);
+
+ sh = shProg->_LinkedShaders[_mesa_shader_stage_from_subroutine_uniform(res->Type)];
+ count = 0;
+ for (i = 0; i < sh->NumSubroutineFunctions; i++) {
+ struct gl_subroutine_function *fn = &sh->SubroutineFunctions[i];
+ for (j = 0; j < fn->num_compat_types; j++) {
+ if (fn->types[j] == uni->type) {
+ val[count++] = i;
+ break;
+ }
+ }
+ }
+ return count;
+ }
/* GL_ARB_tessellation_shader */
case GL_IS_PER_PATCH:
- case GL_REFERENCED_BY_TESS_CONTROL_SHADER:
- case GL_REFERENCED_BY_TESS_EVALUATION_SHADER:
+ switch (res->Type) {
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ *val = RESOURCE_VAR(res)->data.patch;
+ return 1;
+ default:
+ goto invalid_operation;
+ }
default:
goto invalid_enum;
}
@@ -1057,14 +1135,14 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
invalid_enum:
_mesa_error(ctx, GL_INVALID_ENUM, "%s(%s prop %s)", caller,
- _mesa_lookup_enum_by_nr(res->Type),
- _mesa_lookup_enum_by_nr(prop));
+ _mesa_enum_to_string(res->Type),
+ _mesa_enum_to_string(prop));
return 0;
invalid_operation:
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s prop %s)", caller,
- _mesa_lookup_enum_by_nr(res->Type),
- _mesa_lookup_enum_by_nr(prop));
+ _mesa_enum_to_string(res->Type),
+ _mesa_enum_to_string(prop));
return 0;
}
@@ -1086,7 +1164,7 @@ _mesa_get_program_resourceiv(struct gl_shader_program *shProg,
if (!res || bufSize < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetProgramResourceiv(%s index %d bufSize %d)",
- _mesa_lookup_enum_by_nr(programInterface), index, bufSize);
+ _mesa_enum_to_string(programInterface), index, bufSize);
return;
}
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index a4296adf799..f9a7d130f9c 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -110,6 +110,7 @@ _mesa_init_shader_state(struct gl_context *ctx)
*/
struct gl_shader_compiler_options options;
gl_shader_stage sh;
+ int i;
memset(&options, 0, sizeof(options));
options.MaxUnrollIterations = 32;
@@ -126,6 +127,12 @@ _mesa_init_shader_state(struct gl_context *ctx)
/* Extended for ARB_separate_shader_objects */
ctx->Shader.RefCount = 1;
mtx_init(&ctx->Shader.Mutex, mtx_plain);
+
+ ctx->TessCtrlProgram.patch_vertices = 3;
+ for (i = 0; i < 4; ++i)
+ ctx->TessCtrlProgram.patch_default_outer_level[i] = 1.0;
+ for (i = 0; i < 2; ++i)
+ ctx->TessCtrlProgram.patch_default_inner_level[i] = 1.0;
}
@@ -199,6 +206,9 @@ _mesa_validate_shader_target(const struct gl_context *ctx, GLenum type)
return ctx == NULL || ctx->Extensions.ARB_vertex_shader;
case GL_GEOMETRY_SHADER_ARB:
return ctx == NULL || _mesa_has_geometry_shaders(ctx);
+ case GL_TESS_CONTROL_SHADER:
+ case GL_TESS_EVALUATION_SHADER:
+ return ctx == NULL || _mesa_has_tessellation(ctx);
case GL_COMPUTE_SHADER:
return ctx == NULL || ctx->Extensions.ARB_compute_shader;
default:
@@ -415,6 +425,8 @@ detach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
/* sanity check - make sure the new list's entries are sensible */
for (j = 0; j < shProg->NumShaders; j++) {
assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
+ shProg->Shaders[j]->Type == GL_TESS_CONTROL_SHADER ||
+ shProg->Shaders[j]->Type == GL_TESS_EVALUATION_SHADER ||
shProg->Shaders[j]->Type == GL_GEOMETRY_SHADER ||
shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
assert(shProg->Shaders[j]->RefCount > 0);
@@ -511,6 +523,57 @@ check_gs_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
/**
+ * Check if a tessellation control shader query is valid at this time.
+ * If not, report an error and return false.
+ *
+ * From GL 4.0 section 6.1.12 (Shader and Program Queries):
+ *
+ * "If TESS_CONTROL_OUTPUT_VERTICES is queried for a program which has
+ * not been linked successfully, or which does not contain objects to
+ * form a tessellation control shader, then an INVALID_OPERATION error is
+ * generated."
+ */
+static bool
+check_tcs_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
+{
+ if (shProg->LinkStatus &&
+ shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL] != NULL) {
+ return true;
+ }
+
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetProgramv(linked tessellation control shader required)");
+ return false;
+}
+
+
+/**
+ * Check if a tessellation evaluation shader query is valid at this time.
+ * If not, report an error and return false.
+ *
+ * From GL 4.0 section 6.1.12 (Shader and Program Queries):
+ *
+ * "If any of the pname values in this paragraph are queried for a program
+ * which has not been linked successfully, or which does not contain
+ * objects to form a tessellation evaluation shader, then an
+ * INVALID_OPERATION error is generated."
+ *
+ */
+static bool
+check_tes_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
+{
+ if (shProg->LinkStatus &&
+ shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL] != NULL) {
+ return true;
+ }
+
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramv(linked tessellation "
+ "evaluation shader required)");
+ return false;
+}
+
+
+/**
* glGetProgramiv() - get shader program state.
* Note that this is for GLSL shader programs, not ARB vertex/fragment
* programs (see glGetProgramivARB).
@@ -533,6 +596,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
* and GL 3.2) are available in this context
*/
const bool has_core_gs = _mesa_has_geometry_shaders(ctx);
+ const bool has_tess = _mesa_has_tessellation(ctx);
/* Are uniform buffer objects available in this context?
*/
@@ -711,12 +775,44 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
case GL_PROGRAM_SEPARABLE:
*params = shProg->SeparateShader;
return;
+
+ /* ARB_tessellation_shader */
+ case GL_TESS_CONTROL_OUTPUT_VERTICES:
+ if (!has_tess)
+ break;
+ if (check_tcs_query(ctx, shProg))
+ *params = shProg->TessCtrl.VerticesOut;
+ return;
+ case GL_TESS_GEN_MODE:
+ if (!has_tess)
+ break;
+ if (check_tes_query(ctx, shProg))
+ *params = shProg->TessEval.PrimitiveMode;
+ return;
+ case GL_TESS_GEN_SPACING:
+ if (!has_tess)
+ break;
+ if (check_tes_query(ctx, shProg))
+ *params = shProg->TessEval.Spacing;
+ return;
+ case GL_TESS_GEN_VERTEX_ORDER:
+ if (!has_tess)
+ break;
+ if (check_tes_query(ctx, shProg))
+ *params = shProg->TessEval.VertexOrder;
+ return;
+ case GL_TESS_GEN_POINT_MODE:
+ if (!has_tess)
+ break;
+ if (check_tes_query(ctx, shProg))
+ *params = shProg->TessEval.PointMode;
+ return;
default:
break;
}
_mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
}
@@ -992,6 +1088,12 @@ print_shader_info(const struct gl_shader_program *shProg)
if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY])
printf(" geom prog %u\n",
shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program->Id);
+ if (shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL])
+ printf(" tesc prog %u\n",
+ shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program->Id);
+ if (shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL])
+ printf(" tese prog %u\n",
+ shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->Program->Id);
}
@@ -1037,11 +1139,9 @@ use_shader_program(struct gl_context *ctx, gl_shader_stage stage,
*/
switch (stage) {
case MESA_SHADER_VERTEX:
- /* Empty for now. */
- break;
+ case MESA_SHADER_TESS_CTRL:
+ case MESA_SHADER_TESS_EVAL:
case MESA_SHADER_GEOMETRY:
- /* Empty for now. */
- break;
case MESA_SHADER_COMPUTE:
/* Empty for now. */
break;
@@ -1071,6 +1171,7 @@ _mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
use_shader_program(ctx, i, shProg, &ctx->Shader);
_mesa_active_program(ctx, shProg, "glUseProgram");
+ _mesa_shader_program_init_subroutine_defaults(shProg);
if (ctx->Driver.UseProgram)
ctx->Driver.UseProgram(ctx, shProg);
}
@@ -1172,7 +1273,7 @@ _mesa_CreateShader(GLenum type)
{
GET_CURRENT_CONTEXT(ctx);
if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glCreateShader %s\n", _mesa_lookup_enum_by_nr(type));
+ _mesa_debug(ctx, "glCreateShader %s\n", _mesa_enum_to_string(type));
return create_shader(ctx, type);
}
@@ -1331,7 +1432,7 @@ void GLAPIENTRY
_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
GLfloat *params)
{
- GLint iparams[1]; /* XXX is one element enough? */
+ GLint iparams[1] = {0}; /* XXX is one element enough? */
_mesa_GetObjectParameterivARB(object, pname, iparams);
params[0] = (GLfloat) iparams[0];
}
@@ -1460,7 +1561,7 @@ read_shader(const char *fname)
*/
void GLAPIENTRY
_mesa_ShaderSource(GLhandleARB shaderObj, GLsizei count,
- const GLcharARB * const * string, const GLint * length)
+ const GLcharARB * const * string, const GLint * length)
{
GET_CURRENT_CONTEXT(ctx);
GLint *offsets;
@@ -1692,12 +1793,23 @@ _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
const void* binary, GLint length)
{
GET_CURRENT_CONTEXT(ctx);
- (void) n;
(void) shaders;
(void) binaryformat;
(void) binary;
- (void) length;
- _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderBinary");
+
+ /* Page 68, section 7.2 'Shader Binaries" of the of the OpenGL ES 3.1, and
+ * page 88 of the OpenGL 4.5 specs state:
+ *
+ * "An INVALID_VALUE error is generated if count or length is negative.
+ * An INVALID_ENUM error is generated if binaryformat is not a supported
+ * format returned in SHADER_BINARY_FORMATS."
+ */
+ if (n < 0 || length < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glShaderBinary(count or length < 0)");
+ return;
+ }
+
+ _mesa_error(ctx, GL_INVALID_ENUM, "glShaderBinary(format)");
}
@@ -1857,7 +1969,7 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
return;
}
@@ -1865,7 +1977,7 @@ invalid_value:
_mesa_error(ctx, GL_INVALID_VALUE,
"glProgramParameteri(pname=%s, value=%d): "
"value must be 0 or 1.",
- _mesa_lookup_enum_by_nr(pname),
+ _mesa_enum_to_string(pname),
value);
}
@@ -1885,7 +1997,8 @@ _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)
+ GLenum type, GLsizei count,
+ const GLchar* const *strings)
{
const GLuint shader = create_shader(ctx, type);
GLuint program = 0;
@@ -1920,8 +2033,8 @@ _mesa_create_shader_program(struct gl_context* ctx, GLboolean separate,
}
#endif
}
-
- ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
+ if (sh->InfoLog)
+ ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
}
delete_shader(ctx, shader);
@@ -1944,6 +2057,22 @@ _mesa_copy_linked_program_data(gl_shader_stage type,
case MESA_SHADER_VERTEX:
dst->UsesClipDistanceOut = src->Vert.UsesClipDistance;
break;
+ case MESA_SHADER_TESS_CTRL: {
+ struct gl_tess_ctrl_program *dst_tcp =
+ (struct gl_tess_ctrl_program *) dst;
+ dst_tcp->VerticesOut = src->TessCtrl.VerticesOut;
+ break;
+ }
+ case MESA_SHADER_TESS_EVAL: {
+ struct gl_tess_eval_program *dst_tep =
+ (struct gl_tess_eval_program *) dst;
+ dst_tep->PrimitiveMode = src->TessEval.PrimitiveMode;
+ dst_tep->Spacing = src->TessEval.Spacing;
+ dst_tep->VertexOrder = src->TessEval.VertexOrder;
+ dst_tep->PointMode = src->TessEval.PointMode;
+ dst->UsesClipDistanceOut = src->TessEval.UsesClipDistance;
+ break;
+ }
case MESA_SHADER_GEOMETRY: {
struct gl_geometry_program *dst_gp = (struct gl_geometry_program *) dst;
dst_gp->VerticesIn = src->Geom.VerticesIn;
@@ -1954,20 +2083,20 @@ _mesa_copy_linked_program_data(gl_shader_stage type,
dst->UsesClipDistanceOut = src->Geom.UsesClipDistance;
dst_gp->UsesEndPrimitive = src->Geom.UsesEndPrimitive;
dst_gp->UsesStreams = src->Geom.UsesStreams;
- }
break;
+ }
case MESA_SHADER_FRAGMENT: {
struct gl_fragment_program *dst_fp = (struct gl_fragment_program *) dst;
dst_fp->FragDepthLayout = src->FragDepthLayout;
- }
break;
+ }
case MESA_SHADER_COMPUTE: {
struct gl_compute_program *dst_cp = (struct gl_compute_program *) dst;
int i;
for (i = 0; i < 3; i++)
dst_cp->LocalSize[i] = src->Comp.LocalSize[i];
- }
break;
+ }
default:
break;
}
@@ -1984,3 +2113,568 @@ _mesa_CreateShaderProgramv(GLenum type, GLsizei count,
return _mesa_create_shader_program(ctx, GL_TRUE, type, count, strings);
}
+
+
+/**
+ * For GL_ARB_tessellation_shader
+ */
+extern void GLAPIENTRY
+_mesa_PatchParameteri(GLenum pname, GLint value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!_mesa_has_tessellation(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glPatchParameteri");
+ return;
+ }
+
+ if (pname != GL_PATCH_VERTICES) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glPatchParameteri");
+ return;
+ }
+
+ if (value <= 0 || value > ctx->Const.MaxPatchVertices) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glPatchParameteri");
+ return;
+ }
+
+ ctx->TessCtrlProgram.patch_vertices = value;
+}
+
+
+extern void GLAPIENTRY
+_mesa_PatchParameterfv(GLenum pname, const GLfloat *values)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!_mesa_has_tessellation(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glPatchParameterfv");
+ return;
+ }
+
+ switch(pname) {
+ case GL_PATCH_DEFAULT_OUTER_LEVEL:
+ FLUSH_VERTICES(ctx, 0);
+ memcpy(ctx->TessCtrlProgram.patch_default_outer_level, values,
+ 4 * sizeof(GLfloat));
+ ctx->NewDriverState |= ctx->DriverFlags.NewDefaultTessLevels;
+ return;
+ case GL_PATCH_DEFAULT_INNER_LEVEL:
+ FLUSH_VERTICES(ctx, 0);
+ memcpy(ctx->TessCtrlProgram.patch_default_inner_level, values,
+ 2 * sizeof(GLfloat));
+ ctx->NewDriverState |= ctx->DriverFlags.NewDefaultTessLevels;
+ return;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glPatchParameterfv");
+ return;
+ }
+}
+
+/**
+ * ARB_shader_subroutine
+ */
+GLint GLAPIENTRY
+_mesa_GetSubroutineUniformLocation(GLuint program, GLenum shadertype,
+ const GLchar *name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const char *api_name = "glGetSubroutineUniformLocation";
+ struct gl_shader_program *shProg;
+ GLenum resource_type;
+ gl_shader_stage stage;
+
+ if (!_mesa_has_shader_subroutine(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return -1;
+ }
+
+ if (!_mesa_validate_shader_target(ctx, shadertype)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return -1;
+ }
+
+ shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
+ if (!shProg)
+ return -1;
+
+ stage = _mesa_shader_enum_to_shader_stage(shadertype);
+ if (!shProg->_LinkedShaders[stage]) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return -1;
+ }
+
+ resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
+ return _mesa_program_resource_location(shProg, resource_type, name);
+}
+
+GLuint GLAPIENTRY
+_mesa_GetSubroutineIndex(GLuint program, GLenum shadertype,
+ const GLchar *name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const char *api_name = "glGetSubroutineIndex";
+ struct gl_shader_program *shProg;
+ struct gl_program_resource *res;
+ GLenum resource_type;
+ gl_shader_stage stage;
+
+ if (!_mesa_has_shader_subroutine(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return -1;
+ }
+
+ if (!_mesa_validate_shader_target(ctx, shadertype)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return -1;
+ }
+
+ shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
+ if (!shProg)
+ return -1;
+
+ stage = _mesa_shader_enum_to_shader_stage(shadertype);
+ if (!shProg->_LinkedShaders[stage]) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return -1;
+ }
+
+ resource_type = _mesa_shader_stage_to_subroutine(stage);
+ res = _mesa_program_resource_find_name(shProg, resource_type, name, NULL);
+ if (!res) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return -1;
+ }
+
+ return _mesa_program_resource_index(shProg, res);
+}
+
+
+GLvoid GLAPIENTRY
+_mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype,
+ GLuint index, GLenum pname, GLint *values)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const char *api_name = "glGetActiveSubroutineUniformiv";
+ struct gl_shader_program *shProg;
+ struct gl_shader *sh;
+ gl_shader_stage stage;
+ struct gl_program_resource *res;
+ const struct gl_uniform_storage *uni;
+ GLenum resource_type;
+ int count, i, j;
+
+ if (!_mesa_has_shader_subroutine(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ if (!_mesa_validate_shader_target(ctx, shadertype)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
+ if (!shProg)
+ return;
+
+ stage = _mesa_shader_enum_to_shader_stage(shadertype);
+ resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
+
+ sh = shProg->_LinkedShaders[stage];
+ if (!sh) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ switch (pname) {
+ case GL_NUM_COMPATIBLE_SUBROUTINES: {
+ res = _mesa_program_resource_find_index(shProg, resource_type, index);
+ if (res) {
+ uni = res->Data;
+ values[0] = uni->num_compatible_subroutines;
+ }
+ break;
+ }
+ case GL_COMPATIBLE_SUBROUTINES: {
+ res = _mesa_program_resource_find_index(shProg, resource_type, index);
+ if (res) {
+ uni = res->Data;
+ count = 0;
+ for (i = 0; i < sh->NumSubroutineFunctions; i++) {
+ struct gl_subroutine_function *fn = &sh->SubroutineFunctions[i];
+ for (j = 0; j < fn->num_compat_types; j++) {
+ if (fn->types[j] == uni->type) {
+ values[count++] = i;
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+ case GL_UNIFORM_SIZE:
+ res = _mesa_program_resource_find_index(shProg, resource_type, index);
+ if (res) {
+ uni = res->Data;
+ values[0] = uni->array_elements ? uni->array_elements : 1;
+ }
+ break;
+ case GL_UNIFORM_NAME_LENGTH:
+ res = _mesa_program_resource_find_index(shProg, resource_type, index);
+ if (res) {
+ values[0] = strlen(_mesa_program_resource_name(res)) + 1
+ + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0);;
+ }
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+}
+
+
+GLvoid GLAPIENTRY
+_mesa_GetActiveSubroutineUniformName(GLuint program, GLenum shadertype,
+ GLuint index, GLsizei bufsize,
+ GLsizei *length, GLchar *name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const char *api_name = "glGetActiveSubroutineUniformName";
+ struct gl_shader_program *shProg;
+ GLenum resource_type;
+ gl_shader_stage stage;
+
+ if (!_mesa_has_shader_subroutine(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ if (!_mesa_validate_shader_target(ctx, shadertype)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
+ if (!shProg)
+ return;
+
+ stage = _mesa_shader_enum_to_shader_stage(shadertype);
+ if (!shProg->_LinkedShaders[stage]) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
+ /* get program resource name */
+ _mesa_get_program_resource_name(shProg, resource_type,
+ index, bufsize,
+ length, name, api_name);
+}
+
+
+GLvoid GLAPIENTRY
+_mesa_GetActiveSubroutineName(GLuint program, GLenum shadertype,
+ GLuint index, GLsizei bufsize,
+ GLsizei *length, GLchar *name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const char *api_name = "glGetActiveSubroutineName";
+ struct gl_shader_program *shProg;
+ GLenum resource_type;
+ gl_shader_stage stage;
+
+ if (!_mesa_has_shader_subroutine(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ if (!_mesa_validate_shader_target(ctx, shadertype)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
+ if (!shProg)
+ return;
+
+ stage = _mesa_shader_enum_to_shader_stage(shadertype);
+ if (!shProg->_LinkedShaders[stage]) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+ resource_type = _mesa_shader_stage_to_subroutine(stage);
+ _mesa_get_program_resource_name(shProg, resource_type,
+ index, bufsize,
+ length, name, api_name);
+}
+
+
+GLvoid GLAPIENTRY
+_mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count,
+ const GLuint *indices)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const char *api_name = "glUniformSubroutinesuiv";
+ struct gl_shader_program *shProg;
+ struct gl_shader *sh;
+ gl_shader_stage stage;
+ int i;
+
+ if (!_mesa_has_shader_subroutine(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ if (!_mesa_validate_shader_target(ctx, shadertype)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ stage = _mesa_shader_enum_to_shader_stage(shadertype);
+ shProg = ctx->_Shader->CurrentProgram[stage];
+ if (!shProg) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ sh = shProg->_LinkedShaders[stage];
+ if (!sh) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ if (count != sh->NumSubroutineUniformRemapTable) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
+ return;
+ }
+
+ i = 0;
+ do {
+ struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i];
+ int uni_count = uni->array_elements ? uni->array_elements : 1;
+ int j, k;
+
+ for (j = i; j < i + uni_count; j++) {
+ struct gl_subroutine_function *subfn;
+ if (indices[j] >= sh->NumSubroutineFunctions) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
+ return;
+ }
+
+ subfn = &sh->SubroutineFunctions[indices[j]];
+ for (k = 0; k < subfn->num_compat_types; k++) {
+ if (subfn->types[k] == uni->type)
+ break;
+ }
+ if (k == subfn->num_compat_types) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+ }
+ i += uni_count;
+ } while(i < count);
+
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+ i = 0;
+ do {
+ struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i];
+ int uni_count = uni->array_elements ? uni->array_elements : 1;
+
+ memcpy(&uni->storage[0], &indices[i],
+ sizeof(GLuint) * uni_count);
+
+ uni->initialized = true;
+ _mesa_propagate_uniforms_to_driver_storage(uni, 0, uni_count);
+ i += uni_count;
+ } while(i < count);
+}
+
+
+GLvoid GLAPIENTRY
+_mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location,
+ GLuint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const char *api_name = "glGetUniformSubroutineuiv";
+ struct gl_shader_program *shProg;
+ struct gl_shader *sh;
+ gl_shader_stage stage;
+
+ if (!_mesa_has_shader_subroutine(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ if (!_mesa_validate_shader_target(ctx, shadertype)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ stage = _mesa_shader_enum_to_shader_stage(shadertype);
+ shProg = ctx->_Shader->CurrentProgram[stage];
+ if (!shProg) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ sh = shProg->_LinkedShaders[stage];
+ if (!sh) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ if (location >= sh->NumSubroutineUniformRemapTable) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
+ return;
+ }
+
+ {
+ struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[location];
+ int offset = location - uni->subroutine[stage].index;
+ memcpy(params, &uni->storage[offset],
+ sizeof(GLuint));
+ }
+}
+
+
+GLvoid GLAPIENTRY
+_mesa_GetProgramStageiv(GLuint program, GLenum shadertype,
+ GLenum pname, GLint *values)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const char *api_name = "glGetProgramStageiv";
+ struct gl_shader_program *shProg;
+ struct gl_shader *sh;
+ gl_shader_stage stage;
+
+ if (!_mesa_has_shader_subroutine(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ if (!_mesa_validate_shader_target(ctx, shadertype)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
+ if (!shProg)
+ return;
+
+ stage = _mesa_shader_enum_to_shader_stage(shadertype);
+ sh = shProg->_LinkedShaders[stage];
+ if (!sh) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
+ return;
+ }
+
+ switch (pname) {
+ case GL_ACTIVE_SUBROUTINES:
+ values[0] = sh->NumSubroutineFunctions;
+ break;
+ case GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS:
+ values[0] = sh->NumSubroutineUniformRemapTable;
+ break;
+ case GL_ACTIVE_SUBROUTINE_UNIFORMS:
+ values[0] = sh->NumSubroutineUniformTypes;
+ break;
+ case GL_ACTIVE_SUBROUTINE_MAX_LENGTH:
+ {
+ unsigned i;
+ GLint max_len = 0;
+ GLenum resource_type;
+ struct gl_program_resource *res;
+
+ resource_type = _mesa_shader_stage_to_subroutine(stage);
+ for (i = 0; i < sh->NumSubroutineFunctions; i++) {
+ res = _mesa_program_resource_find_index(shProg, resource_type, i);
+ if (res) {
+ const GLint len = strlen(_mesa_program_resource_name(res)) + 1;
+ if (len > max_len)
+ max_len = len;
+ }
+ }
+ values[0] = max_len;
+ break;
+ }
+ case GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH:
+ {
+ unsigned i;
+ GLint max_len = 0;
+ GLenum resource_type;
+ struct gl_program_resource *res;
+
+ resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
+ for (i = 0; i < sh->NumSubroutineUniformRemapTable; i++) {
+ res = _mesa_program_resource_find_index(shProg, resource_type, i);
+ if (res) {
+ const GLint len = strlen(_mesa_program_resource_name(res)) + 1
+ + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0);
+
+ if (len > max_len)
+ max_len = len;
+ }
+ }
+ values[0] = max_len;
+ break;
+ }
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s", api_name);
+ values[0] = -1;
+ break;
+ }
+}
+
+static int
+find_compat_subroutine(struct gl_shader *sh, const struct glsl_type *type)
+{
+ int i, j;
+
+ for (i = 0; i < sh->NumSubroutineFunctions; i++) {
+ struct gl_subroutine_function *fn = &sh->SubroutineFunctions[i];
+ for (j = 0; j < fn->num_compat_types; j++) {
+ if (fn->types[j] == type)
+ return i;
+ }
+ }
+ return 0;
+}
+
+static void
+_mesa_shader_init_subroutine_defaults(struct gl_shader *sh)
+{
+ int i, j;
+
+ for (i = 0; i < sh->NumSubroutineUniformRemapTable; i++) {
+ struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i];
+ int uni_count;
+ int val;
+
+ if (!uni)
+ continue;
+ uni_count = uni->array_elements ? uni->array_elements : 1;
+ val = find_compat_subroutine(sh, uni->type);
+
+ for (j = 0; j < uni_count; j++)
+ memcpy(&uni->storage[j], &val, sizeof(int));
+ uni->initialized = true;
+ _mesa_propagate_uniforms_to_driver_storage(uni, 0, uni_count);
+ }
+}
+
+void
+_mesa_shader_program_init_subroutine_defaults(struct gl_shader_program *shProg)
+{
+ int i;
+
+ if (!shProg)
+ return;
+
+ for (i = 0; i < MESA_SHADER_STAGES; i++) {
+ if (!shProg->_LinkedShaders[i])
+ continue;
+
+ _mesa_shader_init_subroutine_defaults(shProg->_LinkedShaders[i]);
+ }
+}
diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h
index aba6d5d8306..0a10191684f 100644
--- a/src/mesa/main/shaderapi.h
+++ b/src/mesa/main/shaderapi.h
@@ -232,7 +232,8 @@ _mesa_program_resource_index(struct gl_shader_program *shProg,
extern struct gl_program_resource *
_mesa_program_resource_find_name(struct gl_shader_program *shProg,
- GLenum programInterface, const char *name);
+ GLenum programInterface, const char *name,
+ unsigned *array_index);
extern struct gl_program_resource *
_mesa_program_resource_find_index(struct gl_shader_program *shProg,
@@ -264,6 +265,51 @@ _mesa_get_program_resourceiv(struct gl_shader_program *shProg,
GLsizei bufSize, GLsizei *length,
GLint *params);
+/* GL_ARB_tessellation_shader */
+extern void GLAPIENTRY
+_mesa_PatchParameteri(GLenum pname, GLint value);
+
+extern void GLAPIENTRY
+_mesa_PatchParameterfv(GLenum pname, const GLfloat *values);
+
+/* GL_ARB_shader_subroutine */
+void
+_mesa_shader_program_init_subroutine_defaults(struct gl_shader_program *shProg);
+
+extern GLint GLAPIENTRY
+_mesa_GetSubroutineUniformLocation(GLuint program, GLenum shadertype,
+ const GLchar *name);
+
+extern GLuint GLAPIENTRY
+_mesa_GetSubroutineIndex(GLuint program, GLenum shadertype,
+ const GLchar *name);
+
+extern GLvoid GLAPIENTRY
+_mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype,
+ GLuint index, GLenum pname, GLint *values);
+
+extern GLvoid GLAPIENTRY
+_mesa_GetActiveSubroutineUniformName(GLuint program, GLenum shadertype,
+ GLuint index, GLsizei bufsize,
+ GLsizei *length, GLchar *name);
+
+extern GLvoid GLAPIENTRY
+_mesa_GetActiveSubroutineName(GLuint program, GLenum shadertype,
+ GLuint index, GLsizei bufsize,
+ GLsizei *length, GLchar *name);
+
+extern GLvoid GLAPIENTRY
+_mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count,
+ const GLuint *indices);
+
+extern GLvoid GLAPIENTRY
+_mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location,
+ GLuint *params);
+
+extern GLvoid GLAPIENTRY
+_mesa_GetProgramStageiv(GLuint program, GLenum shadertype,
+ GLenum pname, GLint *values);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/mesa/main/shaderimage.c b/src/mesa/main/shaderimage.c
index 80b77275f93..a348cdb0405 100644
--- a/src/mesa/main/shaderimage.c
+++ b/src/mesa/main/shaderimage.c
@@ -610,7 +610,7 @@ _mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures)
"glBindImageTextures(the internal format %s of "
"the level zero texture image of textures[%d]=%u "
"is not supported)",
- _mesa_lookup_enum_by_nr(tex_format),
+ _mesa_enum_to_string(tex_format),
i, texture);
continue;
}
diff --git a/src/mesa/main/shaderobj.h b/src/mesa/main/shaderobj.h
index 3d696a1887e..943044e37cd 100644
--- a/src/mesa/main/shaderobj.h
+++ b/src/mesa/main/shaderobj.h
@@ -111,6 +111,10 @@ _mesa_shader_enum_to_shader_stage(GLenum v)
return MESA_SHADER_FRAGMENT;
case GL_GEOMETRY_SHADER:
return MESA_SHADER_GEOMETRY;
+ case GL_TESS_CONTROL_SHADER:
+ return MESA_SHADER_TESS_CTRL;
+ case GL_TESS_EVALUATION_SHADER:
+ return MESA_SHADER_TESS_EVAL;
case GL_COMPUTE_SHADER:
return MESA_SHADER_COMPUTE;
default:
@@ -119,6 +123,107 @@ _mesa_shader_enum_to_shader_stage(GLenum v)
}
}
+/* 8 bytes + another underscore */
+#define MESA_SUBROUTINE_PREFIX_LEN 9
+static inline const char *
+_mesa_shader_stage_to_subroutine_prefix(gl_shader_stage stage)
+{
+ switch (stage) {
+ case MESA_SHADER_VERTEX:
+ return "__subu_v";
+ case MESA_SHADER_GEOMETRY:
+ return "__subu_g";
+ case MESA_SHADER_FRAGMENT:
+ return "__subu_f";
+ case MESA_SHADER_COMPUTE:
+ return "__subu_c";
+ case MESA_SHADER_TESS_CTRL:
+ return "__subu_t";
+ case MESA_SHADER_TESS_EVAL:
+ return "__subu_e";
+ default:
+ return NULL;
+ }
+}
+
+static inline gl_shader_stage
+_mesa_shader_stage_from_subroutine_uniform(GLenum subuniform)
+{
+ switch (subuniform) {
+ default:
+ case GL_VERTEX_SUBROUTINE_UNIFORM:
+ return MESA_SHADER_VERTEX;
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ return MESA_SHADER_GEOMETRY;
+ case GL_FRAGMENT_SUBROUTINE_UNIFORM:
+ return MESA_SHADER_FRAGMENT;
+ case GL_COMPUTE_SUBROUTINE_UNIFORM:
+ return MESA_SHADER_COMPUTE;
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ return MESA_SHADER_TESS_CTRL;
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
+ return MESA_SHADER_TESS_EVAL;
+ }
+}
+
+static inline gl_shader_stage
+_mesa_shader_stage_from_subroutine(GLenum subroutine)
+{
+ switch (subroutine) {
+ case GL_VERTEX_SUBROUTINE:
+ return MESA_SHADER_VERTEX;
+ case GL_GEOMETRY_SUBROUTINE:
+ return MESA_SHADER_GEOMETRY;
+ case GL_FRAGMENT_SUBROUTINE:
+ return MESA_SHADER_FRAGMENT;
+ case GL_COMPUTE_SUBROUTINE:
+ return MESA_SHADER_COMPUTE;
+ case GL_TESS_CONTROL_SUBROUTINE:
+ return MESA_SHADER_TESS_CTRL;
+ case GL_TESS_EVALUATION_SUBROUTINE:
+ return MESA_SHADER_TESS_EVAL;
+ }
+}
+
+static inline GLenum
+_mesa_shader_stage_to_subroutine(gl_shader_stage stage)
+{
+ switch (stage) {
+ default:
+ case MESA_SHADER_VERTEX:
+ return GL_VERTEX_SUBROUTINE;
+ case MESA_SHADER_GEOMETRY:
+ return GL_GEOMETRY_SUBROUTINE;
+ case MESA_SHADER_FRAGMENT:
+ return GL_FRAGMENT_SUBROUTINE;
+ case MESA_SHADER_COMPUTE:
+ return GL_COMPUTE_SUBROUTINE;
+ case MESA_SHADER_TESS_CTRL:
+ return GL_TESS_CONTROL_SUBROUTINE;
+ case MESA_SHADER_TESS_EVAL:
+ return GL_TESS_EVALUATION_SUBROUTINE;
+ }
+}
+
+static inline GLenum
+_mesa_shader_stage_to_subroutine_uniform(gl_shader_stage stage)
+{
+ switch (stage) {
+ default:
+ case MESA_SHADER_VERTEX:
+ return GL_VERTEX_SUBROUTINE_UNIFORM;
+ case MESA_SHADER_GEOMETRY:
+ return GL_GEOMETRY_SUBROUTINE_UNIFORM;
+ case MESA_SHADER_FRAGMENT:
+ return GL_FRAGMENT_SUBROUTINE_UNIFORM;
+ case MESA_SHADER_COMPUTE:
+ return GL_COMPUTE_SUBROUTINE_UNIFORM;
+ case MESA_SHADER_TESS_CTRL:
+ return GL_TESS_CONTROL_SUBROUTINE_UNIFORM;
+ case MESA_SHADER_TESS_EVAL:
+ return GL_TESS_EVALUATION_SUBROUTINE_UNIFORM;
+ }
+}
#ifdef __cplusplus
}
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index bede7fe1d0e..d3b1c72b08d 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -79,8 +79,8 @@ update_program_enables(struct gl_context *ctx)
/**
- * Update the ctx->Vertex/Geometry/FragmentProgram._Current pointers to point
- * to the current/active programs. Then call ctx->Driver.BindProgram() to
+ * Update the ctx->*Program._Current pointers to point to the
+ * current/active programs. Then call ctx->Driver.BindProgram() to
* tell the driver which programs to use.
*
* Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment
@@ -97,6 +97,10 @@ update_program(struct gl_context *ctx)
{
const struct gl_shader_program *vsProg =
ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX];
+ const struct gl_shader_program *tcsProg =
+ ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL];
+ const struct gl_shader_program *tesProg =
+ ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
const struct gl_shader_program *gsProg =
ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY];
struct gl_shader_program *fsProg =
@@ -106,6 +110,8 @@ update_program(struct gl_context *ctx)
const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current;
const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current;
const struct gl_geometry_program *prevGP = ctx->GeometryProgram._Current;
+ const struct gl_tess_ctrl_program *prevTCP = ctx->TessCtrlProgram._Current;
+ const struct gl_tess_eval_program *prevTEP = ctx->TessEvalProgram._Current;
const struct gl_compute_program *prevCP = ctx->ComputeProgram._Current;
GLbitfield new_state = 0x0;
@@ -175,6 +181,30 @@ update_program(struct gl_context *ctx)
_mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL);
}
+ if (tesProg && tesProg->LinkStatus
+ && tesProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]) {
+ /* Use GLSL tessellation evaluation shader */
+ _mesa_reference_tesseprog(ctx, &ctx->TessEvalProgram._Current,
+ gl_tess_eval_program(
+ tesProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->Program));
+ }
+ else {
+ /* No tessellation evaluation program */
+ _mesa_reference_tesseprog(ctx, &ctx->TessEvalProgram._Current, NULL);
+ }
+
+ if (tcsProg && tcsProg->LinkStatus
+ && tcsProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]) {
+ /* Use GLSL tessellation control shader */
+ _mesa_reference_tesscprog(ctx, &ctx->TessCtrlProgram._Current,
+ gl_tess_ctrl_program(
+ tcsProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program));
+ }
+ else {
+ /* No tessellation control program */
+ _mesa_reference_tesscprog(ctx, &ctx->TessCtrlProgram._Current, NULL);
+ }
+
/* Examine vertex program after fragment program as
* _mesa_get_fixed_func_vertex_program() needs to know active
* fragprog inputs.
@@ -230,6 +260,22 @@ update_program(struct gl_context *ctx)
}
}
+ if (ctx->TessEvalProgram._Current != prevTEP) {
+ new_state |= _NEW_PROGRAM;
+ if (ctx->Driver.BindProgram) {
+ ctx->Driver.BindProgram(ctx, GL_TESS_EVALUATION_PROGRAM_NV,
+ (struct gl_program *) ctx->TessEvalProgram._Current);
+ }
+ }
+
+ if (ctx->TessCtrlProgram._Current != prevTCP) {
+ new_state |= _NEW_PROGRAM;
+ if (ctx->Driver.BindProgram) {
+ ctx->Driver.BindProgram(ctx, GL_TESS_CONTROL_PROGRAM_NV,
+ (struct gl_program *) ctx->TessCtrlProgram._Current);
+ }
+ }
+
if (ctx->VertexProgram._Current != prevVP) {
new_state |= _NEW_PROGRAM;
if (ctx->Driver.BindProgram) {
@@ -266,8 +312,8 @@ update_program_constants(struct gl_context *ctx)
}
}
- /* Don't handle geometry shaders here. They don't use any state
- * constants.
+ /* Don't handle tessellation and geometry shaders here. They don't use
+ * any state constants.
*/
if (ctx->VertexProgram._Current) {
diff --git a/src/mesa/main/tests/dispatch_sanity.cpp b/src/mesa/main/tests/dispatch_sanity.cpp
index 800720b798e..af89d2c1cfb 100644
--- a/src/mesa/main/tests/dispatch_sanity.cpp
+++ b/src/mesa/main/tests/dispatch_sanity.cpp
@@ -563,6 +563,8 @@ const struct function common_desktop_functions_possible[] = {
/* GL 4.0 */
{ "glMinSampleShading", 40, -1 },
+ { "glPatchParameteri", 40, -1 },
+ { "glPatchParameterfv", 40, -1 },
{ "glBlendEquationi", 40, -1 },
{ "glBlendEquationSeparatei", 40, -1 },
{ "glBlendFunci", 40, -1 },
@@ -930,6 +932,11 @@ const struct function common_desktop_functions_possible[] = {
/* GL_EXT_polygon_offset_clamp */
{ "glPolygonOffsetClampEXT", 11, -1 },
+
+ /* GL_ARB_get_texture_sub_image */
+ { "glGetTextureSubImage", 20, -1 },
+ { "glGetCompressedTextureSubImage", 20, -1 },
+
{ NULL, 0, -1 }
};
@@ -1424,6 +1431,16 @@ const struct function gl_core_functions_possible[] = {
/* GL 3.2 */
{ "glFramebufferTexture", 32, -1 },
+ /* GL 4.0 */
+ { "glGetSubroutineUniformLocation", 40, -1 },
+ { "glGetSubroutineIndex", 40, -1 },
+ { "glGetActiveSubroutineUniformiv", 40, -1 },
+ { "glGetActiveSubroutineUniformName", 40, -1 },
+ { "glGetActiveSubroutineName", 40, -1 },
+ { "glUniformSubroutinesuiv", 40, -1 },
+ { "glGetUniformSubroutineuiv", 40, -1 },
+ { "glGetProgramStageiv", 40, -1 },
+
/* GL 4.3 */
{ "glIsRenderbuffer", 43, -1 },
{ "glBindRenderbuffer", 43, -1 },
@@ -1562,16 +1579,6 @@ const struct function gl_core_functions_possible[] = {
{ "glUniformMatrix4x2dv", 40, -1 },
{ "glUniformMatrix4x3dv", 40, -1 },
{ "glGetUniformdv", 43, -1 },
-// { "glGetSubroutineUniformLocation", 43, -1 }, // XXX: Add to xml
-// { "glGetSubroutineIndex", 43, -1 }, // XXX: Add to xml
-// { "glGetActiveSubroutineUniformiv", 43, -1 }, // XXX: Add to xml
-// { "glGetActiveSubroutineUniformName", 43, -1 }, // XXX: Add to xml
-// { "glGetActiveSubroutineName", 43, -1 }, // XXX: Add to xml
-// { "glUniformSubroutinesuiv", 43, -1 }, // XXX: Add to xml
-// { "glGetUniformSubroutineuiv", 43, -1 }, // XXX: Add to xml
-// { "glGetProgramStageiv", 43, -1 }, // XXX: Add to xml
-// { "glPatchParameteri", 43, -1 }, // XXX: Add to xml
-// { "glPatchParameterfv", 43, -1 }, // XXX: Add to xml
{ "glBindTransformFeedback", 43, -1 },
{ "glDeleteTransformFeedbacks", 43, -1 },
diff --git a/src/mesa/main/tests/enum_strings.cpp b/src/mesa/main/tests/enum_strings.cpp
index dc5fe751a86..8218cc9a685 100644
--- a/src/mesa/main/tests/enum_strings.cpp
+++ b/src/mesa/main/tests/enum_strings.cpp
@@ -39,13 +39,13 @@ TEST(EnumStrings, LookUpByNumber)
{
for (unsigned i = 0; everything[i].name != NULL; i++) {
EXPECT_STREQ(everything[i].name,
- _mesa_lookup_enum_by_nr(everything[i].value));
+ _mesa_enum_to_string(everything[i].value));
}
}
TEST(EnumStrings, LookUpUnknownNumber)
{
- EXPECT_STRCASEEQ("0xEEEE", _mesa_lookup_enum_by_nr(0xEEEE));
+ EXPECT_STRCASEEQ("0xEEEE", _mesa_enum_to_string(0xEEEE));
}
/* Please type the name and the value. This makes it easier to detect
@@ -1731,6 +1731,10 @@ const struct enum_info everything[] = {
{ 0x8DDF, "GL_MAX_GEOMETRY_UNIFORM_COMPONENTS" },
{ 0x8DE0, "GL_MAX_GEOMETRY_OUTPUT_VERTICES" },
{ 0x8DE1, "GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS" },
+ { 0x8DE5, "GL_ACTIVE_SUBROUTINES" },
+ { 0x8DE6, "GL_ACTIVE_SUBROUTINE_UNIFORMS" },
+ { 0x8DE7, "GL_MAX_SUBROUTINES" },
+ { 0x8DE8, "GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS" },
{ 0x8DF0, "GL_LOW_FLOAT" },
{ 0x8DF1, "GL_MEDIUM_FLOAT" },
{ 0x8DF2, "GL_HIGH_FLOAT" },
@@ -1759,6 +1763,11 @@ const struct enum_info everything[] = {
{ 0x8E44, "GL_TEXTURE_SWIZZLE_B" },
{ 0x8E45, "GL_TEXTURE_SWIZZLE_A" },
{ 0x8E46, "GL_TEXTURE_SWIZZLE_RGBA" },
+ { 0x8E47, "GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS" },
+ { 0x8E48, "GL_ACTIVE_SUBROUTINE_MAX_LENGTH" },
+ { 0x8E49, "GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH" },
+ { 0x8E4A, "GL_NUM_COMPATIBLE_SUBROUTINES" },
+ { 0x8E4B, "GL_COMPATIBLE_SUBROUTINES" },
{ 0x8E4C, "GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION" },
{ 0x8E4D, "GL_FIRST_VERTEX_CONVENTION" },
{ 0x8E4E, "GL_LAST_VERTEX_CONVENTION" },
diff --git a/src/mesa/main/texenv.c b/src/mesa/main/texenv.c
index 3edafc0f776..091922161c5 100644
--- a/src/mesa/main/texenv.c
+++ b/src/mesa/main/texenv.c
@@ -42,7 +42,7 @@
#define TE_ERROR(errCode, msg, value) \
- _mesa_error(ctx, errCode, msg, _mesa_lookup_enum_by_nr(value));
+ _mesa_error(ctx, errCode, msg, _mesa_enum_to_string(value));
/** Set texture env mode */
@@ -482,16 +482,16 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(target=%s)",
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
_mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n",
- _mesa_lookup_enum_by_nr(target),
- _mesa_lookup_enum_by_nr(pname),
+ _mesa_enum_to_string(target),
+ _mesa_enum_to_string(pname),
*param,
- _mesa_lookup_enum_by_nr((GLenum) iparam0));
+ _mesa_enum_to_string((GLenum) iparam0));
/* Tell device driver about the new texture environment */
if (ctx->Driver.TexEnv) {
diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c
index 3c4baca7026..f4d17e1bdb5 100644
--- a/src/mesa/main/texformat.c
+++ b/src/mesa/main/texformat.c
@@ -847,7 +847,7 @@ _mesa_choose_tex_format(struct gl_context *ctx, GLenum target,
}
_mesa_problem(ctx, "unexpected format %s in _mesa_choose_tex_format()",
- _mesa_lookup_enum_by_nr(internalFormat));
+ _mesa_enum_to_string(internalFormat));
return MESA_FORMAT_NONE;
}
diff --git a/src/mesa/main/texgen.c b/src/mesa/main/texgen.c
index 41e428b69e7..24ba295746a 100644
--- a/src/mesa/main/texgen.c
+++ b/src/mesa/main/texgen.c
@@ -76,10 +76,10 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
_mesa_debug(ctx, "glTexGen %s %s %.1f(%s)...\n",
- _mesa_lookup_enum_by_nr(coord),
- _mesa_lookup_enum_by_nr(pname),
+ _mesa_enum_to_string(coord),
+ _mesa_enum_to_string(pname),
*params,
- _mesa_lookup_enum_by_nr((GLenum) (GLint) *params));
+ _mesa_enum_to_string((GLenum) (GLint) *params));
if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glTexGen(current unit)");
diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c
index 92b4d6795c6..c0ccce3d50e 100644
--- a/src/mesa/main/texgetimage.c
+++ b/src/mesa/main/texgetimage.c
@@ -75,12 +75,11 @@ type_needs_clamping(GLenum type)
*/
static void
get_tex_depth(struct gl_context *ctx, GLuint dimensions,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLint depth,
GLenum format, GLenum type, GLvoid *pixels,
struct gl_texture_image *texImage)
{
- const GLint width = texImage->Width;
- GLint height = texImage->Height;
- GLint depth = texImage->Depth;
GLint img, row;
GLfloat *depthRow = malloc(width * sizeof(GLfloat));
@@ -94,14 +93,15 @@ get_tex_depth(struct gl_context *ctx, GLuint dimensions,
height = 1;
}
+ assert(zoffset + depth <= texImage->Depth);
for (img = 0; img < depth; img++) {
GLubyte *srcMap;
GLint srcRowStride;
/* map src texture buffer */
- ctx->Driver.MapTextureImage(ctx, texImage, img,
- 0, 0, width, height, GL_MAP_READ_BIT,
- &srcMap, &srcRowStride);
+ ctx->Driver.MapTextureImage(ctx, texImage, zoffset + img,
+ xoffset, yoffset, width, height,
+ GL_MAP_READ_BIT, &srcMap, &srcRowStride);
if (srcMap) {
for (row = 0; row < height; row++) {
@@ -113,7 +113,7 @@ get_tex_depth(struct gl_context *ctx, GLuint dimensions,
_mesa_pack_depth_span(ctx, width, dest, type, depthRow, &ctx->Pack);
}
- ctx->Driver.UnmapTextureImage(ctx, texImage, img);
+ ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + img);
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
@@ -130,26 +130,26 @@ get_tex_depth(struct gl_context *ctx, GLuint dimensions,
*/
static void
get_tex_depth_stencil(struct gl_context *ctx, GLuint dimensions,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLint depth,
GLenum format, GLenum type, GLvoid *pixels,
struct gl_texture_image *texImage)
{
- const GLint width = texImage->Width;
- const GLint height = texImage->Height;
- const GLint depth = texImage->Depth;
GLint img, row;
assert(format == GL_DEPTH_STENCIL);
assert(type == GL_UNSIGNED_INT_24_8 ||
type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+ assert(zoffset + depth <= texImage->Depth);
for (img = 0; img < depth; img++) {
GLubyte *srcMap;
GLint rowstride;
/* map src texture buffer */
- ctx->Driver.MapTextureImage(ctx, texImage, img,
- 0, 0, width, height, GL_MAP_READ_BIT,
- &srcMap, &rowstride);
+ ctx->Driver.MapTextureImage(ctx, texImage, zoffset + img,
+ xoffset, yoffset, width, height,
+ GL_MAP_READ_BIT, &srcMap, &rowstride);
if (srcMap) {
for (row = 0; row < height; row++) {
@@ -166,7 +166,7 @@ get_tex_depth_stencil(struct gl_context *ctx, GLuint dimensions,
}
}
- ctx->Driver.UnmapTextureImage(ctx, texImage, img);
+ ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + img);
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
@@ -180,12 +180,11 @@ get_tex_depth_stencil(struct gl_context *ctx, GLuint dimensions,
*/
static void
get_tex_stencil(struct gl_context *ctx, GLuint dimensions,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLint depth,
GLenum format, GLenum type, GLvoid *pixels,
struct gl_texture_image *texImage)
{
- const GLint width = texImage->Width;
- const GLint height = texImage->Height;
- const GLint depth = texImage->Depth;
GLint img, row;
assert(format == GL_STENCIL_INDEX);
@@ -195,8 +194,9 @@ get_tex_stencil(struct gl_context *ctx, GLuint dimensions,
GLint rowstride;
/* map src texture buffer */
- ctx->Driver.MapTextureImage(ctx, texImage, img,
- 0, 0, width, height, GL_MAP_READ_BIT,
+ ctx->Driver.MapTextureImage(ctx, texImage, zoffset + img,
+ xoffset, yoffset, width, height,
+ GL_MAP_READ_BIT,
&srcMap, &rowstride);
if (srcMap) {
@@ -211,7 +211,7 @@ get_tex_stencil(struct gl_context *ctx, GLuint dimensions,
dest);
}
- ctx->Driver.UnmapTextureImage(ctx, texImage, img);
+ ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + img);
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
@@ -226,22 +226,22 @@ get_tex_stencil(struct gl_context *ctx, GLuint dimensions,
*/
static void
get_tex_ycbcr(struct gl_context *ctx, GLuint dimensions,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLint depth,
GLenum format, GLenum type, GLvoid *pixels,
struct gl_texture_image *texImage)
{
- const GLint width = texImage->Width;
- const GLint height = texImage->Height;
- const GLint depth = texImage->Depth;
GLint img, row;
+ assert(zoffset + depth <= texImage->Depth);
for (img = 0; img < depth; img++) {
GLubyte *srcMap;
GLint rowstride;
/* map src texture buffer */
- ctx->Driver.MapTextureImage(ctx, texImage, img,
- 0, 0, width, height, GL_MAP_READ_BIT,
- &srcMap, &rowstride);
+ ctx->Driver.MapTextureImage(ctx, texImage, zoffset + img,
+ xoffset, yoffset, width, height,
+ GL_MAP_READ_BIT, &srcMap, &rowstride);
if (srcMap) {
for (row = 0; row < height; row++) {
@@ -264,7 +264,7 @@ get_tex_ycbcr(struct gl_context *ctx, GLuint dimensions,
}
}
- ctx->Driver.UnmapTextureImage(ctx, texImage, img);
+ ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + img);
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
@@ -279,6 +279,8 @@ get_tex_ycbcr(struct gl_context *ctx, GLuint dimensions,
*/
static void
get_tex_rgba_compressed(struct gl_context *ctx, GLuint dimensions,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLint depth,
GLenum format, GLenum type, GLvoid *pixels,
struct gl_texture_image *texImage,
GLbitfield transferOps)
@@ -287,9 +289,6 @@ get_tex_rgba_compressed(struct gl_context *ctx, GLuint dimensions,
const mesa_format texFormat =
_mesa_get_srgb_format_linear(texImage->TexFormat);
const GLenum baseFormat = _mesa_get_format_base_format(texFormat);
- const GLuint width = texImage->Width;
- const GLuint height = texImage->Height;
- const GLuint depth = texImage->Depth;
GLfloat *tempImage, *tempSlice;
GLuint slice;
int srcStride, dstStride;
@@ -312,15 +311,15 @@ get_tex_rgba_compressed(struct gl_context *ctx, GLuint dimensions,
tempSlice = tempImage + slice * 4 * width * height;
- ctx->Driver.MapTextureImage(ctx, texImage, slice,
- 0, 0, width, height,
+ ctx->Driver.MapTextureImage(ctx, texImage, zoffset + slice,
+ xoffset, yoffset, width, height,
GL_MAP_READ_BIT,
&srcMap, &srcRowStride);
if (srcMap) {
_mesa_decompress_image(texFormat, width, height,
srcMap, srcRowStride, tempSlice);
- ctx->Driver.UnmapTextureImage(ctx, texImage, slice);
+ ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + slice);
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
@@ -409,6 +408,8 @@ _mesa_base_pack_format(GLenum format)
*/
static void
get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLint depth,
GLenum format, GLenum type, GLvoid *pixels,
struct gl_texture_image *texImage,
GLbitfield transferOps)
@@ -416,9 +417,6 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
/* don't want to apply sRGB -> RGB conversion here so override the format */
const mesa_format texFormat =
_mesa_get_srgb_format_linear(texImage->TexFormat);
- const GLuint width = texImage->Width;
- GLuint height = texImage->Height;
- GLuint depth = texImage->Depth;
GLuint img;
GLboolean dst_is_integer;
uint32_t dst_format;
@@ -430,6 +428,8 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
depth = height;
height = 1;
+ zoffset = yoffset;
+ yoffset = 0;
}
/* Depending on the base format involved we may need to apply a rebase
@@ -449,7 +449,8 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
rebaseSwizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
rebaseSwizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
rebaseSwizzle[3] = MESA_FORMAT_SWIZZLE_W;
- } else if (texImage->_BaseFormat != _mesa_get_format_base_format(texFormat)) {
+ } else if (texImage->_BaseFormat !=
+ _mesa_get_format_base_format(texFormat)) {
needsRebase =
_mesa_compute_rgba2base2rgba_component_mapping(texImage->_BaseFormat,
rebaseSwizzle);
@@ -480,8 +481,9 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
uint32_t src_format;
/* map src texture buffer */
- ctx->Driver.MapTextureImage(ctx, texImage, img,
- 0, 0, width, height, GL_MAP_READ_BIT,
+ ctx->Driver.MapTextureImage(ctx, texImage, zoffset + img,
+ xoffset, yoffset, width, height,
+ GL_MAP_READ_BIT,
&srcMap, &rowstride);
if (!srcMap) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
@@ -530,8 +532,8 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
/* If we had to rebase, we have already handled that */
needsRebase = false;
- /* If we were lucky and our RGBA conversion matches the dst format, then
- * we are done.
+ /* If we were lucky and our RGBA conversion matches the dst format,
+ * then we are done.
*/
if (!need_convert)
goto do_swap;
@@ -568,7 +570,7 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
}
/* Unmap the src texture buffer */
- ctx->Driver.UnmapTextureImage(ctx, texImage, img);
+ ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + img);
}
done:
@@ -583,6 +585,8 @@ done:
*/
static void
get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLint depth,
GLenum format, GLenum type, GLvoid *pixels,
struct gl_texture_image *texImage)
{
@@ -604,11 +608,17 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
}
if (_mesa_is_format_compressed(texImage->TexFormat)) {
- get_tex_rgba_compressed(ctx, dimensions, format, type,
+ get_tex_rgba_compressed(ctx, dimensions,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, type,
pixels, texImage, transferOps);
}
else {
- get_tex_rgba_uncompressed(ctx, dimensions, format, type,
+ get_tex_rgba_uncompressed(ctx, dimensions,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, type,
pixels, texImage, transferOps);
}
}
@@ -619,8 +629,10 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
* \return GL_TRUE if done, GL_FALSE otherwise
*/
static GLboolean
-get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type,
- GLvoid *pixels,
+get_tex_memcpy(struct gl_context *ctx,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLint depth,
+ GLenum format, GLenum type, GLvoid *pixels,
struct gl_texture_image *texImage)
{
const GLenum target = texImage->TexObject->Target;
@@ -642,20 +654,25 @@ get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type,
ctx->Pack.SwapBytes);
}
+ if (depth > 1) {
+ /* only a single slice is supported at this time */
+ memCopy = FALSE;
+ }
+
if (memCopy) {
const GLuint bpp = _mesa_get_format_bytes(texImage->TexFormat);
- const GLint bytesPerRow = texImage->Width * bpp;
+ const GLint bytesPerRow = width * bpp;
GLubyte *dst =
- _mesa_image_address2d(&ctx->Pack, pixels, texImage->Width,
- texImage->Height, format, type, 0, 0);
+ _mesa_image_address2d(&ctx->Pack, pixels, width, height,
+ format, type, 0, 0);
const GLint dstRowStride =
- _mesa_image_row_stride(&ctx->Pack, texImage->Width, format, type);
+ _mesa_image_row_stride(&ctx->Pack, width, format, type);
GLubyte *src;
GLint srcRowStride;
/* map src texture buffer */
- ctx->Driver.MapTextureImage(ctx, texImage, 0,
- 0, 0, texImage->Width, texImage->Height,
+ ctx->Driver.MapTextureImage(ctx, texImage, zoffset,
+ xoffset, yoffset, width, height,
GL_MAP_READ_BIT, &src, &srcRowStride);
if (src) {
@@ -664,7 +681,7 @@ get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type,
}
else {
GLuint row;
- for (row = 0; row < texImage->Height; row++) {
+ for (row = 0; row < height; row++) {
memcpy(dst, src, bytesPerRow);
dst += dstRowStride;
src += srcRowStride;
@@ -672,7 +689,7 @@ get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type,
}
/* unmap src texture buffer */
- ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
+ ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset);
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
@@ -684,15 +701,17 @@ get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type,
/**
- * This is the software fallback for Driver.GetTexImage().
+ * This is the software fallback for Driver.GetTexSubImage().
* All error checking will have been done before this routine is called.
* We'll call ctx->Driver.MapTextureImage() to access the data, then
* unmap with ctx->Driver.UnmapTextureImage().
*/
void
-_mesa_GetTexImage_sw(struct gl_context *ctx,
- GLenum format, GLenum type, GLvoid *pixels,
- struct gl_texture_image *texImage)
+_mesa_GetTexSubImage_sw(struct gl_context *ctx,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLint depth,
+ GLenum format, GLenum type, GLvoid *pixels,
+ struct gl_texture_image *texImage)
{
const GLuint dimensions =
_mesa_get_texture_dimensions(texImage->TexObject->Target);
@@ -720,23 +739,30 @@ _mesa_GetTexImage_sw(struct gl_context *ctx,
pixels = ADD_POINTERS(buf, pixels);
}
- if (get_tex_memcpy(ctx, format, type, pixels, texImage)) {
+ if (get_tex_memcpy(ctx, xoffset, yoffset, zoffset, width, height, depth,
+ format, type, pixels, texImage)) {
/* all done */
}
else if (format == GL_DEPTH_COMPONENT) {
- get_tex_depth(ctx, dimensions, format, type, pixels, texImage);
+ get_tex_depth(ctx, dimensions, xoffset, yoffset, zoffset,
+ width, height, depth, format, type, pixels, texImage);
}
else if (format == GL_DEPTH_STENCIL_EXT) {
- get_tex_depth_stencil(ctx, dimensions, format, type, pixels, texImage);
+ get_tex_depth_stencil(ctx, dimensions, xoffset, yoffset, zoffset,
+ width, height, depth, format, type, pixels,
+ texImage);
}
else if (format == GL_STENCIL_INDEX) {
- get_tex_stencil(ctx, dimensions, format, type, pixels, texImage);
+ get_tex_stencil(ctx, dimensions, xoffset, yoffset, zoffset,
+ width, height, depth, format, type, pixels, texImage);
}
else if (format == GL_YCBCR_MESA) {
- get_tex_ycbcr(ctx, dimensions, format, type, pixels, texImage);
+ get_tex_ycbcr(ctx, dimensions, xoffset, yoffset, zoffset,
+ width, height, depth, format, type, pixels, texImage);
}
else {
- get_tex_rgba(ctx, dimensions, format, type, pixels, texImage);
+ get_tex_rgba(ctx, dimensions, xoffset, yoffset, zoffset,
+ width, height, depth, format, type, pixels, texImage);
}
if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
@@ -747,13 +773,16 @@ _mesa_GetTexImage_sw(struct gl_context *ctx,
/**
- * This is the software fallback for Driver.GetCompressedTexImage().
+ * This is the software fallback for Driver.GetCompressedTexSubImage().
* All error checking will have been done before this routine is called.
*/
void
-_mesa_GetCompressedTexImage_sw(struct gl_context *ctx,
- struct gl_texture_image *texImage,
- GLvoid *img)
+_mesa_GetCompressedTexSubImage_sw(struct gl_context *ctx,
+ struct gl_texture_image *texImage,
+ GLint xoffset, GLint yoffset,
+ GLint zoffset, GLsizei width,
+ GLint height, GLint depth,
+ GLvoid *img)
{
const GLuint dimensions =
_mesa_get_texture_dimensions(texImage->TexObject->Target);
@@ -762,10 +791,8 @@ _mesa_GetCompressedTexImage_sw(struct gl_context *ctx,
GLubyte *dest;
_mesa_compute_compressed_pixelstore(dimensions, texImage->TexFormat,
- texImage->Width, texImage->Height,
- texImage->Depth,
- &ctx->Pack,
- &store);
+ width, height, depth,
+ &ctx->Pack, &store);
if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack texture image into a PBO */
@@ -791,8 +818,8 @@ _mesa_GetCompressedTexImage_sw(struct gl_context *ctx,
GLubyte *src;
/* map src texture buffer */
- ctx->Driver.MapTextureImage(ctx, texImage, slice,
- 0, 0, texImage->Width, texImage->Height,
+ ctx->Driver.MapTextureImage(ctx, texImage, zoffset + slice,
+ xoffset, yoffset, width, height,
GL_MAP_READ_BIT, &src, &srcRowStride);
if (src) {
@@ -803,10 +830,11 @@ _mesa_GetCompressedTexImage_sw(struct gl_context *ctx,
src += srcRowStride;
}
- ctx->Driver.UnmapTextureImage(ctx, texImage, slice);
+ ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + slice);
/* Advance to next slice */
- dest += store.TotalBytesPerRow * (store.TotalRowsPerSlice - store.CopyRowsPerSlice);
+ dest += store.TotalBytesPerRow * (store.TotalRowsPerSlice -
+ store.CopyRowsPerSlice);
} else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetCompresssedTexImage");
@@ -863,29 +891,299 @@ legal_getteximage_target(struct gl_context *ctx, GLenum target, bool dsa)
/**
- * Do error checking for a glGetTex(ture)Image() call.
- * \return GL_TRUE if any error, GL_FALSE if no errors.
+ * Wrapper for _mesa_select_tex_image() which can handle target being
+ * GL_TEXTURE_CUBE_MAP_ARB in which case we use zoffset to select a cube face.
+ * This can happen for glGetTextureImage and glGetTextureSubImage (DSA
+ * functions).
*/
-static GLboolean
+static struct gl_texture_image *
+select_tex_image(const struct gl_texture_object *texObj, GLenum target,
+ GLint level, GLint zoffset)
+{
+ assert(level >= 0);
+ assert(level < MAX_TEXTURE_LEVELS);
+ if (target == GL_TEXTURE_CUBE_MAP) {
+ assert(zoffset >= 0);
+ assert(zoffset < 6);
+ target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset;
+ }
+ return _mesa_select_tex_image(texObj, target, level);
+}
+
+
+/**
+ * Error-check the offset and size arguments to
+ * glGet[Compressed]TextureSubImage(). Also checks if the specified
+ * texture image is missing.
+ * \return true if error, false if no error.
+ */
+static bool
+dimensions_error_check(struct gl_context *ctx,
+ struct gl_texture_object *texObj,
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ const char *caller)
+{
+ const struct gl_texture_image *texImage;
+ int i;
+
+ if (xoffset < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(xoffset = %d)", caller, xoffset);
+ return true;
+ }
+
+ if (yoffset < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(yoffset = %d)", caller, yoffset);
+ return true;
+ }
+
+ if (zoffset < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(zoffset = %d)", caller, zoffset);
+ return true;
+ }
+
+ if (width < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(width = %d)", caller, width);
+ return true;
+ }
+
+ if (height < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(height = %d)", caller, height);
+ return true;
+ }
+
+ if (depth < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(depth = %d)", caller, depth);
+ return true;
+ }
+
+ /* do special per-target checks */
+ switch (target) {
+ case GL_TEXTURE_1D:
+ if (yoffset != 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(1D, yoffset = %d)", caller, yoffset);
+ return true;
+ }
+ if (height > 1) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(1D, height = %d)", caller, height);
+ return true;
+ }
+ /* fall-through */
+ case GL_TEXTURE_1D_ARRAY:
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_RECTANGLE:
+ if (zoffset != 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(zoffset = %d)", caller, zoffset);
+ return true;
+ }
+ if (depth > 1) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(depth = %d)", caller, depth);
+ return true;
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP:
+ /* Non-array cube maps are special because we have a gl_texture_image
+ * per face.
+ */
+ if (zoffset + depth > 6) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(zoffset + depth = %d)", caller, zoffset + depth);
+ return true;
+ }
+ /* check that the range of faces exist */
+ for (i = 0; i < depth; i++) {
+ GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset + i;
+ if (!_mesa_select_tex_image(texObj, face, level)) {
+ /* non-existant face */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(missing cube face)", caller);
+ return true;
+ }
+ }
+ break;
+ default:
+ ; /* nothing */
+ }
+
+ texImage = select_tex_image(texObj, target, level, zoffset);
+ if (!texImage) {
+ /* missing texture image */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(missing image)", caller);
+ return true;
+ }
+
+ if (xoffset + width > texImage->Width) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(xoffset %d + width %d > %u)",
+ caller, xoffset, width, texImage->Width);
+ return true;
+ }
+
+ if (yoffset + height > texImage->Height) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(yoffset %d + height %d > %u)",
+ caller, yoffset, height, texImage->Height);
+ return true;
+ }
+
+ if (target != GL_TEXTURE_CUBE_MAP) {
+ /* Cube map error checking was done above */
+ if (zoffset + depth > texImage->Depth) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(zoffset %d + depth %d > %u)",
+ caller, zoffset, depth, texImage->Depth);
+ return true;
+ }
+ }
+
+ /* Extra checks for compressed textures */
+ {
+ GLuint bw, bh;
+ _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
+ if (bw > 1 || bh > 1) {
+ /* offset must be multiple of block size */
+ if (xoffset % bw != 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(xoffset = %d)", caller, xoffset);
+ return true;
+ }
+ if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY) {
+ if (yoffset % bh != 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(yoffset = %d)", caller, yoffset);
+ return true;
+ }
+ }
+
+ /* The size must be a multiple of bw x bh, or we must be using a
+ * offset+size that exactly hits the edge of the image.
+ */
+ if ((width % bw != 0) &&
+ (xoffset + width != (GLint) texImage->Width)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(width = %d)", caller, width);
+ return true;
+ }
+
+ if ((height % bh != 0) &&
+ (yoffset + height != (GLint) texImage->Height)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(height = %d)", caller, height);
+ return true;
+ }
+ }
+ }
+
+ if (width == 0 || height == 0 || depth == 0) {
+ /* Not an error, but nothing to do. Return 'true' so that the
+ * caller simply returns.
+ */
+ return true;
+ }
+
+ return false;
+}
+
+
+/**
+ * Do PBO-related error checking for getting uncompressed images.
+ * \return true if there was an error (or the GetTexImage is to be a no-op)
+ */
+static bool
+pbo_error_check(struct gl_context *ctx, GLenum target,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, GLsizei clientMemSize,
+ GLvoid *pixels,
+ const char *caller)
+{
+ const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
+
+ if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, width, height, depth,
+ format, type, clientMemSize, pixels)) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(out of bounds PBO access)", caller);
+ } else {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(out of bounds access: bufSize (%d) is too small)",
+ caller, clientMemSize);
+ }
+ return true;
+ }
+
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
+ /* PBO should not be mapped */
+ if (_mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(PBO is mapped)", caller);
+ return true;
+ }
+ }
+
+ if (!_mesa_is_bufferobj(ctx->Pack.BufferObj) && !pixels) {
+ /* not an error, do nothing */
+ return true;
+ }
+
+ return false;
+}
+
+
+/**
+ * Do error checking for all (non-compressed) get-texture-image functions.
+ * \return true if any error, false if no errors.
+ */
+static bool
getteximage_error_check(struct gl_context *ctx,
- struct gl_texture_image *texImage,
+ struct gl_texture_object *texObj,
GLenum target, GLint level,
- GLenum format, GLenum type, GLsizei clientMemSize,
- GLvoid *pixels, bool dsa)
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, GLsizei bufSize,
+ GLvoid *pixels, const char *caller)
{
- const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
- const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
- GLenum baseFormat;
- const char *suffix = dsa ? "ture" : "";
+ struct gl_texture_image *texImage;
+ GLenum baseFormat, err;
+ GLint maxLevels;
- assert(texImage);
- assert(maxLevels != 0);
+ assert(texObj);
+
+ if (texObj->Target == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture)", caller);
+ return true;
+ }
+
+ maxLevels = _mesa_max_texture_levels(ctx, target);
if (level < 0 || level >= maxLevels) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glGetTex%sImage(level out of range)", suffix);
- return GL_TRUE;
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(level = %d)", caller, level);
+ return true;
}
+ err = _mesa_error_check_format_and_type(ctx, format, type);
+ if (err != GL_NO_ERROR) {
+ _mesa_error(ctx, err, "%s(format/type)", caller);
+ return true;
+ }
+
+ if (dimensions_error_check(ctx, texObj, target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth, caller)) {
+ return true;
+ }
+
+ if (pbo_error_check(ctx, target, width, height, depth,
+ format, type, bufSize, pixels, caller)) {
+ return true;
+ }
+
+ texImage = select_tex_image(texObj, target, level, zoffset);
+ assert(texImage);
+
/*
* Format and type checking has been moved up to GetnTexImage and
* GetTextureImage so that it happens before getting the texImage object.
@@ -899,494 +1197,579 @@ getteximage_error_check(struct gl_context *ctx,
if (_mesa_is_color_format(format)
&& !_mesa_is_color_format(baseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetTex%sImage(format mismatch)", suffix);
- return GL_TRUE;
+ "%s(format mismatch)", caller);
+ return true;
}
else if (_mesa_is_depth_format(format)
&& !_mesa_is_depth_format(baseFormat)
&& !_mesa_is_depthstencil_format(baseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetTex%sImage(format mismatch)", suffix);
- return GL_TRUE;
+ "%s(format mismatch)", caller);
+ return true;
}
else if (_mesa_is_stencil_format(format)
&& !ctx->Extensions.ARB_texture_stencil8) {
_mesa_error(ctx, GL_INVALID_ENUM,
- "glGetTex%sImage(format=GL_STENCIL_INDEX)", suffix);
- return GL_TRUE;
+ "%s(format=GL_STENCIL_INDEX)", caller);
+ return true;
}
else if (_mesa_is_ycbcr_format(format)
&& !_mesa_is_ycbcr_format(baseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetTex%sImage(format mismatch)", suffix);
- return GL_TRUE;
+ "%s(format mismatch)", caller);
+ return true;
}
else if (_mesa_is_depthstencil_format(format)
&& !_mesa_is_depthstencil_format(baseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetTex%sImage(format mismatch)", suffix);
- return GL_TRUE;
+ "%s(format mismatch)", caller);
+ return true;
}
- else if (!_mesa_is_stencil_format(format) && _mesa_is_enum_format_integer(format) !=
+ else if (!_mesa_is_stencil_format(format) &&
+ _mesa_is_enum_format_integer(format) !=
_mesa_is_format_integer(texImage->TexFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetTex%sImage(format mismatch)", suffix);
- return GL_TRUE;
+ "%s(format mismatch)", caller);
+ return true;
}
- if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width,
- texImage->Height, texImage->Depth,
- format, type, clientMemSize, pixels)) {
- if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetTex%sImage(out of bounds PBO access)", suffix);
- } else {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(out of bounds access:"
- " bufSize (%d) is too small)",
- dsa ? "glGetTextureImage" : "glGetnTexImageARB",
- clientMemSize);
- }
- return GL_TRUE;
+ return false;
+}
+
+
+/**
+ * Return the width, height and depth of a texture image.
+ * This function must be resilient to bad parameter values since
+ * this is called before full error checking.
+ */
+static void
+get_texture_image_dims(const struct gl_texture_object *texObj,
+ GLenum target, GLint level,
+ GLsizei *width, GLsizei *height, GLsizei *depth)
+{
+ const struct gl_texture_image *texImage = NULL;
+
+ if (level >= 0 && level < MAX_TEXTURE_LEVELS) {
+ texImage = _mesa_select_tex_image(texObj, target, level);
}
- if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
- /* PBO should not be mapped */
- if (_mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetTex%sImage(PBO is mapped)", suffix);
- return GL_TRUE;
+ if (texImage) {
+ *width = texImage->Width;
+ *height = texImage->Height;
+ if (target == GL_TEXTURE_CUBE_MAP) {
+ *depth = 6;
+ }
+ else {
+ *depth = texImage->Depth;
}
}
-
- return GL_FALSE;
+ else {
+ *width = *height = *depth = 0;
+ }
}
/**
- * This is the implementation for glGetnTexImageARB, glGetTextureImage,
- * and glGetTexImage.
- *
- * Requires caller to pass in texImage object because _mesa_GetTextureImage
- * must handle the GL_TEXTURE_CUBE_MAP target.
- *
- * \param target texture target.
+ * Common code for all (uncompressed) get-texture-image functions.
+ * \param texObj the texture object (should not be null)
+ * \param target user-provided target, or 0 for DSA
* \param level image level.
* \param format pixel data format for returned image.
* \param type pixel data type for returned image.
* \param bufSize size of the pixels data buffer.
* \param pixels returned pixel data.
- * \param dsa True when the caller is an ARB_direct_state_access function,
- * false otherwise
+ * \param caller name of calling function
*/
-void
-_mesa_get_texture_image(struct gl_context *ctx,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage, GLenum target,
- GLint level, GLenum format, GLenum type,
- GLsizei bufSize, GLvoid *pixels, bool dsa)
+static void
+get_texture_image(struct gl_context *ctx,
+ struct gl_texture_object *texObj,
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLint depth,
+ GLenum format, GLenum type,
+ GLvoid *pixels, const char *caller)
{
- assert(texObj);
- assert(texImage);
+ struct gl_texture_image *texImage;
+ unsigned firstFace, numFaces, i;
+ GLint imageStride;
FLUSH_VERTICES(ctx, 0);
- /*
- * Legal target checking has been moved up to GetnTexImage and
- * GetTextureImage so that it can be caught before receiving a NULL
- * texImage object and exiting.
- */
-
- if (getteximage_error_check(ctx, texImage, target, level, format,
- type, bufSize, pixels, dsa)) {
- return;
- }
+ texImage = select_tex_image(texObj, target, level, zoffset);
+ assert(texImage); /* should have been error checked already */
- if (!_mesa_is_bufferobj(ctx->Pack.BufferObj) && !pixels) {
- /* not an error, do nothing */
+ if (_mesa_is_zero_size_texture(texImage)) {
+ /* no image data to return */
return;
}
- if (_mesa_is_zero_size_texture(texImage))
- return;
-
if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) {
- _mesa_debug(ctx, "glGetTex%sImage(tex %u) format = %s, w=%d, h=%d,"
+ _mesa_debug(ctx, "%s(tex %u) format = %s, w=%d, h=%d,"
" dstFmt=0x%x, dstType=0x%x\n",
- dsa ? "ture": "",
- texObj->Name,
+ caller, texObj->Name,
_mesa_get_format_name(texImage->TexFormat),
texImage->Width, texImage->Height,
format, type);
}
+ if (target == GL_TEXTURE_CUBE_MAP) {
+ /* Compute stride between cube faces */
+ imageStride = _mesa_image_image_stride(&ctx->Pack, width, height,
+ format, type);
+ firstFace = zoffset;
+ numFaces = depth;
+ zoffset = 0;
+ depth = 1;
+ }
+ else {
+ imageStride = 0;
+ firstFace = _mesa_tex_target_to_face(target);
+ numFaces = 1;
+ }
+
_mesa_lock_texture(ctx, texObj);
- {
- ctx->Driver.GetTexImage(ctx, format, type, pixels, texImage);
+
+ for (i = 0; i < numFaces; i++) {
+ texImage = texObj->Image[firstFace + i][level];
+ assert(texImage);
+
+ ctx->Driver.GetTexSubImage(ctx, xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, type, pixels, texImage);
+
+ /* next cube face */
+ pixels = (GLubyte *) pixels + imageStride;
}
+
_mesa_unlock_texture(ctx, texObj);
}
-/**
- * Get texture image. Called by glGetTexImage.
- *
- * \param target texture target.
- * \param level image level.
- * \param format pixel data format for returned image.
- * \param type pixel data type for returned image.
- * \param bufSize size of the pixels data buffer.
- * \param pixels returned pixel data.
- */
+
void GLAPIENTRY
-_mesa_GetnTexImageARB(GLenum target, GLint level, GLenum format,
- GLenum type, GLsizei bufSize, GLvoid *pixels)
+_mesa_GetnTexImageARB(GLenum target, GLint level, GLenum format, GLenum type,
+ GLsizei bufSize, GLvoid *pixels)
{
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- GLenum err;
GET_CURRENT_CONTEXT(ctx);
+ static const char *caller = "glGetnTexImageARB";
+ GLsizei width, height, depth;
+ struct gl_texture_object *texObj;
- /*
- * This has been moved here because a format/type mismatch can cause a NULL
- * texImage object, which in turn causes the mismatch error to be
- * ignored.
- */
- err = _mesa_error_check_format_and_type(ctx, format, type);
- if (err != GL_NO_ERROR) {
- _mesa_error(ctx, err, "glGetnTexImage(format/type)");
- return;
- }
-
- /*
- * Legal target checking has been moved here to prevent exiting with a NULL
- * texImage object.
- */
if (!legal_getteximage_target(ctx, target, false)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetnTexImage(target=0x%x)",
- target);
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s", caller);
return;
}
texObj = _mesa_get_current_tex_object(ctx, target);
- if (!texObj)
- return;
+ assert(texObj);
+
+ get_texture_image_dims(texObj, target, level, &width, &height, &depth);
- texImage = _mesa_select_tex_image(texObj, target, level);
- if (!texImage)
+ if (getteximage_error_check(ctx, texObj, target, level,
+ 0, 0, 0, width, height, depth,
+ format, type, bufSize, pixels, caller)) {
return;
+ }
- _mesa_get_texture_image(ctx, texObj, texImage, target, level, format, type,
- bufSize, pixels, false);
+ get_texture_image(ctx, texObj, target, level,
+ 0, 0, 0, width, height, depth,
+ format, type, pixels, caller);
}
void GLAPIENTRY
-_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
- GLenum type, GLvoid *pixels )
+_mesa_GetTexImage(GLenum target, GLint level, GLenum format, GLenum type,
+ GLvoid *pixels )
{
- _mesa_GetnTexImageARB(target, level, format, type, INT_MAX, pixels);
+ GET_CURRENT_CONTEXT(ctx);
+ static const char *caller = "glGetTexImage";
+ GLsizei width, height, depth;
+ struct gl_texture_object *texObj;
+
+ if (!legal_getteximage_target(ctx, target, false)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s", caller);
+ return;
+ }
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
+ assert(texObj);
+
+ get_texture_image_dims(texObj, target, level, &width, &height, &depth);
+
+ if (getteximage_error_check(ctx, texObj, target, level,
+ 0, 0, 0, width, height, depth,
+ format, type, INT_MAX, pixels, caller)) {
+ return;
+ }
+
+ get_texture_image(ctx, texObj, target, level,
+ 0, 0, 0, width, height, depth,
+ format, type, pixels, caller);
}
-/**
- * Get texture image.
- *
- * \param texture texture name.
- * \param level image level.
- * \param format pixel data format for returned image.
- * \param type pixel data type for returned image.
- * \param bufSize size of the pixels data buffer.
- * \param pixels returned pixel data.
- */
+
void GLAPIENTRY
-_mesa_GetTextureImage(GLuint texture, GLint level, GLenum format,
- GLenum type, GLsizei bufSize, GLvoid *pixels)
+_mesa_GetTextureImage(GLuint texture, GLint level, GLenum format, GLenum type,
+ GLsizei bufSize, GLvoid *pixels)
{
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- int i;
- GLint image_stride;
- GLenum err;
GET_CURRENT_CONTEXT(ctx);
+ GLsizei width, height, depth;
+ static const char *caller = "glGetTextureImage";
+ struct gl_texture_object *texObj =
+ _mesa_lookup_texture_err(ctx, texture, caller);
- /*
- * This has been moved here because a format/type mismatch can cause a NULL
- * texImage object, which in turn causes the mismatch error to be
- * ignored.
- */
- err = _mesa_error_check_format_and_type(ctx, format, type);
- if (err != GL_NO_ERROR) {
- _mesa_error(ctx, err, "glGetTextureImage(format/type)");
+ if (!texObj) {
return;
}
- texObj = _mesa_lookup_texture_err(ctx, texture, "glGetTextureImage");
- if (!texObj)
- return;
+ get_texture_image_dims(texObj, texObj->Target, level,
+ &width, &height, &depth);
- /*
- * Legal target checking has been moved here to prevent exiting with a NULL
- * texImage object.
- */
- if (!legal_getteximage_target(ctx, texObj->Target, true)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTextureImage(target=%s)",
- _mesa_lookup_enum_by_nr(texObj->Target));
+ if (getteximage_error_check(ctx, texObj, texObj->Target, level,
+ 0, 0, 0, width, height, depth,
+ format, type, bufSize, pixels, caller)) {
return;
}
- /* Must handle special case GL_TEXTURE_CUBE_MAP. */
- if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
-
- /* Make sure the texture object is a proper cube.
- * (See texturesubimage in teximage.c for details on why this check is
- * performed.)
- */
- if (!_mesa_cube_level_complete(texObj, level)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetTextureImage(cube map incomplete)");
- return;
- }
+ get_texture_image(ctx, texObj, texObj->Target, level,
+ 0, 0, 0, width, height, depth,
+ format, type, pixels, caller);
+}
- /* Copy each face. */
- for (i = 0; i < 6; ++i) {
- texImage = texObj->Image[i][level];
- assert(texImage);
- _mesa_get_texture_image(ctx, texObj, texImage, texObj->Target, level,
- format, type, bufSize, pixels, true);
+void GLAPIENTRY
+_mesa_GetTextureSubImage(GLuint texture, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, GLsizei bufSize,
+ void *pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ static const char *caller = "glGetTextureSubImage";
+ struct gl_texture_object *texObj =
+ _mesa_lookup_texture_err(ctx, texture, caller);
- image_stride = _mesa_image_image_stride(&ctx->Pack, texImage->Width,
- texImage->Height, format,
- type);
- pixels = (GLubyte *) pixels + image_stride;
- bufSize -= image_stride;
- }
+ if (!texObj) {
+ return;
}
- else {
- texImage = _mesa_select_tex_image(texObj, texObj->Target, level);
- if (!texImage)
- return;
- _mesa_get_texture_image(ctx, texObj, texImage, texObj->Target, level,
- format, type, bufSize, pixels, true);
+ if (getteximage_error_check(ctx, texObj, texObj->Target, level,
+ xoffset, yoffset, zoffset, width, height, depth,
+ format, type, bufSize, pixels, caller)) {
+ return;
}
+
+ get_texture_image(ctx, texObj, texObj->Target, level,
+ xoffset, yoffset, zoffset, width, height, depth,
+ format, type, pixels, caller);
}
+
+
/**
- * Do error checking for a glGetCompressedTexImage() call.
- * \return GL_TRUE if any error, GL_FALSE if no errors.
+ * Compute the number of bytes which will be written when retrieving
+ * a sub-region of a compressed texture.
*/
-static GLboolean
+static GLsizei
+packed_compressed_size(GLuint dimensions, mesa_format format,
+ GLsizei width, GLsizei height, GLsizei depth,
+ const struct gl_pixelstore_attrib *packing)
+{
+ struct compressed_pixelstore st;
+ GLsizei totalBytes;
+
+ _mesa_compute_compressed_pixelstore(dimensions, format,
+ width, height, depth,
+ packing, &st);
+ totalBytes =
+ (st.CopySlices - 1) * st.TotalRowsPerSlice * st.TotalBytesPerRow +
+ st.SkipBytes +
+ (st.CopyRowsPerSlice - 1) * st.TotalBytesPerRow +
+ st.CopyBytesPerRow;
+
+ return totalBytes;
+}
+
+
+/**
+ * Do error checking for getting compressed texture images.
+ * \return true if any error, false if no errors.
+ */
+static bool
getcompressedteximage_error_check(struct gl_context *ctx,
- struct gl_texture_image *texImage,
- GLenum target,
- GLint level, GLsizei clientMemSize,
- GLvoid *img, bool dsa)
+ struct gl_texture_object *texObj,
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei bufSize, GLvoid *pixels,
+ const char *caller)
{
- const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
- GLuint compressedSize, dimensions;
- const char *suffix = dsa ? "ture" : "";
+ struct gl_texture_image *texImage;
+ GLint maxLevels;
+ GLsizei totalBytes;
+ GLuint dimensions;
- assert(texImage);
+ assert(texObj);
- if (!legal_getteximage_target(ctx, target, dsa)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetCompressedTex%sImage(target=%s)", suffix,
- _mesa_lookup_enum_by_nr(target));
- return GL_TRUE;
+ if (texObj->Target == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture)", caller);
+ return true;
}
- assert(maxLevels != 0);
+ maxLevels = _mesa_max_texture_levels(ctx, target);
if (level < 0 || level >= maxLevels) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glGetCompressedTex%sImage(bad level = %d)", suffix, level);
- return GL_TRUE;
+ "%s(bad level = %d)", caller, level);
+ return true;
+ }
+
+ if (dimensions_error_check(ctx, texObj, target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth, caller)) {
+ return true;
}
+ texImage = select_tex_image(texObj, target, level, zoffset);
+ assert(texImage);
+
if (!_mesa_is_format_compressed(texImage->TexFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetCompressedTex%sImage(texture is not compressed)",
- suffix);
- return GL_TRUE;
+ "%s(texture is not compressed)", caller);
+ return true;
}
- compressedSize = _mesa_format_image_size(texImage->TexFormat,
- texImage->Width,
- texImage->Height,
- texImage->Depth);
-
/* Check for invalid pixel storage modes */
- dimensions = _mesa_get_texture_dimensions(texImage->TexObject->Target);
+ dimensions = _mesa_get_texture_dimensions(texObj->Target);
if (!_mesa_compressed_pixel_storage_error_check(ctx, dimensions,
- &ctx->Pack, dsa ?
- "glGetCompressedTextureImage":
- "glGetCompressedTexImage")) {
- return GL_TRUE;
+ &ctx->Pack,
+ caller)) {
+ return true;
}
- if (!_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
- /* do bounds checking on writing to client memory */
- if (clientMemSize < (GLsizei) compressedSize) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(out of bounds access: bufSize (%d) is too small)",
- dsa ? "glGetCompressedTextureImage" :
- "glGetnCompressedTexImageARB", clientMemSize);
- return GL_TRUE;
- }
- } else {
+ /* Compute number of bytes that may be touched in the dest buffer */
+ totalBytes = packed_compressed_size(dimensions, texImage->TexFormat,
+ width, height, depth,
+ &ctx->Pack);
+
+ /* Do dest buffer bounds checking */
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* do bounds checking on PBO write */
- if ((const GLubyte *) img + compressedSize >
- (const GLubyte *) ctx->Pack.BufferObj->Size) {
+ if ((GLubyte *) pixels + totalBytes >
+ (GLubyte *) ctx->Pack.BufferObj->Size) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetCompressedTex%sImage(out of bounds PBO access)",
- suffix);
- return GL_TRUE;
+ "%s(out of bounds PBO access)", caller);
+ return true;
}
/* make sure PBO is not mapped */
if (_mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)", caller);
+ return true;
+ }
+ }
+ else {
+ /* do bounds checking on writing to client memory */
+ if (totalBytes > bufSize) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetCompressedTex%sImage(PBO is mapped)", suffix);
- return GL_TRUE;
+ "%s(out of bounds access: bufSize (%d) is too small)",
+ caller, bufSize);
+ return true;
}
}
- return GL_FALSE;
+ if (!_mesa_is_bufferobj(ctx->Pack.BufferObj) && !pixels) {
+ /* not an error, but do nothing */
+ return true;
+ }
+
+ return false;
}
-/** Implements glGetnCompressedTexImageARB, glGetCompressedTexImage, and
- * glGetCompressedTextureImage.
- *
- * texImage must be passed in because glGetCompressedTexImage must handle the
- * target GL_TEXTURE_CUBE_MAP.
+
+/**
+ * Common helper for all glGetCompressed-teximage functions.
*/
-void
-_mesa_get_compressed_texture_image(struct gl_context *ctx,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage,
- GLenum target, GLint level,
- GLsizei bufSize, GLvoid *pixels,
- bool dsa)
+static void
+get_compressed_texture_image(struct gl_context *ctx,
+ struct gl_texture_object *texObj,
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLint depth,
+ GLvoid *pixels,
+ const char *caller)
{
- assert(texObj);
- assert(texImage);
+ struct gl_texture_image *texImage;
+ unsigned firstFace, numFaces, i, imageStride;
FLUSH_VERTICES(ctx, 0);
- if (getcompressedteximage_error_check(ctx, texImage, target, level,
- bufSize, pixels, dsa)) {
- return;
- }
-
- if (!_mesa_is_bufferobj(ctx->Pack.BufferObj) && !pixels) {
- /* not an error, do nothing */
- return;
- }
+ texImage = select_tex_image(texObj, target, level, zoffset);
+ assert(texImage); /* should have been error checked already */
if (_mesa_is_zero_size_texture(texImage))
return;
if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) {
_mesa_debug(ctx,
- "glGetCompressedTex%sImage(tex %u) format = %s, w=%d, h=%d\n",
- dsa ? "ture" : "", texObj->Name,
+ "%s(tex %u) format = %s, w=%d, h=%d\n",
+ caller, texObj->Name,
_mesa_get_format_name(texImage->TexFormat),
texImage->Width, texImage->Height);
}
+ if (target == GL_TEXTURE_CUBE_MAP) {
+ struct compressed_pixelstore store;
+
+ /* Compute image stride between cube faces */
+ _mesa_compute_compressed_pixelstore(2, texImage->TexFormat,
+ width, height, depth,
+ &ctx->Pack, &store);
+ imageStride = store.TotalBytesPerRow * store.TotalRowsPerSlice;
+
+ firstFace = zoffset;
+ numFaces = depth;
+ zoffset = 0;
+ depth = 1;
+ }
+ else {
+ imageStride = 0;
+ firstFace = _mesa_tex_target_to_face(target);
+ numFaces = 1;
+ }
+
_mesa_lock_texture(ctx, texObj);
- {
- ctx->Driver.GetCompressedTexImage(ctx, texImage, pixels);
+
+ for (i = 0; i < numFaces; i++) {
+ texImage = texObj->Image[firstFace + i][level];
+ assert(texImage);
+
+ ctx->Driver.GetCompressedTexSubImage(ctx, texImage,
+ xoffset, yoffset, zoffset,
+ width, height, depth, pixels);
+
+ /* next cube face */
+ pixels = (GLubyte *) pixels + imageStride;
}
+
_mesa_unlock_texture(ctx, texObj);
}
+
void GLAPIENTRY
_mesa_GetnCompressedTexImageARB(GLenum target, GLint level, GLsizei bufSize,
- GLvoid *img)
+ GLvoid *pixels)
{
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
GET_CURRENT_CONTEXT(ctx);
+ static const char *caller = "glGetnCompressedTexImageARB";
+ GLsizei width, height, depth;
+ struct gl_texture_object *texObj;
- texObj = _mesa_get_current_tex_object(ctx, target);
- if (!texObj)
+ if (!legal_getteximage_target(ctx, target, false)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s", caller);
return;
+ }
- texImage = _mesa_select_tex_image(texObj, target, level);
- if (!texImage)
+ texObj = _mesa_get_current_tex_object(ctx, target);
+ assert(texObj);
+
+ get_texture_image_dims(texObj, target, level, &width, &height, &depth);
+
+ if (getcompressedteximage_error_check(ctx, texObj, target, level,
+ 0, 0, 0, width, height, depth,
+ INT_MAX, pixels, caller)) {
return;
+ }
- _mesa_get_compressed_texture_image(ctx, texObj, texImage, target, level,
- bufSize, img, false);
+ get_compressed_texture_image(ctx, texObj, target, level,
+ 0, 0, 0, width, height, depth,
+ pixels, caller);
}
+
void GLAPIENTRY
-_mesa_GetCompressedTexImage(GLenum target, GLint level, GLvoid *img)
+_mesa_GetCompressedTexImage(GLenum target, GLint level, GLvoid *pixels)
{
- _mesa_GetnCompressedTexImageARB(target, level, INT_MAX, img);
+ GET_CURRENT_CONTEXT(ctx);
+ static const char *caller = "glGetCompressedTexImage";
+ GLsizei width, height, depth;
+ struct gl_texture_object *texObj;
+
+ if (!legal_getteximage_target(ctx, target, false)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s", caller);
+ return;
+ }
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
+ assert(texObj);
+
+ get_texture_image_dims(texObj, target, level,
+ &width, &height, &depth);
+
+ if (getcompressedteximage_error_check(ctx, texObj, target, level,
+ 0, 0, 0, width, height, depth,
+ INT_MAX, pixels, caller)) {
+ return;
+ }
+
+ get_compressed_texture_image(ctx, texObj, target, level,
+ 0, 0, 0, width, height, depth,
+ pixels, caller);
}
-/**
- * Get compressed texture image.
- *
- * \param texture texture name.
- * \param level image level.
- * \param bufSize size of the pixels data buffer.
- * \param pixels returned pixel data.
- */
+
void GLAPIENTRY
_mesa_GetCompressedTextureImage(GLuint texture, GLint level,
GLsizei bufSize, GLvoid *pixels)
{
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- int i;
- GLint image_stride;
GET_CURRENT_CONTEXT(ctx);
+ static const char *caller = "glGetCompressedTextureImage";
+ GLsizei width, height, depth;
+ struct gl_texture_object *texObj =
+ _mesa_lookup_texture_err(ctx, texture, caller);
- texObj = _mesa_lookup_texture_err(ctx, texture,
- "glGetCompressedTextureImage");
- if (!texObj)
+ if (!texObj) {
return;
+ }
- /* Must handle special case GL_TEXTURE_CUBE_MAP. */
- if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
+ get_texture_image_dims(texObj, texObj->Target, level,
+ &width, &height, &depth);
- /* Make sure the texture object is a proper cube.
- * (See texturesubimage in teximage.c for details on why this check is
- * performed.)
- */
- if (!_mesa_cube_level_complete(texObj, level)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetCompressedTextureImage(cube map incomplete)");
- return;
- }
+ if (getcompressedteximage_error_check(ctx, texObj, texObj->Target, level,
+ 0, 0, 0, width, height, depth,
+ bufSize, pixels, caller)) {
+ return;
+ }
- /* Copy each face. */
- for (i = 0; i < 6; ++i) {
- texImage = texObj->Image[i][level];
- assert(texImage);
+ get_compressed_texture_image(ctx, texObj, texObj->Target, level,
+ 0, 0, 0, width, height, depth,
+ pixels, caller);
+}
- _mesa_get_compressed_texture_image(ctx, texObj, texImage,
- texObj->Target, level,
- bufSize, pixels, true);
- /* Compressed images don't have a client format */
- image_stride = _mesa_format_image_size(texImage->TexFormat,
- texImage->Width,
- texImage->Height, 1);
+void APIENTRY
+_mesa_GetCompressedTextureSubImage(GLuint texture, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint zoffset, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLsizei bufSize, void *pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ static const char *caller = "glGetCompressedTextureImage";
+ struct gl_texture_object *texObj;
- pixels = (GLubyte *) pixels + image_stride;
- bufSize -= image_stride;
- }
+ texObj = _mesa_lookup_texture_err(ctx, texture, caller);
+ if (!texObj) {
+ return;
}
- else {
- texImage = _mesa_select_tex_image(texObj, texObj->Target, level);
- if (!texImage)
- return;
- _mesa_get_compressed_texture_image(ctx, texObj, texImage,
- texObj->Target, level, bufSize,
- pixels, true);
+ if (getcompressedteximage_error_check(ctx, texObj, texObj->Target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ bufSize, pixels, caller)) {
+ return;
}
+
+ get_compressed_texture_image(ctx, texObj, texObj->Target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ pixels, caller);
}
diff --git a/src/mesa/main/texgetimage.h b/src/mesa/main/texgetimage.h
index 1fa2f59dcdc..63c75eb931d 100644
--- a/src/mesa/main/texgetimage.h
+++ b/src/mesa/main/texgetimage.h
@@ -37,22 +37,19 @@ extern GLenum
_mesa_base_pack_format(GLenum format);
extern void
-_mesa_GetTexImage_sw(struct gl_context *ctx,
- GLenum format, GLenum type, GLvoid *pixels,
- struct gl_texture_image *texImage);
-
-
-extern void
-_mesa_GetCompressedTexImage_sw(struct gl_context *ctx,
- struct gl_texture_image *texImage,
- GLvoid *data);
+_mesa_GetTexSubImage_sw(struct gl_context *ctx,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLint depth,
+ GLenum format, GLenum type, GLvoid *pixels,
+ struct gl_texture_image *texImage);
extern void
-_mesa_get_texture_image(struct gl_context *ctx,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage, GLenum target,
- GLint level, GLenum format, GLenum type,
- GLsizei bufSize, GLvoid *pixels, bool dsa);
+_mesa_GetCompressedTexSubImage_sw(struct gl_context *ctx,
+ struct gl_texture_image *texImage,
+ GLint xoffset, GLint yoffset,
+ GLint zoffset, GLsizei width,
+ GLint height, GLint depth,
+ GLvoid *data);
extern void
_mesa_get_compressed_texture_image( struct gl_context *ctx,
@@ -74,6 +71,14 @@ _mesa_GetTextureImage(GLuint texture, GLint level, GLenum format,
GLenum type, GLsizei bufSize, GLvoid *pixels);
extern void GLAPIENTRY
+_mesa_GetTextureSubImage(GLuint texture, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, GLsizei bufSize,
+ void *pixels);
+
+
+extern void GLAPIENTRY
_mesa_GetCompressedTexImage(GLenum target, GLint lod, GLvoid *img);
extern void GLAPIENTRY
@@ -84,4 +89,11 @@ extern void GLAPIENTRY
_mesa_GetCompressedTextureImage(GLuint texture, GLint level, GLsizei bufSize,
GLvoid *pixels);
+extern void APIENTRY
+_mesa_GetCompressedTextureSubImage(GLuint texture, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint zoffset, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLsizei bufSize, void *pixels);
+
#endif /* TEXGETIMAGE_H */
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 3d85615fa45..3a556a6ad6e 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -1008,7 +1008,7 @@ _mesa_max_texture_levels(struct gl_context *ctx, GLenum target)
case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
- return _mesa_is_desktop_gl(ctx)
+ return (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx))
&& ctx->Extensions.ARB_texture_multisample
? 1 : 0;
case GL_TEXTURE_EXTERNAL_OES:
@@ -1793,8 +1793,6 @@ GLboolean
_mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target,
GLenum intFormat)
{
- (void) intFormat; /* not used yet */
-
switch (target) {
case GL_TEXTURE_2D:
case GL_PROXY_TEXTURE_2D:
@@ -1814,6 +1812,16 @@ _mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target,
case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
case GL_TEXTURE_CUBE_MAP_ARRAY:
return ctx->Extensions.ARB_texture_cube_map_array;
+ 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;
+ }
default:
return GL_FALSE;
}
@@ -2081,6 +2089,53 @@ texture_formats_agree(GLenum internalFormat,
}
/**
+ * Test the combination of format, type and internal format arguments of
+ * different texture operations on GLES.
+ *
+ * \param ctx GL context.
+ * \param format pixel data format given by the user.
+ * \param type pixel data type given by the user.
+ * \param internalFormat internal format given by the user.
+ * \param dimensions texture image dimensions (must be 1, 2 or 3).
+ * \param callerName name of the caller function to print in the error message
+ *
+ * \return true if a error is found, false otherwise
+ *
+ * Currently, it is used by texture_error_check() and texsubimage_error_check().
+ */
+static bool
+texture_format_error_check_gles(struct gl_context *ctx, GLenum format,
+ GLenum type, GLenum internalFormat,
+ GLuint dimensions, const char *callerName)
+{
+ GLenum err;
+
+ if (_mesa_is_gles3(ctx)) {
+ err = _mesa_es3_error_check_format_and_type(ctx, format, type,
+ internalFormat);
+ if (err != GL_NO_ERROR) {
+ _mesa_error(ctx, err,
+ "%s(format = %s, type = %s, internalformat = %s)",
+ callerName, _mesa_enum_to_string(format),
+ _mesa_enum_to_string(type),
+ _mesa_enum_to_string(internalFormat));
+ return true;
+ }
+ }
+ else {
+ err = _mesa_es_error_check_format_and_type(format, type, dimensions);
+ if (err != GL_NO_ERROR) {
+ _mesa_error(ctx, err, "%s(format = %s, type = %s)",
+ callerName, _mesa_enum_to_string(format),
+ _mesa_enum_to_string(type));
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
* Test the glTexImage[123]D() parameters for errors.
*
* \param ctx GL context.
@@ -2151,39 +2206,17 @@ texture_error_check( struct gl_context *ctx,
* Formats and types that require additional extensions (e.g., GL_FLOAT
* requires GL_OES_texture_float) are filtered elsewhere.
*/
-
- if (_mesa_is_gles(ctx)) {
- if (_mesa_is_gles3(ctx)) {
- err = _mesa_es3_error_check_format_and_type(ctx, format, type,
- internalFormat);
- } else {
- if (format != internalFormat) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexImage%dD(format = %s, internalFormat = %s)",
- dimensions,
- _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(internalFormat));
- return GL_TRUE;
- }
-
- err = _mesa_es_error_check_format_and_type(format, type, dimensions);
- }
- if (err != GL_NO_ERROR) {
- _mesa_error(ctx, err,
- "glTexImage%dD(format = %s, type = %s, internalFormat = %s)",
- dimensions,
- _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type),
- _mesa_lookup_enum_by_nr(internalFormat));
- return GL_TRUE;
- }
+ if (_mesa_is_gles(ctx) &&
+ texture_format_error_check_gles(ctx, format, type, internalFormat,
+ dimensions, "glTexImage%dD")) {
+ return GL_TRUE;
}
/* Check internalFormat */
if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glTexImage%dD(internalFormat=%s)",
- dimensions, _mesa_lookup_enum_by_nr(internalFormat));
+ dimensions, _mesa_enum_to_string(internalFormat));
return GL_TRUE;
}
@@ -2192,8 +2225,8 @@ texture_error_check( struct gl_context *ctx,
if (err != GL_NO_ERROR) {
_mesa_error(ctx, err,
"glTexImage%dD(incompatible format = %s, type = %s)",
- dimensions, _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type));
+ dimensions, _mesa_enum_to_string(format),
+ _mesa_enum_to_string(type));
return GL_TRUE;
}
@@ -2208,8 +2241,8 @@ texture_error_check( struct gl_context *ctx,
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),
- _mesa_lookup_enum_by_nr(format));
+ dimensions, _mesa_enum_to_string(internalFormat),
+ _mesa_enum_to_string(format));
return GL_TRUE;
}
@@ -2324,7 +2357,7 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
if (!_mesa_is_compressed_format(ctx, internalFormat)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glCompressedTexImage%dD(internalFormat=%s)",
- dimensions, _mesa_lookup_enum_by_nr(internalFormat));
+ dimensions, _mesa_enum_to_string(internalFormat));
return GL_TRUE;
}
@@ -2479,40 +2512,38 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
return GL_TRUE;
}
- /* check target (proxies not allowed) */
- if (!legal_texsubimage_target(ctx, dimensions, target, dsa)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "%s(target=%s)",
- callerName, _mesa_lookup_enum_by_nr(target));
- return GL_TRUE;
- }
-
/* level check */
if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
_mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", callerName, level);
return GL_TRUE;
}
- /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
- * combinations of format and type that can be used. Formats and types
- * that require additional extensions (e.g., GL_FLOAT requires
- * GL_OES_texture_float) are filtered elsewhere.
- */
- if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) {
- err = _mesa_es_error_check_format_and_type(format, type, dimensions);
- if (err != GL_NO_ERROR) {
- _mesa_error(ctx, err, "%s(format = %s, type = %s)",
- callerName, _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type));
- return GL_TRUE;
- }
+ texImage = _mesa_select_tex_image(texObj, target, level);
+ if (!texImage) {
+ /* non-existant texture level */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture image)",
+ callerName);
+ return GL_TRUE;
}
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)",
- callerName, _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type));
+ callerName, _mesa_enum_to_string(format),
+ _mesa_enum_to_string(type));
+ return GL_TRUE;
+ }
+
+ /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
+ * combinations of format, internalFormat, and type that can be used.
+ * Formats and types that require additional extensions (e.g., GL_FLOAT
+ * requires GL_OES_texture_float) are filtered elsewhere.
+ */
+ if (_mesa_is_gles(ctx) &&
+ texture_format_error_check_gles(ctx, format, type,
+ texImage->InternalFormat,
+ dimensions, callerName)) {
return GL_TRUE;
}
@@ -2523,14 +2554,6 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
return GL_TRUE;
}
- texImage = _mesa_select_tex_image(texObj, target, level);
- if (!texImage) {
- /* non-existant texture level */
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture image)",
- callerName);
- return GL_TRUE;
- }
-
if (error_check_subtexture_dimensions(ctx, dimensions,
texImage, xoffset, yoffset, zoffset,
width, height, depth, callerName)) {
@@ -2590,7 +2613,7 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
/* check target */
if (!legal_texsubimage_target(ctx, dimensions, target, false)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)",
- dimensions, _mesa_lookup_enum_by_nr(target));
+ dimensions, _mesa_enum_to_string(target));
return GL_TRUE;
}
@@ -2629,13 +2652,6 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
return GL_TRUE;
}
- rb = _mesa_get_read_renderbuffer_for_format(ctx, internalFormat);
- if (rb == NULL) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glCopyTexImage%dD(read buffer)", dimensions);
- return GL_TRUE;
- }
-
/* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
* internalFormat.
*/
@@ -2648,18 +2664,25 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
case GL_LUMINANCE_ALPHA:
break;
default:
- _mesa_error(ctx, GL_INVALID_VALUE,
+ _mesa_error(ctx, GL_INVALID_ENUM,
"glCopyTexImage%dD(internalFormat=%s)", dimensions,
- _mesa_lookup_enum_by_nr(internalFormat));
+ _mesa_enum_to_string(internalFormat));
return GL_TRUE;
}
}
baseFormat = _mesa_base_tex_format(ctx, internalFormat);
if (baseFormat < 0) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
+ _mesa_error(ctx, GL_INVALID_ENUM,
"glCopyTexImage%dD(internalFormat=%s)", dimensions,
- _mesa_lookup_enum_by_nr(internalFormat));
+ _mesa_enum_to_string(internalFormat));
+ return GL_TRUE;
+ }
+
+ rb = _mesa_get_read_renderbuffer_for_format(ctx, internalFormat);
+ if (rb == NULL) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexImage%dD(read buffer)", dimensions);
return GL_TRUE;
}
@@ -2669,7 +2692,7 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
if (rb_base_format < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glCopyTexImage%dD(internalFormat=%s)", dimensions,
- _mesa_lookup_enum_by_nr(internalFormat));
+ _mesa_enum_to_string(internalFormat));
return GL_TRUE;
}
}
@@ -2696,7 +2719,7 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
if (!valid) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyTexImage%dD(internalFormat=%s)", dimensions,
- _mesa_lookup_enum_by_nr(internalFormat));
+ _mesa_enum_to_string(internalFormat));
return GL_TRUE;
}
}
@@ -2735,10 +2758,10 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
* types for SNORM formats. Also, conversion to SNORM formats is not
* allowed by Table 3.2 on Page 110.
*/
- if(_mesa_is_enum_format_snorm(internalFormat)) {
+ if (_mesa_is_enum_format_snorm(internalFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyTexImage%dD(internalFormat=%s)", dimensions,
- _mesa_lookup_enum_by_nr(internalFormat));
+ _mesa_enum_to_string(internalFormat));
return GL_TRUE;
}
}
@@ -3103,8 +3126,8 @@ _mesa_choose_texture_format(struct gl_context *ctx,
"DXT compression requested (%s), "
"but libtxc_dxtn library not installed. Using %s "
"instead.",
- _mesa_lookup_enum_by_nr(before),
- _mesa_lookup_enum_by_nr(internalFormat));
+ _mesa_enum_to_string(before),
+ _mesa_enum_to_string(internalFormat));
}
}
@@ -3191,18 +3214,18 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
_mesa_debug(ctx,
"glCompressedTexImage%uD %s %d %s %d %d %d %d %p\n",
dims,
- _mesa_lookup_enum_by_nr(target), level,
- _mesa_lookup_enum_by_nr(internalFormat),
+ _mesa_enum_to_string(target), level,
+ _mesa_enum_to_string(internalFormat),
width, height, depth, border, pixels);
else
_mesa_debug(ctx,
"glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n",
dims,
- _mesa_lookup_enum_by_nr(target), level,
- _mesa_lookup_enum_by_nr(internalFormat),
+ _mesa_enum_to_string(target), level,
+ _mesa_enum_to_string(internalFormat),
width, height, depth, border,
- _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type), pixels);
+ _mesa_enum_to_string(format),
+ _mesa_enum_to_string(type), pixels);
}
internalFormat = override_internal_format(internalFormat, width, height);
@@ -3210,7 +3233,7 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
/* target error checking */
if (!legal_teximage_target(ctx, dims, target)) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s%uD(target=%s)",
- func, dims, _mesa_lookup_enum_by_nr(target));
+ func, dims, _mesa_enum_to_string(target));
return;
}
@@ -3313,16 +3336,16 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
if (!dimensionsOK) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage%uD(invalid width or height or depth)",
- dims);
+ "%s%uD(invalid width or height or depth)",
+ func, dims);
return;
}
if (!sizeOK) {
_mesa_error(ctx, GL_OUT_OF_MEMORY,
- "glTexImage%uD(image too large: %d x %d x %d, %s format)",
- dims, width, height, depth,
- _mesa_lookup_enum_by_nr(internalFormat));
+ "%s%uD(image too large: %d x %d x %d, %s format)",
+ func, dims, width, height, depth,
+ _mesa_enum_to_string(internalFormat));
return;
}
@@ -3495,7 +3518,6 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image)
_mesa_dirty_texobj(ctx, texObj);
}
_mesa_unlock_texture(ctx, texObj);
-
}
@@ -3515,14 +3537,6 @@ _mesa_texture_sub_image(struct gl_context *ctx, GLuint dims,
{
FLUSH_VERTICES(ctx, 0);
- /* check target (proxies not allowed) */
- if (!legal_texsubimage_target(ctx, dims, target, dsa)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sSubImage%uD(target=%s)",
- dsa ? "ture" : "",
- dims, _mesa_lookup_enum_by_nr(target));
- return;
- }
-
if (ctx->NewState & _NEW_PIXEL)
_mesa_update_state(ctx);
@@ -3572,6 +3586,13 @@ texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
+ /* check target (proxies not allowed) */
+ if (!legal_texsubimage_target(ctx, dims, target, false)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)",
+ dims, _mesa_enum_to_string(target));
+ return;
+ }
+
texObj = _mesa_get_current_tex_object(ctx, target);
if (!texObj)
return;
@@ -3589,10 +3610,10 @@ texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
_mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n",
dims,
- _mesa_lookup_enum_by_nr(target), level,
+ _mesa_enum_to_string(target), level,
xoffset, yoffset, zoffset, width, height, depth,
- _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type), pixels);
+ _mesa_enum_to_string(format),
+ _mesa_enum_to_string(type), pixels);
_mesa_texture_sub_image(ctx, dims, texObj, texImage, target, level,
xoffset, yoffset, zoffset, width, height, depth,
@@ -3621,8 +3642,8 @@ texturesubimage(struct gl_context *ctx, GLuint dims,
"glTextureSubImage%uD %d %d %d %d %d %d %d %d %s %s %p\n",
dims, texture, level,
xoffset, yoffset, zoffset, width, height, depth,
- _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type), pixels);
+ _mesa_enum_to_string(format),
+ _mesa_enum_to_string(type), pixels);
/* Get the texture object by Name. */
texObj = _mesa_lookup_texture(ctx, texture);
@@ -3632,6 +3653,13 @@ texturesubimage(struct gl_context *ctx, GLuint dims,
return;
}
+ /* check target (proxies not allowed) */
+ if (!legal_texsubimage_target(ctx, dims, texObj->Target, true)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(target=%s)",
+ callerName, _mesa_enum_to_string(texObj->Target));
+ return;
+ }
+
if (texsubimage_error_check(ctx, dims, texObj, texObj->Target, level,
xoffset, yoffset, zoffset,
width, height, depth, format, type,
@@ -3842,8 +3870,7 @@ copytexsubimage_by_slice(struct gl_context *ctx,
}
static GLboolean
-formats_differ_in_component_sizes (mesa_format f1,
- mesa_format f2)
+formats_differ_in_component_sizes(mesa_format f1, mesa_format f2)
{
GLint f1_r_bits = _mesa_get_format_bits(f1, GL_RED_BITS);
GLint f1_g_bits = _mesa_get_format_bits(f1, GL_GREEN_BITS);
@@ -3883,8 +3910,8 @@ copyteximage(struct gl_context *ctx, GLuint dims,
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
_mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n",
dims,
- _mesa_lookup_enum_by_nr(target), level,
- _mesa_lookup_enum_by_nr(internalFormat),
+ _mesa_enum_to_string(target), level,
+ _mesa_enum_to_string(internalFormat),
x, y, width, height, border);
if (ctx->NewState & NEW_COPY_TEX_STATE)
@@ -3916,8 +3943,8 @@ copyteximage(struct gl_context *ctx, GLuint dims,
*/
if (rb->InternalFormat == GL_RGB10_A2) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glCopyTexImage%uD(Reading from GL_RGB10_A2 buffer and"
- " writing to unsized internal format)", dims);
+ "glCopyTexImage%uD(Reading from GL_RGB10_A2 buffer"
+ " and writing to unsized internal format)", dims);
return;
}
}
@@ -4043,7 +4070,7 @@ _mesa_copy_texture_sub_image(struct gl_context *ctx, GLuint dims,
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
_mesa_debug(ctx, "%s %s %d %d %d %d %d %d %d %d\n", caller,
- _mesa_lookup_enum_by_nr(target),
+ _mesa_enum_to_string(target),
level, xoffset, yoffset, zoffset, x, y, width, height);
if (ctx->NewState & NEW_COPY_TEX_STATE)
@@ -4105,7 +4132,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
*/
if (!legal_texsubimage_target(ctx, 1, target, false)) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
@@ -4133,7 +4160,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
*/
if (!legal_texsubimage_target(ctx, 2, target, false)) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
@@ -4162,7 +4189,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
*/
if (!legal_texsubimage_target(ctx, 3, target, false)) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
@@ -4190,7 +4217,7 @@ _mesa_CopyTextureSubImage1D(GLuint texture, GLint level,
/* Check target (proxies not allowed). */
if (!legal_texsubimage_target(ctx, 1, texObj->Target, true)) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
- _mesa_lookup_enum_by_nr(texObj->Target));
+ _mesa_enum_to_string(texObj->Target));
return;
}
@@ -4214,7 +4241,7 @@ _mesa_CopyTextureSubImage2D(GLuint texture, GLint level,
/* Check target (proxies not allowed). */
if (!legal_texsubimage_target(ctx, 2, texObj->Target, true)) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
- _mesa_lookup_enum_by_nr(texObj->Target));
+ _mesa_enum_to_string(texObj->Target));
return;
}
@@ -4241,7 +4268,7 @@ _mesa_CopyTextureSubImage3D(GLuint texture, GLint level,
/* Check target (proxies not allowed). */
if (!legal_texsubimage_target(ctx, 3, texObj->Target, true)) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
- _mesa_lookup_enum_by_nr(texObj->Target));
+ _mesa_enum_to_string(texObj->Target));
return;
}
@@ -4288,8 +4315,8 @@ check_clear_tex_image(struct gl_context *ctx,
_mesa_error(ctx, err,
"%s(incompatible format = %s, type = %s)",
function,
- _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type));
+ _mesa_enum_to_string(format),
+ _mesa_enum_to_string(type));
return false;
}
@@ -4298,8 +4325,8 @@ check_clear_tex_image(struct gl_context *ctx,
_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));
+ _mesa_enum_to_string(internalFormat),
+ _mesa_enum_to_string(format));
return false;
}
@@ -4541,7 +4568,7 @@ compressed_subtexture_target_check(struct gl_context *ctx, GLenum target,
if (dsa && target == GL_TEXTURE_RECTANGLE) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", caller,
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return GL_TRUE;
}
@@ -4549,13 +4576,15 @@ compressed_subtexture_target_check(struct gl_context *ctx, GLenum target,
case 2:
switch (target) {
case GL_TEXTURE_2D:
+ targetOK = GL_TRUE;
+ break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- targetOK = GL_TRUE;
+ targetOK = ctx->Extensions.ARB_texture_cube_map;
break;
default:
targetOK = GL_FALSE;
@@ -4563,52 +4592,59 @@ compressed_subtexture_target_check(struct gl_context *ctx, GLenum target,
}
break;
case 3:
- targetOK = (target == GL_TEXTURE_3D) ||
- (target == GL_TEXTURE_2D_ARRAY) ||
- (target == GL_TEXTURE_CUBE_MAP_ARRAY) ||
- (target == GL_TEXTURE_CUBE_MAP && dsa);
-
- /* OpenGL 4.5 spec (30.10.2014) says in Section 8.7 Compressed Texture
- * Images:
- * "An INVALID_OPERATION error is generated by
- * CompressedTex*SubImage3D if the internal format of the texture is
- * one of the EAC, ETC2, or RGTC formats and either border is
- * non-zero, or the effective target for the texture is not
- * TEXTURE_2D_ARRAY."
- */
- if (target != GL_TEXTURE_2D_ARRAY) {
- bool invalidformat;
+ switch (target) {
+ case GL_TEXTURE_CUBE_MAP:
+ targetOK = dsa && ctx->Extensions.ARB_texture_cube_map;
+ break;
+ case GL_TEXTURE_2D_ARRAY:
+ targetOK = _mesa_is_gles3(ctx) ||
+ (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array);
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ targetOK = ctx->Extensions.ARB_texture_cube_map_array;
+ break;
+ case GL_TEXTURE_3D:
+ targetOK = GL_TRUE;
+ /*
+ * OpenGL 4.5 spec (30.10.2014) says in Section 8.7 Compressed Texture
+ * Images:
+ * "An INVALID_OPERATION error is generated by
+ * CompressedTex*SubImage3D if the internal format of the texture
+ * is one of the EAC, ETC2, or RGTC formats and either border is
+ * non-zero, or the effective target for the texture is not
+ * TEXTURE_2D_ARRAY."
+ *
+ * NOTE: that's probably a spec error. It should probably say
+ * "... or the effective target for the texture is not
+ * TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP, nor
+ * GL_TEXTURE_CUBE_MAP_ARRAY."
+ * since those targets are 2D images and they support all compression
+ * formats.
+ *
+ * Instead of listing all these, just list those which are allowed,
+ * which is (at this time) only bptc. Otherwise we'd say s3tc (and
+ * more) are valid here, which they are not, but of course not
+ * mentioned by core spec.
+ */
switch (format) {
- /* These came from _mesa_is_compressed_format in glformats.c. */
- /* EAC formats */
- case GL_COMPRESSED_RGBA8_ETC2_EAC:
- case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
- case GL_COMPRESSED_R11_EAC:
- case GL_COMPRESSED_RG11_EAC:
- case GL_COMPRESSED_SIGNED_R11_EAC:
- case GL_COMPRESSED_SIGNED_RG11_EAC:
- /* ETC2 formats */
- case GL_COMPRESSED_RGB8_ETC2:
- case GL_COMPRESSED_SRGB8_ETC2:
- case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
- case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
- /* RGTC formats */
- case GL_COMPRESSED_RED_RGTC1:
- case GL_COMPRESSED_SIGNED_RED_RGTC1:
- case GL_COMPRESSED_RG_RGTC2:
- case GL_COMPRESSED_SIGNED_RG_RGTC2:
- invalidformat = true;
- break;
- default:
- invalidformat = false;
- }
- if (invalidformat) {
+ /* These are the only 3D compression formats supported at this time */
+ 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:
+ /* valid format */
+ break;
+ default:
+ /* invalid format */
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(invalid target %s for format %s)", caller,
- _mesa_lookup_enum_by_nr(target),
- _mesa_lookup_enum_by_nr(format));
+ _mesa_enum_to_string(target),
+ _mesa_enum_to_string(format));
return GL_TRUE;
}
+ break;
+ default:
+ targetOK = GL_FALSE;
}
break;
@@ -4621,7 +4657,7 @@ compressed_subtexture_target_check(struct gl_context *ctx, GLenum target,
if (!targetOK) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", caller,
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return GL_TRUE;
}
@@ -4834,8 +4870,7 @@ _mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset,
if (!texObj)
return;
- if (compressed_subtexture_target_check(ctx, texObj->Target, 1, format,
- true,
+ if (compressed_subtexture_target_check(ctx, texObj->Target, 1, format, true,
"glCompressedTextureSubImage1D")) {
return;
}
@@ -4912,8 +4947,7 @@ _mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset,
if (!texObj)
return;
- if (compressed_subtexture_target_check(ctx, texObj->Target, 2, format,
- true,
+ if (compressed_subtexture_target_check(ctx, texObj->Target, 2, format, true,
"glCompressedTextureSubImage2D")) {
return;
}
@@ -4990,8 +5024,7 @@ _mesa_CompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset,
if (!texObj)
return;
- if (compressed_subtexture_target_check(ctx, texObj->Target, 3, format,
- true,
+ if (compressed_subtexture_target_check(ctx, texObj->Target, 3, format, true,
"glCompressedTextureSubImage3D")) {
return;
}
@@ -5440,7 +5473,6 @@ _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer,
return;
} else {
-
/* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
* Textures (PDF page 254):
* "If buffer is zero, then any buffer object attached to the buffer
@@ -5508,7 +5540,6 @@ _mesa_TextureBufferRange(GLuint texture, GLenum internalFormat, GLuint buffer,
return;
} else {
-
/* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
* Textures (PDF page 254):
* "If buffer is zero, then any buffer object attached to the buffer
@@ -5554,19 +5585,17 @@ check_multisample_target(GLuint dims, GLenum target, bool dsa)
return dims == 2;
case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
return dims == 2 && !dsa;
-
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
return dims == 3;
case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
return dims == 3 && !dsa;
-
default:
return GL_FALSE;
}
}
-void
+static void
_mesa_texture_image_multisample(struct gl_context *ctx, GLuint dims,
struct gl_texture_object *texObj,
GLenum target, GLsizei samples,
@@ -5581,8 +5610,8 @@ _mesa_texture_image_multisample(struct gl_context *ctx, GLuint dims,
GLenum sample_count_error;
bool dsa = strstr(func, "ture") ? true : false;
- if (!(ctx->Extensions.ARB_texture_multisample
- && _mesa_is_desktop_gl(ctx))) {
+ if (!((ctx->Extensions.ARB_texture_multisample
+ && _mesa_is_desktop_gl(ctx))) && !_mesa_is_gles31(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
return;
}
@@ -5605,14 +5634,21 @@ _mesa_texture_image_multisample(struct gl_context *ctx, GLuint dims,
if (immutable && !_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"%s(internalformat=%s not legal for immutable-format)",
- func, _mesa_lookup_enum_by_nr(internalformat));
+ func, _mesa_enum_to_string(internalformat));
return;
}
if (!is_renderable_texture_format(ctx, internalformat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(internalformat=%s)",
- func, _mesa_lookup_enum_by_nr(internalformat));
+ /* Page 172 of OpenGL ES 3.1 spec says:
+ * "An INVALID_ENUM error is generated if sizedinternalformat is not
+ * color-renderable, depth-renderable, or stencil-renderable (as
+ * defined in section 9.4).
+ *
+ * (Same error is also defined for desktop OpenGL for multisample
+ * teximage/texstorage functions.)
+ */
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalformat=%s)", func,
+ _mesa_enum_to_string(internalformat));
return;
}
@@ -5671,13 +5707,12 @@ _mesa_texture_image_multisample(struct gl_context *ctx, GLuint dims,
else {
if (!dimensionsOK) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "%s(invalid width or height)", func);
+ "%s(invalid width or height)", func);
return;
}
if (!sizeOK) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY,
- "%s(texture too large)", func);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(texture too large)", func);
return;
}
@@ -5695,7 +5730,7 @@ _mesa_texture_image_multisample(struct gl_context *ctx, GLuint dims,
if (width > 0 && height > 0 && depth > 0) {
if (!ctx->Driver.AllocTextureStorage(ctx, texObj, 1,
- width, height, depth)) {
+ width, height, depth)) {
/* tidy up the texture image state. strictly speaking,
* we're allowed to just leave this in whatever state we
* like, but being tidy is good.
diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h
index 1eebaa8b631..bf729daf534 100644
--- a/src/mesa/main/teximage.h
+++ b/src/mesa/main/teximage.h
@@ -200,15 +200,6 @@ _mesa_copy_texture_sub_image(struct gl_context *ctx, GLuint dims,
const char *caller);
extern 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);
-
-extern void
_mesa_texture_buffer_range(struct gl_context *ctx,
struct gl_texture_object *texObj,
GLenum internalFormat,
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index c563f1e7434..cd7cfd6a4fb 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -1255,7 +1255,7 @@ create_textures(struct gl_context *ctx, GLenum target,
if (targetIndex < 0) { /* Bad Target */
mtx_unlock(&ctx->Shared->Mutex);
_mesa_error(ctx, GL_INVALID_ENUM, "gl%sTextures(target = %s)",
- func, _mesa_lookup_enum_by_nr(texObj->Target));
+ func, _mesa_enum_to_string(texObj->Target));
return;
}
assert(targetIndex < NUM_TEXTURE_TARGETS);
@@ -1606,8 +1606,8 @@ _mesa_tex_target_to_index(const struct gl_context *ctx, GLenum target)
return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_cube_map_array
? TEXTURE_CUBE_ARRAY_INDEX : -1;
case GL_TEXTURE_2D_MULTISAMPLE:
- return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample
- ? TEXTURE_2D_MULTISAMPLE_INDEX: -1;
+ return ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample) ||
+ _mesa_is_gles31(ctx)) ? TEXTURE_2D_MULTISAMPLE_INDEX: -1;
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample
? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX: -1;
@@ -1642,7 +1642,7 @@ _mesa_BindTexture( GLenum target, GLuint texName )
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
_mesa_debug(ctx, "glBindTexture %s %d\n",
- _mesa_lookup_enum_by_nr(target), (GLint) texName);
+ _mesa_enum_to_string(target), (GLint) texName);
targetIndex = _mesa_tex_target_to_index(ctx, target);
if (targetIndex < 0) {
@@ -1806,7 +1806,7 @@ _mesa_BindTextureUnit(GLuint unit, GLuint texture)
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
_mesa_debug(ctx, "glBindTextureUnit %s %d\n",
- _mesa_lookup_enum_by_nr(GL_TEXTURE0+unit), (GLint) texture);
+ _mesa_enum_to_string(GL_TEXTURE0+unit), (GLint) texture);
/* Section 8.1 (Texture Objects) of the OpenGL 4.5 core profile spec
* (20141030) says:
diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c
index d74134f41b1..c0611c3e489 100644
--- a/src/mesa/main/texparam.c
+++ b/src/mesa/main/texparam.c
@@ -381,7 +381,7 @@ set_tex_parameteri(struct gl_context *ctx,
if (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glTex%sParameter(target=%s, param=%d)", suffix,
- _mesa_lookup_enum_by_nr(texObj->Target), params[0]);
+ _mesa_enum_to_string(texObj->Target), params[0]);
return GL_FALSE;
}
incomplete(ctx, texObj);
@@ -500,7 +500,9 @@ set_tex_parameteri(struct gl_context *ctx,
goto invalid_pname;
case GL_DEPTH_STENCIL_TEXTURE_MODE:
- if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_stencil_texturing) {
+ if ((_mesa_is_desktop_gl(ctx) &&
+ ctx->Extensions.ARB_stencil_texturing) ||
+ _mesa_is_gles31(ctx)) {
bool stencil = params[0] == GL_STENCIL_INDEX;
if (!stencil && params[0] != GL_DEPTH_COMPONENT)
goto invalid_param;
@@ -610,22 +612,22 @@ set_tex_parameteri(struct gl_context *ctx,
invalid_pname:
_mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)",
- suffix, _mesa_lookup_enum_by_nr(pname));
+ suffix, _mesa_enum_to_string(pname));
return GL_FALSE;
invalid_param:
_mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(param=%s)",
- suffix, _mesa_lookup_enum_by_nr(params[0]));
+ suffix, _mesa_enum_to_string(params[0]));
return GL_FALSE;
invalid_operation:
_mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sParameter(pname=%s)",
- suffix, _mesa_lookup_enum_by_nr(pname));
+ suffix, _mesa_enum_to_string(pname));
return GL_FALSE;
invalid_enum:
_mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)",
- suffix, _mesa_lookup_enum_by_nr(pname));
+ suffix, _mesa_enum_to_string(pname));
return GL_FALSE;
}
@@ -683,7 +685,7 @@ set_tex_parameterf(struct gl_context *ctx,
if (texObj->Sampler.MaxAnisotropy == params[0])
return GL_FALSE;
- if (params[0] < 1.0) {
+ if (params[0] < 1.0F) {
_mesa_error(ctx, GL_INVALID_VALUE, "glTex%sParameter(param)",
suffix);
return GL_FALSE;
@@ -745,12 +747,12 @@ set_tex_parameterf(struct gl_context *ctx,
invalid_pname:
_mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)",
- suffix, _mesa_lookup_enum_by_nr(pname));
+ suffix, _mesa_enum_to_string(pname));
return GL_FALSE;
invalid_enum:
_mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)",
- suffix, _mesa_lookup_enum_by_nr(pname));
+ suffix, _mesa_enum_to_string(pname));
return GL_FALSE;
}
@@ -1395,7 +1397,7 @@ get_tex_level_parameter_image(struct gl_context *ctx,
else {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
}
break;
case GL_TEXTURE_COMPRESSED:
@@ -1444,7 +1446,7 @@ get_tex_level_parameter_image(struct gl_context *ctx,
invalid_pname:
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
}
@@ -1528,7 +1530,7 @@ get_tex_level_parameter_buffer(struct gl_context *ctx,
/* Always illegal for GL_TEXTURE_BUFFER */
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
break;
/* GL_ARB_texture_float */
@@ -1557,7 +1559,7 @@ get_tex_level_parameter_buffer(struct gl_context *ctx,
invalid_pname:
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
}
@@ -1586,7 +1588,7 @@ get_tex_level_parameteriv(struct gl_context *ctx,
if (!legal_get_tex_level_parameter_target(ctx, target, dsa)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetTex%sLevelParameter[if]v(target=%s)", suffix,
- _mesa_lookup_enum_by_nr(target));
+ _mesa_enum_to_string(target));
return;
}
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index 1af9d47f030..9b5928c4306 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -123,21 +123,21 @@ _mesa_print_texunit_state( struct gl_context *ctx, GLuint unit )
{
const struct gl_texture_unit *texUnit = ctx->Texture.Unit + unit;
printf("Texture Unit %d\n", unit);
- printf(" GL_TEXTURE_ENV_MODE = %s\n", _mesa_lookup_enum_by_nr(texUnit->EnvMode));
- printf(" GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB));
- printf(" GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA));
- printf(" GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[0]));
- printf(" GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[1]));
- printf(" GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[2]));
- printf(" GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[0]));
- printf(" GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[1]));
- printf(" GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[2]));
- printf(" GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[0]));
- printf(" GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[1]));
- printf(" GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[2]));
- printf(" GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[0]));
- printf(" GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[1]));
- printf(" GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[2]));
+ printf(" GL_TEXTURE_ENV_MODE = %s\n", _mesa_enum_to_string(texUnit->EnvMode));
+ printf(" GL_COMBINE_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.ModeRGB));
+ printf(" GL_COMBINE_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.ModeA));
+ printf(" GL_SOURCE0_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[0]));
+ printf(" GL_SOURCE1_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[1]));
+ printf(" GL_SOURCE2_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[2]));
+ printf(" GL_SOURCE0_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[0]));
+ printf(" GL_SOURCE1_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[1]));
+ printf(" GL_SOURCE2_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[2]));
+ printf(" GL_OPERAND0_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[0]));
+ printf(" GL_OPERAND1_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[1]));
+ printf(" GL_OPERAND2_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[2]));
+ printf(" GL_OPERAND0_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[0]));
+ printf(" GL_OPERAND1_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[1]));
+ printf(" GL_OPERAND2_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[2]));
printf(" GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB);
printf(" GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA);
printf(" GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]);
@@ -289,23 +289,23 @@ _mesa_ActiveTexture(GLenum texture)
GLuint k;
GET_CURRENT_CONTEXT(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glActiveTexture %s\n",
+ _mesa_enum_to_string(texture));
+
+ if (ctx->Texture.CurrentUnit == texUnit)
+ return;
+
k = _mesa_max_tex_unit(ctx);
assert(k <= ARRAY_SIZE(ctx->Texture.Unit));
- if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glActiveTexture %s\n",
- _mesa_lookup_enum_by_nr(texture));
-
if (texUnit >= k) {
_mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture=%s)",
- _mesa_lookup_enum_by_nr(texture));
+ _mesa_enum_to_string(texture));
return;
}
- if (ctx->Texture.CurrentUnit == texUnit)
- return;
-
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
ctx->Texture.CurrentUnit = texUnit;
@@ -325,16 +325,16 @@ _mesa_ClientActiveTexture(GLenum texture)
if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE))
_mesa_debug(ctx, "glClientActiveTexture %s\n",
- _mesa_lookup_enum_by_nr(texture));
+ _mesa_enum_to_string(texture));
+
+ if (ctx->Array.ActiveTexture == texUnit)
+ return;
if (texUnit >= ctx->Const.MaxTextureCoordUnits) {
_mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(texture)");
return;
}
- if (ctx->Array.ActiveTexture == texUnit)
- return;
-
FLUSH_VERTICES(ctx, _NEW_ARRAY);
ctx->Array.ActiveTexture = texUnit;
}
diff --git a/src/mesa/main/texstate.h b/src/mesa/main/texstate.h
index 662435b47cc..bee8c9c3316 100644
--- a/src/mesa/main/texstate.h
+++ b/src/mesa/main/texstate.h
@@ -77,7 +77,7 @@ _mesa_get_tex_unit_err(struct gl_context *ctx, GLuint unit, const char *func)
* implementation."
*/
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(unit=%s)", func,
- _mesa_lookup_enum_by_nr(GL_TEXTURE0+unit));
+ _mesa_enum_to_string(GL_TEXTURE0+unit));
return NULL;
}
diff --git a/src/mesa/main/texstorage.c b/src/mesa/main/texstorage.c
index 53cb2c091f8..4a2cc6065df 100644
--- a/src/mesa/main/texstorage.c
+++ b/src/mesa/main/texstorage.c
@@ -308,7 +308,8 @@ tex_storage_error_check(struct gl_context *ctx,
_mesa_error(ctx, _mesa_is_desktop_gl(ctx)?
GL_INVALID_ENUM : GL_INVALID_OPERATION,
"glTex%sStorage%dD(internalformat = %s)", suffix, dims,
- _mesa_lookup_enum_by_nr(internalformat));
+ _mesa_enum_to_string(internalformat));
+ return GL_TRUE;
}
/* levels check */
@@ -464,21 +465,21 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,
if (!legal_texobj_target(ctx, dims, target)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glTexStorage%uD(illegal target=%s)",
- dims, _mesa_lookup_enum_by_nr(target));
+ dims, _mesa_enum_to_string(target));
return;
}
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
_mesa_debug(ctx, "glTexStorage%uD %s %d %s %d %d %d\n",
dims,
- _mesa_lookup_enum_by_nr(target), levels,
- _mesa_lookup_enum_by_nr(internalformat),
+ _mesa_enum_to_string(target), levels,
+ _mesa_enum_to_string(internalformat),
width, height, depth);
/* Check the format to make sure it is sized. */
if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glTexStorage%uD(internalformat = %s)", dims,
- _mesa_lookup_enum_by_nr(internalformat));
+ _mesa_enum_to_string(internalformat));
return;
}
@@ -504,14 +505,14 @@ texturestorage(GLuint dims, GLuint texture, GLsizei levels,
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
_mesa_debug(ctx, "glTextureStorage%uD %d %d %s %d %d %d\n",
dims, texture, levels,
- _mesa_lookup_enum_by_nr(internalformat),
+ _mesa_enum_to_string(internalformat),
width, height, depth);
/* Check the format to make sure it is sized. */
if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glTextureStorage%uD(internalformat = %s)", dims,
- _mesa_lookup_enum_by_nr(internalformat));
+ _mesa_enum_to_string(internalformat));
return;
}
@@ -529,7 +530,7 @@ texturestorage(GLuint dims, GLuint texture, GLsizei levels,
if (!legal_texobj_target(ctx, dims, texObj->Target)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glTextureStorage%uD(illegal target=%s)",
- dims, _mesa_lookup_enum_by_nr(texObj->Target));
+ dims, _mesa_enum_to_string(texObj->Target));
return;
}
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index 1525205981b..37c05690091 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -787,6 +787,7 @@ texstore_rgba(TEXSTORE_PARAMS)
srcType = GL_FLOAT;
srcRowStride = srcWidth * 4 * sizeof(float);
srcMesaFormat = RGBA32_FLOAT;
+ srcPacking = &ctx->DefaultPacking;
}
src = (GLubyte *)
diff --git a/src/mesa/main/textureview.c b/src/mesa/main/textureview.c
index 6b0aed4ea1a..5a3282a40c1 100644
--- a/src/mesa/main/textureview.c
+++ b/src/mesa/main/textureview.c
@@ -313,7 +313,7 @@ target_valid(struct gl_context *ctx, GLenum origTarget, GLenum newTarget)
}
_mesa_error(ctx, GL_INVALID_OPERATION,
"glTextureView(illegal target=%s)",
- _mesa_lookup_enum_by_nr(newTarget));
+ _mesa_enum_to_string(newTarget));
return false;
}
#undef RETURN_IF_SUPPORTED
@@ -435,8 +435,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE))
_mesa_debug(ctx, "glTextureView %d %s %d %s %d %d %d %d\n",
- texture, _mesa_lookup_enum_by_nr(target), origtexture,
- _mesa_lookup_enum_by_nr(internalformat),
+ texture, _mesa_enum_to_string(target), origtexture,
+ _mesa_enum_to_string(internalformat),
minlevel, numlevels, minlayer, numlayers);
if (origtexture == 0) {
@@ -523,8 +523,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
internalformat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glTextureView(internalformat %s not compatible with origtexture %s)",
- _mesa_lookup_enum_by_nr(internalformat),
- _mesa_lookup_enum_by_nr(origTexObj->Image[0][0]->InternalFormat));
+ _mesa_enum_to_string(internalformat),
+ _mesa_enum_to_string(origTexObj->Image[0][0]->InternalFormat));
return;
}
diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index cab5083e81b..036530e91b6 100644
--- a/src/mesa/main/uniform_query.cpp
+++ b/src/mesa/main/uniform_query.cpp
@@ -978,81 +978,6 @@ _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
}
-/**
- * Called via glGetUniformLocation().
- *
- * Returns the uniform index into UniformStorage (also the
- * glGetActiveUniformsiv uniform index), and stores the referenced
- * array offset in *offset, or GL_INVALID_INDEX (-1).
- */
-extern "C" unsigned
-_mesa_get_uniform_location(struct gl_shader_program *shProg,
- const GLchar *name,
- unsigned *out_offset)
-{
- /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says:
- *
- * "The first element of a uniform array is identified using the
- * name of the uniform array appended with "[0]". Except if the last
- * part of the string name indicates a uniform array, then the
- * location of the first element of that array can be retrieved by
- * either using the name of the uniform array, or the name of the
- * uniform array appended with "[0]"."
- *
- * Note: since uniform names are not allowed to use whitespace, and array
- * indices within uniform names are not allowed to use "+", "-", or leading
- * zeros, it follows that each uniform has a unique name up to the possible
- * ambiguity with "[0]" noted above. Therefore we don't need to worry
- * about mal-formed inputs--they will properly fail when we try to look up
- * the uniform name in shProg->UniformHash.
- */
-
- const GLchar *base_name_end;
- long offset = parse_program_resource_name(name, &base_name_end);
- bool array_lookup = offset >= 0;
- char *name_copy;
-
- if (array_lookup) {
- name_copy = (char *) malloc(base_name_end - name + 1);
- memcpy(name_copy, name, base_name_end - name);
- name_copy[base_name_end - name] = '\0';
- } else {
- name_copy = (char *) name;
- offset = 0;
- }
-
- unsigned location = 0;
- const bool found = shProg->UniformHash->get(location, name_copy);
-
- assert(!found
- || strcmp(name_copy, shProg->UniformStorage[location].name) == 0);
-
- /* Free the temporary buffer *before* possibly returning an error.
- */
- if (name_copy != name)
- free(name_copy);
-
- if (!found)
- return GL_INVALID_INDEX;
-
- /* If the uniform is built-in, fail. */
- if (shProg->UniformStorage[location].builtin)
- return GL_INVALID_INDEX;
-
- /* If the uniform is an array, fail if the index is out of bounds.
- * (A negative index is caught above.) This also fails if the uniform
- * is not an array, but the user is trying to index it, because
- * array_elements is zero and offset >= 0.
- */
- if (array_lookup
- && offset >= (long) shProg->UniformStorage[location].array_elements) {
- return GL_INVALID_INDEX;
- }
-
- *out_offset = offset;
- return location;
-}
-
extern "C" bool
_mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
char *errMsg, size_t errMsgLength)
@@ -1101,18 +1026,23 @@ _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline)
for (unsigned i = 0; i < shProg[idx]->NumUniformStorage; i++) {
const struct gl_uniform_storage *const storage =
&shProg[idx]->UniformStorage[i];
- const glsl_type *const t = (storage->type->is_array())
- ? storage->type->fields.array : storage->type;
- if (!t->is_sampler())
+ if (!storage->type->is_sampler())
continue;
active_samplers++;
- const unsigned count = MAX2(1, storage->type->array_size());
+ const unsigned count = MAX2(1, storage->array_elements);
for (unsigned j = 0; j < count; j++) {
const unsigned unit = storage->storage[j].i;
+ /* FIXME: Samplers are initialized to 0 and Mesa doesn't do a
+ * great job of eliminating unused uniforms currently so for now
+ * don't throw an error if two sampler types both point to 0.
+ */
+ if (unit == 0)
+ continue;
+
/* The types of the samplers associated with a particular texture
* unit must be an exact match. Page 74 (page 89 of the PDF) of
* the OpenGL 3.3 core spec says:
@@ -1122,13 +1052,14 @@ _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline)
* program object."
*/
if (unit_types[unit] == NULL) {
- unit_types[unit] = t;
- } else if (unit_types[unit] != t) {
+ unit_types[unit] = storage->type;
+ } else if (unit_types[unit] != storage->type) {
pipeline->InfoLog =
ralloc_asprintf(pipeline,
"Texture unit %d is accessed both as %s "
"and %s",
- unit, unit_types[unit]->name, t->name);
+ unit, unit_types[unit]->name,
+ storage->type->name);
return false;
}
}
diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
index 5548d1d026f..ff1df72e1d6 100644
--- a/src/mesa/main/uniforms.c
+++ b/src/mesa/main/uniforms.c
@@ -952,7 +952,7 @@ _mesa_GetUniformBlockIndex(GLuint program,
struct gl_program_resource *res =
_mesa_program_resource_find_name(shProg, GL_UNIFORM_BLOCK,
- uniformBlockName);
+ uniformBlockName, NULL);
if (!res)
return GL_INVALID_INDEX;
@@ -987,7 +987,8 @@ _mesa_GetUniformIndices(GLuint program,
for (i = 0; i < uniformCount; i++) {
struct gl_program_resource *res =
- _mesa_program_resource_find_name(shProg, GL_UNIFORM, uniformNames[i]);
+ _mesa_program_resource_find_name(shProg, GL_UNIFORM, uniformNames[i],
+ NULL);
uniformIndices[i] = _mesa_program_resource_index(shProg, res);
}
}
@@ -1092,6 +1093,21 @@ mesa_bufferiv(struct gl_shader_program *shProg, GLenum type,
GL_REFERENCED_BY_VERTEX_SHADER, params,
caller);
return;
+
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER:
+ case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER:
+ _mesa_program_resource_prop(shProg, res, index,
+ GL_REFERENCED_BY_TESS_CONTROL_SHADER, params,
+ caller);
+ return;
+
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER:
+ case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER:
+ _mesa_program_resource_prop(shProg, res, index,
+ GL_REFERENCED_BY_TESS_EVALUATION_SHADER, params,
+ caller);
+ return;
+
case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER:
case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER:
_mesa_program_resource_prop(shProg, res, index,
@@ -1104,16 +1120,10 @@ mesa_bufferiv(struct gl_shader_program *shProg, GLenum type,
GL_REFERENCED_BY_FRAGMENT_SHADER, params,
caller);
return;
- case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER:
- params[0] = GL_FALSE;
- return;
- case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER:
- params[0] = GL_FALSE;
- return;
default:
_mesa_error(ctx, GL_INVALID_ENUM,
"%s(pname 0x%x (%s))", caller, pname,
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
return;
}
}
diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h
index bd7b05e207a..e62eaa53ccc 100644
--- a/src/mesa/main/uniforms.h
+++ b/src/mesa/main/uniforms.h
@@ -343,10 +343,6 @@ void GLAPIENTRY
_mesa_ProgramUniformMatrix4x3dv(GLuint program, GLint location, GLsizei count,
GLboolean transpose, const GLdouble *value);
-unsigned
-_mesa_get_uniform_location(struct gl_shader_program *shProg,
- const GLchar *name, unsigned *offset);
-
void
_mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shader_program,
GLint location, GLsizei count,
diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c
index ebdd9eaf02e..3bab9850588 100644
--- a/src/mesa/main/varray.c
+++ b/src/mesa/main/varray.c
@@ -300,7 +300,7 @@ update_array_format(struct gl_context *ctx,
typeBit = type_to_bit(ctx, type);
if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)",
- func, _mesa_lookup_enum_by_nr(type));
+ func, _mesa_enum_to_string(type));
return false;
}
@@ -333,7 +333,7 @@ update_array_format(struct gl_context *ctx,
if (bgra_error) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=GL_BGRA and type=%s)",
- func, _mesa_lookup_enum_by_nr(type));
+ func, _mesa_enum_to_string(type));
return false;
}
@@ -2310,7 +2310,7 @@ print_array(const char *name, GLint index, const struct gl_client_array *array)
else
fprintf(stderr, " %s: ", name);
fprintf(stderr, "Ptr=%p, Type=%s, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %lu)\n",
- array->Ptr, _mesa_lookup_enum_by_nr(array->Type), array->Size,
+ array->Ptr, _mesa_enum_to_string(array->Type), array->Size,
array->_ElementSize, array->StrideB, array->BufferObj->Name,
(unsigned long) array->BufferObj->Size);
}
diff --git a/src/mesa/main/version.c b/src/mesa/main/version.c
index 8bc00ace5c4..fd7ae53ccbd 100644
--- a/src/mesa/main/version.c
+++ b/src/mesa/main/version.c
@@ -309,7 +309,7 @@ compute_version(const struct gl_extensions *extensions,
extensions->ARB_gpu_shader5 &&
extensions->ARB_gpu_shader_fp64 &&
extensions->ARB_sample_shading &&
- false /*extensions->ARB_shader_subroutine*/ &&
+ extensions->ARB_shader_subroutine &&
extensions->ARB_tessellation_shader &&
extensions->ARB_texture_buffer_object_rgb32 &&
extensions->ARB_texture_cube_map_array &&
diff --git a/src/mesa/main/viewport.c b/src/mesa/main/viewport.c
index b27063031c4..7d8914291c3 100644
--- a/src/mesa/main/viewport.c
+++ b/src/mesa/main/viewport.c
@@ -391,8 +391,8 @@ _mesa_ClipControl(GLenum origin, GLenum depth)
if (MESA_VERBOSE&VERBOSE_API)
_mesa_debug(ctx, "glClipControl(%s, %s)\n",
- _mesa_lookup_enum_by_nr(origin),
- _mesa_lookup_enum_by_nr(depth));
+ _mesa_enum_to_string(origin),
+ _mesa_enum_to_string(depth));
ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -443,12 +443,12 @@ _mesa_ClipControl(GLenum origin, GLenum depth)
*/
void
_mesa_get_viewport_xform(struct gl_context *ctx, unsigned i,
- double scale[3], double translate[3])
+ float scale[3], float translate[3])
{
- double x = ctx->ViewportArray[i].X;
- double y = ctx->ViewportArray[i].Y;
- double half_width = 0.5*ctx->ViewportArray[i].Width;
- double half_height = 0.5*ctx->ViewportArray[i].Height;
+ float x = ctx->ViewportArray[i].X;
+ float y = ctx->ViewportArray[i].Y;
+ float half_width = 0.5f * ctx->ViewportArray[i].Width;
+ float half_height = 0.5f * ctx->ViewportArray[i].Height;
double n = ctx->ViewportArray[i].Near;
double f = ctx->ViewportArray[i].Far;
@@ -462,8 +462,8 @@ _mesa_get_viewport_xform(struct gl_context *ctx, unsigned i,
translate[1] = half_height + y;
}
if (ctx->Transform.ClipDepthMode == GL_NEGATIVE_ONE_TO_ONE) {
- scale[2] = 0.5*(f - n);
- translate[2] = 0.5*(n + f);
+ scale[2] = 0.5 * (f - n);
+ translate[2] = 0.5 * (n + f);
} else {
scale[2] = f - n;
translate[2] = n;
diff --git a/src/mesa/main/viewport.h b/src/mesa/main/viewport.h
index 899dc2d0bcc..b0675db1096 100644
--- a/src/mesa/main/viewport.h
+++ b/src/mesa/main/viewport.h
@@ -73,6 +73,6 @@ _mesa_ClipControl(GLenum origin, GLenum depth);
extern void
_mesa_get_viewport_xform(struct gl_context *ctx, unsigned i,
- double scale[3], double translate[3]);
+ float scale[3], float translate[3]);
#endif