diff options
author | marha <marha@users.sourceforge.net> | 2013-08-19 09:03:18 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2013-08-19 09:03:18 +0200 |
commit | 854ec4da20ddff9b830be0a7d5b81d8cb4774132 (patch) | |
tree | 223425d84b5ea3727f74546c92dee8b03c074158 /mesalib/src/mesa | |
parent | 0659c77949b38440a2a9ba67e1ee9cacef1f3a7f (diff) | |
download | vcxsrv-854ec4da20ddff9b830be0a7d5b81d8cb4774132.tar.gz vcxsrv-854ec4da20ddff9b830be0a7d5b81d8cb4774132.tar.bz2 vcxsrv-854ec4da20ddff9b830be0a7d5b81d8cb4774132.zip |
fontconfig libX11 libXdmcp libxcb xkeyboard-config mesa pixman xserver git update 19 aug 2013
xserver commit fe7463b8ce0de301c2f82b108c93963424f77219
libxcb commit 5648ddd2b97068f549268284129a438a6845e14c
libxcb/xcb-proto commit 56a82005ac388fcb7a4d1c82e07c7e72eaf69a32
xkeyboard-config commit 87c865aee1844b2cc6b1a5a208116dd095f4d76a
libX11 commit 9b291044a240e5b9b031ed814e0c84e53a1c3084
libXdmcp commit 66514a4af7eaa47e8718434356d7efce95e570cf
libXext commit 7378d4bdbd33ed49ed6cfa5c4f73d7527982aab4
libfontenc commit 3acba630d8b57084f7e92c15732408711ed5137a
libXinerama commit 6e1d1dc328ba8162bba2f4694e7f3c706a1491ff
libXau commit 899790011304c4029e15abf410e49ce7cec17e0a
xkbcomp commit 0ebdf47fd4bc434ac3d2339544c022a869510738
pixman commit 3518a0dafa63098d41e466f73d105b7e3e4b12de
xextproto commit f27fcc99d1cf935cc289933326f7d3baacd5107a
randrproto commit ca7cc541c2e43e6c784df19b4583ac35829d2f72
glproto commit 8e3407e02980d088e20041e79bdcdd3737e7827e
mkfontscale commit f48de13423c7300f4da9f61993b624426b38ddc0
xwininfo commit ba0d1b0da21d2dbdd81098ed5778f3792b472e13
libXft commit c5e760a239afc62a1c75e0509868e35957c8df52
libXmu commit d5dac08d65c4865f311cb62c161dbb1300eecd11
libxtrans commit f6a161f2a003f4da0a2e414b4faa0ee0de0c01f0
fontconfig commit 084cf7c44e985dd48c088d921ad0d9a43b0b00b4
mesa commit d13003f544417db6de44c65a0c118bd2b189458a
Diffstat (limited to 'mesalib/src/mesa')
22 files changed, 575 insertions, 223 deletions
diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index 4a3497c9a..60157af98 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -704,9 +704,14 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state) _mesa_LoadIdentity(); _mesa_MatrixMode(GL_PROJECTION); _mesa_LoadIdentity(); - _mesa_Ortho(0.0, ctx->DrawBuffer->Width, - 0.0, ctx->DrawBuffer->Height, - -1.0, 1.0); + + /* glOrtho with width = 0 or height = 0 generates GL_INVALID_VALUE. + * This can occur when there is no draw buffer. + */ + if (ctx->DrawBuffer->Width != 0 && ctx->DrawBuffer->Height != 0) + _mesa_Ortho(0.0, ctx->DrawBuffer->Width, + 0.0, ctx->DrawBuffer->Height, + -1.0, 1.0); } if (state & MESA_META_CLIP) { @@ -956,7 +961,7 @@ _mesa_meta_end(struct gl_context *ctx) if (ctx->Extensions.ARB_vertex_shader) _mesa_use_shader_program(ctx, GL_VERTEX_SHADER, save->VertexShader); - if (ctx->Extensions.ARB_geometry_shader4) + if (_mesa_has_geometry_shaders(ctx)) _mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, save->GeometryShader); @@ -1879,19 +1884,24 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx, const GLenum rb_base_format = _mesa_base_tex_format(ctx, colorReadRb->InternalFormat); - newTex = alloc_texture(tex, srcW, srcH, rb_base_format); - setup_copypix_texture(ctx, tex, newTex, srcX, srcY, srcW, srcH, + /* Using the exact source rectangle to create the texture does incorrect + * linear filtering along the edges. So, allocate the texture extended along + * edges by one pixel in x, y directions. + */ + newTex = alloc_texture(tex, srcW + 2, srcH + 2, rb_base_format); + setup_copypix_texture(ctx, tex, newTex, + srcX - 1, srcY - 1, srcW + 2, srcH + 2, rb_base_format, filter); /* texcoords (after texture allocation!) */ { - verts[0].s = 0.0F; - verts[0].t = 0.0F; - verts[1].s = tex->Sright; - verts[1].t = 0.0F; - verts[2].s = tex->Sright; - verts[2].t = tex->Ttop; - verts[3].s = 0.0F; - verts[3].t = tex->Ttop; + verts[0].s = 1.0F; + verts[0].t = 1.0F; + verts[1].s = tex->Sright - 1.0F; + verts[1].t = 1.0F; + verts[2].s = tex->Sright - 1.0F; + verts[2].t = tex->Ttop - 1.0F; + verts[3].s = 1.0F; + verts[3].t = tex->Ttop - 1.0F; /* upload new vertex data */ _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c index 9ed9df4b3..fa520ea90 100644 --- a/mesalib/src/mesa/drivers/dri/common/dri_util.c +++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c @@ -52,8 +52,6 @@ PUBLIC const char __dri2ConfigOptions[] = DRI_CONF_SECTION_END DRI_CONF_END; -static const uint __dri2NConfigOptions = 1; - /*****************************************************************/ /** \name Screen handling functions */ /*****************************************************************/ @@ -112,7 +110,7 @@ dri2CreateNewScreen(int scrn, int fd, return NULL; } - driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions, __dri2NConfigOptions); + driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions); driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum, "dri2"); return psp; diff --git a/mesalib/src/mesa/drivers/dri/common/xmlconfig.c b/mesalib/src/mesa/drivers/dri/common/xmlconfig.c index 5c97c20fc..b95e452f1 100644 --- a/mesalib/src/mesa/drivers/dri/common/xmlconfig.c +++ b/mesalib/src/mesa/drivers/dri/common/xmlconfig.c @@ -132,16 +132,6 @@ static GLuint findOption (const driOptionCache *cache, const char *name) { return hash; } -/** \brief Count the real number of options in an option cache */ -static GLuint countOptions (const driOptionCache *cache) { - GLuint size = 1 << cache->tableSize; - GLuint i, count = 0; - for (i = 0; i < size; ++i) - if (cache->info[i].name) - count++; - return count; -} - /** \brief Like strdup but using malloc and with error checking. */ #define XSTRDUP(dest,source) do { \ GLuint len = strlen (source); \ @@ -685,25 +675,18 @@ static void optInfoEndElem (void *userData, const XML_Char *name) { } } -void driParseOptionInfo (driOptionCache *info, - const char *configOptions, GLuint nConfigOptions) { +void driParseOptionInfo (driOptionCache *info, const char *configOptions) { XML_Parser p; int status; struct OptInfoData userData; struct OptInfoData *data = &userData; - GLuint realNoptions; - - /* determine hash table size and allocate memory: - * 3/2 of the number of options, rounded up, so there remains always - * at least one free entry. This is needed for detecting undefined - * options in configuration files without getting a hash table overflow. - * Round this up to a power of two. */ - GLuint minSize = (nConfigOptions*3 + 1) / 2; - GLuint size, log2size; - for (size = 1, log2size = 0; size < minSize; size <<= 1, ++log2size); - info->tableSize = log2size; - info->info = calloc(size, sizeof (driOptionInfo)); - info->values = calloc(size, sizeof (driOptionValue)); + + /* Make the hash table big enough to fit more than the maximum number of + * config options we've ever seen in a driver. + */ + info->tableSize = 6; + info->info = calloc(1 << info->tableSize, sizeof (driOptionInfo)); + info->values = calloc(1 << info->tableSize, sizeof (driOptionValue)); if (info->info == NULL || info->values == NULL) { fprintf (stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); abort(); @@ -728,17 +711,6 @@ void driParseOptionInfo (driOptionCache *info, XML_FATAL ("%s.", XML_ErrorString(XML_GetErrorCode(p))); XML_ParserFree (p); - - /* Check if the actual number of options matches nConfigOptions. - * A mismatch is not fatal (a hash table overflow would be) but we - * want the driver developer's attention anyway. */ - realNoptions = countOptions (info); - if (realNoptions != nConfigOptions) { - fprintf (stderr, - "Error: nConfigOptions (%u) does not match the actual number of options in\n" - " __driConfigOptions (%u).\n", - nConfigOptions, realNoptions); - } } /** \brief Parser context for configuration files. */ diff --git a/mesalib/src/mesa/drivers/dri/common/xmlconfig.h b/mesalib/src/mesa/drivers/dri/common/xmlconfig.h index c363af764..d0ad42c19 100644 --- a/mesalib/src/mesa/drivers/dri/common/xmlconfig.h +++ b/mesalib/src/mesa/drivers/dri/common/xmlconfig.h @@ -76,7 +76,6 @@ typedef struct driOptionCache { GLuint tableSize; /**< \brief Size of the arrays * - * Depending on the hash function this may differ from __driNConfigOptions. * In the current implementation it's not actually a size but log2(size). * The value is the same in the screen and all contexts. */ } driOptionCache; @@ -87,14 +86,13 @@ typedef struct driOptionCache { * * \param info pointer to a driOptionCache that will store the option info * \param configOptions XML document describing available configuration opts - * \param nConfigOptions number of options, used to choose a hash table size * * For the option information to be available to external configuration tools * it must be a public symbol __driConfigOptions. It is also passed as a * parameter to driParseOptionInfo in order to avoid driver-independent code * depending on symbols in driver-specific code. */ void driParseOptionInfo (driOptionCache *info, - const char *configOptions, GLuint nConfigOptions); + const char *configOptions); /** \brief Initialize option cache from info and parse configuration files * * To be called in <driver>CreateContext. screenNum and driverName select diff --git a/mesalib/src/mesa/main/api_validate.c b/mesalib/src/mesa/main/api_validate.c index 7ab8e305d..243bb89d1 100644 --- a/mesalib/src/mesa/main/api_validate.c +++ b/mesalib/src/mesa/main/api_validate.c @@ -222,7 +222,7 @@ _mesa_is_valid_prim_mode(struct gl_context *ctx, GLenum mode) case GL_LINE_STRIP_ADJACENCY: case GL_TRIANGLES_ADJACENCY: case GL_TRIANGLE_STRIP_ADJACENCY: - return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4; + return _mesa_has_geometry_shaders(ctx); default: return false; } @@ -245,6 +245,74 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name) return GL_FALSE; } + /* From the ARB_geometry_shader4 spec: + * + * The error INVALID_OPERATION is generated if Begin, or any command that + * implicitly calls Begin, is called when a geometry shader is active and: + * + * * the input primitive type of the current geometry shader is + * POINTS and <mode> is not POINTS, + * + * * the input primitive type of the current geometry shader is + * LINES and <mode> is not LINES, LINE_STRIP, or LINE_LOOP, + * + * * the input primitive type of the current geometry shader is + * TRIANGLES and <mode> is not TRIANGLES, TRIANGLE_STRIP or + * TRIANGLE_FAN, + * + * * the input primitive type of the current geometry shader is + * LINES_ADJACENCY_ARB and <mode> is not LINES_ADJACENCY_ARB or + * LINE_STRIP_ADJACENCY_ARB, or + * + * * the input primitive type of the current geometry shader is + * TRIANGLES_ADJACENCY_ARB and <mode> is not + * TRIANGLES_ADJACENCY_ARB or TRIANGLE_STRIP_ADJACENCY_ARB. + * + */ + if (ctx->Shader.CurrentGeometryProgram) { + const GLenum geom_mode = + ctx->Shader.CurrentGeometryProgram->Geom.InputType; + switch (mode) { + case GL_POINTS: + valid_enum = (geom_mode == GL_POINTS); + break; + case GL_LINES: + case GL_LINE_LOOP: + case GL_LINE_STRIP: + valid_enum = (geom_mode == GL_LINES); + break; + case GL_TRIANGLES: + case GL_TRIANGLE_STRIP: + case GL_TRIANGLE_FAN: + valid_enum = (geom_mode == GL_TRIANGLES); + break; + case GL_QUADS: + case GL_QUAD_STRIP: + case GL_POLYGON: + valid_enum = false; + break; + case GL_LINES_ADJACENCY: + case GL_LINE_STRIP_ADJACENCY: + valid_enum = (geom_mode == GL_LINES_ADJACENCY); + break; + case GL_TRIANGLES_ADJACENCY: + case GL_TRIANGLE_STRIP_ADJACENCY: + valid_enum = (geom_mode == GL_TRIANGLES_ADJACENCY); + break; + default: + valid_enum = false; + break; + } + if (!valid_enum) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(mode=%s vs geometry shader input %s)", + name, + _mesa_lookup_prim_by_nr(mode), + _mesa_lookup_prim_by_nr(geom_mode)); + return GL_FALSE; + } + } + /* From the GL_EXT_transform_feedback spec: * * "The error INVALID_OPERATION is generated if Begin, or any command diff --git a/mesalib/src/mesa/main/context.h b/mesalib/src/mesa/main/context.h index 8872be1f4..792ab4cd5 100644 --- a/mesalib/src/mesa/main/context.h +++ b/mesalib/src/mesa/main/context.h @@ -312,6 +312,17 @@ _mesa_is_gles3(const struct gl_context *ctx) } +/** + * Checks if the context supports geometry shaders. + */ +static inline GLboolean +_mesa_has_geometry_shaders(const struct gl_context *ctx) +{ + return _mesa_is_desktop_gl(ctx) && + (ctx->Version >= 32 || ctx->Extensions.ARB_geometry_shader4); +} + + #ifdef __cplusplus } #endif diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index bf7e85c88..1034c7a71 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -343,6 +343,28 @@ _mesa_remove_attachment(struct gl_context *ctx, } /** + * Verify a couple error conditions that will lead to an incomplete FBO and + * may cause problems for the driver's RenderTexture path. + */ +static bool +driver_RenderTexture_is_safe(const struct gl_renderbuffer_attachment *att) +{ + const struct gl_texture_image *const texImage = + att->Texture->Image[att->CubeMapFace][att->TextureLevel]; + + if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0) + return false; + + if ((texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY + && att->Zoffset >= texImage->Height) + || (texImage->TexObject->Target != GL_TEXTURE_1D_ARRAY + && att->Zoffset >= texImage->Depth)) + return false; + + return true; +} + +/** * Create a renderbuffer which will be set up by the driver to wrap the * texture image slice. * @@ -363,8 +385,6 @@ _mesa_update_texture_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb; texImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; - if (!texImage) - return; rb = att->Renderbuffer; if (!rb) { @@ -383,6 +403,9 @@ _mesa_update_texture_renderbuffer(struct gl_context *ctx, rb->NeedsFinishRenderTexture = ctx->Driver.FinishRenderTexture != NULL; } + if (!texImage) + return; + rb->_BaseFormat = texImage->_BaseFormat; rb->Format = texImage->TexFormat; rb->InternalFormat = texImage->InternalFormat; @@ -391,7 +414,8 @@ _mesa_update_texture_renderbuffer(struct gl_context *ctx, rb->NumSamples = texImage->NumSamples; rb->TexImage = texImage; - ctx->Driver.RenderTexture(ctx, fb, att); + if (driver_RenderTexture_is_safe(att)) + ctx->Driver.RenderTexture(ctx, fb, att); } /** @@ -703,15 +727,39 @@ test_attachment_completeness(const struct gl_context *ctx, GLenum format, } if (texImage->Width < 1 || texImage->Height < 1) { att_incomplete("teximage width/height=0"); - printf("texobj = %u\n", texObj->Name); - printf("level = %d\n", att->TextureLevel); att->Complete = GL_FALSE; return; } - if (texObj->Target == GL_TEXTURE_3D && att->Zoffset >= texImage->Depth) { - att_incomplete("bad z offset"); - att->Complete = GL_FALSE; - return; + + switch (texObj->Target) { + case GL_TEXTURE_3D: + if (att->Zoffset >= texImage->Depth) { + att_incomplete("bad z offset"); + att->Complete = GL_FALSE; + return; + } + break; + case GL_TEXTURE_1D_ARRAY: + if (att->Zoffset >= texImage->Height) { + att_incomplete("bad 1D-array layer"); + att->Complete = GL_FALSE; + return; + } + break; + case GL_TEXTURE_2D_ARRAY: + if (att->Zoffset >= texImage->Depth) { + att_incomplete("bad 2D-array layer"); + att->Complete = GL_FALSE; + return; + } + break; + case GL_TEXTURE_CUBE_MAP_ARRAY: + if (att->Zoffset >= texImage->Depth) { + att_incomplete("bad cube-array layer"); + att->Complete = GL_FALSE; + return; + } + break; } baseFormat = _mesa_get_format_base_format(texImage->TexFormat); @@ -1104,8 +1152,8 @@ _mesa_IsRenderbuffer(GLuint renderbuffer) } -void GLAPIENTRY -_mesa_BindRenderbuffer(GLenum target, GLuint renderbuffer) +static void +bind_renderbuffer(GLenum target, GLuint renderbuffer, bool allow_user_names) { struct gl_renderbuffer *newRb; GET_CURRENT_CONTEXT(ctx); @@ -1125,9 +1173,7 @@ _mesa_BindRenderbuffer(GLenum target, GLuint renderbuffer) /* ID was reserved, but no real renderbuffer object made yet */ newRb = NULL; } - else if (!newRb - && _mesa_is_desktop_gl(ctx) - && ctx->Extensions.ARB_framebuffer_object) { + else if (!newRb && !allow_user_names) { /* All RB IDs must be Gen'd */ _mesa_error(ctx, GL_INVALID_OPERATION, "glBindRenderbuffer(buffer)"); return; @@ -1154,32 +1200,68 @@ _mesa_BindRenderbuffer(GLenum target, GLuint renderbuffer) _mesa_reference_renderbuffer(&ctx->CurrentRenderbuffer, newRb); } +void GLAPIENTRY +_mesa_BindRenderbuffer(GLenum target, GLuint renderbuffer) +{ + GET_CURRENT_CONTEXT(ctx); + + /* OpenGL ES glBindRenderbuffer and glBindRenderbufferOES use this same + * entry point, but they allow the use of user-generated names. + */ + bind_renderbuffer(target, renderbuffer, _mesa_is_gles(ctx)); +} void GLAPIENTRY _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer) { - _mesa_BindRenderbuffer(target, renderbuffer); + /* This function should not be in the dispatch table for core profile / + * OpenGL 3.1, so execution should never get here in those cases -- no + * need for an explicit test. + */ + bind_renderbuffer(target, renderbuffer, true); } /** - * If the given renderbuffer is anywhere attached to the framebuffer, detach - * the renderbuffer. - * This is used when a renderbuffer object is deleted. - * The spec calls for unbinding. + * Remove the specified renderbuffer or texture from any attachment point in + * the framebuffer. + * + * \returns + * \c true if the renderbuffer was detached from an attachment point. \c + * false otherwise. */ -static void -detach_renderbuffer(struct gl_context *ctx, - struct gl_framebuffer *fb, - struct gl_renderbuffer *rb) +bool +_mesa_detach_renderbuffer(struct gl_context *ctx, + struct gl_framebuffer *fb, + const void *att) { - GLuint i; + unsigned i; + bool progress = false; + for (i = 0; i < BUFFER_COUNT; i++) { - if (fb->Attachment[i].Renderbuffer == rb) { + if (fb->Attachment[i].Texture == att + || fb->Attachment[i].Renderbuffer == att) { _mesa_remove_attachment(ctx, &fb->Attachment[i]); + progress = true; } } - invalidate_framebuffer(fb); + + /* Section 4.4.4 (Framebuffer Completeness), subsection "Whole Framebuffer + * Completeness," of the OpenGL 3.1 spec says: + * + * "Performing any of the following actions may change whether the + * framebuffer is considered complete or incomplete: + * + * ... + * + * - Deleting, with DeleteTextures or DeleteRenderbuffers, an object + * containing an image that is attached to a framebuffer object + * that is bound to the framebuffer." + */ + if (progress) + invalidate_framebuffer(fb); + + return progress; } @@ -1203,12 +1285,29 @@ _mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) _mesa_BindRenderbuffer(GL_RENDERBUFFER_EXT, 0); } + /* Section 4.4.2 (Attaching Images to Framebuffer Objects), + * subsection "Attaching Renderbuffer Images to a Framebuffer," of + * the OpenGL 3.1 spec says: + * + * "If a renderbuffer object is deleted while its image is + * attached to one or more attachment points in the currently + * bound framebuffer, then it is as if FramebufferRenderbuffer + * had been called, with a renderbuffer of 0, for each + * attachment point to which this image was attached in the + * currently bound framebuffer. In other words, this + * renderbuffer image is first detached from all attachment + * points in the currently bound framebuffer. Note that the + * renderbuffer image is specifically not detached from any + * non-bound framebuffers. Detaching the image from any + * non-bound framebuffers is the responsibility of the + * application. + */ if (_mesa_is_user_fbo(ctx->DrawBuffer)) { - detach_renderbuffer(ctx, ctx->DrawBuffer, rb); + _mesa_detach_renderbuffer(ctx, ctx->DrawBuffer, rb); } if (_mesa_is_user_fbo(ctx->ReadBuffer) && ctx->ReadBuffer != ctx->DrawBuffer) { - detach_renderbuffer(ctx, ctx->ReadBuffer, rb); + _mesa_detach_renderbuffer(ctx, ctx->ReadBuffer, rb); } /* Remove from hash table immediately, to free the ID. @@ -1875,7 +1974,8 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) for (i = 0; i < BUFFER_COUNT; i++) { struct gl_renderbuffer_attachment *att = fb->Attachment + i; - if (att->Texture && att->Renderbuffer->TexImage) { + if (att->Texture && att->Renderbuffer->TexImage + && driver_RenderTexture_is_safe(att)) { ctx->Driver.RenderTexture(ctx, fb, att); } } @@ -1906,8 +2006,8 @@ check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) } -void GLAPIENTRY -_mesa_BindFramebuffer(GLenum target, GLuint framebuffer) +static void +bind_framebuffer(GLenum target, GLuint framebuffer, bool allow_user_names) { struct gl_framebuffer *newDrawFb, *newReadFb; struct gl_framebuffer *oldDrawFb, *oldReadFb; @@ -1953,9 +2053,7 @@ _mesa_BindFramebuffer(GLenum target, GLuint framebuffer) /* ID was reserved, but no real framebuffer object made yet */ newDrawFb = NULL; } - else if (!newDrawFb - && _mesa_is_desktop_gl(ctx) - && ctx->Extensions.ARB_framebuffer_object) { + else if (!newDrawFb && !allow_user_names) { /* All FBO IDs must be Gen'd */ _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFramebuffer(buffer)"); return; @@ -2033,12 +2131,25 @@ _mesa_BindFramebuffer(GLenum target, GLuint framebuffer) } void GLAPIENTRY -_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer) +_mesa_BindFramebuffer(GLenum target, GLuint framebuffer) { - _mesa_BindFramebuffer(target, framebuffer); -} + GET_CURRENT_CONTEXT(ctx); + /* OpenGL ES glBindFramebuffer and glBindFramebufferOES use this same entry + * point, but they allow the use of user-generated names. + */ + bind_framebuffer(target, framebuffer, _mesa_is_gles(ctx)); +} +void GLAPIENTRY +_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer) +{ + /* This function should not be in the dispatch table for core profile / + * OpenGL 3.1, so execution should never get here in those cases -- no + * need for an explicit test. + */ + bind_framebuffer(target, framebuffer, true); +} void GLAPIENTRY _mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers) @@ -2476,7 +2587,7 @@ _mesa_FramebufferTexture(GLenum target, GLenum attachment, { GET_CURRENT_CONTEXT(ctx); - if (ctx->Version >= 32 || ctx->Extensions.ARB_geometry_shader4) { + if (_mesa_has_geometry_shaders(ctx)) { framebuffer_texture(ctx, "Layer", target, attachment, 0, texture, level, 0, GL_TRUE); } else { diff --git a/mesalib/src/mesa/main/fbobject.h b/mesalib/src/mesa/main/fbobject.h index 0a2a5cc59..ab138cfff 100644 --- a/mesalib/src/mesa/main/fbobject.h +++ b/mesalib/src/mesa/main/fbobject.h @@ -28,6 +28,7 @@ #include "compiler.h" #include "glheader.h" +#include <stdbool.h> struct gl_context; struct gl_texture_object; @@ -113,6 +114,11 @@ _mesa_is_legal_color_format(const struct gl_context *ctx, GLenum baseFormat); extern GLenum _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat); +extern bool +_mesa_detach_renderbuffer(struct gl_context *ctx, + struct gl_framebuffer *fb, + const void *att); + extern GLboolean GLAPIENTRY _mesa_IsRenderbuffer(GLuint renderbuffer); diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c index 0b33fa49b..09b008a07 100644 --- a/mesalib/src/mesa/main/get.c +++ b/mesalib/src/mesa/main/get.c @@ -989,7 +989,7 @@ check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d case EXTRA_EXT_UBO_GS4: api_check = GL_TRUE; api_found = (ctx->Extensions.ARB_uniform_buffer_object && - ctx->Extensions.ARB_geometry_shader4); + _mesa_has_geometry_shaders(ctx)); break; case EXTRA_END: break; diff --git a/mesalib/src/mesa/main/lines.c b/mesalib/src/mesa/main/lines.c index 0df9d66b0..3c08ed2e7 100644 --- a/mesalib/src/mesa/main/lines.c +++ b/mesalib/src/mesa/main/lines.c @@ -62,7 +62,8 @@ _mesa_LineWidth( GLfloat width ) */ if (ctx->API == API_OPENGL_CORE && ((ctx->Const.ContextFlags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) - != 0)) { + != 0) + && width > 1.0) { _mesa_error( ctx, GL_INVALID_VALUE, "glLineWidth" ); return; } diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 5bb680745..5f9b7f983 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1152,31 +1152,32 @@ struct gl_sampler_object */ struct gl_texture_object { - _glthread_Mutex Mutex; /**< for thread safety */ - GLint RefCount; /**< reference count */ - GLuint Name; /**< the user-visible texture object ID */ - GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */ + _glthread_Mutex Mutex; /**< for thread safety */ + GLint RefCount; /**< reference count */ + GLuint Name; /**< the user-visible texture object ID */ + GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */ struct gl_sampler_object Sampler; - GLenum DepthMode; /**< GL_ARB_depth_texture */ - - GLfloat Priority; /**< in [0,1] */ - GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */ - GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */ - GLint ImmutableLevels; /**< ES 3.0 / ARB_texture_view */ - GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */ - GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */ - GLint CropRect[4]; /**< GL_OES_draw_texture */ - GLenum Swizzle[4]; /**< GL_EXT_texture_swizzle */ - GLuint _Swizzle; /**< same as Swizzle, but SWIZZLE_* format */ - GLboolean GenerateMipmap; /**< GL_SGIS_generate_mipmap */ - GLboolean _BaseComplete; /**< Is the base texture level valid? */ - GLboolean _MipmapComplete; /**< Is the whole mipmap valid? */ - GLboolean _IsIntegerFormat; /**< Does the texture store integer values? */ - GLboolean _RenderToTexture; /**< Any rendering to this texture? */ - GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ - GLboolean Immutable; /**< GL_ARB_texture_storage */ + GLenum DepthMode; /**< GL_ARB_depth_texture */ + + GLfloat Priority; /**< in [0,1] */ + GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */ + GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */ + GLint ImmutableLevels; /**< ES 3.0 / ARB_texture_view */ + GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */ + GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - p in spec) */ + GLint CropRect[4]; /**< GL_OES_draw_texture */ + GLenum Swizzle[4]; /**< GL_EXT_texture_swizzle */ + GLuint _Swizzle; /**< same as Swizzle, but SWIZZLE_* format */ + GLboolean GenerateMipmap; /**< GL_SGIS_generate_mipmap */ + GLboolean _BaseComplete; /**< Is the base texture level valid? */ + GLboolean _MipmapComplete; /**< Is the whole mipmap valid? */ + GLboolean _IsIntegerFormat; /**< Does the texture store integer values? */ + GLboolean _RenderToTexture; /**< Any rendering to this texture? */ + GLboolean Purgeable; /**< Is the buffer purgeable under memory + pressure? */ + GLboolean Immutable; /**< GL_ARB_texture_storage */ /** Actual texture images, indexed by [cube face] and [mipmap level] */ struct gl_texture_image *Image[MAX_FACES][MAX_TEXTURE_LEVELS]; @@ -1851,7 +1852,7 @@ struct gl_program GLuint Id; GLubyte *String; /**< Null-terminated program text */ GLint RefCount; - GLenum Target; /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB */ + GLenum Target; /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_GEOMETRY_PROGRAM_NV */ GLenum Format; /**< String encoding format */ struct prog_instruction *Instructions; @@ -1918,6 +1919,7 @@ struct gl_geometry_program { struct gl_program Base; /**< base class */ + GLint VerticesIn; GLint VerticesOut; GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB, GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */ @@ -2169,6 +2171,24 @@ struct gl_shader /** Shaders containing built-in functions that are used for linking. */ struct gl_shader *builtins_to_link[16]; unsigned num_builtins_to_link; + + /** + * Geometry shader state from GLSL 1.50 layout qualifiers. + */ + struct { + GLint VerticesOut; + /** + * GL_POINTS, GL_LINES, GL_LINES_ADJACENCY, GL_TRIANGLES, or + * GL_TRIANGLES_ADJACENCY, or PRIM_UNKNOWN if it's not set in this + * shader. + */ + GLenum InputType; + /** + * GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP, or PRIM_UNKNOWN if + * it's not set in this shader. + */ + GLenum OutputType; + } Geom; }; @@ -2318,17 +2338,25 @@ struct gl_shader_program /** Post-link gl_FragDepth layout for ARB_conservative_depth. */ enum gl_frag_depth_layout FragDepthLayout; - /** Geometry shader state - copied into gl_geometry_program at link time */ + /** + * Geometry shader state - copied into gl_geometry_program by + * _mesa_copy_linked_program_data(). + */ struct { + GLint VerticesIn; GLint VerticesOut; GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB, GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */ GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */ } Geom; - /** Vertex shader state - copied into gl_vertex_program at link time */ + /** Vertex shader state */ struct { - GLboolean UsesClipDistance; /**< True if gl_ClipDistance is written to. */ + /** + * True if gl_ClipDistance is written to. Copied into gl_vertex_program + * by _mesa_copy_linked_program_data(). + */ + GLboolean UsesClipDistance; GLuint ClipDistanceArraySize; /**< Size of the gl_ClipDistance array, or 0 if not present. */ } Vert; diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index c349b0cb5..d184b114c 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -179,7 +179,7 @@ validate_shader_target(const struct gl_context *ctx, GLenum type) case GL_VERTEX_SHADER: return ctx->Extensions.ARB_vertex_shader; case GL_GEOMETRY_SHADER_ARB: - return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4; + return _mesa_has_geometry_shaders(ctx); default: return false; } @@ -478,8 +478,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param /* Are geometry shaders available in this context? */ - const bool has_gs = - _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4; + const bool has_gs = _mesa_has_geometry_shaders(ctx); /* Are uniform buffer objects available in this context? */ @@ -743,6 +742,12 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj) if (!sh) return; + /* Geometry shaders are not yet fully supported, so issue a warning message + * if we're compiling one. + */ + if (sh->Type == GL_GEOMETRY_SHADER) + printf("WARNING: Geometry shader support is currently experimental.\n"); + options = &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(sh->Type)]; /* set default pragma state for shader */ @@ -1635,10 +1640,10 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value) if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4) break; - if (value < 1 || + if (value < 0 || (unsigned) value > ctx->Const.MaxGeometryOutputVertices) { _mesa_error(ctx, GL_INVALID_VALUE, - "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d", + "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d)", value); return; } @@ -1658,7 +1663,7 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value) break; default: _mesa_error(ctx, GL_INVALID_VALUE, - "glProgramParameteri(geometry input type = %s", + "glProgramParameteri(geometry input type = %s)", _mesa_lookup_enum_by_nr(value)); return; } @@ -1675,7 +1680,7 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value) break; default: _mesa_error(ctx, GL_INVALID_VALUE, - "glProgramParameteri(geometry output type = %s", + "glProgramParameteri(geometry output type = %s)", _mesa_lookup_enum_by_nr(value)); return; } @@ -1843,3 +1848,32 @@ _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string) return program; } + + +/** + * Copy program-specific data generated by linking from the gl_shader_program + * object to a specific gl_program object. + */ +void +_mesa_copy_linked_program_data(gl_shader_type type, + const struct gl_shader_program *src, + struct gl_program *dst) +{ + switch (type) { + case MESA_SHADER_VERTEX: { + struct gl_vertex_program *dst_vp = (struct gl_vertex_program *) dst; + dst_vp->UsesClipDistance = src->Vert.UsesClipDistance; + } + break; + case MESA_SHADER_GEOMETRY: { + struct gl_geometry_program *dst_gp = (struct gl_geometry_program *) dst; + dst_gp->VerticesIn = src->Geom.VerticesIn; + dst_gp->VerticesOut = src->Geom.VerticesOut; + dst_gp->InputType = src->Geom.InputType; + dst_gp->OutputType = src->Geom.OutputType; + } + break; + default: + break; + } +} diff --git a/mesalib/src/mesa/main/shaderapi.h b/mesalib/src/mesa/main/shaderapi.h index 1cd4ffcea..fe58e7de9 100644 --- a/mesalib/src/mesa/main/shaderapi.h +++ b/mesalib/src/mesa/main/shaderapi.h @@ -210,6 +210,11 @@ _mesa_ActiveProgramEXT(GLuint program); extern GLuint GLAPIENTRY _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string); +extern void +_mesa_copy_linked_program_data(gl_shader_type type, + const struct gl_shader_program *src, + struct gl_program *dst); + #ifdef __cplusplus } diff --git a/mesalib/src/mesa/main/shared.c b/mesalib/src/mesa/main/shared.c index 5ef88098f..2f73cf3ca 100644 --- a/mesalib/src/mesa/main/shared.c +++ b/mesalib/src/mesa/main/shared.c @@ -218,7 +218,8 @@ delete_shader_cb(GLuint id, void *data, void *userData) { struct gl_context *ctx = (struct gl_context *) userData; struct gl_shader *sh = (struct gl_shader *) data; - if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) { + if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER || + sh->Type == GL_GEOMETRY_SHADER) { ctx->Driver.DeleteShader(ctx, sh); } else { diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c index 334dee77b..7c8f04db9 100644 --- a/mesalib/src/mesa/main/texobj.c +++ b/mesalib/src/mesa/main/texobj.c @@ -548,12 +548,13 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, ASSERT(maxLevels > 0); - t->_MaxLevel = - baseLevel + baseImage->MaxNumLevels - 1; /* 'p' in the GL spec */ - t->_MaxLevel = MIN2(t->_MaxLevel, t->MaxLevel); - t->_MaxLevel = MIN2(t->_MaxLevel, maxLevels - 1); /* 'q' in the GL spec */ + t->_MaxLevel = MIN3(t->MaxLevel, + /* 'p' in the GL spec */ + baseLevel + baseImage->MaxNumLevels - 1, + /* 'q' in the GL spec */ + maxLevels - 1); - /* Compute _MaxLambda = q - b (see the 1.2 spec) used during mipmapping */ + /* Compute _MaxLambda = q - p in the spec used during mipmapping */ t->_MaxLambda = (GLfloat) (t->_MaxLevel - baseLevel); if (t->Immutable) { @@ -1040,23 +1041,35 @@ static void unbind_texobj_from_fbo(struct gl_context *ctx, struct gl_texture_object *texObj) { - const GLuint n = (ctx->DrawBuffer == ctx->ReadBuffer) ? 1 : 2; - GLuint i; + bool progress = false; - for (i = 0; i < n; i++) { - struct gl_framebuffer *fb = (i == 0) ? ctx->DrawBuffer : ctx->ReadBuffer; - if (_mesa_is_user_fbo(fb)) { - GLuint j; - for (j = 0; j < BUFFER_COUNT; j++) { - if (fb->Attachment[j].Type == GL_TEXTURE && - fb->Attachment[j].Texture == texObj) { - /* Vertices are already flushed by _mesa_DeleteTextures */ - ctx->NewState |= _NEW_BUFFERS; - _mesa_remove_attachment(ctx, fb->Attachment + j); - } - } - } + /* Section 4.4.2 (Attaching Images to Framebuffer Objects), subsection + * "Attaching Texture Images to a Framebuffer," of the OpenGL 3.1 spec + * says: + * + * "If a texture object is deleted while its image is attached to one + * or more attachment points in the currently bound framebuffer, then + * it is as if FramebufferTexture* had been called, with a texture of + * zero, for each attachment point to which this image was attached in + * the currently bound framebuffer. In other words, this texture image + * is first detached from all attachment points in the currently bound + * framebuffer. Note that the texture image is specifically not + * detached from any other framebuffer objects. Detaching the texture + * image from any other framebuffer objects is the responsibility of + * the application." + */ + if (_mesa_is_user_fbo(ctx->DrawBuffer)) { + progress = _mesa_detach_renderbuffer(ctx, ctx->DrawBuffer, texObj); } + if (_mesa_is_user_fbo(ctx->ReadBuffer) + && ctx->ReadBuffer != ctx->DrawBuffer) { + progress = _mesa_detach_renderbuffer(ctx, ctx->ReadBuffer, texObj) + || progress; + } + + if (progress) + /* Vertices are already flushed by _mesa_DeleteTextures */ + ctx->NewState |= _NEW_BUFFERS; } diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c index 32109951c..757ae80ec 100644 --- a/mesalib/src/mesa/main/texparam.c +++ b/mesalib/src/mesa/main/texparam.c @@ -386,7 +386,13 @@ set_tex_parameteri(struct gl_context *ctx, return GL_FALSE; } incomplete(ctx, texObj); - texObj->BaseLevel = params[0]; + + /** See note about ARB_texture_storage below */ + if (texObj->Immutable) + texObj->BaseLevel = MIN2(texObj->ImmutableLevels - 1, params[0]); + else + texObj->BaseLevel = params[0]; + return GL_TRUE; case GL_TEXTURE_MAX_LEVEL: @@ -399,7 +405,19 @@ set_tex_parameteri(struct gl_context *ctx, return GL_FALSE; } incomplete(ctx, texObj); - texObj->MaxLevel = params[0]; + + /** From ARB_texture_storage: + * However, if TEXTURE_IMMUTABLE_FORMAT is TRUE, then level_base is + * clamped to the range [0, <levels> - 1] and level_max is then clamped to + * the range [level_base, <levels> - 1], where <levels> is the parameter + * passed the call to TexStorage* for the texture object. + */ + if (texObj->Immutable) + texObj->MaxLevel = CLAMP(params[0], texObj->BaseLevel, + texObj->ImmutableLevels - 1); + else + texObj->MaxLevel = params[0]; + return GL_TRUE; case GL_GENERATE_MIPMAP_SGIS: diff --git a/mesalib/src/mesa/main/texstate.c b/mesalib/src/mesa/main/texstate.c index afff01359..dad69a8f6 100644 --- a/mesalib/src/mesa/main/texstate.c +++ b/mesalib/src/mesa/main/texstate.c @@ -528,6 +528,7 @@ update_texture_state( struct gl_context *ctx ) GLuint unit; struct gl_program *fprog = NULL; struct gl_program *vprog = NULL; + struct gl_program *gprog = NULL; GLbitfield enabledFragUnits = 0x0; if (ctx->Shader.CurrentVertexProgram && @@ -535,6 +536,11 @@ update_texture_state( struct gl_context *ctx ) vprog = ctx->Shader.CurrentVertexProgram->_LinkedShaders[MESA_SHADER_VERTEX]->Program; } + if (ctx->Shader.CurrentGeometryProgram && + ctx->Shader.CurrentGeometryProgram->LinkStatus) { + gprog = ctx->Shader.CurrentGeometryProgram->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program; + } + if (ctx->Shader.CurrentFragmentProgram && ctx->Shader.CurrentFragmentProgram->LinkStatus) { fprog = ctx->Shader.CurrentFragmentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program; @@ -543,10 +549,6 @@ update_texture_state( struct gl_context *ctx ) fprog = &ctx->FragmentProgram.Current->Base; } - /* FINISHME: Geometry shader texture accesses should also be considered - * FINISHME: here. - */ - /* TODO: only set this if there are actual changes */ ctx->NewState |= _NEW_TEXTURE; @@ -562,6 +564,7 @@ update_texture_state( struct gl_context *ctx ) struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; GLbitfield enabledVertTargets = 0x0; GLbitfield enabledFragTargets = 0x0; + GLbitfield enabledGeomTargets = 0x0; GLbitfield enabledTargets = 0x0; GLuint texIndex; @@ -575,6 +578,10 @@ update_texture_state( struct gl_context *ctx ) enabledVertTargets |= vprog->TexturesUsed[unit]; } + if (gprog) { + enabledGeomTargets |= gprog->TexturesUsed[unit]; + } + if (fprog) { enabledFragTargets |= fprog->TexturesUsed[unit]; } @@ -583,7 +590,8 @@ update_texture_state( struct gl_context *ctx ) enabledFragTargets |= texUnit->Enabled; } - enabledTargets = enabledVertTargets | enabledFragTargets; + enabledTargets = enabledVertTargets | enabledFragTargets | + enabledGeomTargets; texUnit->_ReallyEnabled = 0x0; diff --git a/mesalib/src/mesa/main/varray.c b/mesalib/src/mesa/main/varray.c index 529d93324..dee476abb 100644 --- a/mesalib/src/mesa/main/varray.c +++ b/mesalib/src/mesa/main/varray.c @@ -196,6 +196,16 @@ update_array(struct gl_context *ctx, if (ctx->Extensions.EXT_vertex_array_bgra && sizeMax == BGRA_OR_4 && size == GL_BGRA) { + /* Page 298 of the PDF of the OpenGL 4.3 (Core Profile) spec says: + * + * "An INVALID_OPERATION error is generated under any of the following + * conditions: + * ... + * • size is BGRA and type is not UNSIGNED_BYTE, INT_2_10_10_10_REV + * or UNSIGNED_INT_2_10_10_10_REV; + * ... + * • size is BGRA and normalized is FALSE;" + */ GLboolean bgra_error = GL_FALSE; if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) { @@ -207,9 +217,17 @@ update_array(struct gl_context *ctx, bgra_error = GL_TRUE; if (bgra_error) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s(GL_BGRA/GLubyte)", func); + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=GL_BGRA and type=%s)", + func, _mesa_lookup_enum_by_nr(type)); return; } + + if (!normalized) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(size=GL_BGRA and normalized=GL_FALSE)", func); + return; + } + format = GL_BGRA; size = 4; } diff --git a/mesalib/src/mesa/main/version.c b/mesalib/src/mesa/main/version.c index ab9b14c02..55411faf8 100644 --- a/mesalib/src/mesa/main/version.c +++ b/mesalib/src/mesa/main/version.c @@ -262,7 +262,6 @@ compute_version(struct gl_context *ctx) ctx->Extensions.ARB_depth_clamp && ctx->Extensions.ARB_draw_elements_base_vertex && ctx->Extensions.ARB_fragment_coord_conventions && - ctx->Extensions.ARB_geometry_shader4 && ctx->Extensions.EXT_provoking_vertex && ctx->Extensions.ARB_seamless_cube_map && ctx->Extensions.ARB_sync && diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index f0fc1b9b1..f612f41ba 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -265,6 +265,8 @@ public: virtual void visit(ir_discard *); virtual void visit(ir_texture *); virtual void visit(ir_if *); + virtual void visit(ir_emit_vertex *); + virtual void visit(ir_end_primitive *); /*@}*/ src_reg result; @@ -2252,6 +2254,18 @@ ir_to_mesa_visitor::visit(ir_if *ir) if_inst = emit(ir->condition, OPCODE_ENDIF); } +void +ir_to_mesa_visitor::visit(ir_emit_vertex *ir) +{ + assert(!"Geometry shaders not supported."); +} + +void +ir_to_mesa_visitor::visit(ir_end_primitive *ir) +{ + assert(!"Geometry shaders not supported."); +} + ir_to_mesa_visitor::ir_to_mesa_visitor() { result.file = PROGRAM_UNDEFINED; @@ -2961,7 +2975,7 @@ get_mesa_program(struct gl_context *ctx, */ mesa_instructions = NULL; - do_set_program_inouts(shader->ir, prog, shader->Type == GL_FRAGMENT_SHADER); + do_set_program_inouts(shader->ir, prog, shader->Type); prog->SamplersUsed = shader->active_samplers; prog->ShadowSamplers = shader->shadow_samplers; @@ -3073,10 +3087,7 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]); if (linked_prog) { - if (i == MESA_SHADER_VERTEX) { - ((struct gl_vertex_program *)linked_prog)->UsesClipDistance - = prog->Vert.UsesClipDistance; - } + _mesa_copy_linked_program_data((gl_shader_type) i, prog, linked_prog); _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program, linked_prog); diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 3dfd5e5b3..4e29e4500 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -369,6 +369,8 @@ public: virtual void visit(ir_discard *); virtual void visit(ir_texture *); virtual void visit(ir_if *); + virtual void visit(ir_emit_vertex *); + virtual void visit(ir_end_primitive *); /*@}*/ st_src_reg result; @@ -418,8 +420,6 @@ public: void emit_scalar(ir_instruction *ir, unsigned op, st_dst_reg dst, st_src_reg src0, st_src_reg src1); - void try_emit_float_set(ir_instruction *ir, unsigned op, st_dst_reg dst); - void emit_arl(ir_instruction *ir, st_dst_reg dst, st_src_reg src0); void emit_scs(ir_instruction *ir, unsigned op, @@ -592,9 +592,6 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, this->instructions.push_tail(inst); - if (native_integers) - try_emit_float_set(ir, op, dst); - return inst; } @@ -620,25 +617,6 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op) return emit(ir, op, undef_dst, undef_src, undef_src, undef_src); } - /** - * Emits the code to convert the result of float SET instructions to integers. - */ -void -glsl_to_tgsi_visitor::try_emit_float_set(ir_instruction *ir, unsigned op, - st_dst_reg dst) -{ - if ((op == TGSI_OPCODE_SEQ || - op == TGSI_OPCODE_SNE || - op == TGSI_OPCODE_SGE || - op == TGSI_OPCODE_SLT)) - { - st_src_reg src = st_src_reg(dst); - src.negate = ~src.negate; - dst.type = GLSL_TYPE_FLOAT; - emit(ir, TGSI_OPCODE_F2I, dst, src); - } -} - /** * Determines whether to use an integer, unsigned integer, or float opcode * based on the operands and input opcode, then emits the result. @@ -662,14 +640,30 @@ glsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op, #define case4(c, f, i, u) \ case TGSI_OPCODE_##c: \ - if (type == GLSL_TYPE_INT) op = TGSI_OPCODE_##i; \ - else if (type == GLSL_TYPE_UINT) op = TGSI_OPCODE_##u; \ - else op = TGSI_OPCODE_##f; \ + if (type == GLSL_TYPE_INT) \ + op = TGSI_OPCODE_##i; \ + else if (type == GLSL_TYPE_UINT) \ + op = TGSI_OPCODE_##u; \ + else \ + op = TGSI_OPCODE_##f; \ break; + #define case3(f, i, u) case4(f, f, i, u) #define case2fi(f, i) case4(f, f, i, i) #define case2iu(i, u) case4(i, LAST, i, u) - + +#define casecomp(c, f, i, u) \ + case TGSI_OPCODE_##c: \ + if (type == GLSL_TYPE_INT) \ + op = TGSI_OPCODE_##i; \ + else if (type == GLSL_TYPE_UINT) \ + op = TGSI_OPCODE_##u; \ + else if (native_integers) \ + op = TGSI_OPCODE_##f; \ + else \ + op = TGSI_OPCODE_##c; \ + break; + switch(op) { case2fi(ADD, UADD); case2fi(MUL, UMUL); @@ -678,12 +672,12 @@ glsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op, case3(MAX, IMAX, UMAX); case3(MIN, IMIN, UMIN); case2iu(MOD, UMOD); - - case2fi(SEQ, USEQ); - case2fi(SNE, USNE); - case3(SGE, ISGE, USGE); - case3(SLT, ISLT, USLT); - + + casecomp(SEQ, FSEQ, USEQ, USEQ); + casecomp(SNE, FSNE, USNE, USNE); + casecomp(SGE, FSGE, ISGE, USGE); + casecomp(SLT, FSLT, ISLT, USLT); + case2iu(ISHR, USHR); case2fi(SSG, ISSG); @@ -3015,6 +3009,18 @@ glsl_to_tgsi_visitor::visit(ir_if *ir) if_inst = emit(ir->condition, TGSI_OPCODE_ENDIF); } +void +glsl_to_tgsi_visitor::visit(ir_emit_vertex *ir) +{ + assert(!"Geometry shaders not supported."); +} + +void +glsl_to_tgsi_visitor::visit(ir_end_primitive *ir) +{ + assert(!"Geometry shaders not supported."); +} + glsl_to_tgsi_visitor::glsl_to_tgsi_visitor() { result.file = PROGRAM_UNDEFINED; @@ -5121,7 +5127,7 @@ get_mesa_program(struct gl_context *ctx, prog->Instructions = NULL; prog->NumInstructions = 0; - do_set_program_inouts(shader->ir, prog, shader->Type == GL_FRAGMENT_SHADER); + do_set_program_inouts(shader->ir, prog, shader->Type); count_resources(v, prog); _mesa_reference_program(ctx, &shader->Program, prog); diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c index 75831faf9..bd05cd0c3 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_array.c +++ b/mesalib/src/mesa/vbo/vbo_exec_array.c @@ -442,41 +442,77 @@ recalculate_input_bindings(struct gl_context *ctx) break; case VP_ARB: - /* GL_ARB_vertex_program or GLSL vertex shader - Only the generic[0] + /* There are no shaders in OpenGL ES 1.x, so this code path should be + * impossible to reach. The meta code is careful to not use shaders in + * ES1. + */ + assert(ctx->API != API_OPENGLES); + + /* In the compatibility profile of desktop OpenGL, the generic[0] * attribute array aliases and overrides the legacy position array. - * * Otherwise, legacy attributes available in the legacy slots, * generic attributes in the generic slots and materials are not * available as per-vertex attributes. + * + * In all other APIs, only the generic attributes exist, and none of the + * slots are considered "magic." */ - if (vertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) - inputs[0] = &vertexAttrib[VERT_ATTRIB_GENERIC0]; - else if (vertexAttrib[VERT_ATTRIB_POS].Enabled) - inputs[0] = &vertexAttrib[VERT_ATTRIB_POS]; - else { - inputs[0] = &vbo->currval[VBO_ATTRIB_POS]; - const_inputs |= VERT_BIT_POS; - } + if (ctx->API == API_OPENGL_COMPAT) { + if (vertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) + inputs[0] = &vertexAttrib[VERT_ATTRIB_GENERIC0]; + else if (vertexAttrib[VERT_ATTRIB_POS].Enabled) + inputs[0] = &vertexAttrib[VERT_ATTRIB_POS]; + else { + inputs[0] = &vbo->currval[VBO_ATTRIB_POS]; + const_inputs |= VERT_BIT_POS; + } - for (i = 1; i < VERT_ATTRIB_FF_MAX; i++) { - if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled) - inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; - else { - inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; + for (i = 1; i < VERT_ATTRIB_FF_MAX; i++) { + if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled) + inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; + else { + inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; + const_inputs |= VERT_BIT_FF(i); + } + } + + for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) { + if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) + inputs[VERT_ATTRIB_GENERIC(i)] = + &vertexAttrib[VERT_ATTRIB_GENERIC(i)]; + else { + inputs[VERT_ATTRIB_GENERIC(i)] = + &vbo->currval[VBO_ATTRIB_GENERIC0+i]; + const_inputs |= VERT_BIT_GENERIC(i); + } + } + + inputs[VERT_ATTRIB_GENERIC0] = inputs[0]; + } else { + /* Other parts of the code assume that inputs[0] through + * inputs[VERT_ATTRIB_FF_MAX] will be non-NULL. However, in OpenGL + * ES 2.0+ or OpenGL core profile, none of these arrays should ever + * be enabled. + */ + for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) { + assert(!vertexAttrib[VERT_ATTRIB_FF(i)].Enabled); + + inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; const_inputs |= VERT_BIT_FF(i); } - } - for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) { - if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) - inputs[VERT_ATTRIB_GENERIC(i)] = &vertexAttrib[VERT_ATTRIB_GENERIC(i)]; - else { - inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i]; - const_inputs |= VERT_BIT_GENERIC(i); + for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) { + if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) + inputs[VERT_ATTRIB_GENERIC(i)] = + &vertexAttrib[VERT_ATTRIB_GENERIC(i)]; + else { + inputs[VERT_ATTRIB_GENERIC(i)] = + &vbo->currval[VBO_ATTRIB_GENERIC0+i]; + const_inputs |= VERT_BIT_GENERIC(i); + } } } - inputs[VERT_ATTRIB_GENERIC0] = inputs[0]; break; } |