summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/api_exec.h3
-rw-r--r--src/mesa/main/api_loopback.c2
-rw-r--r--src/mesa/main/attrib.c22
-rw-r--r--src/mesa/main/blend.c37
-rw-r--r--src/mesa/main/blend.h16
-rw-r--r--src/mesa/main/blit.c212
-rw-r--r--src/mesa/main/blit.h13
-rw-r--r--src/mesa/main/buffers.c240
-rw-r--r--src/mesa/main/buffers.h29
-rw-r--r--src/mesa/main/clear.c74
-rw-r--r--src/mesa/main/clear.h16
-rw-r--r--src/mesa/main/config.h13
-rw-r--r--src/mesa/main/context.c78
-rw-r--r--src/mesa/main/copyimage.c39
-rw-r--r--src/mesa/main/depth.c6
-rw-r--r--src/mesa/main/dlist.c30
-rw-r--r--src/mesa/main/errors.c30
-rw-r--r--src/mesa/main/errors.h9
-rw-r--r--src/mesa/main/extensions.c3
-rw-r--r--src/mesa/main/fbobject.c1425
-rw-r--r--src/mesa/main/fbobject.h87
-rw-r--r--src/mesa/main/formats.c11
-rw-r--r--src/mesa/main/framebuffer.c71
-rw-r--r--src/mesa/main/framebuffer.h38
-rw-r--r--src/mesa/main/get.c22
-rw-r--r--src/mesa/main/get_hash_params.py28
-rw-r--r--src/mesa/main/getstring.c16
-rw-r--r--src/mesa/main/glformats.c43
-rw-r--r--src/mesa/main/glformats.h2
-rw-r--r--src/mesa/main/glheader.h6
-rw-r--r--src/mesa/main/hash.c28
-rw-r--r--src/mesa/main/hash.h3
-rw-r--r--src/mesa/main/imports.h32
-rw-r--r--src/mesa/main/mtypes.h78
-rw-r--r--src/mesa/main/objectlabel.c10
-rw-r--r--src/mesa/main/pipelineobj.c76
-rw-r--r--src/mesa/main/pipelineobj.h3
-rw-r--r--src/mesa/main/program_resource.c6
-rw-r--r--src/mesa/main/readpix.c29
-rw-r--r--src/mesa/main/readpix.h3
-rw-r--r--src/mesa/main/shader_query.cpp29
-rw-r--r--src/mesa/main/shaderapi.c6
-rw-r--r--src/mesa/main/shaderobj.c4
-rw-r--r--src/mesa/main/shared.c1
-rw-r--r--src/mesa/main/state.c18
-rw-r--r--src/mesa/main/tests/dispatch_sanity.cpp1032
-rw-r--r--src/mesa/main/texenv.c2
-rw-r--r--src/mesa/main/teximage.c2
-rw-r--r--src/mesa/main/texparam.c2
-rw-r--r--src/mesa/main/textureview.c95
-rw-r--r--src/mesa/main/textureview.h9
-rw-r--r--src/mesa/main/uniform_query.cpp15
-rw-r--r--src/mesa/main/uniforms.h4
-rw-r--r--src/mesa/main/varray.c8
-rw-r--r--src/mesa/main/version.c109
-rw-r--r--src/mesa/main/version.h3
-rw-r--r--src/mesa/main/vtxfmt.c2
57 files changed, 3291 insertions, 939 deletions
diff --git a/src/mesa/main/api_exec.h b/src/mesa/main/api_exec.h
index 12249fec228..655cb32d0a4 100644
--- a/src/mesa/main/api_exec.h
+++ b/src/mesa/main/api_exec.h
@@ -38,6 +38,9 @@ _mesa_initialize_exec_table(struct gl_context *ctx);
extern void
_mesa_initialize_dispatch_tables(struct gl_context *ctx);
+extern struct _glapi_table *
+_mesa_new_nop_table(unsigned numEntries);
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/src/mesa/main/api_loopback.c b/src/mesa/main/api_loopback.c
index 9932a837336..a7fd82c531f 100644
--- a/src/mesa/main/api_loopback.c
+++ b/src/mesa/main/api_loopback.c
@@ -1772,7 +1772,9 @@ _mesa_loopback_init_api_table(const struct gl_context *ctx,
SET_VertexAttribI4sv(dest, _mesa_VertexAttribI4sv);
SET_VertexAttribI4ubv(dest, _mesa_VertexAttribI4ubv);
SET_VertexAttribI4usv(dest, _mesa_VertexAttribI4usv);
+ }
+ if (ctx->API == API_OPENGL_CORE) {
/* GL 4.1 / GL_ARB_vertex_attrib_64bit */
SET_VertexAttribL1d(dest, _mesa_VertexAttribL1d);
SET_VertexAttribL2d(dest, _mesa_VertexAttribL2d);
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index b163c0aa699..53626e38be9 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -177,6 +177,10 @@ struct texture_state
};
+/** An unused GL_*_BIT value */
+#define DUMMY_BIT 0x10000000
+
+
/**
* Allocate new attribute node of given type/kind. Attach payload data.
* Insert it into the linked list named by 'head'.
@@ -253,6 +257,15 @@ _mesa_PushAttrib(GLbitfield mask)
/* groups specified by the mask. */
head = NULL;
+ if (mask == 0) {
+ /* if mask is zero we still need to push something so that we
+ * don't get a GL_STACK_UNDERFLOW error in glPopAttrib().
+ */
+ GLuint dummy = 0;
+ if (!push_attrib(ctx, &head, DUMMY_BIT, sizeof(dummy), &dummy))
+ goto end;
+ }
+
if (mask & GL_ACCUM_BUFFER_BIT) {
if (!push_attrib(ctx, &head, GL_ACCUM_BUFFER_BIT,
sizeof(struct gl_accum_attrib),
@@ -928,6 +941,10 @@ _mesa_PopAttrib(void)
}
switch (attr->kind) {
+ case DUMMY_BIT:
+ /* do nothing */
+ break;
+
case GL_ACCUM_BUFFER_BIT:
{
const struct gl_accum_attrib *accum;
@@ -1074,6 +1091,11 @@ _mesa_PopAttrib(void)
_mesa_ClearDepth(depth->Clear);
_mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test);
_mesa_DepthMask(depth->Mask);
+ if (ctx->Extensions.EXT_depth_bounds_test) {
+ _mesa_set_enable(ctx, GL_DEPTH_BOUNDS_TEST_EXT,
+ depth->BoundsTest);
+ _mesa_DepthBoundsEXT(depth->BoundsMin, depth->BoundsMax);
+ }
}
break;
case GL_ENABLE_BIT:
diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c
index 774fc888ec4..d869fa2aa09 100644
--- a/src/mesa/main/blend.c
+++ b/src/mesa/main/blend.c
@@ -769,7 +769,7 @@ _mesa_ClampColor(GLenum target, GLenum clamp)
}
FLUSH_VERTICES(ctx, _NEW_LIGHT);
ctx->Light.ClampVertexColor = clamp;
- _mesa_update_clamp_vertex_color(ctx);
+ _mesa_update_clamp_vertex_color(ctx, ctx->DrawBuffer);
break;
case GL_CLAMP_FRAGMENT_COLOR_ARB:
if (ctx->API == API_OPENGL_CORE &&
@@ -778,7 +778,7 @@ _mesa_ClampColor(GLenum target, GLenum clamp)
}
FLUSH_VERTICES(ctx, _NEW_FRAG_CLAMP);
ctx->Color.ClampFragmentColor = clamp;
- _mesa_update_clamp_fragment_color(ctx);
+ _mesa_update_clamp_fragment_color(ctx, ctx->DrawBuffer);
break;
case GL_CLAMP_READ_COLOR_ARB:
ctx->Color.ClampReadColor = clamp;
@@ -807,50 +807,55 @@ get_clamp_color(const struct gl_framebuffer *fb, GLenum clamp)
}
GLboolean
-_mesa_get_clamp_fragment_color(const struct gl_context *ctx)
+_mesa_get_clamp_fragment_color(const struct gl_context *ctx,
+ const struct gl_framebuffer *drawFb)
{
- return get_clamp_color(ctx->DrawBuffer,
- ctx->Color.ClampFragmentColor);
+ return get_clamp_color(drawFb, ctx->Color.ClampFragmentColor);
}
GLboolean
-_mesa_get_clamp_vertex_color(const struct gl_context *ctx)
+_mesa_get_clamp_vertex_color(const struct gl_context *ctx,
+ const struct gl_framebuffer *drawFb)
{
- return get_clamp_color(ctx->DrawBuffer, ctx->Light.ClampVertexColor);
+ return get_clamp_color(drawFb, ctx->Light.ClampVertexColor);
}
GLboolean
-_mesa_get_clamp_read_color(const struct gl_context *ctx)
+_mesa_get_clamp_read_color(const struct gl_context *ctx,
+ const struct gl_framebuffer *readFb)
{
- return get_clamp_color(ctx->ReadBuffer, ctx->Color.ClampReadColor);
+ return get_clamp_color(readFb, ctx->Color.ClampReadColor);
}
/**
* Update the ctx->Color._ClampFragmentColor field
*/
void
-_mesa_update_clamp_fragment_color(struct gl_context *ctx)
+_mesa_update_clamp_fragment_color(struct gl_context *ctx,
+ const struct gl_framebuffer *drawFb)
{
- struct gl_framebuffer *fb = ctx->DrawBuffer;
-
/* Don't clamp if:
* - there is no colorbuffer
* - all colorbuffers are unsigned normalized, so clamping has no effect
* - there is an integer colorbuffer
*/
- if (!fb || !fb->_HasSNormOrFloatColorBuffer || fb->_IntegerColor)
+ if (!drawFb || !drawFb->_HasSNormOrFloatColorBuffer ||
+ drawFb->_IntegerColor)
ctx->Color._ClampFragmentColor = GL_FALSE;
else
- ctx->Color._ClampFragmentColor = _mesa_get_clamp_fragment_color(ctx);
+ ctx->Color._ClampFragmentColor =
+ _mesa_get_clamp_fragment_color(ctx, drawFb);
}
/**
* Update the ctx->Color._ClampVertexColor field
*/
void
-_mesa_update_clamp_vertex_color(struct gl_context *ctx)
+_mesa_update_clamp_vertex_color(struct gl_context *ctx,
+ const struct gl_framebuffer *drawFb)
{
- ctx->Light._ClampVertexColor = _mesa_get_clamp_vertex_color(ctx);
+ ctx->Light._ClampVertexColor =
+ _mesa_get_clamp_vertex_color(ctx, drawFb);
}
/**
diff --git a/src/mesa/main/blend.h b/src/mesa/main/blend.h
index fe31a7440f0..8ab9e02fc13 100644
--- a/src/mesa/main/blend.h
+++ b/src/mesa/main/blend.h
@@ -37,6 +37,7 @@
#include "formats.h"
struct gl_context;
+struct gl_framebuffer;
extern void GLAPIENTRY
@@ -101,19 +102,24 @@ extern void GLAPIENTRY
_mesa_ClampColor(GLenum target, GLenum clamp);
extern GLboolean
-_mesa_get_clamp_fragment_color(const struct gl_context *ctx);
+_mesa_get_clamp_fragment_color(const struct gl_context *ctx,
+ const struct gl_framebuffer *drawFb);
extern GLboolean
-_mesa_get_clamp_vertex_color(const struct gl_context *ctx);
+_mesa_get_clamp_vertex_color(const struct gl_context *ctx,
+ const struct gl_framebuffer *drawFb);
extern GLboolean
-_mesa_get_clamp_read_color(const struct gl_context *ctx);
+_mesa_get_clamp_read_color(const struct gl_context *ctx,
+ const struct gl_framebuffer *readFb);
extern void
-_mesa_update_clamp_fragment_color(struct gl_context *ctx);
+_mesa_update_clamp_fragment_color(struct gl_context *ctx,
+ const struct gl_framebuffer *drawFb);
extern void
-_mesa_update_clamp_vertex_color(struct gl_context *ctx);
+_mesa_update_clamp_vertex_color(struct gl_context *ctx,
+ const struct gl_framebuffer *drawFb);
extern mesa_format
_mesa_get_render_format(const struct gl_context *ctx, mesa_format format);
diff --git a/src/mesa/main/blit.c b/src/mesa/main/blit.c
index 0694466eb75..db8fee5a414 100644
--- a/src/mesa/main/blit.c
+++ b/src/mesa/main/blit.c
@@ -34,6 +34,7 @@
#include "enums.h"
#include "blit.h"
#include "fbobject.h"
+#include "framebuffer.h"
#include "glformats.h"
#include "mtypes.h"
#include "state.h"
@@ -148,38 +149,25 @@ is_valid_blit_filter(const struct gl_context *ctx, GLenum filter)
}
-/**
- * Blit rectangular region, optionally from one framebuffer to another.
- *
- * Note, if the src buffer is multisampled and the dest is not, this is
- * when the samples must be resolved to a single color.
- */
-void GLAPIENTRY
-_mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
+void
+_mesa_blit_framebuffer(struct gl_context *ctx,
+ struct gl_framebuffer *readFb,
+ struct gl_framebuffer *drawFb,
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter, const char *func)
{
const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT);
- const struct gl_framebuffer *readFb, *drawFb;
- GET_CURRENT_CONTEXT(ctx);
FLUSH_VERTICES(ctx, 0);
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx,
- "glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d, 0x%x, %s)\n",
- srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1,
- mask, _mesa_lookup_enum_by_nr(filter));
-
- if (ctx->NewState) {
- _mesa_update_state(ctx);
- }
+ /* Update completeness status of readFb and drawFb. */
+ _mesa_update_framebuffer(ctx, readFb, drawFb);
- readFb = ctx->ReadBuffer;
- drawFb = ctx->DrawBuffer;
+ /* Make sure drawFb has an initialized bounding box. */
+ _mesa_update_draw_buffer_bounds(ctx, drawFb);
if (!readFb || !drawFb) {
/* This will normally never happen but someday we may want to
@@ -192,12 +180,12 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
_mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glBlitFramebufferEXT(incomplete draw/read buffers)");
+ "%s(incomplete draw/read buffers)", func);
return;
}
if (!is_valid_blit_filter(ctx, filter)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlitFramebufferEXT(%s)",
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid filter %s)", func,
_mesa_lookup_enum_by_nr(filter));
return;
}
@@ -205,13 +193,13 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
filter == GL_SCALED_RESOLVE_NICEST_EXT) &&
(readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT(%s)",
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s: invalid samples)", func,
_mesa_lookup_enum_by_nr(filter));
return;
}
if (mask & ~legalMaskBits) {
- _mesa_error( ctx, GL_INVALID_VALUE, "glBlitFramebufferEXT(mask)");
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid mask bits set)", func);
return;
}
@@ -219,13 +207,13 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
&& filter != GL_NEAREST) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(depth/stencil requires GL_NEAREST filter)");
+ "%s(depth/stencil requires GL_NEAREST filter)", func);
return;
}
/* get color read/draw renderbuffers */
if (mask & GL_COLOR_BUFFER_BIT) {
- const GLuint numColorDrawBuffers = ctx->DrawBuffer->_NumColorDrawBuffers;
+ const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
const struct gl_renderbuffer *colorDrawRb = NULL;
GLuint i;
@@ -241,7 +229,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
}
else {
for (i = 0; i < numColorDrawBuffers; i++) {
- colorDrawRb = ctx->DrawBuffer->_ColorDrawBuffers[i];
+ colorDrawRb = drawFb->_ColorDrawBuffers[i];
if (!colorDrawRb)
continue;
@@ -257,15 +245,15 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
*/
if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebuffer(source and destination color "
- "buffer cannot be the same)");
+ "%s(source and destination color "
+ "buffer cannot be the same)", func);
return;
}
if (!compatible_color_datatypes(colorReadRb->Format,
colorDrawRb->Format)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(color buffer datatypes mismatch)");
+ "%s(color buffer datatypes mismatch)", func);
return;
}
/* extra checks for multisample copies... */
@@ -273,7 +261,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
/* color formats must match */
if (!compatible_resolve_formats(colorReadRb, colorDrawRb)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(bad src/dst multisample pixel formats)");
+ "%s(bad src/dst multisample pixel formats)", func);
return;
}
}
@@ -286,7 +274,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
if (type == GL_INT || type == GL_UNSIGNED_INT) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(integer color type)");
+ "%s(integer color type)", func);
return;
}
}
@@ -306,15 +294,15 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
* ignored."
*/
if ((readRb == NULL) || (drawRb == NULL)) {
- mask &= ~GL_STENCIL_BUFFER_BIT;
+ mask &= ~GL_STENCIL_BUFFER_BIT;
}
else {
int read_z_bits, draw_z_bits;
if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebuffer(source and destination stencil "
- "buffer cannot be the same)");
+ "%s(source and destination stencil "
+ "buffer cannot be the same)", func);
return;
}
@@ -324,7 +312,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
* there is only one: GL_UNSIGNED_INT.
*/
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebuffer(stencil attachment format mismatch)");
+ "%s(stencil attachment format mismatch)", func);
return;
}
@@ -340,8 +328,8 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
_mesa_get_format_datatype(readRb->Format) !=
_mesa_get_format_datatype(drawRb->Format))) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer"
- "(stencil attachment depth format mismatch)");
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(stencil attachment depth format mismatch)", func);
return;
}
}
@@ -360,15 +348,15 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
* ignored."
*/
if ((readRb == NULL) || (drawRb == NULL)) {
- mask &= ~GL_DEPTH_BUFFER_BIT;
+ mask &= ~GL_DEPTH_BUFFER_BIT;
}
else {
int read_s_bit, draw_s_bit;
if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebuffer(source and destination depth "
- "buffer cannot be the same)");
+ "%s(source and destination depth "
+ "buffer cannot be the same)", func);
return;
}
@@ -377,7 +365,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
(_mesa_get_format_datatype(readRb->Format) !=
_mesa_get_format_datatype(drawRb->Format))) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebuffer(depth attachment format mismatch)");
+ "%s(depth attachment format mismatch)", func);
return;
}
@@ -389,8 +377,8 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
* we should ignore the stencil format check.
*/
if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer"
- "(depth attachment stencil bits mismatch)");
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(depth attachment stencil bits mismatch)", func);
return;
}
}
@@ -406,7 +394,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
*/
if (drawFb->Visual.samples > 0) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebuffer(destination samples must be 0)");
+ "%s(destination samples must be 0)", func);
return;
}
@@ -426,7 +414,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
&& (srcX0 != dstX0 || srcY0 != dstY0
|| srcX1 != dstX1 || srcY1 != dstY1)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebuffer(bad src/dst multisample region)");
+ "%s(bad src/dst multisample region)", func);
return;
}
} else {
@@ -434,7 +422,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
drawFb->Visual.samples > 0 &&
readFb->Visual.samples != drawFb->Visual.samples) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(mismatched samples)");
+ "%s(mismatched samples)", func);
return;
}
@@ -445,7 +433,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) ||
abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(bad src/dst multisample region sizes)");
+ "%s(bad src/dst multisample region sizes)", func);
return;
}
}
@@ -457,43 +445,44 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
const struct gl_renderbuffer *colorDrawRb = NULL;
GLuint i = 0;
- printf("glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d,"
- " 0x%x, 0x%x)\n",
- srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1,
- mask, filter);
+ printf("%s(%d, %d, %d, %d, %d, %d, %d, %d,"
+ " 0x%x, 0x%x)\n", func,
+ srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, filter);
+
if (colorReadRb) {
const struct gl_renderbuffer_attachment *att;
att = find_attachment(readFb, colorReadRb);
printf(" Src FBO %u RB %u (%dx%d) ",
- readFb->Name, colorReadRb->Name,
- colorReadRb->Width, colorReadRb->Height);
+ readFb->Name, colorReadRb->Name,
+ colorReadRb->Width, colorReadRb->Height);
if (att && att->Texture) {
printf("Tex %u tgt 0x%x level %u face %u",
- att->Texture->Name,
- att->Texture->Target,
- att->TextureLevel,
- att->CubeMapFace);
+ att->Texture->Name,
+ att->Texture->Target,
+ att->TextureLevel,
+ att->CubeMapFace);
}
printf("\n");
/* Print all active color render buffers */
- for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
- colorDrawRb = ctx->DrawBuffer->_ColorDrawBuffers[i];
+ for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) {
+ colorDrawRb = drawFb->_ColorDrawBuffers[i];
if (!colorDrawRb)
continue;
att = find_attachment(drawFb, colorDrawRb);
printf(" Dst FBO %u RB %u (%dx%d) ",
- drawFb->Name, colorDrawRb->Name,
- colorDrawRb->Width, colorDrawRb->Height);
+ drawFb->Name, colorDrawRb->Name,
+ colorDrawRb->Width, colorDrawRb->Height);
if (att && att->Texture) {
printf("Tex %u tgt 0x%x level %u face %u",
- att->Texture->Name,
- att->Texture->Target,
- att->TextureLevel,
- att->CubeMapFace);
+ att->Texture->Name,
+ att->Texture->Target,
+ att->TextureLevel,
+ att->CubeMapFace);
}
printf("\n");
}
@@ -507,8 +496,87 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
}
assert(ctx->Driver.BlitFramebuffer);
- ctx->Driver.BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
+ ctx->Driver.BlitFramebuffer(ctx, readFb, drawFb,
srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1,
mask, filter);
}
+
+
+/**
+ * Blit rectangular region, optionally from one framebuffer to another.
+ *
+ * Note, if the src buffer is multisampled and the dest is not, this is
+ * when the samples must be resolved to a single color.
+ */
+void GLAPIENTRY
+_mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx,
+ "glBlitFramebuffer(%d, %d, %d, %d, "
+ " %d, %d, %d, %d, 0x%x, %s)\n",
+ srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, _mesa_lookup_enum_by_nr(filter));
+
+ _mesa_blit_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
+ srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, filter, "glBlitFramebuffer");
+}
+
+
+void GLAPIENTRY
+_mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer,
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_framebuffer *readFb, *drawFb;
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx,
+ "glBlitNamedFramebuffer(%u %u %d, %d, %d, %d, "
+ " %d, %d, %d, %d, 0x%x, %s)\n",
+ readFramebuffer, drawFramebuffer,
+ srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, _mesa_lookup_enum_by_nr(filter));
+
+ /*
+ * According to PDF page 533 of the OpenGL 4.5 core spec (30.10.2014,
+ * Section 18.3 Copying Pixels):
+ * "... if readFramebuffer or drawFramebuffer is zero (for
+ * BlitNamedFramebuffer), then the default read or draw framebuffer is
+ * used as the corresponding source or destination framebuffer,
+ * respectively."
+ */
+ if (readFramebuffer) {
+ readFb = _mesa_lookup_framebuffer_err(ctx, readFramebuffer,
+ "glBlitNamedFramebuffer");
+ if (!readFb)
+ return;
+ }
+ else
+ readFb = ctx->WinSysReadBuffer;
+
+ if (drawFramebuffer) {
+ drawFb = _mesa_lookup_framebuffer_err(ctx, drawFramebuffer,
+ "glBlitNamedFramebuffer");
+ if (!drawFb)
+ return;
+ }
+ else
+ drawFb = ctx->WinSysDrawBuffer;
+
+ _mesa_blit_framebuffer(ctx, readFb, drawFb,
+ srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, filter, "glBlitNamedFramebuffer");
+}
diff --git a/src/mesa/main/blit.h b/src/mesa/main/blit.h
index 01a958af5a2..54b946e3192 100644
--- a/src/mesa/main/blit.h
+++ b/src/mesa/main/blit.h
@@ -28,11 +28,24 @@
#include "glheader.h"
+extern void
+_mesa_blit_framebuffer(struct gl_context *ctx,
+ struct gl_framebuffer *readFb,
+ struct gl_framebuffer *drawFb,
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter, const char *func);
extern void GLAPIENTRY
_mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter);
+extern void GLAPIENTRY
+_mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer,
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter);
+
#endif /* BLIT_H */
diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c
index 37a9790923b..0536266d756 100644
--- a/src/mesa/main/buffers.c
+++ b/src/mesa/main/buffers.c
@@ -242,16 +242,16 @@ read_buffer_enum_to_index(GLenum buffer)
*
* See the GL_EXT_framebuffer_object spec for more info.
*/
-void GLAPIENTRY
-_mesa_DrawBuffer(GLenum buffer)
+void
+_mesa_draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLenum buffer, const char *caller)
{
GLbitfield destMask;
- GET_CURRENT_CONTEXT(ctx);
FLUSH_VERTICES(ctx, 0);
if (MESA_VERBOSE & VERBOSE_API) {
- _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
+ _mesa_debug(ctx, "%s %s\n", caller, _mesa_lookup_enum_by_nr(buffer));
}
if (buffer == GL_NONE) {
@@ -259,33 +259,60 @@ _mesa_DrawBuffer(GLenum buffer)
}
else {
const GLbitfield supportedMask
- = supported_buffer_bitmask(ctx, ctx->DrawBuffer);
+ = supported_buffer_bitmask(ctx, fb);
destMask = draw_buffer_enum_to_bitmask(ctx, buffer);
if (destMask == BAD_MASK) {
/* totally bogus buffer */
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glDrawBuffer(buffer=0x%x)", buffer);
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)", caller,
+ _mesa_lookup_enum_by_nr(buffer));
return;
}
destMask &= supportedMask;
if (destMask == 0x0) {
/* none of the named color buffers exist! */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glDrawBuffer(buffer=0x%x)", buffer);
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid buffer %s)",
+ caller, _mesa_lookup_enum_by_nr(buffer));
return;
}
}
/* if we get here, there's no error so set new state */
- _mesa_drawbuffers(ctx, 1, &buffer, &destMask);
+ _mesa_drawbuffers(ctx, fb, 1, &buffer, &destMask);
+
+ /* Call device driver function only if fb is the bound draw buffer */
+ if (fb == ctx->DrawBuffer) {
+ if (ctx->Driver.DrawBuffers)
+ ctx->Driver.DrawBuffers(ctx, 1, &buffer);
+ else if (ctx->Driver.DrawBuffer)
+ ctx->Driver.DrawBuffer(ctx, buffer);
+ }
+}
- /*
- * Call device driver function.
- */
- if (ctx->Driver.DrawBuffers)
- ctx->Driver.DrawBuffers(ctx, 1, &buffer);
- else if (ctx->Driver.DrawBuffer)
- ctx->Driver.DrawBuffer(ctx, buffer);
+
+void GLAPIENTRY
+_mesa_DrawBuffer(GLenum buffer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_draw_buffer(ctx, ctx->DrawBuffer, buffer, "glDrawBuffer");
+}
+
+
+void GLAPIENTRY
+_mesa_NamedFramebufferDrawBuffer(GLuint framebuffer, GLenum buf)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_framebuffer *fb;
+
+ if (framebuffer) {
+ fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+ "glNamedFramebufferDrawBuffer");
+ if (!fb)
+ return;
+ }
+ else
+ fb = ctx->WinSysDrawBuffer;
+
+ _mesa_draw_buffer(ctx, fb, buf, "glNamedFramebufferDrawBuffer");
}
@@ -298,13 +325,13 @@ _mesa_DrawBuffer(GLenum buffer)
* names cannot specify more than one buffer. For example,
* GL_FRONT_AND_BACK is illegal.
*/
-void GLAPIENTRY
-_mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
+void
+_mesa_draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLsizei n, const GLenum *buffers, const char *caller)
{
GLuint output;
GLbitfield usedBufferMask, supportedMask;
GLbitfield destMask[MAX_DRAW_BUFFERS];
- GET_CURRENT_CONTEXT(ctx);
FLUSH_VERTICES(ctx, 0);
@@ -315,12 +342,18 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
* "An INVALID_VALUE error is generated if n is greater than
* MAX_DRAW_BUFFERS."
*/
- if (n < 0 || n > (GLsizei) ctx->Const.MaxDrawBuffers) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)");
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", caller);
+ return;
+ }
+
+ if (n > (GLsizei) ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(n > maximum number of draw buffers)", caller);
return;
}
- supportedMask = supported_buffer_bitmask(ctx, ctx->DrawBuffer);
+ supportedMask = supported_buffer_bitmask(ctx, fb);
usedBufferMask = 0x0;
/* From the ES 3.0 specification, page 180:
@@ -328,9 +361,9 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
* and the constant must be BACK or NONE."
* (same restriction applies with GL_EXT_draw_buffers specification)
*/
- if (ctx->API == API_OPENGLES2 && _mesa_is_winsys_fbo(ctx->DrawBuffer) &&
+ if (ctx->API == API_OPENGLES2 && _mesa_is_winsys_fbo(fb) &&
(n != 1 || (buffers[0] != GL_NONE && buffers[0] != GL_BACK))) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffers(buffer)");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid buffers)", caller);
return;
}
@@ -362,9 +395,11 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
* or equal to the value of MAX_COLOR_ATTACHMENTS, then the error
* INVALID_OPERATION results."
*/
- if (_mesa_is_user_fbo(ctx->DrawBuffer) && buffers[output] >=
+ if (_mesa_is_user_fbo(fb) && buffers[output] >=
GL_COLOR_ATTACHMENT0 + ctx->Const.MaxDrawBuffers) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB(buffer)");
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(buffers[%d] >= maximum number of draw buffers)",
+ caller, output);
return;
}
@@ -375,9 +410,10 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
* 4.5 or 4.6. Otherwise, an INVALID_ENUM error is generated.
*/
if (destMask[output] == BAD_MASK) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)");
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)",
+ caller, _mesa_lookup_enum_by_nr(buffers[output]));
return;
- }
+ }
/* From the OpenGL 4.0 specification, page 256:
* "For both the default framebuffer and framebuffer objects, the
@@ -390,7 +426,8 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
* but the Khronos conformance tests expect INVALID_ENUM.
*/
if (_mesa_bitcount(destMask[output]) > 1) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)");
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)",
+ caller, _mesa_lookup_enum_by_nr(buffers[output]));
return;
}
@@ -407,7 +444,8 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
destMask[output] &= supportedMask;
if (destMask[output] == 0) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glDrawBuffersARB(unsupported buffer)");
+ "%s(unsupported buffer %s)",
+ caller, _mesa_lookup_enum_by_nr(buffers[output]));
return;
}
@@ -416,10 +454,12 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
* in bufs must be COLOR_ATTACHMENTi or NONE. [...] INVALID_OPERATION."
* (same restriction applies with GL_EXT_draw_buffers specification)
*/
- if (ctx->API == API_OPENGLES2 && _mesa_is_user_fbo(ctx->DrawBuffer) &&
+ if (ctx->API == API_OPENGLES2 && _mesa_is_user_fbo(fb) &&
buffers[output] != GL_NONE &&
buffers[output] != GL_COLOR_ATTACHMENT0 + output) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffers(buffer)");
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(unsupported buffer %s)",
+ caller, _mesa_lookup_enum_by_nr(buffers[output]));
return;
}
@@ -430,7 +470,8 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
*/
if (destMask[output] & usedBufferMask) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glDrawBuffersARB(duplicated buffer)");
+ "%s(duplicated buffer %s)",
+ caller, _mesa_lookup_enum_by_nr(buffers[output]));
return;
}
@@ -440,17 +481,48 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
}
/* OK, if we get here, there were no errors so set the new state */
- _mesa_drawbuffers(ctx, n, buffers, destMask);
+ _mesa_drawbuffers(ctx, fb, n, buffers, destMask);
/*
- * Call device driver function. Note that n can be equal to 0,
+ * Call device driver function if fb is the bound draw buffer.
+ * Note that n can be equal to 0,
* in which case we don't want to reference buffers[0], which
* may not be valid.
*/
- if (ctx->Driver.DrawBuffers)
- ctx->Driver.DrawBuffers(ctx, n, buffers);
- else if (ctx->Driver.DrawBuffer)
- ctx->Driver.DrawBuffer(ctx, n > 0 ? buffers[0] : GL_NONE);
+ if (fb == ctx->DrawBuffer) {
+ if (ctx->Driver.DrawBuffers)
+ ctx->Driver.DrawBuffers(ctx, n, buffers);
+ else if (ctx->Driver.DrawBuffer)
+ ctx->Driver.DrawBuffer(ctx, n > 0 ? buffers[0] : GL_NONE);
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_draw_buffers(ctx, ctx->DrawBuffer, n, buffers, "glDrawBuffers");
+}
+
+
+void GLAPIENTRY
+_mesa_NamedFramebufferDrawBuffers(GLuint framebuffer, GLsizei n,
+ const GLenum *bufs)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_framebuffer *fb;
+
+ if (framebuffer) {
+ fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+ "glNamedFramebufferDrawBuffers");
+ if (!fb)
+ return;
+ }
+ else
+ fb = ctx->WinSysDrawBuffer;
+
+ _mesa_draw_buffers(ctx, fb, n, bufs, "glNamedFramebufferDrawBuffers");
}
@@ -459,13 +531,11 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
* actual change.
*/
static void
-updated_drawbuffers(struct gl_context *ctx)
+updated_drawbuffers(struct gl_context *ctx, struct gl_framebuffer *fb)
{
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
if (ctx->API == API_OPENGL_COMPAT && !ctx->Extensions.ARB_ES2_compatibility) {
- struct gl_framebuffer *fb = ctx->DrawBuffer;
-
/* Flag the FBO as requiring validation. */
if (_mesa_is_user_fbo(fb)) {
fb->_Status = 0;
@@ -482,6 +552,7 @@ updated_drawbuffers(struct gl_context *ctx)
* so nothing should go wrong at this point.
*
* \param ctx current context
+ * \param fb the desired draw buffer
* \param n number of color outputs to set
* \param buffers array[n] of colorbuffer names, like GL_LEFT.
* \param destMask array[n] of BUFFER_BIT_* bitmasks which correspond to the
@@ -489,10 +560,9 @@ updated_drawbuffers(struct gl_context *ctx)
* BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT).
*/
void
-_mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
- const GLbitfield *destMask)
+_mesa_drawbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLuint n, const GLenum *buffers, const GLbitfield *destMask)
{
- struct gl_framebuffer *fb = ctx->DrawBuffer;
GLbitfield mask[MAX_DRAW_BUFFERS];
GLuint buf;
@@ -518,7 +588,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
while (destMask0) {
GLint bufIndex = ffs(destMask0) - 1;
if (fb->_ColorDrawBufferIndexes[count] != bufIndex) {
- updated_drawbuffers(ctx);
+ updated_drawbuffers(ctx, fb);
fb->_ColorDrawBufferIndexes[count] = bufIndex;
}
count++;
@@ -535,14 +605,14 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
/* only one bit should be set in the destMask[buf] field */
assert(_mesa_bitcount(destMask[buf]) == 1);
if (fb->_ColorDrawBufferIndexes[buf] != bufIndex) {
- updated_drawbuffers(ctx);
+ updated_drawbuffers(ctx, fb);
fb->_ColorDrawBufferIndexes[buf] = bufIndex;
}
count = buf + 1;
}
else {
if (fb->_ColorDrawBufferIndexes[buf] != -1) {
- updated_drawbuffers(ctx);
+ updated_drawbuffers(ctx, fb);
fb->_ColorDrawBufferIndexes[buf] = -1;
}
}
@@ -554,7 +624,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
/* set remaining outputs to -1 (GL_NONE) */
for (buf = fb->_NumColorDrawBuffers; buf < ctx->Const.MaxDrawBuffers; buf++) {
if (fb->_ColorDrawBufferIndexes[buf] != -1) {
- updated_drawbuffers(ctx);
+ updated_drawbuffers(ctx, fb);
fb->_ColorDrawBufferIndexes[buf] = -1;
}
}
@@ -566,7 +636,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
/* also set context drawbuffer state */
for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) {
if (ctx->Color.DrawBuffer[buf] != fb->ColorDrawBuffer[buf]) {
- updated_drawbuffers(ctx);
+ updated_drawbuffers(ctx, fb);
ctx->Color.DrawBuffer[buf] = fb->ColorDrawBuffer[buf];
}
}
@@ -585,7 +655,7 @@ _mesa_update_draw_buffers(struct gl_context *ctx)
/* should be a window system FBO */
assert(_mesa_is_winsys_fbo(ctx->DrawBuffer));
- _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers,
+ _mesa_drawbuffers(ctx, ctx->DrawBuffer, ctx->Const.MaxDrawBuffers,
ctx->Color.DrawBuffer, NULL);
}
@@ -598,11 +668,10 @@ _mesa_update_draw_buffers(struct gl_context *ctx)
* \param bufferIndex the numerical index corresponding to 'buffer'
*/
void
-_mesa_readbuffer(struct gl_context *ctx, GLenum buffer, GLint bufferIndex)
+_mesa_readbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLenum buffer, GLint bufferIndex)
{
- struct gl_framebuffer *fb = ctx->ReadBuffer;
-
- if (_mesa_is_winsys_fbo(fb)) {
+ if ((fb == ctx->ReadBuffer) && _mesa_is_winsys_fbo(fb)) {
/* Only update the per-context READ_BUFFER state if we're bound to
* a window-system framebuffer.
*/
@@ -621,23 +690,17 @@ _mesa_readbuffer(struct gl_context *ctx, GLenum buffer, GLint bufferIndex)
* Called by glReadBuffer to set the source renderbuffer for reading pixels.
* \param mode color buffer such as GL_FRONT, GL_BACK, etc.
*/
-void GLAPIENTRY
-_mesa_ReadBuffer(GLenum buffer)
+void
+_mesa_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLenum buffer, const char *caller)
{
- struct gl_framebuffer *fb;
GLbitfield supportedMask;
GLint srcBuffer;
- GET_CURRENT_CONTEXT(ctx);
FLUSH_VERTICES(ctx, 0);
if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
-
- fb = ctx->ReadBuffer;
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
+ _mesa_debug(ctx, "%s %s\n", caller, _mesa_lookup_enum_by_nr(buffer));
if (buffer == GL_NONE) {
/* This is legal--it means that no buffer should be bound for reading. */
@@ -648,24 +711,53 @@ _mesa_ReadBuffer(GLenum buffer)
srcBuffer = read_buffer_enum_to_index(buffer);
if (srcBuffer == -1) {
_mesa_error(ctx, GL_INVALID_ENUM,
- "glReadBuffer(buffer=0x%x)", buffer);
+ "%s(invalid buffer %s)", caller,
+ _mesa_lookup_enum_by_nr(buffer));
return;
}
supportedMask = supported_buffer_bitmask(ctx, fb);
if (((1 << srcBuffer) & supportedMask) == 0) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glReadBuffer(buffer=0x%x)", buffer);
+ "%s(invalid buffer %s)", caller,
+ _mesa_lookup_enum_by_nr(buffer));
return;
}
}
/* OK, all error checking has been completed now */
- _mesa_readbuffer(ctx, buffer, srcBuffer);
+ _mesa_readbuffer(ctx, fb, buffer, srcBuffer);
- /*
- * Call device driver function.
- */
- if (ctx->Driver.ReadBuffer)
- (*ctx->Driver.ReadBuffer)(ctx, buffer);
+ /* Call the device driver function only if fb is the bound read buffer */
+ if (fb == ctx->ReadBuffer) {
+ if (ctx->Driver.ReadBuffer)
+ (*ctx->Driver.ReadBuffer)(ctx, buffer);
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_ReadBuffer(GLenum buffer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_read_buffer(ctx, ctx->ReadBuffer, buffer, "glReadBuffer");
+}
+
+
+void GLAPIENTRY
+_mesa_NamedFramebufferReadBuffer(GLuint framebuffer, GLenum src)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_framebuffer *fb;
+
+ if (framebuffer) {
+ fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+ "glNamedFramebufferReadBuffer");
+ if (!fb)
+ return;
+ }
+ else
+ fb = ctx->WinSysReadBuffer;
+
+ _mesa_read_buffer(ctx, fb, src, "glNamedFramebufferReadBuffer");
}
diff --git a/src/mesa/main/buffers.h b/src/mesa/main/buffers.h
index ebcfa1c1e74..5aa79fda54b 100644
--- a/src/mesa/main/buffers.h
+++ b/src/mesa/main/buffers.h
@@ -36,26 +36,51 @@
#include "glheader.h"
struct gl_context;
+struct gl_framebuffer;
+
+extern void
+_mesa_draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLenum buffer, const char *caller);
extern void GLAPIENTRY
_mesa_DrawBuffer( GLenum mode );
extern void GLAPIENTRY
+_mesa_NamedFramebufferDrawBuffer(GLuint framebuffer, GLenum buf);
+
+extern void
+_mesa_draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLsizei n, const GLenum *buffers, const char *caller);
+
+extern void GLAPIENTRY
_mesa_DrawBuffers(GLsizei n, const GLenum *buffers);
+extern void GLAPIENTRY
+_mesa_NamedFramebufferDrawBuffers(GLuint framebuffer, GLsizei n,
+ const GLenum *bufs);
+
extern void
-_mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
+_mesa_drawbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLuint n, const GLenum *buffers,
const GLbitfield *destMask);
extern void
-_mesa_readbuffer(struct gl_context *ctx, GLenum buffer, GLint bufferIndex);
+_mesa_readbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLenum buffer, GLint bufferIndex);
extern void
_mesa_update_draw_buffers(struct gl_context *ctx);
+extern void
+_mesa_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLenum buffer, const char *caller);
+
extern void GLAPIENTRY
_mesa_ReadBuffer( GLenum mode );
+extern void GLAPIENTRY
+_mesa_NamedFramebufferReadBuffer(GLuint framebuffer, GLenum src);
+
#endif
diff --git a/src/mesa/main/clear.c b/src/mesa/main/clear.c
index 8d707bc34a1..426caea4709 100644
--- a/src/mesa/main/clear.c
+++ b/src/mesa/main/clear.c
@@ -34,6 +34,8 @@
#include "clear.h"
#include "context.h"
#include "enums.h"
+#include "fbobject.h"
+#include "get.h"
#include "macros.h"
#include "mtypes.h"
#include "state.h"
@@ -400,6 +402,24 @@ _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
/**
+ * The ClearBuffer framework is so complicated and so riddled with the
+ * assumption that the framebuffer is bound that, for now, we will just fake
+ * direct state access clearing for the user.
+ */
+void GLAPIENTRY
+_mesa_ClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer,
+ GLint drawbuffer, const GLint *value)
+{
+ GLint oldfb;
+
+ _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
+ _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
+ _mesa_ClearBufferiv(buffer, drawbuffer, value);
+ _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
+}
+
+
+/**
* New in GL 3.0
* Clear unsigned integer color buffer (not depth, not stencil).
*/
@@ -472,6 +492,24 @@ _mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
/**
+ * The ClearBuffer framework is so complicated and so riddled with the
+ * assumption that the framebuffer is bound that, for now, we will just fake
+ * direct state access clearing for the user.
+ */
+void GLAPIENTRY
+_mesa_ClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer,
+ GLint drawbuffer, const GLuint *value)
+{
+ GLint oldfb;
+
+ _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
+ _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
+ _mesa_ClearBufferuiv(buffer, drawbuffer, value);
+ _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
+}
+
+
+/**
* New in GL 3.0
* Clear fixed-pt or float color buffer or depth buffer (not stencil).
*/
@@ -565,6 +603,24 @@ _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
/**
+ * The ClearBuffer framework is so complicated and so riddled with the
+ * assumption that the framebuffer is bound that, for now, we will just fake
+ * direct state access clearing for the user.
+ */
+void GLAPIENTRY
+_mesa_ClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer,
+ GLint drawbuffer, const GLfloat *value)
+{
+ GLint oldfb;
+
+ _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
+ _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
+ _mesa_ClearBufferfv(buffer, drawbuffer, value);
+ _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
+}
+
+
+/**
* New in GL 3.0
* Clear depth/stencil buffer only.
*/
@@ -626,3 +682,21 @@ _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
ctx->Stencil.Clear = clearStencilSave;
}
}
+
+
+/**
+ * The ClearBuffer framework is so complicated and so riddled with the
+ * assumption that the framebuffer is bound that, for now, we will just fake
+ * direct state access clearing for the user.
+ */
+void GLAPIENTRY
+_mesa_ClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer,
+ GLfloat depth, GLint stencil)
+{
+ GLint oldfb;
+
+ _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
+ _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
+ _mesa_ClearBufferfi(buffer, 0, depth, stencil);
+ _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
+}
diff --git a/src/mesa/main/clear.h b/src/mesa/main/clear.h
index 96ce47b929e..c29850676ca 100644
--- a/src/mesa/main/clear.h
+++ b/src/mesa/main/clear.h
@@ -52,13 +52,29 @@ extern void GLAPIENTRY
_mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value);
extern void GLAPIENTRY
+_mesa_ClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer,
+ GLint drawbuffer, const GLint *value);
+
+extern void GLAPIENTRY
_mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value);
extern void GLAPIENTRY
+_mesa_ClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer,
+ GLint drawbuffer, const GLuint *value);
+
+extern void GLAPIENTRY
_mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value);
extern void GLAPIENTRY
+_mesa_ClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer,
+ GLint drawbuffer, const GLfloat *value);
+
+extern void GLAPIENTRY
_mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
GLfloat depth, GLint stencil);
+extern void GLAPIENTRY
+_mesa_ClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer,
+ GLfloat depth, GLint stencil);
+
#endif
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index 5a66a4eec90..9c3baf4c6aa 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -213,19 +213,10 @@
/** For GL_ARB_fragment_program */
/*@{*/
#define MAX_FRAGMENT_PROGRAM_ADDRESS_REGS 0
+#define MAX_FRAGMENT_PROGRAM_PARAMS 64
+#define MAX_FRAGMENT_PROGRAM_INPUTS 12
/*@}*/
-/** For GL_NV_fragment_program */
-/*@{*/
-#define MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS 1024 /* 72 for GL_ARB_f_p */
-#define MAX_NV_FRAGMENT_PROGRAM_TEMPS 96
-#define MAX_NV_FRAGMENT_PROGRAM_PARAMS 64
-#define MAX_NV_FRAGMENT_PROGRAM_INPUTS 12
-#define MAX_NV_FRAGMENT_PROGRAM_OUTPUTS 3
-#define MAX_NV_FRAGMENT_PROGRAM_WRITE_ONLYS 2
-/*@}*/
-
-
/** For GL_ARB_vertex_shader */
/*@{*/
#define MAX_VERTEX_GENERIC_ATTRIBS 16
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 0a192de8c0a..79fa01849e0 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -489,8 +489,8 @@ init_program_limits(struct gl_constants *consts, gl_shader_stage stage,
prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */
break;
case MESA_SHADER_FRAGMENT:
- prog->MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
- prog->MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
+ prog->MaxParameters = MAX_FRAGMENT_PROGRAM_PARAMS;
+ prog->MaxAttribs = MAX_FRAGMENT_PROGRAM_INPUTS;
prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */
@@ -883,6 +883,19 @@ update_default_objects(struct gl_context *ctx)
}
+/* XXX this is temporary and should be removed at some point in the
+ * future when there's a reasonable expectation that the libGL library
+ * contains the _glapi_new_nop_table() and _glapi_set_nop_handler()
+ * functions which were added in Mesa 10.6.
+ */
+#if !defined(_WIN32)
+/* Avoid libGL / driver ABI break */
+#define USE_GLAPI_NOP_FEATURES 0
+#else
+#define USE_GLAPI_NOP_FEATURES 1
+#endif
+
+
/**
* This function is called by the glapi no-op functions. For each OpenGL
* function/entrypoint there's a simple no-op function. These "no-op"
@@ -898,6 +911,7 @@ update_default_objects(struct gl_context *ctx)
*
* \param name the name of the OpenGL function
*/
+#if USE_GLAPI_NOP_FEATURES
static void
nop_handler(const char *name)
{
@@ -914,6 +928,7 @@ nop_handler(const char *name)
}
#endif
}
+#endif
/**
@@ -923,12 +938,52 @@ nop_handler(const char *name)
static void GLAPIENTRY
nop_glFlush(void)
{
- /* don't record an error like we do in _mesa_generic_nop() */
+ /* don't record an error like we do in nop_handler() */
+}
+#endif
+
+
+#if !USE_GLAPI_NOP_FEATURES
+static int
+generic_nop(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "unsupported function called "
+ "(unsupported extension or deprecated function?)");
+ return 0;
}
#endif
/**
+ * Create a new API dispatch table in which all entries point to the
+ * generic_nop() function. This will not work on Windows because of
+ * the __stdcall convention which requires the callee to clean up the
+ * call stack. That's impossible with one generic no-op function.
+ */
+struct _glapi_table *
+_mesa_new_nop_table(unsigned numEntries)
+{
+ struct _glapi_table *table;
+
+#if !USE_GLAPI_NOP_FEATURES
+ table = malloc(numEntries * sizeof(_glapi_proc));
+ if (table) {
+ _glapi_proc *entry = (_glapi_proc *) table;
+ unsigned i;
+ for (i = 0; i < numEntries; i++) {
+ entry[i] = (_glapi_proc) generic_nop;
+ }
+ }
+#else
+ table = _glapi_new_nop_table(numEntries);
+#endif
+ return table;
+}
+
+
+/**
* Allocate and initialize a new dispatch table. The table will be
* populated with pointers to "no-op" functions. In turn, the no-op
* functions will call nop_handler() above.
@@ -941,8 +996,9 @@ alloc_dispatch_table(void)
* Mesa we do this to accommodate different versions of libGL and various
* DRI drivers.
*/
- GLint numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT);
- struct _glapi_table *table = _glapi_new_nop_table(numEntries);
+ int numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT);
+
+ struct _glapi_table *table = _mesa_new_nop_table(numEntries);
#if defined(_WIN32)
if (table) {
@@ -966,7 +1022,9 @@ alloc_dispatch_table(void)
}
#endif
+#if USE_GLAPI_NOP_FEATURES
_glapi_set_nop_handler(nop_handler);
+#endif
return table;
}
@@ -1111,9 +1169,7 @@ _mesa_initialize_context(struct gl_context *ctx,
ctx->HasConfig = GL_FALSE;
}
- if (_mesa_is_desktop_gl(ctx)) {
- _mesa_override_gl_version(ctx);
- }
+ _mesa_override_gl_version(ctx);
/* misc one-time initializations */
one_time_init(ctx);
@@ -1275,7 +1331,6 @@ _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_geomprog(ctx, &ctx->GeometryProgram.Current, NULL);
_mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL);
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
@@ -1565,7 +1620,8 @@ handle_first_current(struct gl_context *ctx)
else
buffer = GL_FRONT;
- _mesa_drawbuffers(ctx, 1, &buffer, NULL /* destMask */);
+ _mesa_drawbuffers(ctx, ctx->DrawBuffer, 1, &buffer,
+ NULL /* destMask */);
}
if (ctx->ReadBuffer != _mesa_get_incomplete_framebuffer()) {
@@ -1578,7 +1634,7 @@ handle_first_current(struct gl_context *ctx)
bufferIndex = BUFFER_FRONT_LEFT;
}
- _mesa_readbuffer(ctx, buffer, bufferIndex);
+ _mesa_readbuffer(ctx, ctx->ReadBuffer, buffer, bufferIndex);
}
}
diff --git a/src/mesa/main/copyimage.c b/src/mesa/main/copyimage.c
index fd22f28892c..e8732c6175b 100644
--- a/src/mesa/main/copyimage.c
+++ b/src/mesa/main/copyimage.c
@@ -40,14 +40,25 @@ enum mesa_block_class {
BLOCK_CLASS_64_BITS
};
+/**
+ * Prepare the source or destination resource, including:
+ * - Error checking
+ * - Creating texture wrappers for renderbuffers
+ * \param name the texture or renderbuffer name
+ * \param target GL_TEXTURE target or GL_RENDERBUFFER. For the later, will
+ * be changed to a compatible GL_TEXTURE target.
+ * \param level mipmap level
+ * \param tex_obj returns a pointer to a texture object
+ * \param tex_image returns a pointer to a texture image
+ * \param tmp_tex returns temporary texture object name
+ * \return true if success, false if error
+ */
static bool
prepare_target(struct gl_context *ctx, GLuint name, GLenum *target, int level,
struct gl_texture_object **tex_obj,
struct gl_texture_image **tex_image, GLuint *tmp_tex,
const char *dbg_prefix)
{
- struct gl_renderbuffer *rb;
-
if (name == 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glCopyImageSubData(%sName = %d)", dbg_prefix, name);
@@ -87,7 +98,7 @@ prepare_target(struct gl_context *ctx, GLuint name, GLenum *target, int level,
}
if (*target == GL_RENDERBUFFER) {
- rb = _mesa_lookup_renderbuffer(ctx, name);
+ struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, name);
if (!rb) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glCopyImageSubData(%sName = %u)", dbg_prefix, name);
@@ -169,8 +180,15 @@ prepare_target(struct gl_context *ctx, GLuint name, GLenum *target, int level,
return true;
}
+
+/**
+ * Check that the x,y,z,width,height,region is within the texture image
+ * dimensions.
+ * \return true if bounds OK, false if regions is out of bounds
+ */
static bool
-check_region_bounds(struct gl_context *ctx, struct gl_texture_image *tex_image,
+check_region_bounds(struct gl_context *ctx,
+ const struct gl_texture_image *tex_image,
int x, int y, int z, int width, int height, int depth,
const char *dbg_prefix)
{
@@ -188,6 +206,7 @@ check_region_bounds(struct gl_context *ctx, struct gl_texture_image *tex_image,
return false;
}
+ /* Check X direction */
if (x + width > tex_image->Width) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glCopyImageSubData(%sX or %sWidth exceeds image bounds)",
@@ -195,6 +214,7 @@ check_region_bounds(struct gl_context *ctx, struct gl_texture_image *tex_image,
return false;
}
+ /* Check Y direction */
switch (tex_image->TexObject->Target) {
case GL_TEXTURE_1D:
case GL_TEXTURE_1D_ARRAY:
@@ -215,6 +235,7 @@ check_region_bounds(struct gl_context *ctx, struct gl_texture_image *tex_image,
break;
}
+ /* Check Z direction */
switch (tex_image->TexObject->Target) {
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
@@ -260,7 +281,7 @@ check_region_bounds(struct gl_context *ctx, struct gl_texture_image *tex_image,
}
static bool
-compressed_format_compatible(struct gl_context *ctx,
+compressed_format_compatible(const struct gl_context *ctx,
GLenum compressedFormat, GLenum otherFormat)
{
enum mesa_block_class compressedClass, otherClass;
@@ -348,8 +369,8 @@ compressed_format_compatible(struct gl_context *ctx,
}
static bool
-copy_format_compatible(struct gl_context *ctx,
- GLenum srcFormat, GLenum dstFormat)
+copy_format_compatible(const struct gl_context *ctx,
+ GLenum srcFormat, GLenum dstFormat)
{
/*
* From ARB_copy_image spec:
@@ -389,7 +410,7 @@ _mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel,
struct gl_texture_object *srcTexObj, *dstTexObj;
struct gl_texture_image *srcTexImage, *dstTexImage;
GLuint src_bw, src_bh, dst_bw, dst_bh;
- int i, srcNewZ, dstNewZ;
+ int i;
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glCopyImageSubData(%u, %s, %d, %d, %d, %d, "
@@ -447,6 +468,8 @@ _mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel,
}
for (i = 0; i < srcDepth; ++i) {
+ int srcNewZ, dstNewZ;
+
if (srcTexObj->Target == GL_TEXTURE_CUBE_MAP) {
srcTexImage = srcTexObj->Image[i + srcZ][srcLevel];
srcNewZ = 0;
diff --git a/src/mesa/main/depth.c b/src/mesa/main/depth.c
index 29851ecb8a4..bb4591cf152 100644
--- a/src/mesa/main/depth.c
+++ b/src/mesa/main/depth.c
@@ -65,6 +65,9 @@ _mesa_DepthFunc( GLenum func )
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glDepthFunc %s\n", _mesa_lookup_enum_by_nr(func));
+ if (ctx->Depth.Func == func)
+ return;
+
switch (func) {
case GL_LESS: /* (default) pass if incoming z < stored z */
case GL_GEQUAL:
@@ -80,9 +83,6 @@ _mesa_DepthFunc( GLenum func )
return;
}
- if (ctx->Depth.Func == func)
- return;
-
FLUSH_VERTICES(ctx, _NEW_DEPTH);
ctx->Depth.Func = func;
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index 431c4b48b79..aafe486fb60 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -7592,28 +7592,6 @@ save_FramebufferTexture(GLenum target, GLenum attachment,
}
}
-static void GLAPIENTRY
-save_FramebufferTextureFace(GLenum target, GLenum attachment,
- GLuint texture, GLint level, GLenum face)
-{
- Node *n;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_FRAMEBUFFER_TEXTURE_FACE, 5);
- if (n) {
- n[1].e = target;
- n[2].e = attachment;
- n[3].ui = texture;
- n[4].i = level;
- n[5].e = face;
- }
- if (ctx->ExecuteFlag) {
- CALL_FramebufferTextureFaceARB(ctx->Exec, (target, attachment, texture,
- level, face));
- }
-}
-
-
static void GLAPIENTRY
save_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
@@ -8873,11 +8851,6 @@ execute_list(struct gl_context *ctx, GLuint list)
CALL_FramebufferTexture(ctx->Exec, (n[1].e, n[2].e,
n[3].ui, n[4].i));
break;
- case OPCODE_FRAMEBUFFER_TEXTURE_FACE:
- CALL_FramebufferTextureFaceARB(ctx->Exec, (n[1].e, n[2].e,
- n[3].ui, n[4].i, n[5].e));
- break;
-
/* GL_ARB_sync */
case OPCODE_WAIT_SYNC:
{
@@ -9644,10 +9617,9 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
SET_BlendEquationiARB(table, save_BlendEquationi);
SET_BlendEquationSeparateiARB(table, save_BlendEquationSeparatei);
- /* GL_ARB_geometry_shader4 */
+ /* OpenGL 3.2 */
SET_ProgramParameteri(table, save_ProgramParameteri);
SET_FramebufferTexture(table, save_FramebufferTexture);
- SET_FramebufferTextureFaceARB(table, save_FramebufferTextureFace);
/* GL_NV_conditional_render */
SET_BeginConditionalRender(table, save_BeginConditionalRender);
diff --git a/src/mesa/main/errors.c b/src/mesa/main/errors.c
index 2aa1deb635f..b3406665d94 100644
--- a/src/mesa/main/errors.c
+++ b/src/mesa/main/errors.c
@@ -39,6 +39,7 @@
#include "mtypes.h"
#include "version.h"
#include "util/hash_table.h"
+#include "util/simple_list.h"
static mtx_t DynamicIDMutex = _MTX_INITIALIZER_NP;
static GLuint NextDynamicID = 1;
@@ -1412,6 +1413,26 @@ should_output(struct gl_context *ctx, GLenum error, const char *fmtString)
void
+_mesa_gl_vdebug(struct gl_context *ctx,
+ GLuint *id,
+ enum mesa_debug_source source,
+ enum mesa_debug_type type,
+ enum mesa_debug_severity severity,
+ const char *fmtString,
+ va_list args)
+{
+ char s[MAX_DEBUG_MESSAGE_LENGTH];
+ int len;
+
+ debug_get_id(id);
+
+ len = _mesa_vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args);
+
+ log_msg(ctx, source, type, *id, severity, len, s);
+}
+
+
+void
_mesa_gl_debug(struct gl_context *ctx,
GLuint *id,
enum mesa_debug_source source,
@@ -1419,17 +1440,10 @@ _mesa_gl_debug(struct gl_context *ctx,
enum mesa_debug_severity severity,
const char *fmtString, ...)
{
- char s[MAX_DEBUG_MESSAGE_LENGTH];
- int len;
va_list args;
-
- debug_get_id(id);
-
va_start(args, fmtString);
- len = _mesa_vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args);
+ _mesa_gl_vdebug(ctx, id, source, type, severity, fmtString, args);
va_end(args);
-
- log_msg(ctx, source, type, *id, severity, len, s);
}
diff --git a/src/mesa/main/errors.h b/src/mesa/main/errors.h
index e6dc9b5f1b9..24f234f7f10 100644
--- a/src/mesa/main/errors.h
+++ b/src/mesa/main/errors.h
@@ -76,6 +76,15 @@ extern FILE *
_mesa_get_log_file(void);
extern void
+_mesa_gl_vdebug(struct gl_context *ctx,
+ GLuint *id,
+ enum mesa_debug_source source,
+ enum mesa_debug_type type,
+ enum mesa_debug_severity severity,
+ const char *fmtString,
+ va_list args);
+
+extern void
_mesa_gl_debug(struct gl_context *ctx,
GLuint *id,
enum mesa_debug_source source,
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index f7ce0642aef..4176a69ed7c 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -104,7 +104,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_depth_clamp", o(ARB_depth_clamp), GL, 2003 },
{ "GL_ARB_depth_texture", o(ARB_depth_texture), GLL, 2001 },
{ "GL_ARB_derivative_control", o(ARB_derivative_control), GL, 2014 },
- { "GL_ARB_direct_state_access", o(dummy_false), GL, 2014 },
+ { "GL_ARB_direct_state_access", o(dummy_true), GLC, 2014 },
{ "GL_ARB_draw_buffers", o(dummy_true), GL, 2002 },
{ "GL_ARB_draw_buffers_blend", o(ARB_draw_buffers_blend), GL, 2009 },
{ "GL_ARB_draw_elements_base_vertex", o(ARB_draw_elements_base_vertex), GL, 2009 },
@@ -117,6 +117,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_fragment_program", o(ARB_fragment_program), GLL, 2002 },
{ "GL_ARB_fragment_program_shadow", o(ARB_fragment_program_shadow), GLL, 2003 },
{ "GL_ARB_fragment_shader", o(ARB_fragment_shader), GL, 2002 },
+ { "GL_ARB_framebuffer_no_attachments", o(ARB_framebuffer_no_attachments), GL, 2012 },
{ "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 },
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 27cf97f1778..f8dcf122d99 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -121,6 +121,27 @@ _mesa_lookup_renderbuffer(struct gl_context *ctx, GLuint id)
/**
+ * A convenience function for direct state access that throws
+ * GL_INVALID_OPERATION if the renderbuffer doesn't exist.
+ */
+struct gl_renderbuffer *
+_mesa_lookup_renderbuffer_err(struct gl_context *ctx, GLuint id,
+ const char *func)
+{
+ struct gl_renderbuffer *rb;
+
+ rb = _mesa_lookup_renderbuffer(ctx, id);
+ if (!rb || rb == &DummyRenderbuffer) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(non-existent renderbuffer %u)", func, id);
+ return NULL;
+ }
+
+ return rb;
+}
+
+
+/**
* Helper routine for getting a gl_framebuffer.
*/
struct gl_framebuffer *
@@ -138,6 +159,27 @@ _mesa_lookup_framebuffer(struct gl_context *ctx, GLuint id)
/**
+ * A convenience function for direct state access that throws
+ * GL_INVALID_OPERATION if the framebuffer doesn't exist.
+ */
+struct gl_framebuffer *
+_mesa_lookup_framebuffer_err(struct gl_context *ctx, GLuint id,
+ const char *func)
+{
+ struct gl_framebuffer *fb;
+
+ fb = _mesa_lookup_framebuffer(ctx, id);
+ if (!fb || fb == &DummyFramebuffer) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(non-existent framebuffer %u)", func, id);
+ return NULL;
+ }
+
+ return fb;
+}
+
+
+/**
* Mark the given framebuffer as invalid. This will force the
* test for framebuffer completeness to be done before the framebuffer
* is used.
@@ -423,7 +465,7 @@ set_texture_attachment(struct gl_context *ctx,
struct gl_framebuffer *fb,
struct gl_renderbuffer_attachment *att,
struct gl_texture_object *texObj,
- GLenum texTarget, GLuint level, GLuint zoffset,
+ GLenum texTarget, GLuint level, GLuint layer,
GLboolean layered)
{
struct gl_renderbuffer *rb = att->Renderbuffer;
@@ -447,7 +489,7 @@ set_texture_attachment(struct gl_context *ctx,
/* always update these fields */
att->TextureLevel = level;
att->CubeMapFace = _mesa_tex_target_to_face(texTarget);
- att->Zoffset = zoffset;
+ att->Zoffset = layer;
att->Layered = layered;
att->Complete = GL_FALSE;
@@ -479,9 +521,10 @@ set_renderbuffer_attachment(struct gl_context *ctx,
* Attach a renderbuffer object to a framebuffer object.
*/
void
-_mesa_framebuffer_renderbuffer(struct gl_context *ctx,
- struct gl_framebuffer *fb,
- GLenum attachment, struct gl_renderbuffer *rb)
+_mesa_FramebufferRenderbuffer_sw(struct gl_context *ctx,
+ struct gl_framebuffer *fb,
+ GLenum attachment,
+ struct gl_renderbuffer *rb)
{
struct gl_renderbuffer_attachment *att;
@@ -914,6 +957,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
fb->Height = 0;
fb->_AllColorBuffersFixedPoint = GL_TRUE;
fb->_HasSNormOrFloatColorBuffer = GL_FALSE;
+ fb->_HasAttachments = true;
/* Start at -2 to more easily loop over all attachment points.
* -2: depth buffer
@@ -1112,14 +1156,48 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
} else if (att_layer_count > max_layer_count) {
max_layer_count = att_layer_count;
}
+
+ /*
+ * The extension GL_ARB_framebuffer_no_attachments places additional
+ * requirement on each attachment. Those additional requirements are
+ * tighter that those of previous versions of GL. In interest of better
+ * compatibility, we will not enforce these restrictions. For the record
+ * those additional restrictions are quoted below:
+ *
+ * "The width and height of image are greater than zero and less than or
+ * equal to the values of the implementation-dependent limits
+ * MAX_FRAMEBUFFER_WIDTH and MAX_FRAMEBUFFER_HEIGHT, respectively."
+ *
+ * "If <image> is a three-dimensional texture or a one- or two-dimensional
+ * array texture and the attachment is layered, the depth or layer count
+ * of the texture is less than or equal to the implementation-dependent
+ * limit MAX_FRAMEBUFFER_LAYERS."
+ *
+ * "If image has multiple samples, its sample count is less than or equal
+ * to the value of the implementation-dependent limit
+ * MAX_FRAMEBUFFER_SAMPLES."
+ *
+ * The same requirements are also in place for GL 4.5,
+ * Section 9.4.1 "Framebuffer Attachment Completeness", pg 310-311
+ */
}
fb->MaxNumLayers = max_layer_count;
if (numImages == 0) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT;
- fbo_incomplete(ctx, "no attachments", -1);
- return;
+ fb->_HasAttachments = false;
+
+ if (!ctx->Extensions.ARB_framebuffer_no_attachments) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT;
+ fbo_incomplete(ctx, "no attachments", -1);
+ return;
+ }
+
+ if (fb->DefaultGeometry.Width == 0 || fb->DefaultGeometry.Height == 0) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT;
+ fbo_incomplete(ctx, "no attachments and default width or height is 0", -1);
+ return;
+ }
}
if (_mesa_is_desktop_gl(ctx) && !ctx->Extensions.ARB_ES2_compatibility) {
@@ -1184,8 +1262,10 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
* renderbuffers/textures are different sizes, the framebuffer
* width/height will be set to the smallest width/height.
*/
- fb->Width = minWidth;
- fb->Height = minHeight;
+ if (numImages != 0) {
+ fb->Width = minWidth;
+ fb->Height = minHeight;
+ }
/* finally, update the visual info for the framebuffer */
_mesa_update_framebuffer_visual(ctx, fb);
@@ -1291,6 +1371,131 @@ _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
bind_renderbuffer(target, renderbuffer, true);
}
+static void
+framebuffer_parameteri(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLenum pname, GLint param, const char *func)
+{
+ switch (pname) {
+ case GL_FRAMEBUFFER_DEFAULT_WIDTH:
+ if (param < 0 || param > ctx->Const.MaxFramebufferWidth)
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s", func);
+ else
+ fb->DefaultGeometry.Width = param;
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
+ if (param < 0 || param > ctx->Const.MaxFramebufferHeight)
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s", func);
+ else
+ fb->DefaultGeometry.Height = param;
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_LAYERS:
+ if (param < 0 || param > ctx->Const.MaxFramebufferLayers)
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s", func);
+ else
+ fb->DefaultGeometry.Layers = param;
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
+ if (param < 0 || param > ctx->Const.MaxFramebufferSamples)
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s", func);
+ else
+ fb->DefaultGeometry.NumSamples = param;
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
+ fb->DefaultGeometry.FixedSampleLocations = param;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "%s(pname=0x%x)", func, pname);
+ }
+}
+
+void GLAPIENTRY
+_mesa_FramebufferParameteri(GLenum target, GLenum pname, GLint param)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_framebuffer *fb;
+
+ if (!ctx->Extensions.ARB_framebuffer_no_attachments) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferParameteriv not supported "
+ "(ARB_framebuffer_no_attachments not implemented)");
+ return;
+ }
+
+ fb = get_framebuffer_target(ctx, target);
+ if (!fb) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferParameteri(target=0x%x)", target);
+ return;
+ }
+
+ /* check framebuffer binding */
+ if (_mesa_is_winsys_fbo(fb)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferParameteri");
+ return;
+ }
+
+ framebuffer_parameteri(ctx, fb, pname, param, "glFramebufferParameteri");
+}
+
+static void
+get_framebuffer_parameteriv(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLenum pname, GLint *params, const char *func)
+{
+ switch (pname) {
+ case GL_FRAMEBUFFER_DEFAULT_WIDTH:
+ *params = fb->DefaultGeometry.Width;
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
+ *params = fb->DefaultGeometry.Height;
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_LAYERS:
+ *params = fb->DefaultGeometry.Layers;
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
+ *params = fb->DefaultGeometry.NumSamples;
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
+ *params = fb->DefaultGeometry.FixedSampleLocations;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "%s(pname=0x%x)", func, pname);
+ }
+}
+
+void GLAPIENTRY
+_mesa_GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_framebuffer *fb;
+
+ if (!ctx->Extensions.ARB_framebuffer_no_attachments) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetFramebufferParameteriv not supported "
+ "(ARB_framebuffer_no_attachments not implemented)");
+ return;
+ }
+
+ fb = get_framebuffer_target(ctx, target);
+ if (!fb) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferParameteriv(target=0x%x)", target);
+ return;
+ }
+
+ /* check framebuffer binding */
+ if (_mesa_is_winsys_fbo(fb)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetFramebufferParameteriv");
+ return;
+ }
+
+ get_framebuffer_parameteriv(ctx, fb, pname, params,
+ "glGetFramebufferParameteriv");
+}
+
/**
* Remove the specified renderbuffer or texture from any attachment point in
@@ -2396,15 +2601,23 @@ _mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
}
-void GLAPIENTRY
-_mesa_GenFramebuffers(GLsizei n, GLuint *framebuffers)
+/**
+ * This is the implementation for glGenFramebuffers and glCreateFramebuffers.
+ * It is not exposed to the rest of Mesa to encourage the use of
+ * nameless buffers in driver internals.
+ */
+static void
+create_framebuffers(GLsizei n, GLuint *framebuffers, bool dsa)
{
GET_CURRENT_CONTEXT(ctx);
GLuint first;
GLint i;
+ struct gl_framebuffer *fb;
+
+ const char *func = dsa ? "glCreateFramebuffers" : "glGenFramebuffers";
if (n < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGenFramebuffersEXT(n)");
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
return;
}
@@ -2416,31 +2629,43 @@ _mesa_GenFramebuffers(GLsizei n, GLuint *framebuffers)
for (i = 0; i < n; i++) {
GLuint name = first + i;
framebuffers[i] = name;
- /* insert dummy placeholder into hash table */
+
+ if (dsa) {
+ fb = ctx->Driver.NewFramebuffer(ctx, framebuffers[i]);
+ if (!fb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
+ return;
+ }
+ }
+ else
+ fb = &DummyFramebuffer;
+
mtx_lock(&ctx->Shared->Mutex);
- _mesa_HashInsert(ctx->Shared->FrameBuffers, name, &DummyFramebuffer);
+ _mesa_HashInsert(ctx->Shared->FrameBuffers, name, fb);
mtx_unlock(&ctx->Shared->Mutex);
}
}
-GLenum GLAPIENTRY
-_mesa_CheckFramebufferStatus(GLenum target)
+void GLAPIENTRY
+_mesa_GenFramebuffers(GLsizei n, GLuint *framebuffers)
{
- struct gl_framebuffer *buffer;
- GET_CURRENT_CONTEXT(ctx);
+ create_framebuffers(n, framebuffers, false);
+}
- ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glCheckFramebufferStatus(%s)\n",
- _mesa_lookup_enum_by_nr(target));
+void GLAPIENTRY
+_mesa_CreateFramebuffers(GLsizei n, GLuint *framebuffers)
+{
+ create_framebuffers(n, framebuffers, true);
+}
- buffer = get_framebuffer_target(ctx, target);
- if (!buffer) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)");
- return 0;
- }
+
+GLenum
+_mesa_check_framebuffer_status(struct gl_context *ctx,
+ struct gl_framebuffer *buffer)
+{
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
if (_mesa_is_winsys_fbo(buffer)) {
/* EGL_KHR_surfaceless_context allows the winsys FBO to be incomplete. */
@@ -2461,6 +2686,67 @@ _mesa_CheckFramebufferStatus(GLenum target)
}
+GLenum GLAPIENTRY
+_mesa_CheckFramebufferStatus(GLenum target)
+{
+ struct gl_framebuffer *fb;
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glCheckFramebufferStatus(%s)\n",
+ _mesa_lookup_enum_by_nr(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));
+ return 0;
+ }
+
+ return _mesa_check_framebuffer_status(ctx, fb);
+}
+
+
+GLenum GLAPIENTRY
+_mesa_CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target)
+{
+ struct gl_framebuffer *fb;
+ GET_CURRENT_CONTEXT(ctx);
+
+ /* Validate the target (for conformance's sake) and grab a reference to the
+ * default framebuffer in case framebuffer = 0.
+ * Section 9.4 Framebuffer Completeness of the OpenGL 4.5 core spec
+ * (30.10.2014, PDF page 336) says:
+ * "If framebuffer is zero, then the status of the default read or
+ * draw framebuffer (as determined by target) is returned."
+ */
+ switch (target) {
+ case GL_DRAW_FRAMEBUFFER:
+ case GL_FRAMEBUFFER:
+ fb = ctx->WinSysDrawBuffer;
+ break;
+ case GL_READ_FRAMEBUFFER:
+ fb = ctx->WinSysReadBuffer;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glCheckNamedFramebufferStatus(invalid target %s)",
+ _mesa_lookup_enum_by_nr(target));
+ return 0;
+ }
+
+ if (framebuffer) {
+ fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+ "glCheckNamedFramebufferStatus");
+ if (!fb)
+ return 0;
+ }
+
+ return _mesa_check_framebuffer_status(ctx, fb);
+}
+
+
/**
* Replicate the src attachment point. Used by framebuffer_texture() when
* the same texture is attached at GL_DEPTH_ATTACHMENT and
@@ -2487,144 +2773,308 @@ reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb,
/**
- * Common code called by glFramebufferTexture1D/2D/3D() and
- * glFramebufferTextureLayer().
+ * Common code called by gl*FramebufferTexture*() to retrieve the correct
+ * texture object pointer.
*
- * \param textarget is the textarget that was passed to the
- * glFramebufferTexture...() function, or 0 if the corresponding function
- * doesn't have a textarget parameter.
+ * \param texObj where the pointer to the texture object is returned. Note
+ * that a successful call may return texObj = NULL.
*
- * \param layered is true if this function was called from
- * glFramebufferTexture(), false otherwise.
+ * \return true if no errors, false if errors
*/
-static void
-framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
- GLenum attachment, GLenum textarget, GLuint texture,
- GLint level, GLuint zoffset, GLboolean layered)
+static bool
+get_texture_for_framebuffer(struct gl_context *ctx, GLuint texture,
+ bool layered, const char *caller,
+ struct gl_texture_object **texObj)
{
- struct gl_renderbuffer_attachment *att;
- struct gl_texture_object *texObj = NULL;
- struct gl_framebuffer *fb;
- GLenum maxLevelsTarget;
+ *texObj = NULL; /* This will get returned if texture = 0. */
- fb = get_framebuffer_target(ctx, target);
- if (!fb) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferTexture%s(target=0x%x)", caller, target);
- return;
+ if (!texture)
+ return true;
+
+ *texObj = _mesa_lookup_texture(ctx, texture);
+ if (*texObj == NULL || (*texObj)->Target == 0) {
+ /* Can't render to a non-existent texture object.
+ *
+ * The OpenGL 4.5 core spec (02.02.2015) in Section 9.2 Binding and
+ * Managing Framebuffer Objects specifies a different error
+ * depending upon the calling function (PDF pages 325-328).
+ * *FramebufferTexture (where layered = GL_TRUE) throws invalid
+ * value, while the other commands throw invalid operation (where
+ * layered = GL_FALSE).
+ */
+ const GLenum error = layered ? GL_INVALID_VALUE :
+ GL_INVALID_OPERATION;
+ _mesa_error(ctx, error,
+ "%s(non-existent texture %u)", caller, texture);
+ return false;
}
- /* check framebuffer binding */
- if (_mesa_is_winsys_fbo(fb)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture%s", caller);
- return;
+ return true;
+}
+
+
+/**
+ * Common code called by gl*FramebufferTexture() to verify the texture target
+ * and decide whether or not the attachment should truly be considered
+ * layered.
+ *
+ * \param layered true if attachment should be considered layered, false if
+ * not
+ *
+ * \return true if no errors, false if errors
+ */
+static bool
+check_layered_texture_target(struct gl_context *ctx, GLenum target,
+ const char *caller, GLboolean *layered)
+{
+ *layered = GL_TRUE;
+
+ switch (target) {
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ case GL_TEXTURE_CUBE_MAP:
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return true;
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_RECTANGLE:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ /* These texture types are valid to pass to
+ * glFramebufferTexture(), but since they aren't layered, it
+ * is equivalent to calling glFramebufferTexture{1D,2D}().
+ */
+ *layered = GL_FALSE;
+ return true;
}
- /* The textarget, level, and zoffset parameters are only validated if
- * texture is non-zero.
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(invalid texture target %s)", caller,
+ _mesa_lookup_enum_by_nr(target));
+ return false;
+}
+
+
+/**
+ * Common code called by gl*FramebufferTextureLayer() to verify the texture
+ * target.
+ *
+ * \return true if no errors, false if errors
+ */
+static bool
+check_texture_target(struct gl_context *ctx, GLenum target,
+ const char *caller)
+{
+ /* We're being called by glFramebufferTextureLayer().
+ * The only legal texture types for that function are 3D,
+ * cube-map, and 1D/2D/cube-map array textures.
+ *
+ * We don't need to check for GL_ARB_texture_cube_map_array because the
+ * application wouldn't have been able to create a texture with a
+ * GL_TEXTURE_CUBE_MAP_ARRAY target if the extension were not enabled.
*/
- if (texture) {
- GLboolean err = GL_TRUE;
-
- texObj = _mesa_lookup_texture(ctx, texture);
- if (texObj != NULL) {
- if (textarget == 0) {
- if (layered) {
- /* We're being called by glFramebufferTexture() and textarget
- * is not used.
- */
- switch (texObj->Target) {
- case GL_TEXTURE_3D:
- case GL_TEXTURE_1D_ARRAY_EXT:
- case GL_TEXTURE_2D_ARRAY_EXT:
- case GL_TEXTURE_CUBE_MAP:
- case GL_TEXTURE_CUBE_MAP_ARRAY:
- case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
- err = false;
- break;
- case GL_TEXTURE_1D:
- case GL_TEXTURE_2D:
- case GL_TEXTURE_RECTANGLE:
- case GL_TEXTURE_2D_MULTISAMPLE:
- /* These texture types are valid to pass to
- * glFramebufferTexture(), but since they aren't layered, it
- * is equivalent to calling glFramebufferTexture{1D,2D}().
- */
- err = false;
- layered = false;
- textarget = texObj->Target;
- break;
- default:
- err = true;
- break;
- }
- } else {
- /* We're being called by glFramebufferTextureLayer() and
- * textarget is not used. The only legal texture types for
- * that function are 3D and 1D/2D arrays textures.
- */
- err = (texObj->Target != GL_TEXTURE_3D) &&
- (texObj->Target != GL_TEXTURE_1D_ARRAY_EXT) &&
- (texObj->Target != GL_TEXTURE_2D_ARRAY_EXT) &&
- (texObj->Target != GL_TEXTURE_CUBE_MAP_ARRAY) &&
- (texObj->Target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
- }
- }
- else {
- /* Make sure textarget is consistent with the texture's type */
- err = (texObj->Target == GL_TEXTURE_CUBE_MAP)
- ? !_mesa_is_cube_face(textarget)
- : (texObj->Target != textarget);
- }
+ switch (target) {
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_1D_ARRAY:
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return true;
+ case GL_TEXTURE_CUBE_MAP:
+ /* We don't need to check the extension (GL_ARB_direct_state_access) or
+ * GL version (4.5) for GL_TEXTURE_CUBE_MAP because DSA is always
+ * enabled in core profile. This can be called from
+ * _mesa_FramebufferTextureLayer in compatibility profile (OpenGL 3.0),
+ * so we do have to check the profile.
+ */
+ return ctx->API == API_OPENGL_CORE;
+ }
+
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(invalid texture target %s)", caller,
+ _mesa_lookup_enum_by_nr(target));
+ return false;
+}
+
+
+/**
+ * Common code called by glFramebufferTexture*D() to verify the texture
+ * target.
+ *
+ * \return true if no errors, false if errors
+ */
+static bool
+check_textarget(struct gl_context *ctx, int dims, GLenum target,
+ GLenum textarget, const char *caller)
+{
+ bool err = false;
+
+ switch (dims) {
+ case 1:
+ switch (textarget) {
+ case GL_TEXTURE_1D:
+ break;
+ case GL_TEXTURE_1D_ARRAY:
+ err = !ctx->Extensions.EXT_texture_array;
+ break;
+ default:
+ err = true;
}
- else {
- /* can't render to a non-existant texture */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture%s(non existant texture)",
- caller);
- return;
+ break;
+ case 2:
+ switch (textarget) {
+ case GL_TEXTURE_2D:
+ break;
+ case GL_TEXTURE_RECTANGLE:
+ err = _mesa_is_gles(ctx)
+ || !ctx->Extensions.NV_texture_rectangle;
+ 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:
+ err = !ctx->Extensions.ARB_texture_cube_map;
+ break;
+ case GL_TEXTURE_2D_ARRAY:
+ err = (_mesa_is_gles(ctx) && ctx->Version < 30)
+ || !ctx->Extensions.EXT_texture_array;
+ break;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ err = _mesa_is_gles(ctx)
+ || !ctx->Extensions.ARB_texture_multisample;
+ break;
+ default:
+ err = true;
}
+ break;
+ case 3:
+ if (textarget != GL_TEXTURE_3D)
+ err = true;
+ break;
+ default:
+ err = true;
+ }
- if (err) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture%s(texture target mismatch)",
- caller);
- return;
- }
+ if (err) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(invalid textarget %s)",
+ caller, _mesa_lookup_enum_by_nr(textarget));
+ return false;
+ }
- if (texObj->Target == GL_TEXTURE_3D) {
- const GLuint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
- if (zoffset >= maxSize) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferTexture%s(zoffset)", caller);
- return;
- }
+ /* Make sure textarget is consistent with the texture's type */
+ err = (target == GL_TEXTURE_CUBE_MAP) ?
+ !_mesa_is_cube_face(textarget): (target != textarget);
+
+ if (err) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(mismatched texture target)", caller);
+ return false;
+ }
+
+ return true;
+}
+
+
+/**
+ * Common code called by gl*FramebufferTextureLayer() and
+ * glFramebufferTexture3D() to validate the layer.
+ *
+ * \return true if no errors, false if errors
+ */
+static bool
+check_layer(struct gl_context *ctx, GLenum target, GLint layer,
+ const char *caller)
+{
+ /* Page 306 (page 328 of the PDF) of the OpenGL 4.5 (Core Profile)
+ * spec says:
+ *
+ * "An INVALID_VALUE error is generated if texture is non-zero
+ * and layer is negative."
+ */
+ if (layer < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(layer %u < 0)", caller, layer);
+ return false;
+ }
+
+ if (target == GL_TEXTURE_3D) {
+ const GLuint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
+ if (layer >= maxSize) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(invalid layer %u)", caller, layer);
+ return false;
}
- else if ((texObj->Target == GL_TEXTURE_1D_ARRAY_EXT) ||
- (texObj->Target == GL_TEXTURE_2D_ARRAY_EXT) ||
- (texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY) ||
- (texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)) {
- if (zoffset >= ctx->Const.MaxArrayTextureLayers) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferTexture%s(layer)", caller);
- return;
- }
+ }
+ else if ((target == GL_TEXTURE_1D_ARRAY) ||
+ (target == GL_TEXTURE_2D_ARRAY) ||
+ (target == GL_TEXTURE_CUBE_MAP_ARRAY) ||
+ (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)) {
+ if (layer >= ctx->Const.MaxArrayTextureLayers) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(layer %u >= GL_MAX_ARRAY_TEXTURE_LAYERS)",
+ caller, layer);
+ return false;
}
-
- maxLevelsTarget = textarget ? textarget : texObj->Target;
- if ((level < 0) ||
- (level >= _mesa_max_texture_levels(ctx, maxLevelsTarget))) {
+ }
+ else if (target == GL_TEXTURE_CUBE_MAP) {
+ if (layer >= 6) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferTexture%s(level)", caller);
- return;
+ "%s(layer %u >= 6)", caller, layer);
+ return false;
}
}
+ return true;
+}
+
+
+/**
+ * Common code called by all gl*FramebufferTexture*() entry points to verify
+ * the level.
+ *
+ * \return true if no errors, false if errors
+ */
+static bool
+check_level(struct gl_context *ctx, GLenum target, GLint level,
+ const char *caller)
+{
+ if ((level < 0) ||
+ (level >= _mesa_max_texture_levels(ctx, target))) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(invalid level %d)", caller, level);
+ return false;
+ }
+
+ return true;
+}
+
+
+void
+_mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLenum attachment,
+ struct gl_texture_object *texObj, GLenum textarget,
+ GLint level, GLuint layer, GLboolean layered,
+ const char *caller)
+{
+ struct gl_renderbuffer_attachment *att;
+
+ /* The window-system framebuffer object is immutable */
+ if (_mesa_is_winsys_fbo(fb)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(window-system framebuffer)",
+ caller);
+ return;
+ }
+
+ /* Not a hash lookup, so we can afford to get the attachment here. */
att = get_attachment(ctx, fb, attachment);
if (att == NULL) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferTexture%s(attachment)", caller);
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid attachment %s)", caller,
+ _mesa_lookup_enum_by_nr(attachment));
return;
}
@@ -2637,7 +3087,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
level == fb->Attachment[BUFFER_STENCIL].TextureLevel &&
_mesa_tex_target_to_face(textarget) ==
fb->Attachment[BUFFER_STENCIL].CubeMapFace &&
- zoffset == fb->Attachment[BUFFER_STENCIL].Zoffset) {
+ layer == fb->Attachment[BUFFER_STENCIL].Zoffset) {
/* The texture object is already attached to the stencil attachment
* point. Don't create a new renderbuffer; just reuse the stencil
* attachment's. This is required to prevent a GL error in
@@ -2650,13 +3100,14 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
level == fb->Attachment[BUFFER_DEPTH].TextureLevel &&
_mesa_tex_target_to_face(textarget) ==
fb->Attachment[BUFFER_DEPTH].CubeMapFace &&
- zoffset == fb->Attachment[BUFFER_DEPTH].Zoffset) {
+ layer == fb->Attachment[BUFFER_DEPTH].Zoffset) {
/* As above, but with depth and stencil transposed. */
reuse_framebuffer_texture_attachment(fb, BUFFER_STENCIL,
BUFFER_DEPTH);
} else {
set_texture_attachment(ctx, fb, att, texObj, textarget,
- level, zoffset, layered);
+ level, layer, layered);
+
if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
/* Above we created a new renderbuffer and attached it to the
* depth attachment point. Now attach it to the stencil attachment
@@ -2692,116 +3143,157 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
}
-void GLAPIENTRY
-_mesa_FramebufferTexture1D(GLenum target, GLenum attachment,
- GLenum textarget, GLuint texture, GLint level)
+static void
+framebuffer_texture_with_dims(int dims, GLenum target,
+ GLenum attachment, GLenum textarget,
+ GLuint texture, GLint level, GLint layer,
+ const char *caller)
{
GET_CURRENT_CONTEXT(ctx);
+ struct gl_framebuffer *fb;
+ struct gl_texture_object *texObj;
+
+ /* Get the framebuffer object */
+ 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));
+ return;
+ }
- if (texture != 0) {
- GLboolean error;
+ /* Get the texture object */
+ if (!get_texture_for_framebuffer(ctx, texture, false, caller, &texObj))
+ return;
- switch (textarget) {
- case GL_TEXTURE_1D:
- error = GL_FALSE;
- break;
- case GL_TEXTURE_1D_ARRAY:
- error = !ctx->Extensions.EXT_texture_array;
- break;
- default:
- error = GL_TRUE;
- }
+ if (texObj) {
+ if (!check_textarget(ctx, dims, texObj->Target, textarget, caller))
+ return;
- if (error) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture1D(textarget=%s)",
- _mesa_lookup_enum_by_nr(textarget));
+ if ((dims == 3) && !check_layer(ctx, texObj->Target, layer, caller))
return;
- }
}
- framebuffer_texture(ctx, "1D", target, attachment, textarget, texture,
- level, 0, GL_FALSE);
+ if (!check_level(ctx, textarget, level, caller))
+ return;
+
+ _mesa_framebuffer_texture(ctx, fb, attachment, texObj, textarget, level,
+ layer, GL_FALSE, caller);
}
void GLAPIENTRY
-_mesa_FramebufferTexture2D(GLenum target, GLenum attachment,
+_mesa_FramebufferTexture1D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level)
{
- GET_CURRENT_CONTEXT(ctx);
-
- if (texture != 0) {
- GLboolean error;
-
- switch (textarget) {
- case GL_TEXTURE_2D:
- error = GL_FALSE;
- break;
- case GL_TEXTURE_RECTANGLE:
- error = _mesa_is_gles(ctx)
- || !ctx->Extensions.NV_texture_rectangle;
- 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:
- error = !ctx->Extensions.ARB_texture_cube_map;
- break;
- case GL_TEXTURE_2D_ARRAY:
- error = (_mesa_is_gles(ctx) && ctx->Version < 30)
- || !ctx->Extensions.EXT_texture_array;
- break;
- case GL_TEXTURE_2D_MULTISAMPLE:
- case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
- error = _mesa_is_gles(ctx)
- || !ctx->Extensions.ARB_texture_multisample;
- break;
- default:
- error = GL_TRUE;
- }
+ framebuffer_texture_with_dims(1, target, attachment, textarget, texture,
+ level, 0, "glFramebufferTexture1D");
+}
- if (error) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture2D(textarget=%s)",
- _mesa_lookup_enum_by_nr(textarget));
- return;
- }
- }
- framebuffer_texture(ctx, "2D", target, attachment, textarget, texture,
- level, 0, GL_FALSE);
+void GLAPIENTRY
+_mesa_FramebufferTexture2D(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level)
+{
+ framebuffer_texture_with_dims(2, target, attachment, textarget, texture,
+ level, 0, "glFramebufferTexture2D");
}
void GLAPIENTRY
_mesa_FramebufferTexture3D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture,
- GLint level, GLint zoffset)
+ GLint level, GLint layer)
+{
+ framebuffer_texture_with_dims(3, target, attachment, textarget, texture,
+ level, layer, "glFramebufferTexture3D");
+}
+
+
+void GLAPIENTRY
+_mesa_FramebufferTextureLayer(GLenum target, GLenum attachment,
+ GLuint texture, GLint level, GLint layer)
{
GET_CURRENT_CONTEXT(ctx);
+ struct gl_framebuffer *fb;
+ struct gl_texture_object *texObj;
+ GLenum textarget = 0;
- if ((texture != 0) && (textarget != GL_TEXTURE_3D)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture3D(textarget)");
+ const char *func = "glFramebufferTextureLayer";
+
+ /* Get the framebuffer object */
+ fb = get_framebuffer_target(ctx, target);
+ if (!fb) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferTextureLayer(invalid target %s)",
+ _mesa_lookup_enum_by_nr(target));
return;
}
- framebuffer_texture(ctx, "3D", target, attachment, textarget, texture,
- level, zoffset, GL_FALSE);
+ /* Get the texture object */
+ if (!get_texture_for_framebuffer(ctx, texture, false, func, &texObj))
+ return;
+
+ if (texObj) {
+ if (!check_texture_target(ctx, texObj->Target, func))
+ return;
+
+ if (!check_layer(ctx, texObj->Target, layer, func))
+ return;
+
+ if (!check_level(ctx, texObj->Target, level, func))
+ return;
+
+ if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
+ assert(layer >= 0 && layer < 6);
+ textarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
+ layer = 0;
+ }
+ }
+
+ _mesa_framebuffer_texture(ctx, fb, attachment, texObj, textarget, level,
+ layer, GL_FALSE, func);
}
void GLAPIENTRY
-_mesa_FramebufferTextureLayer(GLenum target, GLenum attachment,
- GLuint texture, GLint level, GLint layer)
+_mesa_NamedFramebufferTextureLayer(GLuint framebuffer, GLenum attachment,
+ GLuint texture, GLint level, GLint layer)
{
GET_CURRENT_CONTEXT(ctx);
+ struct gl_framebuffer *fb;
+ struct gl_texture_object *texObj;
+ GLenum textarget = 0;
+
+ const char *func = "glNamedFramebufferTextureLayer";
+
+ /* Get the framebuffer object */
+ fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, func);
+ if (!fb)
+ return;
+
+ /* Get the texture object */
+ if (!get_texture_for_framebuffer(ctx, texture, false, func, &texObj))
+ return;
+
+ if (texObj) {
+ if (!check_texture_target(ctx, texObj->Target, func))
+ return;
- framebuffer_texture(ctx, "Layer", target, attachment, 0, texture,
- level, layer, GL_FALSE);
+ if (!check_layer(ctx, texObj->Target, layer, func))
+ return;
+
+ if (!check_level(ctx, texObj->Target, level, func))
+ return;
+
+ if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
+ assert(layer >= 0 && layer < 6);
+ textarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
+ layer = 0;
+ }
+ }
+
+ _mesa_framebuffer_texture(ctx, fb, attachment, texObj, textarget, level,
+ layer, GL_FALSE, func);
}
@@ -2810,82 +3302,115 @@ _mesa_FramebufferTexture(GLenum target, GLenum attachment,
GLuint texture, GLint level)
{
GET_CURRENT_CONTEXT(ctx);
+ struct gl_framebuffer *fb;
+ struct gl_texture_object *texObj;
+ GLboolean layered;
- if (_mesa_has_geometry_shaders(ctx)) {
- framebuffer_texture(ctx, "", target, attachment, 0, texture,
- level, 0, GL_TRUE);
- } else {
+ const char *func = "FramebufferTexture";
+
+ if (!_mesa_has_geometry_shaders(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"unsupported function (glFramebufferTexture) called");
+ return;
}
+
+ /* Get the framebuffer object */
+ fb = get_framebuffer_target(ctx, target);
+ if (!fb) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferTexture(invalid target %s)",
+ _mesa_lookup_enum_by_nr(target));
+ return;
+ }
+
+ /* Get the texture object */
+ if (!get_texture_for_framebuffer(ctx, texture, true, func, &texObj))
+ return;
+
+ if (texObj) {
+ if (!check_layered_texture_target(ctx, texObj->Target, func, &layered))
+ return;
+
+ if (!check_level(ctx, texObj->Target, level, func))
+ return;
+ }
+
+ _mesa_framebuffer_texture(ctx, fb, attachment, texObj, 0, level,
+ 0, layered, func);
}
void GLAPIENTRY
-_mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment,
- GLenum renderbufferTarget,
- GLuint renderbuffer)
+_mesa_NamedFramebufferTexture(GLuint framebuffer, GLenum attachment,
+ GLuint texture, GLint level)
{
- struct gl_renderbuffer_attachment *att;
- struct gl_framebuffer *fb;
- struct gl_renderbuffer *rb;
GET_CURRENT_CONTEXT(ctx);
+ struct gl_framebuffer *fb;
+ struct gl_texture_object *texObj;
+ GLboolean layered;
- fb = get_framebuffer_target(ctx, target);
- if (!fb) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferRenderbuffer(target)");
+ const char *func = "glNamedFramebufferTexture";
+
+ if (!_mesa_has_geometry_shaders(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "unsupported function (glNamedFramebufferTexture) called");
return;
}
- if (renderbufferTarget != GL_RENDERBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferRenderbuffer(renderbufferTarget)");
+ /* Get the framebuffer object */
+ fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, func);
+ if (!fb)
return;
+
+ /* Get the texture object */
+ if (!get_texture_for_framebuffer(ctx, texture, true, func, &texObj))
+ return;
+
+ if (texObj) {
+ if (!check_layered_texture_target(ctx, texObj->Target, func,
+ &layered))
+ return;
+
+ if (!check_level(ctx, texObj->Target, level, func))
+ return;
}
+ _mesa_framebuffer_texture(ctx, fb, attachment, texObj, 0, level,
+ 0, layered, func);
+}
+
+
+void
+_mesa_framebuffer_renderbuffer(struct gl_context *ctx,
+ struct gl_framebuffer *fb,
+ GLenum attachment,
+ struct gl_renderbuffer *rb,
+ const char *func)
+{
+ struct gl_renderbuffer_attachment *att;
+
if (_mesa_is_winsys_fbo(fb)) {
/* Can't attach new renderbuffers to a window system framebuffer */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbuffer");
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(window-system framebuffer)", func);
return;
}
att = get_attachment(ctx, fb, attachment);
if (att == NULL) {
_mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferRenderbuffer(invalid attachment %s)",
+ "%s(invalid attachment %s)", func,
_mesa_lookup_enum_by_nr(attachment));
return;
}
- if (renderbuffer) {
- rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
- if (!rb) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferRenderbuffer(non-existant"
- " renderbuffer %u)", renderbuffer);
- return;
- }
- else if (rb == &DummyRenderbuffer) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferRenderbuffer(renderbuffer %u)",
- renderbuffer);
- return;
- }
- }
- else {
- /* remove renderbuffer attachment */
- rb = NULL;
- }
-
if (attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
rb && rb->Format != MESA_FORMAT_NONE) {
/* make sure the renderbuffer is a depth/stencil format */
const GLenum baseFormat = _mesa_get_format_base_format(rb->Format);
if (baseFormat != GL_DEPTH_STENCIL) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferRenderbuffer(renderbuffer"
- " is not DEPTH_STENCIL format)");
+ "%s(renderbuffer is not DEPTH_STENCIL format)", func);
return;
}
}
@@ -2903,24 +3428,94 @@ _mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment,
void GLAPIENTRY
-_mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
- GLenum pname, GLint *params)
+_mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment,
+ GLenum renderbuffertarget,
+ GLuint renderbuffer)
{
- const struct gl_renderbuffer_attachment *att;
- struct gl_framebuffer *buffer;
- GLenum err;
+ struct gl_framebuffer *fb;
+ struct gl_renderbuffer *rb;
GET_CURRENT_CONTEXT(ctx);
- /* The error differs in GL and GLES. */
- err = _mesa_is_desktop_gl(ctx) ? GL_INVALID_OPERATION : GL_INVALID_ENUM;
+ fb = get_framebuffer_target(ctx, target);
+ if (!fb) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferRenderbuffer(invalid target %s)",
+ _mesa_lookup_enum_by_nr(target));
+ return;
+ }
- buffer = get_framebuffer_target(ctx, target);
- if (!buffer) {
+ if (renderbuffertarget != GL_RENDERBUFFER) {
_mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameteriv(target)");
+ "glFramebufferRenderbuffer(renderbuffertarget is not "
+ "GL_RENDERBUFFER)");
return;
}
+ if (renderbuffer) {
+ rb = _mesa_lookup_renderbuffer_err(ctx, renderbuffer,
+ "glFramebufferRenderbuffer");
+ if (!rb)
+ return;
+ }
+ else {
+ /* remove renderbuffer attachment */
+ rb = NULL;
+ }
+
+ _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb,
+ "glFramebufferRenderbuffer");
+}
+
+
+void GLAPIENTRY
+_mesa_NamedFramebufferRenderbuffer(GLuint framebuffer, GLenum attachment,
+ GLenum renderbuffertarget,
+ GLuint renderbuffer)
+{
+ struct gl_framebuffer *fb;
+ struct gl_renderbuffer *rb;
+ GET_CURRENT_CONTEXT(ctx);
+
+ fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+ "glNamedFramebufferRenderbuffer");
+ if (!fb)
+ return;
+
+ if (renderbuffertarget != GL_RENDERBUFFER) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glNamedFramebufferRenderbuffer(renderbuffertarget is not "
+ "GL_RENDERBUFFER)");
+ return;
+ }
+
+ if (renderbuffer) {
+ rb = _mesa_lookup_renderbuffer_err(ctx, renderbuffer,
+ "glNamedFramebufferRenderbuffer");
+ if (!rb)
+ return;
+ }
+ else {
+ /* remove renderbuffer attachment */
+ rb = NULL;
+ }
+
+ _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb,
+ "glNamedFramebufferRenderbuffer");
+}
+
+
+void
+_mesa_get_framebuffer_attachment_parameter(struct gl_context *ctx,
+ struct gl_framebuffer *buffer,
+ GLenum attachment, GLenum pname,
+ GLint *params, const char *caller)
+{
+ const struct gl_renderbuffer_attachment *att;
+ GLenum err;
+
+ /* The error differs in GL and GLES. */
+ err = _mesa_is_desktop_gl(ctx) ? GL_INVALID_OPERATION : GL_INVALID_ENUM;
+
if (_mesa_is_winsys_fbo(buffer)) {
/* Page 126 (page 136 of the PDF) of the OpenGL ES 2.0.25 spec
* says:
@@ -2936,14 +3531,15 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
!ctx->Extensions.ARB_framebuffer_object)
&& !_mesa_is_gles3(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetFramebufferAttachmentParameteriv(bound FBO = 0)");
+ "%s(window-system framebuffer)", caller);
return;
}
if (_mesa_is_gles3(ctx) && attachment != GL_BACK &&
attachment != GL_DEPTH && attachment != GL_STENCIL) {
_mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameteriv(attachment)");
+ "%s(invalid attachment %s)", caller,
+ _mesa_lookup_enum_by_nr(attachment));
return;
}
/* the default / window-system FBO */
@@ -2955,8 +3551,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
}
if (att == NULL) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameteriv(attachment)");
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid attachment %s)", caller,
+ _mesa_lookup_enum_by_nr(attachment));
return;
}
@@ -2970,9 +3566,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
* attachment, since it does not have a single format."
*/
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetFramebufferAttachmentParameteriv("
- "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE"
- " is invalid for depth+stencil attachment)");
+ "%s(GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE"
+ " is invalid for depth+stencil attachment)", caller);
return;
}
/* the depth and stencil attachments must point to the same buffer */
@@ -2980,8 +3575,7 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
stencilAtt = get_attachment(ctx, buffer, GL_STENCIL_ATTACHMENT);
if (depthAtt->Renderbuffer != stencilAtt->Renderbuffer) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetFramebufferAttachmentParameteriv(DEPTH/STENCIL"
- " attachments differ)");
+ "%s(DEPTH/STENCIL attachments differ)", caller);
return;
}
}
@@ -3014,8 +3608,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
*params = att->TextureLevel;
}
else if (att->Type == GL_NONE) {
- _mesa_error(ctx, err,
- "glGetFramebufferAttachmentParameteriv(pname)");
+ _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
+ _mesa_lookup_enum_by_nr(pname));
}
else {
goto invalid_pname_enum;
@@ -3031,8 +3625,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
}
}
else if (att->Type == GL_NONE) {
- _mesa_error(ctx, err,
- "glGetFramebufferAttachmentParameteriv(pname)");
+ _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
+ _mesa_lookup_enum_by_nr(pname));
}
else {
goto invalid_pname_enum;
@@ -3042,8 +3636,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
if (ctx->API == API_OPENGLES) {
goto invalid_pname_enum;
} else if (att->Type == GL_NONE) {
- _mesa_error(ctx, err,
- "glGetFramebufferAttachmentParameteriv(pname)");
+ _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
+ _mesa_lookup_enum_by_nr(pname));
} else if (att->Type == GL_TEXTURE) {
if (att->Texture && (att->Texture->Target == GL_TEXTURE_3D ||
att->Texture->Target == GL_TEXTURE_2D_ARRAY)) {
@@ -3064,8 +3658,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
goto invalid_pname_enum;
}
else if (att->Type == GL_NONE) {
- _mesa_error(ctx, err,
- "glGetFramebufferAttachmentParameteriv(pname)");
+ _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
+ _mesa_lookup_enum_by_nr(pname));
}
else {
if (ctx->Extensions.EXT_framebuffer_sRGB) {
@@ -3087,8 +3681,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
goto invalid_pname_enum;
}
else if (att->Type == GL_NONE) {
- _mesa_error(ctx, err,
- "glGetFramebufferAttachmentParameteriv(pname)");
+ _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
+ _mesa_lookup_enum_by_nr(pname));
}
else {
mesa_format format = att->Renderbuffer->Format;
@@ -3103,9 +3697,9 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
if (_mesa_is_gles3(ctx) &&
attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetFramebufferAttachmentParameteriv(cannot query "
+ "%s(cannot query "
"GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE of "
- "GL_DEPTH_STENCIL_ATTACHMENT");
+ "GL_DEPTH_STENCIL_ATTACHMENT)", caller);
return;
}
@@ -3139,8 +3733,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
goto invalid_pname_enum;
}
else if (att->Type == GL_NONE) {
- _mesa_error(ctx, err,
- "glGetFramebufferAttachmentParameteriv(pname)");
+ _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
+ _mesa_lookup_enum_by_nr(pname));
}
else if (att->Texture) {
const struct gl_texture_image *texImage =
@@ -3159,8 +3753,7 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
att->Renderbuffer->Format);
}
else {
- _mesa_problem(ctx, "glGetFramebufferAttachmentParameterivEXT:"
- " invalid FBO attachment structure");
+ _mesa_problem(ctx, "%s: invalid FBO attachment structure", caller);
}
return;
case GL_FRAMEBUFFER_ATTACHMENT_LAYERED:
@@ -3169,8 +3762,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
} else if (att->Type == GL_TEXTURE) {
*params = att->Layered;
} else if (att->Type == GL_NONE) {
- _mesa_error(ctx, err,
- "glGetFramebufferAttachmentParameteriv(pname)");
+ _mesa_error(ctx, err, "%s(invalid pname %s)", caller,
+ _mesa_lookup_enum_by_nr(pname));
} else {
goto invalid_pname_enum;
}
@@ -3182,30 +3775,144 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
return;
invalid_pname_enum:
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameteriv(pname)");
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid pname %s)", caller,
+ _mesa_lookup_enum_by_nr(pname));
return;
}
+void GLAPIENTRY
+_mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
+ GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_framebuffer *buffer;
+
+ buffer = get_framebuffer_target(ctx, target);
+ if (!buffer) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameteriv(invalid target %s)",
+ _mesa_lookup_enum_by_nr(target));
+ return;
+ }
+
+ _mesa_get_framebuffer_attachment_parameter(ctx, buffer, attachment, pname,
+ params,
+ "glGetFramebufferAttachmentParameteriv");
+}
+
+
+void GLAPIENTRY
+_mesa_GetNamedFramebufferAttachmentParameteriv(GLuint framebuffer,
+ GLenum attachment,
+ GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_framebuffer *buffer;
+
+ if (framebuffer) {
+ buffer = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+ "glGetNamedFramebufferAttachmentParameteriv");
+ if (!buffer)
+ return;
+ }
+ else {
+ /*
+ * Section 9.2 Binding and Managing Framebuffer Objects of the OpenGL
+ * 4.5 core spec (30.10.2014, PDF page 314):
+ * "If framebuffer is zero, then the default draw framebuffer is
+ * queried."
+ */
+ buffer = ctx->WinSysDrawBuffer;
+ }
+
+ _mesa_get_framebuffer_attachment_parameter(ctx, buffer, attachment, pname,
+ params,
+ "glGetNamedFramebufferAttachmentParameteriv");
+}
+
+
+void GLAPIENTRY
+_mesa_NamedFramebufferParameteri(GLuint framebuffer, GLenum pname,
+ GLint param)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_framebuffer *fb = NULL;
+
+ if (!ctx->Extensions.ARB_framebuffer_no_attachments) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glNamedFramebufferParameteri("
+ "ARB_framebuffer_no_attachments not implemented)");
+ return;
+ }
+
+ fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+ "glNamedFramebufferParameteri");
+
+ if (fb) {
+ framebuffer_parameteri(ctx, fb, pname, param,
+ "glNamedFramebufferParameteriv");
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetNamedFramebufferParameteriv(GLuint framebuffer, GLenum pname,
+ GLint *param)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_framebuffer *fb;
+
+ if (!ctx->Extensions.ARB_framebuffer_no_attachments) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glNamedFramebufferParameteriv("
+ "ARB_framebuffer_no_attachments not implemented)");
+ return;
+ }
+
+ if (framebuffer) {
+ fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+ "glGetNamedFramebufferParameteriv");
+ } else {
+ fb = ctx->WinSysDrawBuffer;
+ }
+
+ if (fb) {
+ get_framebuffer_parameteriv(ctx, fb, pname, param,
+ "glGetNamedFramebufferParameteriv");
+ }
+}
+
+
static void
-invalidate_framebuffer_storage(GLenum target, GLsizei numAttachments,
+invalidate_framebuffer_storage(struct gl_context *ctx,
+ struct gl_framebuffer *fb,
+ GLsizei numAttachments,
const GLenum *attachments, GLint x, GLint y,
GLsizei width, GLsizei height, const char *name)
{
int i;
- struct gl_framebuffer *fb;
- GET_CURRENT_CONTEXT(ctx);
- fb = get_framebuffer_target(ctx, target);
- if (!fb) {
- _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", name);
+ /* Section 17.4 Whole Framebuffer Operations of the OpenGL 4.5 Core
+ * Spec (2.2.2015, PDF page 522) says:
+ * "An INVALID_VALUE error is generated if numAttachments, width, or
+ * height is negative."
+ */
+ if (numAttachments < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(numAttachments < 0)", name);
return;
}
- if (numAttachments < 0) {
+ if (width < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "%s(numAttachments < 0)", name);
+ "%s(width < 0)", name);
+ return;
+ }
+
+ if (height < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(height < 0)", name);
return;
}
@@ -3301,7 +4008,8 @@ invalidate_framebuffer_storage(GLenum target, GLsizei numAttachments,
return;
invalid_enum:
- _mesa_error(ctx, GL_INVALID_ENUM, "%s(attachment)", name);
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid attachment %s)", name,
+ _mesa_lookup_enum_by_nr(attachments[i]));
return;
}
@@ -3311,16 +4019,67 @@ _mesa_InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments,
const GLenum *attachments, GLint x, GLint y,
GLsizei width, GLsizei height)
{
- invalidate_framebuffer_storage(target, numAttachments, attachments,
+ struct gl_framebuffer *fb;
+ GET_CURRENT_CONTEXT(ctx);
+
+ fb = get_framebuffer_target(ctx, target);
+ if (!fb) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glInvalidateSubFramebuffer(invalid target %s)",
+ _mesa_lookup_enum_by_nr(target));
+ return;
+ }
+
+ invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments,
x, y, width, height,
"glInvalidateSubFramebuffer");
}
void GLAPIENTRY
+_mesa_InvalidateNamedFramebufferSubData(GLuint framebuffer,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height)
+{
+ struct gl_framebuffer *fb;
+ GET_CURRENT_CONTEXT(ctx);
+
+ /* The OpenGL 4.5 core spec (02.02.2015) says (in Section 17.4 Whole
+ * Framebuffer Operations, PDF page 522): "If framebuffer is zero, the
+ * default draw framebuffer is affected."
+ */
+ if (framebuffer) {
+ fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+ "glInvalidateNamedFramebufferSubData");
+ if (!fb)
+ return;
+ }
+ else
+ fb = ctx->WinSysDrawBuffer;
+
+ invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments,
+ x, y, width, height,
+ "glInvalidateNamedFramebufferSubData");
+}
+
+
+void GLAPIENTRY
_mesa_InvalidateFramebuffer(GLenum target, GLsizei numAttachments,
const GLenum *attachments)
{
+ struct gl_framebuffer *fb;
+ GET_CURRENT_CONTEXT(ctx);
+
+ fb = get_framebuffer_target(ctx, target);
+ if (!fb) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glInvalidateFramebuffer(invalid target %s)",
+ _mesa_lookup_enum_by_nr(target));
+ return;
+ }
+
/* The GL_ARB_invalidate_subdata spec says:
*
* "The command
@@ -3333,7 +4092,7 @@ _mesa_InvalidateFramebuffer(GLenum target, GLsizei numAttachments,
* <width>, <height> equal to 0, 0, <MAX_VIEWPORT_DIMS[0]>,
* <MAX_VIEWPORT_DIMS[1]> respectively."
*/
- invalidate_framebuffer_storage(target, numAttachments, attachments,
+ invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments,
0, 0,
MAX_VIEWPORT_WIDTH, MAX_VIEWPORT_HEIGHT,
"glInvalidateFramebuffer");
@@ -3341,6 +4100,46 @@ _mesa_InvalidateFramebuffer(GLenum target, GLsizei numAttachments,
void GLAPIENTRY
+_mesa_InvalidateNamedFramebufferData(GLuint framebuffer,
+ GLsizei numAttachments,
+ const GLenum *attachments)
+{
+ struct gl_framebuffer *fb;
+ GET_CURRENT_CONTEXT(ctx);
+
+ /* The OpenGL 4.5 core spec (02.02.2015) says (in Section 17.4 Whole
+ * Framebuffer Operations, PDF page 522): "If framebuffer is zero, the
+ * default draw framebuffer is affected."
+ */
+ if (framebuffer) {
+ fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+ "glInvalidateNamedFramebufferData");
+ if (!fb)
+ return;
+ }
+ else
+ fb = ctx->WinSysDrawBuffer;
+
+ /* The GL_ARB_invalidate_subdata spec says:
+ *
+ * "The command
+ *
+ * void InvalidateFramebuffer(enum target,
+ * sizei numAttachments,
+ * const enum *attachments);
+ *
+ * is equivalent to the command InvalidateSubFramebuffer with <x>, <y>,
+ * <width>, <height> equal to 0, 0, <MAX_VIEWPORT_DIMS[0]>,
+ * <MAX_VIEWPORT_DIMS[1]> respectively."
+ */
+ invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments,
+ 0, 0,
+ MAX_VIEWPORT_WIDTH, MAX_VIEWPORT_HEIGHT,
+ "glInvalidateNamedFramebufferData");
+}
+
+
+void GLAPIENTRY
_mesa_DiscardFramebufferEXT(GLenum target, GLsizei numAttachments,
const GLenum *attachments)
{
diff --git a/src/mesa/main/fbobject.h b/src/mesa/main/fbobject.h
index 61aa1f50308..8dad0ff34e7 100644
--- a/src/mesa/main/fbobject.h
+++ b/src/mesa/main/fbobject.h
@@ -64,9 +64,17 @@ _mesa_get_incomplete_framebuffer(void);
extern struct gl_renderbuffer *
_mesa_lookup_renderbuffer(struct gl_context *ctx, GLuint id);
+extern struct gl_renderbuffer *
+_mesa_lookup_renderbuffer_err(struct gl_context *ctx, GLuint id,
+ const char *func);
+
extern struct gl_framebuffer *
_mesa_lookup_framebuffer(struct gl_context *ctx, GLuint id);
+extern struct gl_framebuffer *
+_mesa_lookup_framebuffer_err(struct gl_context *ctx, GLuint id,
+ const char *func);
+
void
_mesa_update_texture_renderbuffer(struct gl_context *ctx,
@@ -74,9 +82,17 @@ _mesa_update_texture_renderbuffer(struct gl_context *ctx,
struct gl_renderbuffer_attachment *att);
extern void
+_mesa_FramebufferRenderbuffer_sw(struct gl_context *ctx,
+ struct gl_framebuffer *fb,
+ GLenum attachment,
+ struct gl_renderbuffer *rb);
+
+extern void
_mesa_framebuffer_renderbuffer(struct gl_context *ctx,
struct gl_framebuffer *fb,
- GLenum attachment, struct gl_renderbuffer *rb);
+ GLenum attachment,
+ struct gl_renderbuffer *rb,
+ const char *func);
extern void
_mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb);
@@ -99,6 +115,24 @@ _mesa_detach_renderbuffer(struct gl_context *ctx,
struct gl_framebuffer *fb,
const void *att);
+extern void
+_mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLenum attachment,
+ struct gl_texture_object *texObj, GLenum textarget,
+ GLint level, GLuint layer, GLboolean layered,
+ const char *caller);
+
+extern GLenum
+_mesa_check_framebuffer_status(struct gl_context *ctx,
+ struct gl_framebuffer *fb);
+
+extern void
+_mesa_get_framebuffer_attachment_parameter(struct gl_context *ctx,
+ struct gl_framebuffer *buffer,
+ GLenum attachment, GLenum pname,
+ GLint *params, const char *caller);
+
+
extern GLboolean GLAPIENTRY
_mesa_IsRenderbuffer(GLuint renderbuffer);
@@ -165,9 +199,15 @@ _mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers);
extern void GLAPIENTRY
_mesa_GenFramebuffers(GLsizei n, GLuint *framebuffers);
+extern void GLAPIENTRY
+_mesa_CreateFramebuffers(GLsizei n, GLuint *framebuffers);
+
extern GLenum GLAPIENTRY
_mesa_CheckFramebufferStatus(GLenum target);
+extern GLenum GLAPIENTRY
+_mesa_CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target);
+
extern void GLAPIENTRY
_mesa_FramebufferTexture1D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level);
@@ -179,24 +219,49 @@ _mesa_FramebufferTexture2D(GLenum target, GLenum attachment,
extern void GLAPIENTRY
_mesa_FramebufferTexture3D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture,
- GLint level, GLint zoffset);
+ GLint level, GLint layer);
extern void GLAPIENTRY
_mesa_FramebufferTextureLayer(GLenum target, GLenum attachment,
GLuint texture, GLint level, GLint layer);
extern void GLAPIENTRY
+_mesa_NamedFramebufferTextureLayer(GLuint framebuffer, GLenum attachment,
+ GLuint texture, GLint level, GLint layer);
+
+extern void GLAPIENTRY
_mesa_FramebufferTexture(GLenum target, GLenum attachment,
GLuint texture, GLint level);
extern void GLAPIENTRY
+_mesa_NamedFramebufferTexture(GLuint framebuffer, GLenum attachment,
+ GLuint texture, GLint level);
+
+extern void GLAPIENTRY
_mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment,
GLenum renderbuffertarget,
GLuint renderbuffer);
extern void GLAPIENTRY
+_mesa_NamedFramebufferRenderbuffer(GLuint framebuffer, GLenum attachment,
+ GLenum renderbuffertarget,
+ GLuint renderbuffer);
+
+extern void GLAPIENTRY
_mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
GLenum pname, GLint *params);
+extern void GLAPIENTRY
+_mesa_GetNamedFramebufferAttachmentParameteriv(GLuint framebuffer,
+ GLenum attachment,
+ GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_NamedFramebufferParameteri(GLuint framebuffer, GLenum pname,
+ GLint param);
+
+extern void GLAPIENTRY
+_mesa_GetNamedFramebufferParameteriv(GLuint framebuffer, GLenum pname,
+ GLint *param);
extern void GLAPIENTRY
_mesa_InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments,
@@ -204,11 +269,29 @@ _mesa_InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments,
GLsizei width, GLsizei height);
extern void GLAPIENTRY
+_mesa_InvalidateNamedFramebufferSubData(GLuint framebuffer,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height);
+
+extern void GLAPIENTRY
_mesa_InvalidateFramebuffer(GLenum target, GLsizei numAttachments,
const GLenum *attachments);
extern void GLAPIENTRY
+_mesa_InvalidateNamedFramebufferData(GLuint framebuffer,
+ GLsizei numAttachments,
+ const GLenum *attachments);
+
+extern void GLAPIENTRY
_mesa_DiscardFramebufferEXT(GLenum target, GLsizei numAttachments,
const GLenum *attachments);
+extern void GLAPIENTRY
+_mesa_FramebufferParameteri(GLenum target, GLenum pname, GLint param);
+
+extern void GLAPIENTRY
+_mesa_GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params);
+
#endif /* FBOBJECT_H */
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
index 8af44e90520..baeb1bfe5de 100644
--- a/src/mesa/main/formats.c
+++ b/src/mesa/main/formats.c
@@ -397,6 +397,11 @@ format_array_format_table_init(void)
format_array_format_table = _mesa_hash_table_create(NULL, NULL,
array_formats_equal);
+ if (!format_array_format_table) {
+ _mesa_error_no_memory(__func__);
+ return;
+ }
+
for (f = 1; f < MESA_FORMAT_COUNT; ++f) {
info = _mesa_get_format_info(f);
if (!info->ArrayFormat)
@@ -432,6 +437,12 @@ _mesa_format_from_array_format(uint32_t array_format)
call_once(&format_array_format_table_exists, format_array_format_table_init);
+ if (!format_array_format_table) {
+ static const once_flag once_flag_init = ONCE_FLAG_INIT;
+ format_array_format_table_exists = once_flag_init;
+ return MESA_FORMAT_NONE;
+ }
+
entry = _mesa_hash_table_search_pre_hashed(format_array_format_table,
array_format,
(void *)(intptr_t)array_format);
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index 4f7736a64d0..77c04b8dab8 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -157,6 +157,7 @@ _mesa_initialize_window_framebuffer(struct gl_framebuffer *fb,
fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
fb->_AllColorBuffersFixedPoint = !visual->floatMode;
fb->_HasSNormOrFloatColorBuffer = visual->floatMode;
+ fb->_HasAttachments = true;
compute_depth_max(fb);
}
@@ -312,7 +313,7 @@ _mesa_resize_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
if (ctx) {
/* update scissor / window bounds */
- _mesa_update_draw_buffer_bounds(ctx);
+ _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
/* Signal new buffer state so that swrast will update its clipping
* info (the CLIP_BIT flag).
*/
@@ -356,30 +357,20 @@ update_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb)
}
+
/**
- * Calculate the inclusive bounding box for the scissor of a specific viewport
+ * Given a bounding box, intersect the bounding box with the scissor of
+ * a specified vieport.
*
* \param ctx GL context.
- * \param buffer Framebuffer to be checked against
* \param idx Index of the desired viewport
* \param bbox Bounding box for the scissored viewport. Stored as xmin,
* xmax, ymin, ymax.
- *
- * \warning This function assumes that the framebuffer dimensions are up to
- * date (e.g., update_framebuffer_size has been recently called on \c buffer).
- *
- * \sa _mesa_clip_to_region
*/
void
-_mesa_scissor_bounding_box(const struct gl_context *ctx,
- const struct gl_framebuffer *buffer,
- unsigned idx, int *bbox)
+_mesa_intersect_scissor_bounding_box(const struct gl_context *ctx,
+ unsigned idx, int *bbox)
{
- bbox[0] = 0;
- bbox[2] = 0;
- bbox[1] = buffer->Width;
- bbox[3] = buffer->Height;
-
if (ctx->Scissor.EnableFlags & (1u << idx)) {
if (ctx->Scissor.ScissorArray[idx].X > bbox[0]) {
bbox[0] = ctx->Scissor.ScissorArray[idx].X;
@@ -401,6 +392,33 @@ _mesa_scissor_bounding_box(const struct gl_context *ctx,
bbox[2] = bbox[3];
}
}
+}
+
+/**
+ * Calculate the inclusive bounding box for the scissor of a specific viewport
+ *
+ * \param ctx GL context.
+ * \param buffer Framebuffer to be checked against
+ * \param idx Index of the desired viewport
+ * \param bbox Bounding box for the scissored viewport. Stored as xmin,
+ * xmax, ymin, ymax.
+ *
+ * \warning This function assumes that the framebuffer dimensions are up to
+ * date (e.g., update_framebuffer_size has been recently called on \c buffer).
+ *
+ * \sa _mesa_clip_to_region
+ */
+void
+_mesa_scissor_bounding_box(const struct gl_context *ctx,
+ const struct gl_framebuffer *buffer,
+ unsigned idx, int *bbox)
+{
+ bbox[0] = 0;
+ bbox[2] = 0;
+ bbox[1] = buffer->Width;
+ bbox[3] = buffer->Height;
+
+ _mesa_intersect_scissor_bounding_box(ctx, idx, bbox);
assert(bbox[0] <= bbox[1]);
assert(bbox[2] <= bbox[3]);
@@ -413,9 +431,9 @@ _mesa_scissor_bounding_box(const struct gl_context *ctx,
* \param ctx the GL context.
*/
void
-_mesa_update_draw_buffer_bounds(struct gl_context *ctx)
+_mesa_update_draw_buffer_bounds(struct gl_context *ctx,
+ struct gl_framebuffer *buffer)
{
- struct gl_framebuffer *buffer = ctx->DrawBuffer;
int bbox[4];
if (!buffer)
@@ -652,7 +670,7 @@ update_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
* context state (GL_READ_BUFFER too).
*/
if (fb->ColorDrawBuffer[0] != ctx->Color.DrawBuffer[0]) {
- _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers,
+ _mesa_drawbuffers(ctx, fb, ctx->Const.MaxDrawBuffers,
ctx->Color.DrawBuffer, NULL);
}
}
@@ -678,24 +696,21 @@ update_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
/**
- * Update state related to the current draw/read framebuffers.
+ * Update state related to the draw/read framebuffers.
*/
void
-_mesa_update_framebuffer(struct gl_context *ctx)
+_mesa_update_framebuffer(struct gl_context *ctx,
+ struct gl_framebuffer *readFb,
+ struct gl_framebuffer *drawFb)
{
- struct gl_framebuffer *drawFb;
- struct gl_framebuffer *readFb;
-
assert(ctx);
- drawFb = ctx->DrawBuffer;
- readFb = ctx->ReadBuffer;
update_framebuffer(ctx, drawFb);
if (readFb != drawFb)
update_framebuffer(ctx, readFb);
- _mesa_update_clamp_vertex_color(ctx);
- _mesa_update_clamp_fragment_color(ctx);
+ _mesa_update_clamp_vertex_color(ctx, drawFb);
+ _mesa_update_clamp_fragment_color(ctx, drawFb);
}
diff --git a/src/mesa/main/framebuffer.h b/src/mesa/main/framebuffer.h
index a4274216ec2..08e43222045 100644
--- a/src/mesa/main/framebuffer.h
+++ b/src/mesa/main/framebuffer.h
@@ -75,16 +75,50 @@ extern void
_mesa_scissor_bounding_box(const struct gl_context *ctx,
const struct gl_framebuffer *buffer,
unsigned idx, int *bbox);
+extern void
+_mesa_intersect_scissor_bounding_box(const struct gl_context *ctx,
+ unsigned idx, int *bbox);
+
+static inline GLuint
+_mesa_geometric_width(const struct gl_framebuffer *buffer)
+{
+ return buffer->_HasAttachments ?
+ buffer->Width : buffer->DefaultGeometry.Width;
+}
+
+static inline GLuint
+_mesa_geometric_height(const struct gl_framebuffer *buffer)
+{
+ return buffer->_HasAttachments ?
+ buffer->Height : buffer->DefaultGeometry.Height;
+}
+
+static inline GLuint
+_mesa_geometric_samples(const struct gl_framebuffer *buffer)
+{
+ return buffer->_HasAttachments ?
+ buffer->Visual.samples : buffer->DefaultGeometry.NumSamples;
+}
+
+static inline GLuint
+_mesa_geometric_layers(const struct gl_framebuffer *buffer)
+{
+ return buffer->_HasAttachments ?
+ buffer->MaxNumLayers : buffer->DefaultGeometry.Layers;
+}
extern void
-_mesa_update_draw_buffer_bounds(struct gl_context *ctx);
+_mesa_update_draw_buffer_bounds(struct gl_context *ctx,
+ struct gl_framebuffer *drawFb);
extern void
_mesa_update_framebuffer_visual(struct gl_context *ctx,
struct gl_framebuffer *fb);
extern void
-_mesa_update_framebuffer(struct gl_context *ctx);
+_mesa_update_framebuffer(struct gl_context *ctx,
+ struct gl_framebuffer *readFb,
+ struct gl_framebuffer *drawFb);
extern GLboolean
_mesa_source_buffer_exists(struct gl_context *ctx, GLenum format);
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index a881bc589ba..3d6d63916b3 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -138,6 +138,7 @@ enum value_extra {
EXTRA_API_GL_CORE,
EXTRA_API_ES2,
EXTRA_API_ES3,
+ EXTRA_API_ES31,
EXTRA_NEW_BUFFERS,
EXTRA_NEW_FRAG_CLAMP,
EXTRA_VALID_DRAW_BUFFER,
@@ -348,6 +349,12 @@ static const int extra_ARB_shader_image_load_store_and_geometry_shader[] = {
EXTRA_END
};
+static const int extra_ARB_draw_indirect_es31[] = {
+ EXT(ARB_draw_indirect),
+ EXTRA_API_ES31,
+ EXTRA_END
+};
+
EXTRA_EXT(ARB_texture_cube_map);
EXTRA_EXT(EXT_texture_array);
EXTRA_EXT(NV_fog_distance);
@@ -393,6 +400,7 @@ EXTRA_EXT(INTEL_performance_query);
EXTRA_EXT(ARB_explicit_uniform_location);
EXTRA_EXT(ARB_clip_control);
EXTRA_EXT(EXT_polygon_offset_clamp);
+EXTRA_EXT(ARB_framebuffer_no_attachments);
static const int
extra_ARB_color_buffer_float_or_glcore[] = {
@@ -909,13 +917,13 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
break;
case GL_FOG_COLOR:
- if (_mesa_get_clamp_fragment_color(ctx))
+ if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer))
COPY_4FV(v->value_float_4, ctx->Fog.Color);
else
COPY_4FV(v->value_float_4, ctx->Fog.ColorUnclamped);
break;
case GL_COLOR_CLEAR_VALUE:
- if (_mesa_get_clamp_fragment_color(ctx)) {
+ if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer)) {
v->value_float_4[0] = CLAMP(ctx->Color.ClearColor.f[0], 0.0F, 1.0F);
v->value_float_4[1] = CLAMP(ctx->Color.ClearColor.f[1], 0.0F, 1.0F);
v->value_float_4[2] = CLAMP(ctx->Color.ClearColor.f[2], 0.0F, 1.0F);
@@ -924,13 +932,13 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
COPY_4FV(v->value_float_4, ctx->Color.ClearColor.f);
break;
case GL_BLEND_COLOR_EXT:
- if (_mesa_get_clamp_fragment_color(ctx))
+ if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer))
COPY_4FV(v->value_float_4, ctx->Color.BlendColor);
else
COPY_4FV(v->value_float_4, ctx->Color.BlendColorUnclamped);
break;
case GL_ALPHA_TEST_REF:
- if (_mesa_get_clamp_fragment_color(ctx))
+ if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer))
v->value_float = ctx->Color.AlphaRef;
else
v->value_float = ctx->Color.AlphaRefUnclamped;
@@ -1078,6 +1086,11 @@ check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d
if (_mesa_is_gles3(ctx))
api_found = GL_TRUE;
break;
+ case EXTRA_API_ES31:
+ api_check = GL_TRUE;
+ if (_mesa_is_gles31(ctx))
+ api_found = GL_TRUE;
+ break;
case EXTRA_API_GL:
api_check = GL_TRUE;
if (_mesa_is_desktop_gl(ctx))
@@ -1911,6 +1924,7 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v)
if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs)
goto invalid_value;
v->value_int = ctx->Array.VAO->VertexBinding[VERT_ATTRIB_GENERIC(index)].Stride;
+ return TYPE_INT;
/* ARB_shader_image_load_store */
case GL_IMAGE_BINDING_NAME: {
diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py
index 41cb2c17b60..74ff3ba6619 100644
--- a/src/mesa/main/get_hash_params.py
+++ b/src/mesa/main/get_hash_params.py
@@ -409,6 +409,12 @@ descriptor=[
[ "SAMPLER_BINDING", "LOC_CUSTOM, TYPE_INT, GL_SAMPLER_BINDING, NO_EXTRA" ],
]},
+# Enums in OpenGL Core profile and ES 3.1
+{ "apis": ["GL_CORE", "GLES3"], "params": [
+# GL_ARB_draw_indirect / GLES 3.1
+ [ "DRAW_INDIRECT_BUFFER_BINDING", "LOC_CUSTOM, TYPE_INT, 0, extra_ARB_draw_indirect_es31" ],
+]},
+
# Remaining enums are only in OpenGL
{ "apis": ["GL", "GL_CORE"], "params": [
[ "ACCUM_RED_BITS", "BUFFER_INT(Visual.accumRedBits), NO_EXTRA" ],
@@ -793,19 +799,20 @@ descriptor=[
[ "MAX_COMPUTE_UNIFORM_COMPONENTS", "CONST(MAX_COMPUTE_UNIFORM_COMPONENTS), extra_ARB_compute_shader" ],
[ "MAX_COMPUTE_IMAGE_UNIFORMS", "CONST(MAX_COMPUTE_IMAGE_UNIFORMS), extra_ARB_compute_shader" ],
-# GL_ARB_gpu_shader5
- [ "MAX_GEOMETRY_SHADER_INVOCATIONS", "CONST(MAX_GEOMETRY_SHADER_INVOCATIONS), extra_ARB_gpu_shader5" ],
- [ "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_framebuffer_no_attachments
+ ["MAX_FRAMEBUFFER_WIDTH", "CONTEXT_INT(Const.MaxFramebufferWidth), extra_ARB_framebuffer_no_attachments"],
+ ["MAX_FRAMEBUFFER_HEIGHT", "CONTEXT_INT(Const.MaxFramebufferHeight), extra_ARB_framebuffer_no_attachments"],
+ ["MAX_FRAMEBUFFER_LAYERS", "CONTEXT_INT(Const.MaxFramebufferLayers), extra_ARB_framebuffer_no_attachments"],
+ ["MAX_FRAMEBUFFER_SAMPLES", "CONTEXT_INT(Const.MaxFramebufferSamples), extra_ARB_framebuffer_no_attachments"],
+
+# GL_EXT_polygon_offset_clamp
+ [ "POLYGON_OFFSET_CLAMP_EXT", "CONTEXT_FLOAT(Polygon.OffsetClamp), extra_EXT_polygon_offset_clamp" ],
]},
# Enums restricted to OpenGL Core profile
{ "apis": ["GL_CORE"], "params": [
# GL_ARB_texture_buffer_range
[ "TEXTURE_BUFFER_OFFSET_ALIGNMENT", "CONTEXT_INT(Const.TextureBufferOffsetAlignment), extra_ARB_texture_buffer_range" ],
-# GL_ARB_draw_indirect
- [ "DRAW_INDIRECT_BUFFER_BINDING", "LOC_CUSTOM, TYPE_INT, 0, extra_ARB_draw_indirect" ],
# GL_ARB_viewport_array
[ "MAX_VIEWPORTS", "CONTEXT_INT(Const.MaxViewports), extra_ARB_viewport_array" ],
@@ -814,8 +821,11 @@ descriptor=[
[ "LAYER_PROVOKING_VERTEX", "CONTEXT_ENUM(Light.ProvokingVertex), extra_ARB_viewport_array" ],
[ "VIEWPORT_INDEX_PROVOKING_VERTEX", "CONTEXT_ENUM(Light.ProvokingVertex), extra_ARB_viewport_array" ],
-# GL_EXT_polygon_offset_clamp
- [ "POLYGON_OFFSET_CLAMP_EXT", "CONTEXT_FLOAT(Polygon.OffsetClamp), extra_EXT_polygon_offset_clamp" ],
+# GL_ARB_gpu_shader5
+ [ "MAX_GEOMETRY_SHADER_INVOCATIONS", "CONST(MAX_GEOMETRY_SHADER_INVOCATIONS), extra_ARB_gpu_shader5" ],
+ [ "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" ],
]}
]
diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c
index 1b2c7f054f6..72d99ca4e22 100644
--- a/src/mesa/main/getstring.c
+++ b/src/mesa/main/getstring.c
@@ -72,10 +72,18 @@ shading_language_version(struct gl_context *ctx)
break;
case API_OPENGLES2:
- return (ctx->Version < 30)
- ? (const GLubyte *) "OpenGL ES GLSL ES 1.0.16"
- : (const GLubyte *) "OpenGL ES GLSL ES 3.00";
-
+ switch (ctx->Version) {
+ case 20:
+ return (const GLubyte *) "OpenGL ES GLSL ES 1.0.16";
+ case 30:
+ return (const GLubyte *) "OpenGL ES GLSL ES 3.00";
+ case 31:
+ return (const GLubyte *) "OpenGL ES GLSL ES 3.10";
+ default:
+ _mesa_problem(ctx,
+ "Invalid OpenGL ES version in shading_language_version()");
+ return (const GLubyte *) 0;
+ }
case API_OPENGLES:
/* fall-through */
diff --git a/src/mesa/main/glformats.c b/src/mesa/main/glformats.c
index 8ced5794938..ac69fabccaa 100644
--- a/src/mesa/main/glformats.c
+++ b/src/mesa/main/glformats.c
@@ -1200,7 +1200,7 @@ _mesa_is_depth_or_stencil_format(GLenum format)
* \return GL_TRUE if compressed, GL_FALSE if uncompressed
*/
GLboolean
-_mesa_is_compressed_format(struct gl_context *ctx, GLenum format)
+_mesa_is_compressed_format(const struct gl_context *ctx, GLenum format)
{
switch (format) {
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
@@ -1678,6 +1678,10 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
case GL_LUMINANCE:
case GL_ALPHA:
return GL_NO_ERROR;
+ case GL_RG:
+ case GL_RED:
+ if (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_texture_rg)
+ return GL_NO_ERROR;
default:
return GL_INVALID_OPERATION;
}
@@ -2292,8 +2296,18 @@ _mesa_es3_error_check_format_and_type(const struct gl_context *ctx,
break;
case GL_HALF_FLOAT:
- if (internalFormat != GL_RG16F)
- return GL_INVALID_OPERATION;
+ case GL_HALF_FLOAT_OES:
+ switch (internalFormat) {
+ case GL_RG16F:
+ break;
+ case GL_RG:
+ if (ctx->Extensions.ARB_texture_rg &&
+ ctx->Extensions.OES_texture_half_float)
+ break;
+ /* fallthrough */
+ default:
+ return GL_INVALID_OPERATION;
+ }
break;
case GL_FLOAT:
@@ -2301,6 +2315,11 @@ _mesa_es3_error_check_format_and_type(const struct gl_context *ctx,
case GL_RG16F:
case GL_RG32F:
break;
+ case GL_RG:
+ if (ctx->Extensions.ARB_texture_rg &&
+ ctx->Extensions.OES_texture_float)
+ break;
+ /* fallthrough */
default:
return GL_INVALID_OPERATION;
}
@@ -2361,8 +2380,19 @@ _mesa_es3_error_check_format_and_type(const struct gl_context *ctx,
break;
case GL_HALF_FLOAT:
- if (internalFormat != GL_R16F)
+ case GL_HALF_FLOAT_OES:
+ switch (internalFormat) {
+ case GL_R16F:
+ break;
+ case GL_RG:
+ case GL_RED:
+ if (ctx->Extensions.ARB_texture_rg &&
+ ctx->Extensions.OES_texture_half_float)
+ break;
+ /* fallthrough */
+ default:
return GL_INVALID_OPERATION;
+ }
break;
case GL_FLOAT:
@@ -2370,6 +2400,11 @@ _mesa_es3_error_check_format_and_type(const struct gl_context *ctx,
case GL_R16F:
case GL_R32F:
break;
+ case GL_RED:
+ if (ctx->Extensions.ARB_texture_rg &&
+ ctx->Extensions.OES_texture_float)
+ break;
+ /* fallthrough */
default:
return GL_INVALID_OPERATION;
}
diff --git a/src/mesa/main/glformats.h b/src/mesa/main/glformats.h
index e1ecd64d5f9..8881cb7d86b 100644
--- a/src/mesa/main/glformats.h
+++ b/src/mesa/main/glformats.h
@@ -96,7 +96,7 @@ extern GLboolean
_mesa_is_depth_or_stencil_format(GLenum format);
extern GLboolean
-_mesa_is_compressed_format(struct gl_context *ctx, GLenum format);
+_mesa_is_compressed_format(const struct gl_context *ctx, GLenum format);
extern GLenum
_mesa_base_format_to_integer_format(GLenum format);
diff --git a/src/mesa/main/glheader.h b/src/mesa/main/glheader.h
index 7f7f9a39b3b..a2d98d4ddff 100644
--- a/src/mesa/main/glheader.h
+++ b/src/mesa/main/glheader.h
@@ -135,12 +135,6 @@ typedef void *GLeglImageOES;
#define GL_SHADER_PROGRAM_MESA 0x9999
-/**
- * Internal token for geometry programs.
- * Use the value for GL_GEOMETRY_PROGRAM_NV for now.
- */
-#define MESA_GEOMETRY_PROGRAM 0x8c26
-
/* Several fields of struct gl_config can take these as values. Since
* GLX header files may not be available everywhere they need to be used,
* redefine them here.
diff --git a/src/mesa/main/hash.c b/src/mesa/main/hash.c
index d04cccd94d2..315b5d64004 100644
--- a/src/mesa/main/hash.c
+++ b/src/mesa/main/hash.c
@@ -389,34 +389,6 @@ _mesa_HashDeleteAll(struct _mesa_HashTable *table,
/**
- * Clone all entries in a hash table, into a new table.
- *
- * \param table the hash table to clone
- */
-struct _mesa_HashTable *
-_mesa_HashClone(const struct _mesa_HashTable *table)
-{
- /* cast-away const */
- struct _mesa_HashTable *table2 = (struct _mesa_HashTable *) table;
- struct hash_entry *entry;
- struct _mesa_HashTable *clonetable;
-
- assert(table);
- mtx_lock(&table2->Mutex);
-
- clonetable = _mesa_NewHashTable();
- assert(clonetable);
- hash_table_foreach(table->ht, entry) {
- _mesa_HashInsert(clonetable, (GLint)(uintptr_t)entry->key, entry->data);
- }
-
- mtx_unlock(&table2->Mutex);
-
- return clonetable;
-}
-
-
-/**
* Walk over all entries in a hash table, calling callback function for each.
* Note: we use a separate mutex in this function to avoid a recursive
* locking deadlock (in case the callback calls _mesa_HashRemove()) and to
diff --git a/src/mesa/main/hash.h b/src/mesa/main/hash.h
index e3e8f492e8b..da3b9973d24 100644
--- a/src/mesa/main/hash.h
+++ b/src/mesa/main/hash.h
@@ -59,9 +59,6 @@ _mesa_HashDeleteAll(struct _mesa_HashTable *table,
void (*callback)(GLuint key, void *data, void *userData),
void *userData);
-extern struct _mesa_HashTable *
-_mesa_HashClone(const struct _mesa_HashTable *table);
-
extern void
_mesa_HashWalk(const struct _mesa_HashTable *table,
void (*callback)(GLuint key, void *data, void *userData),
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index c4d917ebba4..9ffe3decd0f 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -230,38 +230,6 @@ static inline int IFLOOR(float f)
}
-/** Return (as an integer) ceiling of float */
-static inline int ICEIL(float f)
-{
-#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
- /*
- * IEEE ceil for computers that round to nearest or even.
- * 'f' must be between -4194304 and 4194303.
- * This ceil operation is done by "(iround(f + .5) + iround(f - .5) + 1) >> 1",
- * but uses some IEEE specific tricks for better speed.
- * Contributed by Josh Vanderhoof
- */
- int ai, bi;
- double af, bf;
- af = (3 << 22) + 0.5 + (double)f;
- bf = (3 << 22) + 0.5 - (double)f;
- /* GCC generates an extra fstp/fld without this. */
- __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
- __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
- return (ai - bi + 1) >> 1;
-#else
- int ai, bi;
- double af, bf;
- fi_type u;
- af = (3 << 22) + 0.5 + (double)f;
- bf = (3 << 22) + 0.5 - (double)f;
- u.f = (float) af; ai = u.i;
- u.f = (float) bf; bi = u.i;
- return (ai - bi + 1) >> 1;
-#endif
-}
-
-
/**
* Is x a power of two?
*/
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index bd84113ea91..481fd5e7fdf 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -43,7 +43,6 @@
#include "glapi/glapi.h"
#include "math/m_matrix.h" /* GLmatrix */
#include "glsl/shader_enums.h"
-#include "util/simple_list.h" /* struct simple_node */
#include "main/formats.h" /* MESA_FORMAT_COUNT */
@@ -398,7 +397,6 @@ struct gl_config
{
GLboolean rgbMode;
GLboolean floatMode;
- GLboolean colorIndexMode; /* XXX is this used anywhere? */
GLuint doubleBufferMode;
GLuint stereoMode;
@@ -2099,8 +2097,6 @@ struct gl_program
GLbitfield64 DoubleInputsRead; /**< Bitmask of which input regs are read and are doubles */
GLbitfield64 OutputsWritten; /**< Bitmask of which output regs are written */
GLbitfield SystemValuesRead; /**< Bitmask of SYSTEM_VALUE_x inputs used */
- GLbitfield InputFlags[MAX_PROGRAM_INPUTS]; /**< PROG_PARAM_BIT_x flags */
- GLbitfield OutputFlags[MAX_PROGRAM_OUTPUTS]; /**< PROG_PARAM_BIT_x flags */
GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */
GLbitfield SamplersUsed; /**< Bitfield of which samplers are used */
GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */
@@ -2275,16 +2271,10 @@ struct gl_vertex_program_state
*/
struct gl_geometry_program_state
{
- GLboolean Enabled; /**< GL_ARB_GEOMETRY_SHADER4 */
- GLboolean _Enabled; /**< Enabled and valid program? */
- struct gl_geometry_program *Current; /**< user-bound geometry program */
-
/** Currently enabled and valid program (including internal programs
* and compiled shader programs).
*/
struct gl_geometry_program *_Current;
-
- GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
};
/**
@@ -2320,8 +2310,6 @@ struct gl_fragment_program_state
*/
struct gl_compute_program_state
{
- struct gl_compute_program *Current; /**< user-bound compute program */
-
/** Currently enabled and valid program (including internal programs
* and compiled shader programs).
*/
@@ -2733,7 +2721,7 @@ struct gl_shader_program
} Comp;
/* post-link info: */
- unsigned NumUserUniformStorage;
+ unsigned NumUniformStorage;
unsigned NumHiddenUniforms;
struct gl_uniform_storage *UniformStorage;
@@ -2832,6 +2820,8 @@ struct gl_pipeline_object
mtx_t Mutex;
+ GLchar *Label; /**< GL_KHR_debug */
+
/**
* Programs used for rendering
*
@@ -3009,7 +2999,6 @@ struct gl_shared_state
struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */
struct gl_vertex_program *DefaultVertexProgram;
struct gl_fragment_program *DefaultFragmentProgram;
- struct gl_geometry_program *DefaultGeometryProgram;
/*@}*/
/* GL_ATI_fragment_shader */
@@ -3151,12 +3140,29 @@ struct gl_framebuffer
*/
struct gl_config Visual;
- GLuint Width, Height; /**< size of frame buffer in pixels */
+ /**
+ * Size of frame buffer in pixels. If there are no attachments, then both
+ * of these are 0.
+ */
+ GLuint Width, Height;
- /** \name Drawing bounds (Intersection of buffer size and scissor box) */
+ /**
+ * In the case that the framebuffer has no attachment (i.e.
+ * GL_ARB_framebuffer_no_attachments) then the geometry of
+ * the framebuffer is specified by the default values.
+ */
+ struct {
+ GLuint Width, Height, Layers, NumSamples;
+ GLboolean FixedSampleLocations;
+ } DefaultGeometry;
+
+ /** \name Drawing bounds (Intersection of buffer size and scissor box)
+ * The drawing region is given by [_Xmin, _Xmax) x [_Ymin, _Ymax),
+ * (inclusive for _Xmin and _Ymin while exclusive for _Xmax and _Ymax)
+ */
/*@{*/
- GLint _Xmin, _Xmax; /**< inclusive */
- GLint _Ymin, _Ymax; /**< exclusive */
+ GLint _Xmin, _Xmax;
+ GLint _Ymin, _Ymax;
/*@}*/
/** \name Derived Z buffer stuff */
@@ -3169,6 +3175,22 @@ struct gl_framebuffer
/** One of the GL_FRAMEBUFFER_(IN)COMPLETE_* tokens */
GLenum _Status;
+ /** Whether one of Attachment has Type != GL_NONE
+ * NOTE: the values for Width and Height are set to 0 in case of having
+ * no attachments, a backend driver supporting the extension
+ * GL_ARB_framebuffer_no_attachments must check for the flag _HasAttachments
+ * and if GL_FALSE, must then use the values in DefaultGeometry to initialize
+ * its viewport, scissor and so on (in particular _Xmin, _Xmax, _Ymin and
+ * _Ymax do NOT take into account _HasAttachments being false). To get the
+ * geometry of the framebuffer, the helper functions
+ * _mesa_geometric_width(),
+ * _mesa_geometric_height(),
+ * _mesa_geometric_samples() and
+ * _mesa_geometric_layers()
+ * are available that check _HasAttachments.
+ */
+ bool _HasAttachments;
+
/** Integer color values */
GLboolean _IntegerColor;
@@ -3179,7 +3201,9 @@ struct gl_framebuffer
/**
* The maximum number of layers in the framebuffer, or 0 if the framebuffer
* is not layered. For cube maps and cube map arrays, each cube face
- * counts as a layer.
+ * counts as a layer. As the case for Width, Height a backend driver
+ * supporting GL_ARB_framebuffer_no_attachments must use DefaultGeometry
+ * in the case that _HasAttachments is false
*/
GLuint MaxNumLayers;
@@ -3358,6 +3382,14 @@ struct gl_constants
GLuint MaxRenderbufferSize; /**< GL_EXT_framebuffer_object */
GLuint MaxSamples; /**< GL_ARB_framebuffer_object */
+ /**
+ * GL_ARB_framebuffer_no_attachments
+ */
+ GLuint MaxFramebufferWidth;
+ GLuint MaxFramebufferHeight;
+ GLuint MaxFramebufferLayers;
+ GLuint MaxFramebufferSamples;
+
/** Number of varying vectors between any two shader stages. */
GLuint MaxVarying;
@@ -3635,6 +3667,7 @@ struct gl_extensions
GLboolean ARB_fragment_program;
GLboolean ARB_fragment_program_shadow;
GLboolean ARB_fragment_shader;
+ GLboolean ARB_framebuffer_no_attachments;
GLboolean ARB_framebuffer_object;
GLboolean ARB_explicit_attrib_location;
GLboolean ARB_explicit_uniform_location;
@@ -4422,7 +4455,12 @@ enum _debug
DEBUG_INCOMPLETE_FBO = (1 << 3)
};
-
+static inline bool
+_mesa_active_fragment_shader_has_atomic_ops(const struct gl_context *ctx)
+{
+ return ctx->Shader._CurrentFragmentProgram != NULL &&
+ ctx->Shader._CurrentFragmentProgram->NumAtomicBuffers > 0;
+}
#ifdef __cplusplus
}
diff --git a/src/mesa/main/objectlabel.c b/src/mesa/main/objectlabel.c
index aecb5b1fa51..5626054687b 100644
--- a/src/mesa/main/objectlabel.c
+++ b/src/mesa/main/objectlabel.c
@@ -30,6 +30,7 @@
#include "enums.h"
#include "fbobject.h"
#include "objectlabel.h"
+#include "pipelineobj.h"
#include "queryobj.h"
#include "samplerobj.h"
#include "shaderobj.h"
@@ -214,8 +215,13 @@ get_label_pointer(struct gl_context *ctx, GLenum identifier, GLuint name,
}
break;
case GL_PROGRAM_PIPELINE:
- /* requires GL 4.2 */
- goto invalid_enum;
+ {
+ struct gl_pipeline_object *pipe =
+ _mesa_lookup_pipeline_object(ctx, name);
+ if (pipe)
+ labelPtr = &pipe->Label;
+ }
+ break;
default:
goto invalid_enum;
}
diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
index 0fefa7d568b..279ae2078fe 100644
--- a/src/mesa/main/pipelineobj.c
+++ b/src/mesa/main/pipelineobj.c
@@ -65,6 +65,7 @@ _mesa_delete_pipeline_object(struct gl_context *ctx,
_mesa_reference_shader_program(ctx, &obj->ActiveProgram, NULL);
mtx_destroy(&obj->Mutex);
+ free(obj->Label);
ralloc_free(obj);
}
@@ -136,8 +137,8 @@ _mesa_free_pipeline_data(struct gl_context *ctx)
* a non-existent ID. The spec defines ID 0 as being technically
* non-existent.
*/
-static inline struct gl_pipeline_object *
-lookup_pipeline_object(struct gl_context *ctx, GLuint id)
+struct gl_pipeline_object *
+_mesa_lookup_pipeline_object(struct gl_context *ctx, GLuint id)
{
if (id == 0)
return NULL;
@@ -225,7 +226,7 @@ _mesa_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+ struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline);
struct gl_shader_program *shProg = NULL;
GLbitfield any_valid_stages;
@@ -337,7 +338,7 @@ _mesa_ActiveShaderProgram(GLuint pipeline, GLuint program)
{
GET_CURRENT_CONTEXT(ctx);
struct gl_shader_program *shProg = NULL;
- struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+ struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline);
if (program != 0) {
shProg = _mesa_lookup_shader_program_err(ctx, program,
@@ -399,7 +400,7 @@ _mesa_BindProgramPipeline(GLuint pipeline)
*/
if (pipeline) {
/* non-default pipeline object */
- newObj = lookup_pipeline_object(ctx, pipeline);
+ newObj = _mesa_lookup_pipeline_object(ctx, pipeline);
if (!newObj) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBindProgramPipeline(non-gen name)");
@@ -468,7 +469,7 @@ _mesa_DeleteProgramPipelines(GLsizei n, const GLuint *pipelines)
for (i = 0; i < n; i++) {
struct gl_pipeline_object *obj =
- lookup_pipeline_object(ctx, pipelines[i]);
+ _mesa_lookup_pipeline_object(ctx, pipelines[i]);
if (obj) {
assert(obj->Name == pipelines[i]);
@@ -568,7 +569,7 @@ _mesa_IsProgramPipeline(GLuint pipeline)
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_pipeline_object *obj = lookup_pipeline_object(ctx, pipeline);
+ struct gl_pipeline_object *obj = _mesa_lookup_pipeline_object(ctx, pipeline);
if (obj == NULL)
return GL_FALSE;
@@ -582,7 +583,7 @@ void GLAPIENTRY
_mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+ struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline);
/* Are geometry shaders available in this context?
*/
@@ -673,6 +674,38 @@ program_stages_all_active(struct gl_pipeline_object *pipe,
return status;
}
+static bool
+program_stages_interleaved_illegally(const struct gl_pipeline_object *pipe)
+{
+ struct gl_shader_program *prev = NULL;
+ unsigned i, j;
+
+ /* Look for programs bound to stages: A -> B -> A, with any intervening
+ * sequence of unrelated programs or empty stages.
+ */
+ for (i = 0; i < MESA_SHADER_STAGES; i++) {
+ struct gl_shader_program *cur = pipe->CurrentProgram[i];
+
+ /* Empty stages anywhere in the pipe are OK */
+ if (!cur || cur == prev)
+ continue;
+
+ if (prev) {
+ /* We've seen an A -> B transition; look at the rest of the pipe
+ * to see if we ever see A again.
+ */
+ for (j = i + 1; j < MESA_SHADER_STAGES; j++) {
+ if (pipe->CurrentProgram[j] == prev)
+ return true;
+ }
+ }
+
+ prev = cur;
+ }
+
+ return false;
+}
+
extern GLboolean
_mesa_validate_program_pipeline(struct gl_context* ctx,
struct gl_pipeline_object *pipe,
@@ -721,24 +754,13 @@ _mesa_validate_program_pipeline(struct gl_context* ctx,
* - One program object is active for at least two shader stages
* and a second program is active for a shader stage between two
* stages for which the first program was active."
- *
- * Without Tesselation, the only case where this can occur is the geometry
- * shader between the fragment shader and vertex shader.
*/
- if (pipe->CurrentProgram[MESA_SHADER_GEOMETRY]
- && pipe->CurrentProgram[MESA_SHADER_FRAGMENT]
- && pipe->CurrentProgram[MESA_SHADER_VERTEX]) {
- if (pipe->CurrentProgram[MESA_SHADER_VERTEX]->Name == pipe->CurrentProgram[MESA_SHADER_FRAGMENT]->Name &&
- pipe->CurrentProgram[MESA_SHADER_GEOMETRY]->Name != pipe->CurrentProgram[MESA_SHADER_VERTEX]->Name) {
- pipe->InfoLog =
- ralloc_asprintf(pipe,
- "Program %d is active for geometry stage between "
- "two stages for which another program %d is "
- "active",
- pipe->CurrentProgram[MESA_SHADER_GEOMETRY]->Name,
- pipe->CurrentProgram[MESA_SHADER_VERTEX]->Name);
- goto err;
- }
+ if (program_stages_interleaved_illegally(pipe)) {
+ pipe->InfoLog =
+ ralloc_strdup(pipe,
+ "Program is active for multiple shader stages with an "
+ "intervening stage provided by another program");
+ goto err;
}
/* Section 2.11.11 (Shader Execution), subheading "Validation," of the
@@ -820,7 +842,7 @@ _mesa_ValidateProgramPipeline(GLuint pipeline)
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+ struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline);
if (!pipe) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -838,7 +860,7 @@ _mesa_GetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize,
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+ struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, pipeline);
if (!pipe) {
_mesa_error(ctx, GL_INVALID_VALUE,
diff --git a/src/mesa/main/pipelineobj.h b/src/mesa/main/pipelineobj.h
index b57bcb99e5c..6dee775ab5e 100644
--- a/src/mesa/main/pipelineobj.h
+++ b/src/mesa/main/pipelineobj.h
@@ -45,6 +45,9 @@ _mesa_init_pipeline(struct gl_context *ctx);
extern void
_mesa_free_pipeline_data(struct gl_context *ctx);
+extern struct gl_pipeline_object *
+_mesa_lookup_pipeline_object(struct gl_context *ctx, GLuint id);
+
extern void
_mesa_reference_pipeline_object_(struct gl_context *ctx,
struct gl_pipeline_object **ptr,
diff --git a/src/mesa/main/program_resource.c b/src/mesa/main/program_resource.c
index b15a13210c0..d857b84e60d 100644
--- a/src/mesa/main/program_resource.c
+++ b/src/mesa/main/program_resource.c
@@ -220,12 +220,12 @@ _mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface,
case GL_PROGRAM_INPUT:
case GL_PROGRAM_OUTPUT:
case GL_UNIFORM:
- case GL_UNIFORM_BLOCK:
case GL_TRANSFORM_FEEDBACK_VARYING:
- /* Validate name syntax for arrays. */
+ /* 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)
return GL_INVALID_INDEX;
diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
index ed0104c9e46..a3357cd6419 100644
--- a/src/mesa/main/readpix.c
+++ b/src/mesa/main/readpix.c
@@ -46,15 +46,18 @@
/**
* Return true if the conversion L=R+G+B is needed.
*/
-static GLboolean
-need_rgb_to_luminance_conversion(mesa_format texFormat, GLenum format)
+GLboolean
+_mesa_need_rgb_to_luminance_conversion(mesa_format texFormat, GLenum format)
{
GLenum baseTexFormat = _mesa_get_format_base_format(texFormat);
return (baseTexFormat == GL_RG ||
baseTexFormat == GL_RGB ||
baseTexFormat == GL_RGBA) &&
- (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA);
+ (format == GL_LUMINANCE ||
+ format == GL_LUMINANCE_ALPHA ||
+ format == GL_LUMINANCE_INTEGER_EXT ||
+ format == GL_LUMINANCE_ALPHA_INTEGER_EXT);
}
@@ -83,7 +86,7 @@ get_readpixels_transfer_ops(const struct gl_context *ctx, mesa_format texFormat,
if (uses_blit) {
/* For blit-based ReadPixels packing, the clamping is done automatically
* unless the type is float. */
- if (_mesa_get_clamp_read_color(ctx) &&
+ if (_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) &&
(type == GL_FLOAT || type == GL_HALF_FLOAT)) {
transferOps |= IMAGE_CLAMP_BIT;
}
@@ -91,7 +94,7 @@ get_readpixels_transfer_ops(const struct gl_context *ctx, mesa_format texFormat,
else {
/* For CPU-based ReadPixels packing, the clamping must always be done
* for non-float types, */
- if (_mesa_get_clamp_read_color(ctx) ||
+ if (_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) ||
(type != GL_FLOAT && type != GL_HALF_FLOAT)) {
transferOps |= IMAGE_CLAMP_BIT;
}
@@ -102,7 +105,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 &&
- !need_rgb_to_luminance_conversion(texFormat, format)) {
+ !_mesa_need_rgb_to_luminance_conversion(texFormat, format)) {
transferOps &= ~IMAGE_CLAMP_BIT;
}
@@ -146,7 +149,7 @@ _mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format,
default:
/* Color formats. */
- if (need_rgb_to_luminance_conversion(rb->Format, format)) {
+ if (_mesa_need_rgb_to_luminance_conversion(rb->Format, format)) {
return GL_TRUE;
}
@@ -418,7 +421,7 @@ read_rgba_pixels( struct gl_context *ctx,
const struct gl_pixelstore_attrib *packing )
{
GLbitfield transferOps;
- bool dst_is_integer, dst_is_luminance, needs_rebase;
+ bool dst_is_integer, convert_rgb_to_lum, needs_rebase;
int dst_stride, src_stride, rb_stride;
uint32_t dst_format, src_format;
GLubyte *dst, *map;
@@ -439,10 +442,8 @@ read_rgba_pixels( struct gl_context *ctx,
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);
- dst_is_luminance = format == GL_LUMINANCE ||
- format == GL_LUMINANCE_ALPHA ||
- format == GL_LUMINANCE_INTEGER_EXT ||
- format == GL_LUMINANCE_ALPHA_INTEGER_EXT;
+ convert_rgb_to_lum =
+ _mesa_need_rgb_to_luminance_conversion(rb->Format, format);
dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
format, type, 0, 0);
@@ -490,7 +491,7 @@ read_rgba_pixels( struct gl_context *ctx,
*/
assert(!transferOps || (transferOps && !dst_is_integer));
- needs_rgba = transferOps || dst_is_luminance;
+ needs_rgba = transferOps || convert_rgb_to_lum;
rgba = NULL;
if (needs_rgba) {
uint32_t rgba_format;
@@ -563,7 +564,7 @@ read_rgba_pixels( struct gl_context *ctx,
* If the dst format is Luminance, we need to do the conversion by computing
* L=R+G+B values.
*/
- if (!dst_is_luminance) {
+ if (!convert_rgb_to_lum) {
_mesa_format_convert(dst, dst_format, dst_stride,
src, src_format, src_stride,
width, height,
diff --git a/src/mesa/main/readpix.h b/src/mesa/main/readpix.h
index 4bb35e17e4d..1636dd9ce3e 100644
--- a/src/mesa/main/readpix.h
+++ b/src/mesa/main/readpix.h
@@ -37,6 +37,9 @@ extern GLboolean
_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);
+
extern void
_mesa_readpixels(struct gl_context *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp
index 6e46553724b..a6246a39aad 100644
--- a/src/mesa/main/shader_query.cpp
+++ b/src/mesa/main/shader_query.cpp
@@ -28,6 +28,7 @@
* \author Ian Romanick <[email protected]>
*/
+#include "main/context.h"
#include "main/core.h"
#include "glsl_symbol_table.h"
#include "ir.h"
@@ -478,12 +479,20 @@ _mesa_GetFragDataLocation(GLuint program, const GLchar *name)
const char*
_mesa_program_resource_name(struct gl_program_resource *res)
{
+ const ir_variable *var;
switch (res->Type) {
case GL_UNIFORM_BLOCK:
return RESOURCE_UBO(res)->Name;
case GL_TRANSFORM_FEEDBACK_VARYING:
return RESOURCE_XFB(res)->Name;
case GL_PROGRAM_INPUT:
+ var = RESOURCE_VAR(res);
+ /* Special case gl_VertexIDMESA -> gl_VertexID. */
+ if (var->data.mode == ir_var_system_value &&
+ var->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) {
+ return "gl_VertexID";
+ }
+ /* fallthrough */
case GL_PROGRAM_OUTPUT:
return RESOURCE_VAR(res)->name;
case GL_UNIFORM:
@@ -538,6 +547,17 @@ struct gl_program_resource *
_mesa_program_resource_find_name(struct gl_shader_program *shProg,
GLenum programInterface, const char *name)
{
+ 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)
@@ -562,7 +582,7 @@ _mesa_program_resource_find_name(struct gl_shader_program *shProg,
break;
case GL_PROGRAM_INPUT:
case GL_PROGRAM_OUTPUT:
- if (array_index_of_resource(res, name) >= 0)
+ if (array_index_of_resource(res, full_name) >= 0)
return res;
break;
default:
@@ -727,6 +747,10 @@ program_resource_location(struct gl_shader_program *shProg,
return -1;
}
+ /* Built-in locations should report GL_INVALID_INDEX. */
+ if (is_gl_identifier(name))
+ return GL_INVALID_INDEX;
+
/* VERT_ATTRIB_GENERIC0 and FRAG_RESULT_DATA0 are decremented as these
* offsets are used internally to differentiate between built-in attributes
* and user-defined attributes.
@@ -986,8 +1010,9 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
case GL_ACTIVE_VARIABLES:
return get_buffer_property(shProg, res, prop, val, caller);
case GL_REFERENCED_BY_COMPUTE_SHADER:
- if (!ctx->Extensions.ARB_compute_shader)
+ if (!_mesa_has_compute_shaders(ctx))
goto invalid_enum;
+ /* fallthrough */
case GL_REFERENCED_BY_VERTEX_SHADER:
case GL_REFERENCED_BY_GEOMETRY_SHADER:
case GL_REFERENCED_BY_FRAGMENT_SHADER:
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index a04b28711f7..a4296adf799 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -532,7 +532,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
/* True if geometry shaders (of the form that was adopted into GLSL 1.50
* and GL 3.2) are available in this context
*/
- const bool has_core_gs = _mesa_is_desktop_gl(ctx) && ctx->Version >= 32;
+ const bool has_core_gs = _mesa_has_geometry_shaders(ctx);
/* Are uniform buffer objects available in this context?
*/
@@ -569,13 +569,13 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
*params = _mesa_longest_attribute_name_length(shProg);
return;
case GL_ACTIVE_UNIFORMS:
- *params = shProg->NumUserUniformStorage - shProg->NumHiddenUniforms;
+ *params = shProg->NumUniformStorage - shProg->NumHiddenUniforms;
return;
case GL_ACTIVE_UNIFORM_MAX_LENGTH: {
unsigned i;
GLint max_len = 0;
const unsigned num_uniforms =
- shProg->NumUserUniformStorage - shProg->NumHiddenUniforms;
+ shProg->NumUniformStorage - shProg->NumHiddenUniforms;
for (i = 0; i < num_uniforms; i++) {
/* Add one for the terminating NUL character for a non-array, and
diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
index e428960362d..110a18e1e2c 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -282,10 +282,10 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg)
unsigned i;
if (shProg->UniformStorage) {
- for (i = 0; i < shProg->NumUserUniformStorage; ++i)
+ for (i = 0; i < shProg->NumUniformStorage; ++i)
_mesa_uniform_detach_all_driver_storage(&shProg->UniformStorage[i]);
ralloc_free(shProg->UniformStorage);
- shProg->NumUserUniformStorage = 0;
+ shProg->NumUniformStorage = 0;
shProg->UniformStorage = NULL;
}
diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c
index 0b76cc01218..d5ac9f1fb13 100644
--- a/src/mesa/main/shared.c
+++ b/src/mesa/main/shared.c
@@ -313,7 +313,6 @@ free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
_mesa_DeleteHashTable(shared->Programs);
_mesa_reference_vertprog(ctx, &shared->DefaultVertexProgram, NULL);
- _mesa_reference_geomprog(ctx, &shared->DefaultGeometryProgram, NULL);
_mesa_reference_fragprog(ctx, &shared->DefaultFragmentProgram, NULL);
_mesa_HashDeleteAll(shared->ATIShaders, delete_fragshader_cb, ctx);
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 99db37bafd7..bede7fe1d0e 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -225,7 +225,7 @@ update_program(struct gl_context *ctx)
if (ctx->GeometryProgram._Current != prevGP) {
new_state |= _NEW_PROGRAM;
if (ctx->Driver.BindProgram) {
- ctx->Driver.BindProgram(ctx, MESA_GEOMETRY_PROGRAM,
+ ctx->Driver.BindProgram(ctx, GL_GEOMETRY_PROGRAM_NV,
(struct gl_program *) ctx->GeometryProgram._Current);
}
}
@@ -266,15 +266,9 @@ update_program_constants(struct gl_context *ctx)
}
}
- if (ctx->GeometryProgram._Current) {
- const struct gl_program_parameter_list *params =
- ctx->GeometryProgram._Current->Base.Parameters;
- /*FIXME: StateFlags is always 0 because we have unnamed constant
- * not state changes */
- if (params /*&& params->StateFlags & ctx->NewState*/) {
- new_state |= _NEW_PROGRAM_CONSTANTS;
- }
- }
+ /* Don't handle geometry shaders here. They don't use any state
+ * constants.
+ */
if (ctx->VertexProgram._Current) {
const struct gl_program_parameter_list *params =
@@ -389,10 +383,10 @@ _mesa_update_state_locked( struct gl_context *ctx )
update_frontbit( ctx );
if (new_state & _NEW_BUFFERS)
- _mesa_update_framebuffer(ctx);
+ _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);
if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
- _mesa_update_draw_buffer_bounds( ctx );
+ _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
if (new_state & _NEW_LIGHT)
_mesa_update_lighting( ctx );
diff --git a/src/mesa/main/tests/dispatch_sanity.cpp b/src/mesa/main/tests/dispatch_sanity.cpp
index ccd0124a2bb..800720b798e 100644
--- a/src/mesa/main/tests/dispatch_sanity.cpp
+++ b/src/mesa/main/tests/dispatch_sanity.cpp
@@ -68,10 +68,13 @@ struct function {
int offset;
};
+extern const struct function common_desktop_functions_possible[];
+extern const struct function gl_compatibility_functions_possible[];
extern const struct function gl_core_functions_possible[];
extern const struct function gles11_functions_possible[];
extern const struct function gles2_functions_possible[];
extern const struct function gles3_functions_possible[];
+extern const struct function gles31_functions_possible[];
class DispatchSanity_test : public ::testing::Test {
public:
@@ -96,7 +99,7 @@ DispatchSanity_test::SetUp()
_mesa_init_driver_functions(&driver_functions);
const unsigned size = _glapi_get_dispatch_table_size();
- nop_table = (_glapi_proc *) _glapi_new_nop_table(size);
+ nop_table = (_glapi_proc *) _mesa_new_nop_table(size);
}
void
@@ -175,10 +178,19 @@ validate_nops(struct gl_context *ctx, const _glapi_proc *nop_table)
TEST_F(DispatchSanity_test, GL31_CORE)
{
SetUpCtx(API_OPENGL_CORE, 31);
+ validate_functions(&ctx, common_desktop_functions_possible, nop_table);
validate_functions(&ctx, gl_core_functions_possible, nop_table);
validate_nops(&ctx, nop_table);
}
+TEST_F(DispatchSanity_test, GL30)
+{
+ SetUpCtx(API_OPENGL_COMPAT, 30);
+ validate_functions(&ctx, common_desktop_functions_possible, nop_table);
+ validate_functions(&ctx, gl_compatibility_functions_possible, nop_table);
+ validate_nops(&ctx, nop_table);
+}
+
TEST_F(DispatchSanity_test, GLES11)
{
SetUpCtx(API_OPENGLES, 11);
@@ -201,7 +213,16 @@ TEST_F(DispatchSanity_test, GLES3)
validate_nops(&ctx, nop_table);
}
-const struct function gl_core_functions_possible[] = {
+TEST_F(DispatchSanity_test, GLES31)
+{
+ SetUpCtx(API_OPENGLES2, 31);
+ validate_functions(&ctx, gles2_functions_possible, nop_table);
+ validate_functions(&ctx, gles3_functions_possible, nop_table);
+ validate_functions(&ctx, gles31_functions_possible, nop_table);
+ validate_nops(&ctx, nop_table);
+}
+
+const struct function common_desktop_functions_possible[] = {
{ "glCullFace", 10, -1 },
{ "glFrontFace", 10, -1 },
{ "glHint", 10, -1 },
@@ -213,8 +234,8 @@ const struct function gl_core_functions_possible[] = {
{ "glTexParameterfv", 10, -1 },
{ "glTexParameteri", 10, -1 },
{ "glTexParameteriv", 10, -1 },
- { "glTexImage1D", 10, -1 },
- { "glTexImage2D", 10, -1 },
+ { "glTexImage1D", 10, _gloffset_TexImage1D },
+ { "glTexImage2D", 10, _gloffset_TexImage2D },
{ "glDrawBuffer", 10, -1 },
{ "glClear", 10, -1 },
{ "glClearColor", 10, -1 },
@@ -482,7 +503,6 @@ const struct function gl_core_functions_possible[] = {
/* GL 3.1 */
{ "glDrawArraysInstanced", 31, -1 },
{ "glDrawElementsInstanced", 31, -1 },
- { "glTexBuffer", 31, -1 },
{ "glPrimitiveRestartIndex", 31, -1 },
/* GL_ARB_shader_objects */
@@ -535,12 +555,8 @@ const struct function gl_core_functions_possible[] = {
{ "glGetInteger64i_v", 32, -1 },
{ "glGetBufferParameteri64v", 32, -1 },
{ "glFramebufferTexture", 32, -1 },
-
- /* GL_ARB_geometry_shader4 */
- { "glProgramParameteriARB", 32, -1 },
- { "glFramebufferTextureARB", 32, -1 },
- { "glFramebufferTextureLayerARB", 32, -1 },
- { "glFramebufferTextureFaceARB", 32, -1 },
+ { "glProgramParameteri", 32, -1 },
+ { "glFramebufferTextureLayer", 32, -1 },
/* GL 3.3 */
{ "glVertexAttribDivisor", 33, -1 },
@@ -673,34 +689,6 @@ const struct function gl_core_functions_possible[] = {
{ "glVertexAttribP4uiv", 43, -1 },
{ "glDrawArraysIndirect", 43, -1 },
{ "glDrawElementsIndirect", 43, -1 },
- { "glUniform1d", 40, -1 },
- { "glUniform2d", 40, -1 },
- { "glUniform3d", 40, -1 },
- { "glUniform4d", 40, -1 },
- { "glUniform1dv", 40, -1 },
- { "glUniform2dv", 40, -1 },
- { "glUniform3dv", 40, -1 },
- { "glUniform4dv", 40, -1 },
- { "glUniformMatrix2dv", 40, -1 },
- { "glUniformMatrix3dv", 40, -1 },
- { "glUniformMatrix4dv", 40, -1 },
- { "glUniformMatrix2x3dv", 40, -1 },
- { "glUniformMatrix2x4dv", 40, -1 },
- { "glUniformMatrix3x2dv", 40, -1 },
- { "glUniformMatrix3x4dv", 40, -1 },
- { "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 },
{ "glGenTransformFeedbacks", 43, -1 },
@@ -728,12 +716,12 @@ const struct function gl_core_functions_possible[] = {
{ "glGenProgramPipelines", 43, -1 },
{ "glIsProgramPipeline", 43, -1 },
{ "glGetProgramPipelineiv", 43, -1 },
+ { "glProgramUniform1d", 43, -1 },
+ { "glProgramUniform1dv", 43, -1 },
{ "glProgramUniform1i", 43, -1 },
{ "glProgramUniform1iv", 43, -1 },
{ "glProgramUniform1f", 43, -1 },
{ "glProgramUniform1fv", 43, -1 },
- { "glProgramUniform1d", 40, -1 },
- { "glProgramUniform1dv", 40, -1 },
{ "glProgramUniform1ui", 43, -1 },
{ "glProgramUniform1uiv", 43, -1 },
{ "glProgramUniform2i", 43, -1 },
@@ -754,50 +742,32 @@ const struct function gl_core_functions_possible[] = {
{ "glProgramUniform3uiv", 43, -1 },
{ "glProgramUniform4i", 43, -1 },
{ "glProgramUniform4iv", 43, -1 },
+ { "glProgramUniform4d", 43, -1 },
+ { "glProgramUniform4dv", 43, -1 },
{ "glProgramUniform4f", 43, -1 },
{ "glProgramUniform4fv", 43, -1 },
- { "glProgramUniform4d", 40, -1 },
- { "glProgramUniform4dv", 40, -1 },
{ "glProgramUniform4ui", 43, -1 },
{ "glProgramUniform4uiv", 43, -1 },
+ { "glProgramUniformMatrix2dv", 43, -1 },
{ "glProgramUniformMatrix2fv", 43, -1 },
+ { "glProgramUniformMatrix3dv", 43, -1 },
{ "glProgramUniformMatrix3fv", 43, -1 },
+ { "glProgramUniformMatrix4dv", 43, -1 },
{ "glProgramUniformMatrix4fv", 43, -1 },
- { "glProgramUniformMatrix2dv", 40, -1 },
- { "glProgramUniformMatrix3dv", 40, -1 },
- { "glProgramUniformMatrix4dv", 40, -1 },
+ { "glProgramUniformMatrix2x3dv", 43, -1 },
{ "glProgramUniformMatrix2x3fv", 43, -1 },
+ { "glProgramUniformMatrix3x2dv", 43, -1 },
{ "glProgramUniformMatrix3x2fv", 43, -1 },
+ { "glProgramUniformMatrix2x4dv", 43, -1 },
{ "glProgramUniformMatrix2x4fv", 43, -1 },
+ { "glProgramUniformMatrix4x2dv", 43, -1 },
{ "glProgramUniformMatrix4x2fv", 43, -1 },
+ { "glProgramUniformMatrix3x4dv", 43, -1 },
{ "glProgramUniformMatrix3x4fv", 43, -1 },
+ { "glProgramUniformMatrix4x3dv", 43, -1 },
{ "glProgramUniformMatrix4x3fv", 43, -1 },
- { "glProgramUniformMatrix2x3dv", 40, -1 },
- { "glProgramUniformMatrix3x2dv", 40, -1 },
- { "glProgramUniformMatrix2x4dv", 40, -1 },
- { "glProgramUniformMatrix4x2dv", 40, -1 },
- { "glProgramUniformMatrix3x4dv", 40, -1 },
- { "glProgramUniformMatrix4x3dv", 40, -1 },
{ "glValidateProgramPipeline", 43, -1 },
{ "glGetProgramPipelineInfoLog", 43, -1 },
- { "glVertexAttribL1d", 41, -1 },
- { "glVertexAttribL2d", 41, -1 },
- { "glVertexAttribL3d", 41, -1 },
- { "glVertexAttribL4d", 41, -1 },
- { "glVertexAttribL1dv", 41, -1 },
- { "glVertexAttribL2dv", 41, -1 },
- { "glVertexAttribL3dv", 41, -1 },
- { "glVertexAttribL4dv", 41, -1 },
- { "glVertexAttribLPointer", 41, -1 },
- { "glGetVertexAttribLdv", 41, -1 },
- { "glViewportArrayv", 43, -1 },
- { "glViewportIndexedf", 43, -1 },
- { "glViewportIndexedfv", 43, -1 },
- { "glScissorArrayv", 43, -1 },
- { "glScissorIndexed", 43, -1 },
- { "glScissorIndexedv", 43, -1 },
- { "glDepthRangeArrayv", 43, -1 },
- { "glDepthRangeIndexed", 43, -1 },
{ "glGetFloati_v", 43, -1 },
{ "glGetDoublei_v", 43, -1 },
// { "glCreateSyncFromCLeventARB", 43, -1 }, // XXX: Add to xml
@@ -840,8 +810,6 @@ const struct function gl_core_functions_possible[] = {
{ "glClearBufferSubData", 43, -1 },
// { "glClearNamedBufferDataEXT", 43, -1 }, // XXX: Add to xml
// { "glClearNamedBufferSubDataEXT", 43, -1 }, // XXX: Add to xml
- { "glDispatchCompute", 43, -1 },
- { "glDispatchComputeIndirect", 43, -1 },
{ "glCopyImageSubData", 43, -1 },
{ "glTextureView", 43, -1 },
{ "glBindVertexBuffer", 43, -1 },
@@ -853,11 +821,10 @@ const struct function gl_core_functions_possible[] = {
// { "glVertexArrayBindVertexBufferEXT", 43, -1 }, // XXX: Add to xml
// { "glVertexArrayVertexAttribFormatEXT", 43, -1 }, // XXX: Add to xml
// { "glVertexArrayVertexAttribIFormatEXT", 43, -1 }, // XXX: Add to xml
-// { "glVertexArrayVertexAttribLFormatEXT", 43, -1 }, // XXX: Add to xml
// { "glVertexArrayVertexAttribBindingEXT", 43, -1 }, // XXX: Add to xml
// { "glVertexArrayVertexBindingDivisorEXT", 43, -1 }, // XXX: Add to xml
-// { "glFramebufferParameteri", 43, -1 }, // XXX: Add to xml
-// { "glGetFramebufferParameteriv", 43, -1 }, // XXX: Add to xml
+ { "glFramebufferParameteri", 43, -1 },
+ { "glGetFramebufferParameteriv", 43, -1 },
// { "glNamedFramebufferParameteriEXT", 43, -1 }, // XXX: Add to xml
// { "glGetNamedFramebufferParameterivEXT", 43, -1 }, // XXX: Add to xml
// { "glGetInternalformati64v", 43, -1 }, // XXX: Add to xml
@@ -876,7 +843,6 @@ const struct function gl_core_functions_possible[] = {
{ "glGetProgramResourceLocation", 43, -1 },
{ "glGetProgramResourceLocationIndex", 43, -1 },
// { "glShaderStorageBlockBinding", 43, -1 }, // XXX: Add to xml
- { "glTexBufferRange", 43, -1 },
// { "glTextureBufferRangeEXT", 43, -1 }, // XXX: Add to xml
{ "glTexStorage2DMultisample", 43, -1 },
{ "glTexStorage3DMultisample", 43, -1 },
@@ -958,6 +924,814 @@ const struct function gl_core_functions_possible[] = {
/* GL_ARB_clip_control */
{ "glClipControl", 45, -1 },
+ /* GL_ARB_compute_shader */
+ { "glDispatchCompute", 43, -1 },
+ { "glDispatchComputeIndirect", 43, -1 },
+
+ /* GL_EXT_polygon_offset_clamp */
+ { "glPolygonOffsetClampEXT", 11, -1 },
+ { NULL, 0, -1 }
+};
+
+const struct function gl_compatibility_functions_possible[] = {
+ { "glBindVertexArrayAPPLE", 10, -1 },
+ { "glGenVertexArraysAPPLE", 10, -1 },
+ { "glBindRenderbufferEXT", 10, -1 },
+ { "glBindFramebufferEXT", 10, -1 },
+ { "glNewList", 10, _gloffset_NewList },
+ { "glEndList", 10, _gloffset_EndList },
+ { "glCallList", 10, _gloffset_CallList },
+ { "glCallLists", 10, _gloffset_CallLists },
+ { "glDeleteLists", 10, _gloffset_DeleteLists },
+ { "glGenLists", 10, _gloffset_GenLists },
+ { "glListBase", 10, _gloffset_ListBase },
+ { "glBegin", 10, _gloffset_Begin },
+ { "glBitmap", 10, _gloffset_Bitmap },
+ { "glColor3b", 10, _gloffset_Color3b },
+ { "glColor3bv", 10, _gloffset_Color3bv },
+ { "glColor3d", 10, _gloffset_Color3d },
+ { "glColor3dv", 10, _gloffset_Color3dv },
+ { "glColor3f", 10, _gloffset_Color3f },
+ { "glColor3fv", 10, _gloffset_Color3fv },
+ { "glColor3i", 10, _gloffset_Color3i },
+ { "glColor3iv", 10, _gloffset_Color3iv },
+ { "glColor3s", 10, _gloffset_Color3s },
+ { "glColor3sv", 10, _gloffset_Color3sv },
+ { "glColor3ub", 10, _gloffset_Color3ub },
+ { "glColor3ubv", 10, _gloffset_Color3ubv },
+ { "glColor3ui", 10, _gloffset_Color3ui },
+ { "glColor3uiv", 10, _gloffset_Color3uiv },
+ { "glColor3us", 10, _gloffset_Color3us },
+ { "glColor3usv", 10, _gloffset_Color3usv },
+ { "glColor4b", 10, _gloffset_Color4b },
+ { "glColor4bv", 10, _gloffset_Color4bv },
+ { "glColor4d", 10, _gloffset_Color4d },
+ { "glColor4dv", 10, _gloffset_Color4dv },
+ { "glColor4f", 10, _gloffset_Color4f },
+ { "glColor4fv", 10, _gloffset_Color4fv },
+ { "glColor4i", 10, _gloffset_Color4i },
+ { "glColor4iv", 10, _gloffset_Color4iv },
+ { "glColor4s", 10, _gloffset_Color4s },
+ { "glColor4sv", 10, _gloffset_Color4sv },
+ { "glColor4ub", 10, _gloffset_Color4ub },
+ { "glColor4ubv", 10, _gloffset_Color4ubv },
+ { "glColor4ui", 10, _gloffset_Color4ui },
+ { "glColor4uiv", 10, _gloffset_Color4uiv },
+ { "glColor4us", 10, _gloffset_Color4us },
+ { "glColor4usv", 10, _gloffset_Color4usv },
+ { "glEdgeFlag", 10, _gloffset_EdgeFlag },
+ { "glEdgeFlagv", 10, _gloffset_EdgeFlagv },
+ { "glEnd", 10, _gloffset_End },
+ { "glIndexd", 10, _gloffset_Indexd },
+ { "glIndexdv", 10, _gloffset_Indexdv },
+ { "glIndexf", 10, _gloffset_Indexf },
+ { "glIndexfv", 10, _gloffset_Indexfv },
+ { "glIndexi", 10, _gloffset_Indexi },
+ { "glIndexiv", 10, _gloffset_Indexiv },
+ { "glIndexs", 10, _gloffset_Indexs },
+ { "glIndexsv", 10, _gloffset_Indexsv },
+ { "glNormal3b", 10, _gloffset_Normal3b },
+ { "glNormal3bv", 10, _gloffset_Normal3bv },
+ { "glNormal3d", 10, _gloffset_Normal3d },
+ { "glNormal3dv", 10, _gloffset_Normal3dv },
+ { "glNormal3f", 10, _gloffset_Normal3f },
+ { "glNormal3fv", 10, _gloffset_Normal3fv },
+ { "glNormal3i", 10, _gloffset_Normal3i },
+ { "glNormal3iv", 10, _gloffset_Normal3iv },
+ { "glNormal3s", 10, _gloffset_Normal3s },
+ { "glNormal3sv", 10, _gloffset_Normal3sv },
+ { "glRasterPos2d", 10, _gloffset_RasterPos2d },
+ { "glRasterPos2dv", 10, _gloffset_RasterPos2dv },
+ { "glRasterPos2f", 10, _gloffset_RasterPos2f },
+ { "glRasterPos2fv", 10, _gloffset_RasterPos2fv },
+ { "glRasterPos2i", 10, _gloffset_RasterPos2i },
+ { "glRasterPos2iv", 10, _gloffset_RasterPos2iv },
+ { "glRasterPos2s", 10, _gloffset_RasterPos2s },
+ { "glRasterPos2sv", 10, _gloffset_RasterPos2sv },
+ { "glRasterPos3d", 10, _gloffset_RasterPos3d },
+ { "glRasterPos3dv", 10, _gloffset_RasterPos3dv },
+ { "glRasterPos3f", 10, _gloffset_RasterPos3f },
+ { "glRasterPos3fv", 10, _gloffset_RasterPos3fv },
+ { "glRasterPos3i", 10, _gloffset_RasterPos3i },
+ { "glRasterPos3iv", 10, _gloffset_RasterPos3iv },
+ { "glRasterPos3s", 10, _gloffset_RasterPos3s },
+ { "glRasterPos3sv", 10, _gloffset_RasterPos3sv },
+ { "glRasterPos4d", 10, _gloffset_RasterPos4d },
+ { "glRasterPos4dv", 10, _gloffset_RasterPos4dv },
+ { "glRasterPos4f", 10, _gloffset_RasterPos4f },
+ { "glRasterPos4fv", 10, _gloffset_RasterPos4fv },
+ { "glRasterPos4i", 10, _gloffset_RasterPos4i },
+ { "glRasterPos4iv", 10, _gloffset_RasterPos4iv },
+ { "glRasterPos4s", 10, _gloffset_RasterPos4s },
+ { "glRasterPos4sv", 10, _gloffset_RasterPos4sv },
+ { "glRectd", 10, _gloffset_Rectd },
+ { "glRectdv", 10, _gloffset_Rectdv },
+ { "glRectf", 10, _gloffset_Rectf },
+ { "glRectfv", 10, _gloffset_Rectfv },
+ { "glRecti", 10, _gloffset_Recti },
+ { "glRectiv", 10, _gloffset_Rectiv },
+ { "glRects", 10, _gloffset_Rects },
+ { "glRectsv", 10, _gloffset_Rectsv },
+ { "glTexCoord1d", 10, _gloffset_TexCoord1d },
+ { "glTexCoord1dv", 10, _gloffset_TexCoord1dv },
+ { "glTexCoord1f", 10, _gloffset_TexCoord1f },
+ { "glTexCoord1fv", 10, _gloffset_TexCoord1fv },
+ { "glTexCoord1i", 10, _gloffset_TexCoord1i },
+ { "glTexCoord1iv", 10, _gloffset_TexCoord1iv },
+ { "glTexCoord1s", 10, _gloffset_TexCoord1s },
+ { "glTexCoord1sv", 10, _gloffset_TexCoord1sv },
+ { "glTexCoord2d", 10, _gloffset_TexCoord2d },
+ { "glTexCoord2dv", 10, _gloffset_TexCoord2dv },
+ { "glTexCoord2f", 10, _gloffset_TexCoord2f },
+ { "glTexCoord2fv", 10, _gloffset_TexCoord2fv },
+ { "glTexCoord2i", 10, _gloffset_TexCoord2i },
+ { "glTexCoord2iv", 10, _gloffset_TexCoord2iv },
+ { "glTexCoord2s", 10, _gloffset_TexCoord2s },
+ { "glTexCoord2sv", 10, _gloffset_TexCoord2sv },
+ { "glTexCoord3d", 10, _gloffset_TexCoord3d },
+ { "glTexCoord3dv", 10, _gloffset_TexCoord3dv },
+ { "glTexCoord3f", 10, _gloffset_TexCoord3f },
+ { "glTexCoord3fv", 10, _gloffset_TexCoord3fv },
+ { "glTexCoord3i", 10, _gloffset_TexCoord3i },
+ { "glTexCoord3iv", 10, _gloffset_TexCoord3iv },
+ { "glTexCoord3s", 10, _gloffset_TexCoord3s },
+ { "glTexCoord3sv", 10, _gloffset_TexCoord3sv },
+ { "glTexCoord4d", 10, _gloffset_TexCoord4d },
+ { "glTexCoord4dv", 10, _gloffset_TexCoord4dv },
+ { "glTexCoord4f", 10, _gloffset_TexCoord4f },
+ { "glTexCoord4fv", 10, _gloffset_TexCoord4fv },
+ { "glTexCoord4i", 10, _gloffset_TexCoord4i },
+ { "glTexCoord4iv", 10, _gloffset_TexCoord4iv },
+ { "glTexCoord4s", 10, _gloffset_TexCoord4s },
+ { "glTexCoord4sv", 10, _gloffset_TexCoord4sv },
+ { "glVertex2d", 10, _gloffset_Vertex2d },
+ { "glVertex2dv", 10, _gloffset_Vertex2dv },
+ { "glVertex2f", 10, _gloffset_Vertex2f },
+ { "glVertex2fv", 10, _gloffset_Vertex2fv },
+ { "glVertex2i", 10, _gloffset_Vertex2i },
+ { "glVertex2iv", 10, _gloffset_Vertex2iv },
+ { "glVertex2s", 10, _gloffset_Vertex2s },
+ { "glVertex2sv", 10, _gloffset_Vertex2sv },
+ { "glVertex3d", 10, _gloffset_Vertex3d },
+ { "glVertex3dv", 10, _gloffset_Vertex3dv },
+ { "glVertex3f", 10, _gloffset_Vertex3f },
+ { "glVertex3fv", 10, _gloffset_Vertex3fv },
+ { "glVertex3i", 10, _gloffset_Vertex3i },
+ { "glVertex3iv", 10, _gloffset_Vertex3iv },
+ { "glVertex3s", 10, _gloffset_Vertex3s },
+ { "glVertex3sv", 10, _gloffset_Vertex3sv },
+ { "glVertex4d", 10, _gloffset_Vertex4d },
+ { "glVertex4dv", 10, _gloffset_Vertex4dv },
+ { "glVertex4f", 10, _gloffset_Vertex4f },
+ { "glVertex4fv", 10, _gloffset_Vertex4fv },
+ { "glVertex4i", 10, _gloffset_Vertex4i },
+ { "glVertex4iv", 10, _gloffset_Vertex4iv },
+ { "glVertex4s", 10, _gloffset_Vertex4s },
+ { "glVertex4sv", 10, _gloffset_Vertex4sv },
+ { "glClipPlane", 10, _gloffset_ClipPlane },
+ { "glColorMaterial", 10, _gloffset_ColorMaterial },
+ { "glFogf", 10, _gloffset_Fogf },
+ { "glFogfv", 10, _gloffset_Fogfv },
+ { "glFogi", 10, _gloffset_Fogi },
+ { "glFogiv", 10, _gloffset_Fogiv },
+ { "glLightf", 10, _gloffset_Lightf },
+ { "glLightfv", 10, _gloffset_Lightfv },
+ { "glLighti", 10, _gloffset_Lighti },
+ { "glLightiv", 10, _gloffset_Lightiv },
+ { "glLightModelf", 10, _gloffset_LightModelf },
+ { "glLightModelfv", 10, _gloffset_LightModelfv },
+ { "glLightModeli", 10, _gloffset_LightModeli },
+ { "glLightModeliv", 10, _gloffset_LightModeliv },
+ { "glLineStipple", 10, _gloffset_LineStipple },
+ { "glMaterialf", 10, _gloffset_Materialf },
+ { "glMaterialfv", 10, _gloffset_Materialfv },
+ { "glMateriali", 10, _gloffset_Materiali },
+ { "glMaterialiv", 10, _gloffset_Materialiv },
+ { "glPolygonStipple", 10, _gloffset_PolygonStipple },
+ { "glShadeModel", 10, _gloffset_ShadeModel },
+ { "glTexEnvf", 10, _gloffset_TexEnvf },
+ { "glTexEnvfv", 10, _gloffset_TexEnvfv },
+ { "glTexEnvi", 10, _gloffset_TexEnvi },
+ { "glTexEnviv", 10, _gloffset_TexEnviv },
+ { "glTexGend", 10, _gloffset_TexGend },
+ { "glTexGendv", 10, _gloffset_TexGendv },
+ { "glTexGenf", 10, _gloffset_TexGenf },
+ { "glTexGenfv", 10, _gloffset_TexGenfv },
+ { "glTexGeni", 10, _gloffset_TexGeni },
+ { "glTexGeniv", 10, _gloffset_TexGeniv },
+ { "glFeedbackBuffer", 10, _gloffset_FeedbackBuffer },
+ { "glSelectBuffer", 10, _gloffset_SelectBuffer },
+ { "glRenderMode", 10, _gloffset_RenderMode },
+ { "glInitNames", 10, _gloffset_InitNames },
+ { "glLoadName", 10, _gloffset_LoadName },
+ { "glPassThrough", 10, _gloffset_PassThrough },
+ { "glPopName", 10, _gloffset_PopName },
+ { "glPushName", 10, _gloffset_PushName },
+ { "glClearAccum", 10, _gloffset_ClearAccum },
+ { "glClearIndex", 10, _gloffset_ClearIndex },
+ { "glIndexMask", 10, _gloffset_IndexMask },
+ { "glAccum", 10, _gloffset_Accum },
+ { "glPopAttrib", 10, _gloffset_PopAttrib },
+ { "glPushAttrib", 10, _gloffset_PushAttrib },
+ { "glMap1d", 10, _gloffset_Map1d },
+ { "glMap1f", 10, _gloffset_Map1f },
+ { "glMap2d", 10, _gloffset_Map2d },
+ { "glMap2f", 10, _gloffset_Map2f },
+ { "glMapGrid1d", 10, _gloffset_MapGrid1d },
+ { "glMapGrid1f", 10, _gloffset_MapGrid1f },
+ { "glMapGrid2d", 10, _gloffset_MapGrid2d },
+ { "glMapGrid2f", 10, _gloffset_MapGrid2f },
+ { "glEvalCoord1d", 10, _gloffset_EvalCoord1d },
+ { "glEvalCoord1dv", 10, _gloffset_EvalCoord1dv },
+ { "glEvalCoord1f", 10, _gloffset_EvalCoord1f },
+ { "glEvalCoord1fv", 10, _gloffset_EvalCoord1fv },
+ { "glEvalCoord2d", 10, _gloffset_EvalCoord2d },
+ { "glEvalCoord2dv", 10, _gloffset_EvalCoord2dv },
+ { "glEvalCoord2f", 10, _gloffset_EvalCoord2f },
+ { "glEvalCoord2fv", 10, _gloffset_EvalCoord2fv },
+ { "glEvalMesh1", 10, _gloffset_EvalMesh1 },
+ { "glEvalPoint1", 10, _gloffset_EvalPoint1 },
+ { "glEvalMesh2", 10, _gloffset_EvalMesh2 },
+ { "glEvalPoint2", 10, _gloffset_EvalPoint2 },
+ { "glAlphaFunc", 10, _gloffset_AlphaFunc },
+ { "glPixelZoom", 10, _gloffset_PixelZoom },
+ { "glPixelTransferf", 10, _gloffset_PixelTransferf },
+ { "glPixelTransferi", 10, _gloffset_PixelTransferi },
+ { "glPixelMapfv", 10, _gloffset_PixelMapfv },
+ { "glPixelMapuiv", 10, _gloffset_PixelMapuiv },
+ { "glPixelMapusv", 10, _gloffset_PixelMapusv },
+ { "glCopyPixels", 10, _gloffset_CopyPixels },
+ { "glDrawPixels", 10, _gloffset_DrawPixels },
+ { "glGetClipPlane", 10, _gloffset_GetClipPlane },
+ { "glGetLightfv", 10, _gloffset_GetLightfv },
+ { "glGetLightiv", 10, _gloffset_GetLightiv },
+ { "glGetMapdv", 10, _gloffset_GetMapdv },
+ { "glGetMapfv", 10, _gloffset_GetMapfv },
+ { "glGetMapiv", 10, _gloffset_GetMapiv },
+ { "glGetMaterialfv", 10, _gloffset_GetMaterialfv },
+ { "glGetMaterialiv", 10, _gloffset_GetMaterialiv },
+ { "glGetPixelMapfv", 10, _gloffset_GetPixelMapfv },
+ { "glGetPixelMapuiv", 10, _gloffset_GetPixelMapuiv },
+ { "glGetPixelMapusv", 10, _gloffset_GetPixelMapusv },
+ { "glGetPolygonStipple", 10, _gloffset_GetPolygonStipple },
+ { "glGetTexEnvfv", 10, _gloffset_GetTexEnvfv },
+ { "glGetTexEnviv", 10, _gloffset_GetTexEnviv },
+ { "glGetTexGendv", 10, _gloffset_GetTexGendv },
+ { "glGetTexGenfv", 10, _gloffset_GetTexGenfv },
+ { "glGetTexGeniv", 10, _gloffset_GetTexGeniv },
+ { "glIsList", 10, _gloffset_IsList },
+ { "glFrustum", 10, _gloffset_Frustum },
+ { "glLoadIdentity", 10, _gloffset_LoadIdentity },
+ { "glLoadMatrixf", 10, _gloffset_LoadMatrixf },
+ { "glLoadMatrixd", 10, _gloffset_LoadMatrixd },
+ { "glMatrixMode", 10, _gloffset_MatrixMode },
+ { "glMultMatrixf", 10, _gloffset_MultMatrixf },
+ { "glMultMatrixd", 10, _gloffset_MultMatrixd },
+ { "glOrtho", 10, _gloffset_Ortho },
+ { "glPopMatrix", 10, _gloffset_PopMatrix },
+ { "glPushMatrix", 10, _gloffset_PushMatrix },
+ { "glRotated", 10, _gloffset_Rotated },
+ { "glRotatef", 10, _gloffset_Rotatef },
+ { "glScaled", 10, _gloffset_Scaled },
+ { "glScalef", 10, _gloffset_Scalef },
+ { "glTranslated", 10, _gloffset_Translated },
+ { "glTranslatef", 10, _gloffset_Translatef },
+ { "glArrayElement", 10, _gloffset_ArrayElement },
+ { "glColorPointer", 10, _gloffset_ColorPointer },
+ { "glDisableClientState", 10, _gloffset_DisableClientState },
+ { "glEdgeFlagPointer", 10, _gloffset_EdgeFlagPointer },
+ { "glEnableClientState", 10, _gloffset_EnableClientState },
+ { "glIndexPointer", 10, _gloffset_IndexPointer },
+ { "glInterleavedArrays", 10, _gloffset_InterleavedArrays },
+ { "glNormalPointer", 10, _gloffset_NormalPointer },
+ { "glTexCoordPointer", 10, _gloffset_TexCoordPointer },
+ { "glVertexPointer", 10, _gloffset_VertexPointer },
+ { "glAreTexturesResident", 10, _gloffset_AreTexturesResident },
+ { "glPrioritizeTextures", 10, _gloffset_PrioritizeTextures },
+ { "glIndexub", 10, _gloffset_Indexub },
+ { "glIndexubv", 10, _gloffset_Indexubv },
+ { "glPopClientAttrib", 10, _gloffset_PopClientAttrib },
+ { "glPushClientAttrib", 10, _gloffset_PushClientAttrib },
+ { "glColorTable", 10, _gloffset_ColorTable },
+ { "glColorTableParameterfv", 10, _gloffset_ColorTableParameterfv },
+ { "glColorTableParameteriv", 10, _gloffset_ColorTableParameteriv },
+ { "glCopyColorTable", 10, _gloffset_CopyColorTable },
+ { "glGetColorTable", 10, _gloffset_GetColorTable },
+ { "glGetColorTableParameterfv", 10, _gloffset_GetColorTableParameterfv },
+ { "glGetColorTableParameteriv", 10, _gloffset_GetColorTableParameteriv },
+ { "glColorSubTable", 10, _gloffset_ColorSubTable },
+ { "glCopyColorSubTable", 10, _gloffset_CopyColorSubTable },
+ { "glConvolutionFilter1D", 10, _gloffset_ConvolutionFilter1D },
+ { "glConvolutionFilter2D", 10, _gloffset_ConvolutionFilter2D },
+ { "glConvolutionParameterf", 10, _gloffset_ConvolutionParameterf },
+ { "glConvolutionParameterfv", 10, _gloffset_ConvolutionParameterfv },
+ { "glConvolutionParameteri", 10, _gloffset_ConvolutionParameteri },
+ { "glConvolutionParameteriv", 10, _gloffset_ConvolutionParameteriv },
+ { "glCopyConvolutionFilter1D", 10, _gloffset_CopyConvolutionFilter1D },
+ { "glCopyConvolutionFilter2D", 10, _gloffset_CopyConvolutionFilter2D },
+ { "glGetConvolutionFilter", 10, _gloffset_GetConvolutionFilter },
+ { "glGetConvolutionParameterfv", 10, _gloffset_GetConvolutionParameterfv },
+ { "glGetConvolutionParameteriv", 10, _gloffset_GetConvolutionParameteriv },
+ { "glGetSeparableFilter", 10, _gloffset_GetSeparableFilter },
+ { "glSeparableFilter2D", 10, _gloffset_SeparableFilter2D },
+ { "glGetHistogram", 10, _gloffset_GetHistogram },
+ { "glGetHistogramParameterfv", 10, _gloffset_GetHistogramParameterfv },
+ { "glGetHistogramParameteriv", 10, _gloffset_GetHistogramParameteriv },
+ { "glGetMinmax", 10, _gloffset_GetMinmax },
+ { "glGetMinmaxParameterfv", 10, _gloffset_GetMinmaxParameterfv },
+ { "glGetMinmaxParameteriv", 10, _gloffset_GetMinmaxParameteriv },
+ { "glHistogram", 10, _gloffset_Histogram },
+ { "glMinmax", 10, _gloffset_Minmax },
+ { "glResetHistogram", 10, _gloffset_ResetHistogram },
+ { "glResetMinmax", 10, _gloffset_ResetMinmax },
+ { "glClientActiveTexture", 10, _gloffset_ClientActiveTexture },
+ { "glMultiTexCoord1d", 10, _gloffset_MultiTexCoord1d },
+ { "glMultiTexCoord1dv", 10, _gloffset_MultiTexCoord1dv },
+ { "glMultiTexCoord1f", 10, _gloffset_MultiTexCoord1fARB },
+ { "glMultiTexCoord1fv", 10, _gloffset_MultiTexCoord1fvARB },
+ { "glMultiTexCoord1i", 10, _gloffset_MultiTexCoord1i },
+ { "glMultiTexCoord1iv", 10, _gloffset_MultiTexCoord1iv },
+ { "glMultiTexCoord1s", 10, _gloffset_MultiTexCoord1s },
+ { "glMultiTexCoord1sv", 10, _gloffset_MultiTexCoord1sv },
+ { "glMultiTexCoord2d", 10, _gloffset_MultiTexCoord2d },
+ { "glMultiTexCoord2dv", 10, _gloffset_MultiTexCoord2dv },
+ { "glMultiTexCoord2f", 10, _gloffset_MultiTexCoord2fARB },
+ { "glMultiTexCoord2fv", 10, _gloffset_MultiTexCoord2fvARB },
+ { "glMultiTexCoord2i", 10, _gloffset_MultiTexCoord2i },
+ { "glMultiTexCoord2iv", 10, _gloffset_MultiTexCoord2iv },
+ { "glMultiTexCoord2s", 10, _gloffset_MultiTexCoord2s },
+ { "glMultiTexCoord2sv", 10, _gloffset_MultiTexCoord2sv },
+ { "glMultiTexCoord3d", 10, _gloffset_MultiTexCoord3d },
+ { "glMultiTexCoord3dv", 10, _gloffset_MultiTexCoord3dv },
+ { "glMultiTexCoord3f", 10, _gloffset_MultiTexCoord3fARB },
+ { "glMultiTexCoord3fv", 10, _gloffset_MultiTexCoord3fvARB },
+ { "glMultiTexCoord3i", 10, _gloffset_MultiTexCoord3i },
+ { "glMultiTexCoord3iv", 10, _gloffset_MultiTexCoord3iv },
+ { "glMultiTexCoord3s", 10, _gloffset_MultiTexCoord3s },
+ { "glMultiTexCoord3sv", 10, _gloffset_MultiTexCoord3sv },
+ { "glMultiTexCoord4d", 10, _gloffset_MultiTexCoord4d },
+ { "glMultiTexCoord4dv", 10, _gloffset_MultiTexCoord4dv },
+ { "glMultiTexCoord4f", 10, _gloffset_MultiTexCoord4fARB },
+ { "glMultiTexCoord4fv", 10, _gloffset_MultiTexCoord4fvARB },
+ { "glMultiTexCoord4i", 10, _gloffset_MultiTexCoord4i },
+ { "glMultiTexCoord4iv", 10, _gloffset_MultiTexCoord4iv },
+ { "glMultiTexCoord4s", 10, _gloffset_MultiTexCoord4s },
+ { "glMultiTexCoord4sv", 10, _gloffset_MultiTexCoord4sv },
+ { "glLoadTransposeMatrixf", 10, -1 },
+ { "glLoadTransposeMatrixd", 10, -1 },
+ { "glMultTransposeMatrixf", 10, -1 },
+ { "glMultTransposeMatrixd", 10, -1 },
+ { "glFogCoordf", 10, -1 },
+ { "glFogCoordfv", 10, -1 },
+ { "glFogCoordd", 10, -1 },
+ { "glFogCoorddv", 10, -1 },
+ { "glFogCoordPointer", 10, -1 },
+ { "glSecondaryColor3b", 10, -1 },
+ { "glSecondaryColor3bv", 10, -1 },
+ { "glSecondaryColor3d", 10, -1 },
+ { "glSecondaryColor3dv", 10, -1 },
+ { "glSecondaryColor3f", 10, -1 },
+ { "glSecondaryColor3fv", 10, -1 },
+ { "glSecondaryColor3i", 10, -1 },
+ { "glSecondaryColor3iv", 10, -1 },
+ { "glSecondaryColor3s", 10, -1 },
+ { "glSecondaryColor3sv", 10, -1 },
+ { "glSecondaryColor3ub", 10, -1 },
+ { "glSecondaryColor3ubv", 10, -1 },
+ { "glSecondaryColor3ui", 10, -1 },
+ { "glSecondaryColor3uiv", 10, -1 },
+ { "glSecondaryColor3us", 10, -1 },
+ { "glSecondaryColor3usv", 10, -1 },
+ { "glSecondaryColorPointer", 10, -1 },
+ { "glWindowPos2d", 10, -1 },
+ { "glWindowPos2dv", 10, -1 },
+ { "glWindowPos2f", 10, -1 },
+ { "glWindowPos2fv", 10, -1 },
+ { "glWindowPos2i", 10, -1 },
+ { "glWindowPos2iv", 10, -1 },
+ { "glWindowPos2s", 10, -1 },
+ { "glWindowPos2sv", 10, -1 },
+ { "glWindowPos3d", 10, -1 },
+ { "glWindowPos3dv", 10, -1 },
+ { "glWindowPos3f", 10, -1 },
+ { "glWindowPos3fv", 10, -1 },
+ { "glWindowPos3i", 10, -1 },
+ { "glWindowPos3iv", 10, -1 },
+ { "glWindowPos3s", 10, -1 },
+ { "glWindowPos3sv", 10, -1 },
+ { "glProgramStringARB", 10, -1 },
+ { "glProgramEnvParameter4dARB", 10, -1 },
+ { "glProgramEnvParameter4dvARB", 10, -1 },
+ { "glProgramEnvParameter4fARB", 10, -1 },
+ { "glProgramEnvParameter4fvARB", 10, -1 },
+ { "glProgramLocalParameter4dARB", 10, -1 },
+ { "glProgramLocalParameter4dvARB", 10, -1 },
+ { "glProgramLocalParameter4fARB", 10, -1 },
+ { "glProgramLocalParameter4fvARB", 10, -1 },
+ { "glGetProgramEnvParameterdvARB", 10, -1 },
+ { "glGetProgramEnvParameterfvARB", 10, -1 },
+ { "glGetProgramLocalParameterdvARB", 10, -1 },
+ { "glGetProgramLocalParameterfvARB", 10, -1 },
+ { "glGetProgramivARB", 10, -1 },
+ { "glGetProgramStringARB", 10, -1 },
+ { "glPolygonOffsetEXT", 10, -1 },
+ { "glColorPointerEXT", 10, -1 },
+ { "glEdgeFlagPointerEXT", 10, -1 },
+ { "glIndexPointerEXT", 10, -1 },
+ { "glNormalPointerEXT", 10, -1 },
+ { "glTexCoordPointerEXT", 10, -1 },
+ { "glVertexPointerEXT", 10, -1 },
+ { "glLockArraysEXT", 10, -1 },
+ { "glUnlockArraysEXT", 10, -1 },
+ { "glWindowPos4dMESA", 10, -1 },
+ { "glWindowPos4dvMESA", 10, -1 },
+ { "glWindowPos4fMESA", 10, -1 },
+ { "glWindowPos4fvMESA", 10, -1 },
+ { "glWindowPos4iMESA", 10, -1 },
+ { "glWindowPos4ivMESA", 10, -1 },
+ { "glWindowPos4sMESA", 10, -1 },
+ { "glWindowPos4svMESA", 10, -1 },
+ { "glBindProgramNV", 10, -1 },
+ { "glDeleteProgramsNV", 10, -1 },
+ { "glGenProgramsNV", 10, -1 },
+ { "glIsProgramNV", 10, -1 },
+ { "glVertexAttrib1sNV", 10, -1 },
+ { "glVertexAttrib1svNV", 10, -1 },
+ { "glVertexAttrib2sNV", 10, -1 },
+ { "glVertexAttrib2svNV", 10, -1 },
+ { "glVertexAttrib3sNV", 10, -1 },
+ { "glVertexAttrib3svNV", 10, -1 },
+ { "glVertexAttrib4sNV", 10, -1 },
+ { "glVertexAttrib4svNV", 10, -1 },
+ { "glVertexAttrib1fNV", 10, -1 },
+ { "glVertexAttrib1fvNV", 10, -1 },
+ { "glVertexAttrib2fNV", 10, -1 },
+ { "glVertexAttrib2fvNV", 10, -1 },
+ { "glVertexAttrib3fNV", 10, -1 },
+ { "glVertexAttrib3fvNV", 10, -1 },
+ { "glVertexAttrib4fNV", 10, -1 },
+ { "glVertexAttrib4fvNV", 10, -1 },
+ { "glVertexAttrib1dNV", 10, -1 },
+ { "glVertexAttrib1dvNV", 10, -1 },
+ { "glVertexAttrib2dNV", 10, -1 },
+ { "glVertexAttrib2dvNV", 10, -1 },
+ { "glVertexAttrib3dNV", 10, -1 },
+ { "glVertexAttrib3dvNV", 10, -1 },
+ { "glVertexAttrib4dNV", 10, -1 },
+ { "glVertexAttrib4dvNV", 10, -1 },
+ { "glVertexAttrib4ubNV", 10, -1 },
+ { "glVertexAttrib4ubvNV", 10, -1 },
+ { "glVertexAttribs1svNV", 10, -1 },
+ { "glVertexAttribs2svNV", 10, -1 },
+ { "glVertexAttribs3svNV", 10, -1 },
+ { "glVertexAttribs4svNV", 10, -1 },
+ { "glVertexAttribs1fvNV", 10, -1 },
+ { "glVertexAttribs2fvNV", 10, -1 },
+ { "glVertexAttribs3fvNV", 10, -1 },
+ { "glVertexAttribs4fvNV", 10, -1 },
+ { "glVertexAttribs1dvNV", 10, -1 },
+ { "glVertexAttribs2dvNV", 10, -1 },
+ { "glVertexAttribs3dvNV", 10, -1 },
+ { "glVertexAttribs4dvNV", 10, -1 },
+ { "glVertexAttribs4ubvNV", 10, -1 },
+ { "glGenFragmentShadersATI", 10, -1 },
+ { "glBindFragmentShaderATI", 10, -1 },
+ { "glDeleteFragmentShaderATI", 10, -1 },
+ { "glBeginFragmentShaderATI", 10, -1 },
+ { "glEndFragmentShaderATI", 10, -1 },
+ { "glPassTexCoordATI", 10, -1 },
+ { "glSampleMapATI", 10, -1 },
+ { "glColorFragmentOp1ATI", 10, -1 },
+ { "glColorFragmentOp2ATI", 10, -1 },
+ { "glColorFragmentOp3ATI", 10, -1 },
+ { "glAlphaFragmentOp1ATI", 10, -1 },
+ { "glAlphaFragmentOp2ATI", 10, -1 },
+ { "glAlphaFragmentOp3ATI", 10, -1 },
+ { "glSetFragmentShaderConstantATI", 10, -1 },
+ { "glActiveStencilFaceEXT", 10, -1 },
+ { "glStencilFuncSeparateATI", 10, -1 },
+ { "glProgramEnvParameters4fvEXT", 10, -1 },
+ { "glProgramLocalParameters4fvEXT", 10, -1 },
+ { "glPrimitiveRestartNV", 10, -1 },
+
+ { NULL, 0, -1 }
+};
+
+const struct function gl_core_functions_possible[] = {
+ /* GL 3.1 */
+ { "glTexBuffer", 31, -1 },
+
+ /* GL 3.2 */
+ { "glFramebufferTexture", 32, -1 },
+
+ /* GL 4.3 */
+ { "glIsRenderbuffer", 43, -1 },
+ { "glBindRenderbuffer", 43, -1 },
+ { "glDeleteRenderbuffers", 43, -1 },
+ { "glGenRenderbuffers", 43, -1 },
+ { "glRenderbufferStorage", 43, -1 },
+ { "glGetRenderbufferParameteriv", 43, -1 },
+ { "glIsFramebuffer", 43, -1 },
+ { "glBindFramebuffer", 43, -1 },
+ { "glDeleteFramebuffers", 43, -1 },
+ { "glGenFramebuffers", 43, -1 },
+ { "glCheckFramebufferStatus", 43, -1 },
+ { "glFramebufferTexture1D", 43, -1 },
+ { "glFramebufferTexture2D", 43, -1 },
+ { "glFramebufferTexture3D", 43, -1 },
+ { "glFramebufferRenderbuffer", 43, -1 },
+ { "glGetFramebufferAttachmentParameteriv", 43, -1 },
+ { "glGenerateMipmap", 43, -1 },
+ { "glBlitFramebuffer", 43, -1 },
+ { "glRenderbufferStorageMultisample", 43, -1 },
+ { "glFramebufferTextureLayer", 43, -1 },
+ { "glMapBufferRange", 43, -1 },
+ { "glFlushMappedBufferRange", 43, -1 },
+ { "glBindVertexArray", 43, -1 },
+ { "glDeleteVertexArrays", 43, -1 },
+ { "glGenVertexArrays", 43, -1 },
+ { "glIsVertexArray", 43, -1 },
+ { "glGetUniformIndices", 43, -1 },
+ { "glGetActiveUniformsiv", 43, -1 },
+ { "glGetActiveUniformName", 43, -1 },
+ { "glGetUniformBlockIndex", 43, -1 },
+ { "glGetActiveUniformBlockiv", 43, -1 },
+ { "glGetActiveUniformBlockName", 43, -1 },
+ { "glUniformBlockBinding", 43, -1 },
+ { "glCopyBufferSubData", 43, -1 },
+ { "glDrawElementsBaseVertex", 43, -1 },
+ { "glDrawRangeElementsBaseVertex", 43, -1 },
+ { "glDrawElementsInstancedBaseVertex", 43, -1 },
+ { "glMultiDrawElementsBaseVertex", 43, -1 },
+ { "glProvokingVertex", 43, -1 },
+ { "glFenceSync", 43, -1 },
+ { "glIsSync", 43, -1 },
+ { "glDeleteSync", 43, -1 },
+ { "glClientWaitSync", 43, -1 },
+ { "glWaitSync", 43, -1 },
+ { "glGetInteger64v", 43, -1 },
+ { "glGetSynciv", 43, -1 },
+ { "glTexImage2DMultisample", 43, -1 },
+ { "glTexImage3DMultisample", 43, -1 },
+ { "glGetMultisamplefv", 43, -1 },
+ { "glSampleMaski", 43, -1 },
+ { "glBlendEquationiARB", 43, -1 },
+ { "glBlendEquationSeparateiARB", 43, -1 },
+ { "glBlendFunciARB", 43, -1 },
+ { "glBlendFuncSeparateiARB", 43, -1 },
+ { "glMinSampleShadingARB", 43, -1 }, // XXX: Add to xml
+// { "glNamedStringARB", 43, -1 }, // XXX: Add to xml
+// { "glDeleteNamedStringARB", 43, -1 }, // XXX: Add to xml
+// { "glCompileShaderIncludeARB", 43, -1 }, // XXX: Add to xml
+// { "glIsNamedStringARB", 43, -1 }, // XXX: Add to xml
+// { "glGetNamedStringARB", 43, -1 }, // XXX: Add to xml
+// { "glGetNamedStringivARB", 43, -1 }, // XXX: Add to xml
+ { "glBindFragDataLocationIndexed", 43, -1 },
+ { "glGetFragDataIndex", 43, -1 },
+ { "glGenSamplers", 43, -1 },
+ { "glDeleteSamplers", 43, -1 },
+ { "glIsSampler", 43, -1 },
+ { "glBindSampler", 43, -1 },
+ { "glSamplerParameteri", 43, -1 },
+ { "glSamplerParameteriv", 43, -1 },
+ { "glSamplerParameterf", 43, -1 },
+ { "glSamplerParameterfv", 43, -1 },
+ { "glSamplerParameterIiv", 43, -1 },
+ { "glSamplerParameterIuiv", 43, -1 },
+ { "glGetSamplerParameteriv", 43, -1 },
+ { "glGetSamplerParameterIiv", 43, -1 },
+ { "glGetSamplerParameterfv", 43, -1 },
+ { "glGetSamplerParameterIuiv", 43, -1 },
+ { "glQueryCounter", 43, -1 },
+ { "glGetQueryObjecti64v", 43, -1 },
+ { "glGetQueryObjectui64v", 43, -1 },
+ { "glVertexP2ui", 43, -1 },
+ { "glVertexP2uiv", 43, -1 },
+ { "glVertexP3ui", 43, -1 },
+ { "glVertexP3uiv", 43, -1 },
+ { "glVertexP4ui", 43, -1 },
+ { "glVertexP4uiv", 43, -1 },
+ { "glTexCoordP1ui", 43, -1 },
+ { "glTexCoordP1uiv", 43, -1 },
+ { "glTexCoordP2ui", 43, -1 },
+ { "glTexCoordP2uiv", 43, -1 },
+ { "glTexCoordP3ui", 43, -1 },
+ { "glTexCoordP3uiv", 43, -1 },
+ { "glTexCoordP4ui", 43, -1 },
+ { "glTexCoordP4uiv", 43, -1 },
+ { "glMultiTexCoordP1ui", 43, -1 },
+ { "glMultiTexCoordP1uiv", 43, -1 },
+ { "glMultiTexCoordP2ui", 43, -1 },
+ { "glMultiTexCoordP2uiv", 43, -1 },
+ { "glMultiTexCoordP3ui", 43, -1 },
+ { "glMultiTexCoordP3uiv", 43, -1 },
+ { "glMultiTexCoordP4ui", 43, -1 },
+ { "glMultiTexCoordP4uiv", 43, -1 },
+ { "glNormalP3ui", 43, -1 },
+ { "glNormalP3uiv", 43, -1 },
+ { "glColorP3ui", 43, -1 },
+ { "glColorP3uiv", 43, -1 },
+ { "glColorP4ui", 43, -1 },
+ { "glColorP4uiv", 43, -1 },
+ { "glVertexAttribP1ui", 43, -1 },
+ { "glVertexAttribP1uiv", 43, -1 },
+ { "glVertexAttribP2ui", 43, -1 },
+ { "glVertexAttribP2uiv", 43, -1 },
+ { "glVertexAttribP3ui", 43, -1 },
+ { "glVertexAttribP3uiv", 43, -1 },
+ { "glVertexAttribP4ui", 43, -1 },
+ { "glVertexAttribP4uiv", 43, -1 },
+ { "glDrawArraysIndirect", 43, -1 },
+ { "glDrawElementsIndirect", 43, -1 },
+
+ { "glUniform1d", 40, -1 },
+ { "glUniform2d", 40, -1 },
+ { "glUniform3d", 40, -1 },
+ { "glUniform4d", 40, -1 },
+ { "glUniform1dv", 40, -1 },
+ { "glUniform2dv", 40, -1 },
+ { "glUniform3dv", 40, -1 },
+ { "glUniform4dv", 40, -1 },
+ { "glUniformMatrix2dv", 40, -1 },
+ { "glUniformMatrix3dv", 40, -1 },
+ { "glUniformMatrix4dv", 40, -1 },
+ { "glUniformMatrix2x3dv", 40, -1 },
+ { "glUniformMatrix2x4dv", 40, -1 },
+ { "glUniformMatrix3x2dv", 40, -1 },
+ { "glUniformMatrix3x4dv", 40, -1 },
+ { "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 },
+ { "glGenTransformFeedbacks", 43, -1 },
+ { "glIsTransformFeedback", 43, -1 },
+ { "glPauseTransformFeedback", 43, -1 },
+ { "glResumeTransformFeedback", 43, -1 },
+ { "glDrawTransformFeedback", 43, -1 },
+ { "glDrawTransformFeedbackStream", 43, -1 },
+ { "glBeginQueryIndexed", 43, -1 },
+ { "glEndQueryIndexed", 43, -1 },
+ { "glGetQueryIndexediv", 43, -1 },
+ { "glReleaseShaderCompiler", 43, -1 },
+ { "glShaderBinary", 43, -1 },
+ { "glGetShaderPrecisionFormat", 43, -1 },
+ { "glDepthRangef", 43, -1 },
+ { "glClearDepthf", 43, -1 },
+ { "glGetProgramBinary", 43, -1 },
+ { "glProgramBinary", 43, -1 },
+ { "glProgramParameteri", 43, -1 },
+ { "glUseProgramStages", 43, -1 },
+ { "glActiveShaderProgram", 43, -1 },
+ { "glCreateShaderProgramv", 43, -1 },
+ { "glBindProgramPipeline", 43, -1 },
+ { "glDeleteProgramPipelines", 43, -1 },
+ { "glGenProgramPipelines", 43, -1 },
+ { "glIsProgramPipeline", 43, -1 },
+ { "glGetProgramPipelineiv", 43, -1 },
+ { "glProgramUniform1i", 43, -1 },
+ { "glProgramUniform1iv", 43, -1 },
+ { "glProgramUniform1f", 43, -1 },
+ { "glProgramUniform1fv", 43, -1 },
+ { "glProgramUniform1d", 40, -1 },
+ { "glProgramUniform1dv", 40, -1 },
+ { "glProgramUniform1ui", 43, -1 },
+ { "glProgramUniform1uiv", 43, -1 },
+ { "glProgramUniform2i", 43, -1 },
+ { "glProgramUniform2iv", 43, -1 },
+ { "glProgramUniform2f", 43, -1 },
+ { "glProgramUniform2fv", 43, -1 },
+ { "glProgramUniform2d", 40, -1 },
+ { "glProgramUniform2dv", 40, -1 },
+ { "glProgramUniform2ui", 43, -1 },
+ { "glProgramUniform2uiv", 43, -1 },
+ { "glProgramUniform3i", 43, -1 },
+ { "glProgramUniform3iv", 43, -1 },
+ { "glProgramUniform3f", 43, -1 },
+ { "glProgramUniform3fv", 43, -1 },
+ { "glProgramUniform3d", 40, -1 },
+ { "glProgramUniform3dv", 40, -1 },
+ { "glProgramUniform3ui", 43, -1 },
+ { "glProgramUniform3uiv", 43, -1 },
+ { "glProgramUniform4i", 43, -1 },
+ { "glProgramUniform4iv", 43, -1 },
+ { "glProgramUniform4f", 43, -1 },
+ { "glProgramUniform4fv", 43, -1 },
+ { "glProgramUniform4d", 40, -1 },
+ { "glProgramUniform4dv", 40, -1 },
+ { "glProgramUniform4ui", 43, -1 },
+ { "glProgramUniform4uiv", 43, -1 },
+ { "glProgramUniformMatrix2fv", 43, -1 },
+ { "glProgramUniformMatrix3fv", 43, -1 },
+ { "glProgramUniformMatrix4fv", 43, -1 },
+ { "glProgramUniformMatrix2dv", 40, -1 },
+ { "glProgramUniformMatrix3dv", 40, -1 },
+ { "glProgramUniformMatrix4dv", 40, -1 },
+ { "glProgramUniformMatrix2x3fv", 43, -1 },
+ { "glProgramUniformMatrix3x2fv", 43, -1 },
+ { "glProgramUniformMatrix2x4fv", 43, -1 },
+ { "glProgramUniformMatrix4x2fv", 43, -1 },
+ { "glProgramUniformMatrix3x4fv", 43, -1 },
+ { "glProgramUniformMatrix4x3fv", 43, -1 },
+ { "glProgramUniformMatrix2x3dv", 40, -1 },
+ { "glProgramUniformMatrix3x2dv", 40, -1 },
+ { "glProgramUniformMatrix2x4dv", 40, -1 },
+ { "glProgramUniformMatrix4x2dv", 40, -1 },
+ { "glProgramUniformMatrix3x4dv", 40, -1 },
+ { "glProgramUniformMatrix4x3dv", 40, -1 },
+ { "glValidateProgramPipeline", 43, -1 },
+ { "glGetProgramPipelineInfoLog", 43, -1 },
+
+ { "glVertexAttribL1d", 41, -1 },
+ { "glVertexAttribL2d", 41, -1 },
+ { "glVertexAttribL3d", 41, -1 },
+ { "glVertexAttribL4d", 41, -1 },
+ { "glVertexAttribL1dv", 41, -1 },
+ { "glVertexAttribL2dv", 41, -1 },
+ { "glVertexAttribL3dv", 41, -1 },
+ { "glVertexAttribL4dv", 41, -1 },
+ { "glVertexAttribLPointer", 41, -1 },
+ { "glGetVertexAttribLdv", 41, -1 },
+ { "glViewportArrayv", 43, -1 },
+ { "glViewportIndexedf", 43, -1 },
+ { "glViewportIndexedfv", 43, -1 },
+ { "glScissorArrayv", 43, -1 },
+ { "glScissorIndexed", 43, -1 },
+ { "glScissorIndexedv", 43, -1 },
+ { "glDepthRangeArrayv", 43, -1 },
+ { "glDepthRangeIndexed", 43, -1 },
+
+// { "glCreateSyncFromCLeventARB", 43, -1 }, // XXX: Add to xml
+
+ { "glDrawArraysInstancedBaseInstance", 43, -1 },
+ { "glDrawElementsInstancedBaseInstance", 43, -1 },
+ { "glDrawElementsInstancedBaseVertexBaseInstance", 43, -1 },
+ { "glDrawTransformFeedbackInstanced", 43, -1 },
+ { "glDrawTransformFeedbackStreamInstanced", 43, -1 },
+ { "glGetActiveAtomicCounterBufferiv", 43, -1 },
+ { "glBindImageTexture", 43, -1 },
+ { "glMemoryBarrier", 43, -1 },
+ { "glTexStorage1D", 43, -1 },
+ { "glTexStorage2D", 43, -1 },
+ { "glTexStorage3D", 43, -1 },
+ { "glTextureStorage1DEXT", 43, -1 },
+ { "glTextureStorage2DEXT", 43, -1 },
+ { "glTextureStorage3DEXT", 43, -1 },
+ { "glClearBufferData", 43, -1 },
+ { "glClearBufferSubData", 43, -1 },
+// { "glClearNamedBufferDataEXT", 43, -1 }, // XXX: Add to xml
+// { "glClearNamedBufferSubDataEXT", 43, -1 }, // XXX: Add to xml
+ { "glCopyImageSubData", 43, -1 },
+ { "glTextureView", 43, -1 },
+ { "glBindVertexBuffer", 43, -1 },
+ { "glVertexAttribFormat", 43, -1 },
+ { "glVertexAttribIFormat", 43, -1 },
+ { "glVertexAttribBinding", 43, -1 },
+ { "glVertexBindingDivisor", 43, -1 },
+// { "glVertexArrayBindVertexBufferEXT", 43, -1 }, // XXX: Add to xml
+// { "glVertexArrayVertexAttribFormatEXT", 43, -1 }, // XXX: Add to xml
+// { "glVertexArrayVertexAttribIFormatEXT", 43, -1 }, // XXX: Add to xml
+// { "glVertexArrayVertexAttribLFormatEXT", 43, -1 }, // XXX: Add to xml
+// { "glVertexArrayVertexAttribBindingEXT", 43, -1 }, // XXX: Add to xml
+// { "glVertexArrayVertexBindingDivisorEXT", 43, -1 }, // XXX: Add to xml
+// { "glFramebufferParameteri", 43, -1 }, // XXX: Add to xml
+// { "glGetFramebufferParameteriv", 43, -1 }, // XXX: Add to xml
+// { "glNamedFramebufferParameteriEXT", 43, -1 }, // XXX: Add to xml
+// { "glGetNamedFramebufferParameterivEXT", 43, -1 }, // XXX: Add to xml
+// { "glGetInternalformati64v", 43, -1 }, // XXX: Add to xml
+ { "glInvalidateTexSubImage", 43, -1 },
+ { "glInvalidateTexImage", 43, -1 },
+ { "glInvalidateBufferSubData", 43, -1 },
+ { "glInvalidateBufferData", 43, -1 },
+ { "glInvalidateFramebuffer", 43, -1 },
+ { "glInvalidateSubFramebuffer", 43, -1 },
+ { "glMultiDrawArraysIndirect", 43, -1 },
+ { "glMultiDrawElementsIndirect", 43, -1 },
+ { "glGetProgramInterfaceiv", 43, -1 },
+ { "glGetProgramResourceIndex", 43, -1 },
+ { "glGetProgramResourceName", 43, -1 },
+ { "glGetProgramResourceiv", 43, -1 },
+ { "glGetProgramResourceLocation", 43, -1 },
+ { "glGetProgramResourceLocationIndex", 43, -1 },
+// { "glShaderStorageBlockBinding", 43, -1 }, // XXX: Add to xml
+ { "glTexBufferRange", 43, -1 },
+// { "glTextureBufferRangeEXT", 43, -1 }, // XXX: Add to xml
+ { "glTexStorage2DMultisample", 43, -1 },
+ { "glTexStorage3DMultisample", 43, -1 },
+// { "glTextureStorage2DMultisampleEXT", 43, -1 }, // XXX: Add to xml
+// { "glTextureStorage3DMultisampleEXT", 43, -1 }, // XXX: Add to xml
+
/* GL_ARB_direct_state_access */
{ "glCreateTransformFeedbacks", 45, -1 },
{ "glTransformFeedbackBufferBase", 45, -1 },
@@ -980,6 +1754,24 @@ const struct function gl_core_functions_possible[] = {
{ "glGetNamedBufferParameteri64v", 45, -1 },
{ "glGetNamedBufferPointerv", 45, -1 },
{ "glGetNamedBufferSubData", 45, -1 },
+ { "glCreateFramebuffers", 45, -1 },
+ { "glNamedFramebufferRenderbuffer", 45, -1 },
+ { "glNamedFramebufferParameteri", 45, -1 },
+ { "glNamedFramebufferTexture", 45, -1 },
+ { "glNamedFramebufferTextureLayer", 45, -1 },
+ { "glNamedFramebufferDrawBuffer", 45, -1 },
+ { "glNamedFramebufferDrawBuffers", 45, -1 },
+ { "glNamedFramebufferReadBuffer", 45, -1 },
+ { "glInvalidateNamedFramebufferSubData", 45, -1 },
+ { "glInvalidateNamedFramebufferData", 45, -1 },
+ { "glClearNamedFramebufferiv", 45, -1 },
+ { "glClearNamedFramebufferuiv", 45, -1 },
+ { "glClearNamedFramebufferfv", 45, -1 },
+ { "glClearNamedFramebufferfi", 45, -1 },
+ { "glBlitNamedFramebuffer", 45, -1 },
+ { "glCheckNamedFramebufferStatus", 45, -1 },
+ { "glGetNamedFramebufferParameteriv", 45, -1 },
+ { "glGetNamedFramebufferAttachmentParameteriv", 45, -1 },
{ "glCreateRenderbuffers", 45, -1 },
{ "glNamedRenderbufferStorage", 45, -1 },
{ "glNamedRenderbufferStorageMultisample", 45, -1 },
@@ -1039,9 +1831,6 @@ const struct function gl_core_functions_possible[] = {
{ "glGetQueryBufferObjecti64v", 45, -1 },
{ "glGetQueryBufferObjectui64v", 45, -1 },
- /* GL_EXT_polygon_offset_clamp */
- { "glPolygonOffsetClampEXT", 11, -1 },
-
{ NULL, 0, -1 }
};
@@ -1596,3 +2385,88 @@ const struct function gles3_functions_possible[] = {
{ NULL, 0, -1 }
};
+
+const struct function gles31_functions_possible[] = {
+ { "glDispatchCompute", 31, -1 },
+ { "glDispatchComputeIndirect", 31, -1 },
+ { "glDrawArraysIndirect", 31, -1 },
+ { "glDrawElementsIndirect", 31, -1 },
+
+ // FINISHME: These two functions have not been implemented yet. They come
+ // FINISHME: from the ARB_framebuffer_no_attachments extension.
+ // { "glFramebufferParameteri", 31, -1 },
+ // { "glGetFramebufferParameteriv", 31, -1 },
+
+ { "glGetProgramInterfaceiv", 31, -1 },
+ { "glGetProgramResourceIndex", 31, -1 },
+ { "glGetProgramResourceName", 31, -1 },
+ { "glGetProgramResourceiv", 31, -1 },
+ { "glGetProgramResourceLocation", 31, -1 },
+
+ // We check for the aliased EXT versions in GLES 2
+ // { "glUseProgramStages", 31, -1 },
+ // { "glActiveShaderProgram", 31, -1 },
+ // { "glCreateShaderProgramv", 31, -1 },
+ // { "glBindProgramPipeline", 31, -1 },
+ // { "glDeleteProgramPipelines", 31, -1 },
+ // { "glGenProgramPipelines", 31, -1 },
+ // { "glIsProgramPipeline", 31, -1 },
+ // { "glGetProgramPipelineiv", 31, -1 },
+ // { "glProgramUniform1i", 31, -1 },
+ // { "glProgramUniform2i", 31, -1 },
+ // { "glProgramUniform3i", 31, -1 },
+ // { "glProgramUniform4i", 31, -1 },
+ // { "glProgramUniform1f", 31, -1 },
+ // { "glProgramUniform2f", 31, -1 },
+ // { "glProgramUniform3f", 31, -1 },
+ // { "glProgramUniform4f", 31, -1 },
+ // { "glProgramUniform1iv", 31, -1 },
+ // { "glProgramUniform2iv", 31, -1 },
+ // { "glProgramUniform3iv", 31, -1 },
+ // { "glProgramUniform4iv", 31, -1 },
+ // { "glProgramUniform1fv", 31, -1 },
+ // { "glProgramUniform2fv", 31, -1 },
+ // { "glProgramUniform3fv", 31, -1 },
+ // { "glProgramUniform4fv", 31, -1 },
+ // { "glProgramUniformMatrix2fv", 31, -1 },
+ // { "glProgramUniformMatrix3fv", 31, -1 },
+ // { "glProgramUniformMatrix4fv", 31, -1 },
+ // { "glProgramUniformMatrix2x3fv", 31, -1 },
+ // { "glProgramUniformMatrix3x2fv", 31, -1 },
+ // { "glProgramUniformMatrix2x4fv", 31, -1 },
+ // { "glProgramUniformMatrix4x2fv", 31, -1 },
+ // { "glProgramUniformMatrix3x4fv", 31, -1 },
+ // { "glProgramUniformMatrix4x3fv", 31, -1 },
+ // { "glValidateProgramPipeline", 31, -1 },
+ // { "glGetProgramPipelineInfoLog", 31, -1 },
+
+ // We check for the aliased EXT versions in GLES 3
+ // { "glProgramUniform1ui", 31, -1 },
+ // { "glProgramUniform2ui", 31, -1 },
+ // { "glProgramUniform3ui", 31, -1 },
+ // { "glProgramUniform4ui", 31, -1 },
+ // { "glProgramUniform1uiv", 31, -1 },
+ // { "glProgramUniform2uiv", 31, -1 },
+ // { "glProgramUniform3uiv", 31, -1 },
+ // { "glProgramUniform4uiv", 31, -1 },
+
+ { "glBindImageTexture", 31, -1 },
+ { "glGetBooleani_v", 31, -1 },
+ { "glMemoryBarrier", 31, -1 },
+
+ // FINISHME: This function has not been implemented yet.
+ // { "glMemoryBarrierByRegion", 31, -1 },
+
+ { "glTexStorage2DMultisample", 31, -1 },
+ { "glGetMultisamplefv", 31, -1 },
+ { "glSampleMaski", 31, -1 },
+ { "glGetTexLevelParameteriv", 31, -1 },
+ { "glGetTexLevelParameterfv", 31, -1 },
+ { "glBindVertexBuffer", 31, -1 },
+ { "glVertexAttribFormat", 31, -1 },
+ { "glVertexAttribIFormat", 31, -1 },
+ { "glVertexAttribBinding", 31, -1 },
+ { "glVertexBindingDivisor", 31, -1 },
+
+ { NULL, 0, -1 },
+ };
diff --git a/src/mesa/main/texenv.c b/src/mesa/main/texenv.c
index ec521e6c6e5..3edafc0f776 100644
--- a/src/mesa/main/texenv.c
+++ b/src/mesa/main/texenv.c
@@ -646,7 +646,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
if (pname == GL_TEXTURE_ENV_COLOR) {
if(ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
_mesa_update_state(ctx);
- if (_mesa_get_clamp_fragment_color(ctx))
+ if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer))
COPY_4FV( params, texUnit->EnvColor );
else
COPY_4FV( params, texUnit->EnvColorUnclamped );
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 7bc1da7f805..3d85615fa45 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -222,7 +222,7 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
}
}
- if (ctx->Extensions.ARB_stencil_texturing) {
+ if (ctx->Extensions.ARB_texture_stencil8) {
switch (internalFormat) {
case GL_STENCIL_INDEX:
case GL_STENCIL_INDEX1:
diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c
index b5d42d3047f..d74134f41b1 100644
--- a/src/mesa/main/texparam.c
+++ b/src/mesa/main/texparam.c
@@ -1709,7 +1709,7 @@ get_tex_parameterfv(struct gl_context *ctx,
if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
_mesa_update_state_locked(ctx);
- if (_mesa_get_clamp_fragment_color(ctx)) {
+ if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer)) {
params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
diff --git a/src/mesa/main/textureview.c b/src/mesa/main/textureview.c
index cd87a27d2db..6b0aed4ea1a 100644
--- a/src/mesa/main/textureview.c
+++ b/src/mesa/main/textureview.c
@@ -167,7 +167,7 @@ static const struct internal_format_class_info s3tc_compatible_internal_formats[
* \return VIEW_CLASS if internalformat found in table, false otherwise.
*/
static GLenum
-lookup_view_class(struct gl_context *ctx, GLenum internalformat)
+lookup_view_class(const struct gl_context *ctx, GLenum internalformat)
{
GLuint i;
@@ -176,9 +176,11 @@ lookup_view_class(struct gl_context *ctx, GLenum internalformat)
return compatible_internal_formats[i].view_class;
}
- if (ctx->Extensions.EXT_texture_compression_s3tc && ctx->Extensions.EXT_texture_sRGB) {
+ if (ctx->Extensions.EXT_texture_compression_s3tc &&
+ ctx->Extensions.EXT_texture_sRGB) {
for (i = 0; i < ARRAY_SIZE(s3tc_compatible_internal_formats); i++) {
- if (s3tc_compatible_internal_formats[i].internal_format == internalformat)
+ if (s3tc_compatible_internal_formats[i].internal_format
+ == internalformat)
return s3tc_compatible_internal_formats[i].view_class;
}
}
@@ -226,7 +228,8 @@ initialize_texture_fields(struct gl_context *ctx,
0, internalFormat, texFormat);
}
- _mesa_next_mipmap_level_size(target, 0, levelWidth, levelHeight, levelDepth,
+ _mesa_next_mipmap_level_size(target, 0,
+ levelWidth, levelHeight, levelDepth,
&levelWidth, &levelHeight, &levelDepth);
}
@@ -320,8 +323,8 @@ target_valid(struct gl_context *ctx, GLenum origTarget, GLenum newTarget)
* If an error is found, record it with _mesa_error()
* \return false if any error, true otherwise.
*/
-GLboolean
-_mesa_texture_view_compatible_format(struct gl_context *ctx,
+bool
+_mesa_texture_view_compatible_format(const struct gl_context *ctx,
GLenum origInternalFormat,
GLenum newInternalFormat)
{
@@ -334,15 +337,16 @@ _mesa_texture_view_compatible_format(struct gl_context *ctx,
* or an INVALID_OPERATION error is generated.
*/
if (origInternalFormat == newInternalFormat)
- return GL_TRUE;
+ return true;
origViewClass = lookup_view_class(ctx, origInternalFormat);
newViewClass = lookup_view_class(ctx, newInternalFormat);
if ((origViewClass == newViewClass) && origViewClass != false)
- return GL_TRUE;
+ return true;
- return GL_FALSE;
+ return false;
}
+
/**
* Helper function for TexStorage and teximagemultisample to set immutable
* texture state needed by ARB_texture_view.
@@ -357,17 +361,19 @@ _mesa_set_texture_view_state(struct gl_context *ctx,
/* Get a reference to what will become this View's base level */
texImage = _mesa_select_tex_image(texObj, target, 0);
- /* When an immutable texture is created via glTexStorage or glTexImageMultisample,
+ /* When an immutable texture is created via glTexStorage or
+ * glTexImageMultisample,
* TEXTURE_IMMUTABLE_FORMAT becomes TRUE.
* TEXTURE_IMMUTABLE_LEVELS and TEXTURE_VIEW_NUM_LEVELS become levels.
* If the texture target is TEXTURE_1D_ARRAY then
* TEXTURE_VIEW_NUM_LAYERS becomes height.
* If the texture target is TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY,
- * or TEXTURE_2D_MULTISAMPLE_ARRAY then TEXTURE_VIEW_NUM_LAYERS becomes depth.
+ * or TEXTURE_2D_MULTISAMPLE_ARRAY then TEXTURE_VIEW_NUM_LAYERS becomes
+ * depth.
* If the texture target is TEXTURE_CUBE_MAP, then
* TEXTURE_VIEW_NUM_LAYERS becomes 6.
* For any other texture target, TEXTURE_VIEW_NUM_LAYERS becomes 1.
- *
+ *
* ARB_texture_multisample: Multisample textures do
* not have multiple image levels.
*/
@@ -401,7 +407,6 @@ _mesa_set_texture_view_state(struct gl_context *ctx,
case GL_TEXTURE_CUBE_MAP:
texObj->NumLayers = 6;
break;
-
}
}
@@ -435,16 +440,20 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
minlevel, numlevels, minlayer, numlayers);
if (origtexture == 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)", origtexture);
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)",
+ origtexture);
return;
}
/* Need original texture information to validate arguments */
origTexObj = _mesa_lookup_texture(ctx, origtexture);
- /* If <origtexture> is not the name of a texture, INVALID_VALUE is generated. */
+ /* If <origtexture> is not the name of a texture, INVALID_VALUE
+ * is generated.
+ */
if (!origTexObj) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)", origtexture);
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)",
+ origtexture);
return;
}
@@ -452,7 +461,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
* INVALID_OPERATION is generated.
*/
if (!origTexObj->Immutable) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(origtexture not immutable)");
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTextureView(origtexture not immutable)");
return;
}
@@ -467,7 +477,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
*/
texObj = _mesa_lookup_texture(ctx, texture);
if (texObj == NULL) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(texture = %u non-gen name)", texture);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTextureView(texture = %u non-gen name)", texture);
return;
}
@@ -475,7 +486,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
* the error INVALID_OPERATION is generated.
*/
if (texObj->Target) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(texture = %u already bound)", texture);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTextureView(texture = %u already bound)", texture);
return;
}
@@ -484,33 +496,35 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
return; /* error was recorded */
}
- /* minlevel and minlayer are relative to the view of origtexture
+ /* minlevel and minlayer are relative to the view of origtexture.
* If minlevel or minlayer is greater than level or layer, respectively,
- * of origtexture return INVALID_VALUE.
+ * return INVALID_VALUE.
*/
newViewMinLevel = origTexObj->MinLevel + minlevel;
newViewMinLayer = origTexObj->MinLayer + minlayer;
if (newViewMinLevel >= (origTexObj->MinLevel + origTexObj->NumLevels)) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glTextureView(new minlevel (%d) > orig minlevel (%d) + orig numlevels (%d))",
+ "glTextureView(new minlevel (%d) > orig minlevel (%d)"
+ " + orig numlevels (%d))",
newViewMinLevel, origTexObj->MinLevel, origTexObj->NumLevels);
return;
}
if (newViewMinLayer >= (origTexObj->MinLayer + origTexObj->NumLayers)) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glTextureView(new minlayer (%d) > orig minlayer (%d) + orig numlayers (%d))",
+ "glTextureView(new minlayer (%d) > orig minlayer (%d)"
+ " + orig numlayers (%d))",
newViewMinLayer, origTexObj->MinLayer, origTexObj->NumLayers);
return;
}
if (!_mesa_texture_view_compatible_format(ctx,
- origTexObj->Image[0][0]->InternalFormat,
- internalformat)) {
+ origTexObj->Image[0][0]->InternalFormat,
+ 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));
+ "glTextureView(internalformat %s not compatible with origtexture %s)",
+ _mesa_lookup_enum_by_nr(internalformat),
+ _mesa_lookup_enum_by_nr(origTexObj->Image[0][0]->InternalFormat));
return;
}
@@ -569,14 +583,16 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
width, height, depth, 0);
if (!dimensionsOK) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(invalid width or height or depth)");
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTextureView(invalid width or height or depth)");
return;
}
sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, texFormat,
width, height, depth, 0);
if (!sizeOK) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(invalid texture size)");
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTextureView(invalid texture size)");
return;
}
@@ -591,17 +607,19 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
case GL_TEXTURE_RECTANGLE:
case GL_TEXTURE_2D_MULTISAMPLE:
if (numlayers != 1) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(numlayers %d != 1)", numlayers);
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(numlayers %d != 1)",
+ numlayers);
return;
}
break;
case GL_TEXTURE_CUBE_MAP:
- /* If the new texture's target is TEXTURE_CUBE_MAP, the clamped <numlayers>
- * must be equal to 6.
+ /* If the new texture's target is TEXTURE_CUBE_MAP, the clamped
+ * <numlayers> must be equal to 6.
*/
if (newViewNumLayers != 6) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(clamped numlayers %d != 6)",
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTextureView(clamped numlayers %d != 6)",
newViewNumLayers);
return;
}
@@ -615,7 +633,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
*/
if ((newViewNumLayers % 6) != 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glTextureView(clamped numlayers %d is not a multiple of 6)",
+ "glTextureView(clamped numlayers %d is not"
+ " a multiple of 6)",
newViewNumLayers);
return;
}
@@ -628,7 +647,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
*/
if ((target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) &&
(origTexImage->Width != origTexImage->Height)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(origtexture width (%d) != height (%d))",
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTextureView(origtexture width (%d) != height (%d))",
origTexImage->Width, origTexImage->Height);
return;
}
@@ -662,7 +682,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
texObj->ImmutableLevels = origTexObj->ImmutableLevels;
texObj->Target = target;
- if (ctx->Driver.TextureView != NULL && !ctx->Driver.TextureView(ctx, texObj, origTexObj)) {
+ if (ctx->Driver.TextureView != NULL &&
+ !ctx->Driver.TextureView(ctx, texObj, origTexObj)) {
return; /* driver recorded error */
}
}
diff --git a/src/mesa/main/textureview.h b/src/mesa/main/textureview.h
index 549a13cd809..59e24b68dd0 100644
--- a/src/mesa/main/textureview.h
+++ b/src/mesa/main/textureview.h
@@ -29,8 +29,8 @@
#ifndef TEXTUREVIEW_H
#define TEXTUREVIEW_H
-GLboolean
-_mesa_texture_view_compatible_format(struct gl_context *ctx,
+bool
+_mesa_texture_view_compatible_format(const struct gl_context *ctx,
GLenum origInternalFormat,
GLenum newInternalFormat);
@@ -41,7 +41,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
GLuint minlayer, GLuint numlayers);
extern void
-_mesa_set_texture_view_state(struct gl_context *ctx, struct gl_texture_object *texObj,
- GLenum target, GLuint levels);
+_mesa_set_texture_view_state(struct gl_context *ctx,
+ struct gl_texture_object *texObj,
+ GLenum target, GLuint levels);
#endif /* TEXTUREVIEW_H */
diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index 728bd1bac10..cab5083e81b 100644
--- a/src/mesa/main/uniform_query.cpp
+++ b/src/mesa/main/uniform_query.cpp
@@ -237,6 +237,13 @@ validate_uniform_parameters(struct gl_context *ctx,
struct gl_uniform_storage *const uni = shProg->UniformRemapTable[location];
+ /* Even though no location is assigned to a built-in uniform and this
+ * function should already have returned NULL, this test makes it explicit
+ * that we are not allowing to update the value of a built-in.
+ */
+ if (uni->builtin)
+ return NULL;
+
if (uni->array_elements == 0) {
if (count > 1) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -1028,6 +1035,10 @@ _mesa_get_uniform_location(struct gl_shader_program *shProg,
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
@@ -1047,7 +1058,7 @@ _mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
char *errMsg, size_t errMsgLength)
{
/* Shader does not have samplers. */
- if (shProg->NumUserUniformStorage == 0)
+ if (shProg->NumUniformStorage == 0)
return true;
if (!shProg->SamplersValidated) {
@@ -1087,7 +1098,7 @@ _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline)
if (!shProg[idx])
continue;
- for (unsigned i = 0; i < shProg[idx]->NumUserUniformStorage; i++) {
+ 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())
diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h
index 55fa2357e38..bd7b05e207a 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);
-long
-_mesa_parse_program_resource_name(const GLchar *name,
- const GLchar **out_base_name_end);
-
unsigned
_mesa_get_uniform_location(struct gl_shader_program *shProg,
const GLchar *name, unsigned *offset);
diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c
index 7389037ae85..ebdd9eaf02e 100644
--- a/src/mesa/main/varray.c
+++ b/src/mesa/main/varray.c
@@ -2309,10 +2309,10 @@ print_array(const char *name, GLint index, const struct gl_client_array *array)
fprintf(stderr, " %s[%d]: ", name, index);
else
fprintf(stderr, " %s: ", name);
- fprintf(stderr, "Ptr=%p, Type=0x%x, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %lu)\n",
- array->Ptr, array->Type, array->Size,
- array->_ElementSize, array->StrideB,
- array->BufferObj->Name, (unsigned long) array->BufferObj->Size);
+ 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->_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 699a0de46c2..8bc00ace5c4 100644
--- a/src/mesa/main/version.c
+++ b/src/mesa/main/version.c
@@ -51,31 +51,51 @@ check_for_ending(const char *string, const char *ending)
* fwd_context is only valid if version > 0
*/
static void
-get_gl_override(int *version, bool *fwd_context, bool *compat_context)
+get_gl_override(gl_api api, int *version, bool *fwd_context,
+ bool *compat_context)
{
- const char *env_var = "MESA_GL_VERSION_OVERRIDE";
+ const char *env_var = (api == API_OPENGL_CORE || api == API_OPENGL_COMPAT)
+ ? "MESA_GL_VERSION_OVERRIDE" : "MESA_GLES_VERSION_OVERRIDE";
const char *version_str;
int major, minor, n;
- static int override_version = -1;
- static bool fc_suffix = false;
- static bool compat_suffix = false;
+ static struct override_info {
+ int version;
+ bool fc_suffix;
+ bool compat_suffix;
+ } override[] = {
+ { -1, false, false},
+ { -1, false, false},
+ { -1, false, false},
+ { -1, false, false},
+ };
- if (override_version < 0) {
- override_version = 0;
+ STATIC_ASSERT(ARRAY_SIZE(override) == API_OPENGL_LAST + 1);
+
+ if (api == API_OPENGLES)
+ goto exit;
+
+ if (override[api].version < 0) {
+ override[api].version = 0;
version_str = getenv(env_var);
if (version_str) {
- fc_suffix = check_for_ending(version_str, "FC");
- compat_suffix = check_for_ending(version_str, "COMPAT");
+ override[api].fc_suffix = check_for_ending(version_str, "FC");
+ override[api].compat_suffix = check_for_ending(version_str, "COMPAT");
n = sscanf(version_str, "%u.%u", &major, &minor);
if (n != 2) {
fprintf(stderr, "error: invalid value for %s: %s\n",
env_var, version_str);
- override_version = 0;
+ override[api].version = 0;
} else {
- override_version = major * 10 + minor;
- if (override_version < 30 && fc_suffix) {
+ override[api].version = major * 10 + minor;
+
+ /* There is no such thing as compatibility or forward-compatible for
+ * OpenGL ES 2.0 or 3.x APIs.
+ */
+ if ((override[api].version < 30 && override[api].fc_suffix) ||
+ (api == API_OPENGLES2 && (override[api].fc_suffix ||
+ override[api].compat_suffix))) {
fprintf(stderr, "error: invalid value for %s: %s\n",
env_var, version_str);
}
@@ -83,9 +103,10 @@ get_gl_override(int *version, bool *fwd_context, bool *compat_context)
}
}
- *version = override_version;
- *fwd_context = fc_suffix;
- *compat_context = compat_suffix;
+exit:
+ *version = override[api].version;
+ *fwd_context = override[api].fc_suffix;
+ *compat_context = override[api].compat_suffix;
}
/**
@@ -130,18 +151,26 @@ _mesa_override_gl_version_contextless(struct gl_constants *consts,
int version;
bool fwd_context, compat_context;
- get_gl_override(&version, &fwd_context, &compat_context);
+ get_gl_override(*apiOut, &version, &fwd_context, &compat_context);
if (version > 0) {
*versionOut = version;
- if (version >= 30 && fwd_context) {
- *apiOut = API_OPENGL_CORE;
- consts->ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
- } else if (version >= 31 && !compat_context) {
- *apiOut = API_OPENGL_CORE;
- } else {
- *apiOut = API_OPENGL_COMPAT;
+
+ /* If the API is a desktop API, adjust the context flags. We may also
+ * need to modify the API depending on the version. For example, Mesa
+ * does not support a GL 3.3 compatibility profile.
+ */
+ if (*apiOut == API_OPENGL_CORE || *apiOut == API_OPENGL_COMPAT) {
+ if (version >= 30 && fwd_context) {
+ *apiOut = API_OPENGL_CORE;
+ consts->ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
+ } else if (version >= 31 && !compat_context) {
+ *apiOut = API_OPENGL_CORE;
+ } else {
+ *apiOut = API_OPENGL_COMPAT;
+ }
}
+
return true;
}
return false;
@@ -157,22 +186,6 @@ _mesa_override_gl_version(struct gl_context *ctx)
}
/**
- * Returns the gl override value
- *
- * version > 0 indicates there is an override requested
- */
-int
-_mesa_get_gl_version_override(void)
-{
- int version;
- bool fwd_context, compat_context;
-
- get_gl_override(&version, &fwd_context, &compat_context);
-
- return version;
-}
-
-/**
* Override the context's GLSL version if the environment variable
* MESA_GLSL_VERSION_OVERRIDE is set. Valid values for
* MESA_GLSL_VERSION_OVERRIDE are integers, such as "130".
@@ -433,7 +446,23 @@ compute_version_es2(const struct gl_extensions *extensions)
extensions->EXT_texture_snorm &&
extensions->NV_primitive_restart &&
extensions->OES_depth_texture_cube_map);
- if (ver_3_0) {
+ const bool ver_3_1 = (ver_3_0 &&
+ extensions->ARB_arrays_of_arrays &&
+ extensions->ARB_compute_shader &&
+ extensions->ARB_draw_indirect &&
+ false /*extensions->ARB_framebuffer_no_attachments*/ &&
+ extensions->ARB_shader_atomic_counters &&
+ extensions->ARB_shader_image_load_store &&
+ false /*extensions->ARB_shader_image_size*/ &&
+ false /*extensions->ARB_shader_storage_buffer_object*/ &&
+ extensions->ARB_shading_language_packing &&
+ extensions->ARB_stencil_texturing &&
+ extensions->ARB_gpu_shader5 &&
+ extensions->EXT_shader_integer_mix);
+
+ if (ver_3_1) {
+ return 31;
+ } else if (ver_3_0) {
return 30;
} else if (ver_2_0) {
return 20;
diff --git a/src/mesa/main/version.h b/src/mesa/main/version.h
index 450a0e31d3d..ee7cb7501eb 100644
--- a/src/mesa/main/version.h
+++ b/src/mesa/main/version.h
@@ -47,7 +47,4 @@ _mesa_override_gl_version(struct gl_context *ctx);
extern void
_mesa_override_glsl_version(struct gl_constants *consts);
-extern int
-_mesa_get_gl_version_override(void);
-
#endif /* VERSION_H */
diff --git a/src/mesa/main/vtxfmt.c b/src/mesa/main/vtxfmt.c
index d7ef7e278cd..81bf4c589ea 100644
--- a/src/mesa/main/vtxfmt.c
+++ b/src/mesa/main/vtxfmt.c
@@ -207,7 +207,7 @@ install_vtxfmt(struct gl_context *ctx, struct _glapi_table *tab,
SET_VertexAttribP4uiv(tab, vfmt->VertexAttribP4uiv);
}
- if (_mesa_is_desktop_gl(ctx)) {
+ if (ctx->API == API_OPENGL_CORE) {
SET_VertexAttribL1d(tab, vfmt->VertexAttribL1d);
SET_VertexAttribL2d(tab, vfmt->VertexAttribL2d);
SET_VertexAttribL3d(tab, vfmt->VertexAttribL3d);