From 5cfbe97cd797d8f78ece208bb5114704b83d8aab Mon Sep 17 00:00:00 2001 From: marha Date: Fri, 13 Jan 2012 16:54:57 +0100 Subject: libxtrans libXdmcp libxcb mesa xserver git update 13 jan 2012 --- mesalib/src/mesa/main/api_validate.c | 2 +- mesalib/src/mesa/main/arrayobj.c | 2 +- mesalib/src/mesa/main/bitset.h | 2 +- mesalib/src/mesa/main/buffers.c | 25 +++++--- mesalib/src/mesa/main/clear.c | 15 +++-- mesalib/src/mesa/main/drawpix.c | 6 ++ mesalib/src/mesa/main/fbobject.c | 50 +++++---------- mesalib/src/mesa/main/fbobject.h | 22 +++++++ mesalib/src/mesa/main/ff_fragment_shader.cpp | 42 +++++++++--- mesalib/src/mesa/main/ffvertex_prog.c | 2 +- mesalib/src/mesa/main/framebuffer.c | 9 ++- mesalib/src/mesa/main/hash.c | 20 ++++++ mesalib/src/mesa/main/hash.h | 3 + mesalib/src/mesa/main/imports.c | 15 ++--- mesalib/src/mesa/main/imports.h | 25 ++++---- mesalib/src/mesa/main/mipmap.c | 2 +- mesalib/src/mesa/main/mtypes.h | 20 ++++-- mesalib/src/mesa/main/readpix.c | 5 ++ mesalib/src/mesa/main/renderbuffer.c | 2 +- mesalib/src/mesa/main/shaderapi.c | 95 ++++++++++------------------ mesalib/src/mesa/main/state.c | 12 +++- mesalib/src/mesa/main/teximage.c | 20 +++++- mesalib/src/mesa/main/texobj.c | 10 +-- mesalib/src/mesa/main/texstore.c | 6 +- mesalib/src/mesa/main/uniform_query.cpp | 58 ++++++++++++++--- mesalib/src/mesa/main/uniforms.c | 7 +- mesalib/src/mesa/main/uniforms.h | 6 +- mesalib/src/mesa/main/version.h | 11 ---- 28 files changed, 301 insertions(+), 193 deletions(-) (limited to 'mesalib/src/mesa/main') diff --git a/mesalib/src/mesa/main/api_validate.c b/mesalib/src/mesa/main/api_validate.c index 945f12752..b6871d0db 100644 --- a/mesalib/src/mesa/main/api_validate.c +++ b/mesalib/src/mesa/main/api_validate.c @@ -184,7 +184,7 @@ check_index_bounds(struct gl_context *ctx, GLsizei count, GLenum type, ib.ptr = indices; ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj; - vbo_get_minmax_index(ctx, &prim, &ib, &min, &max); + vbo_get_minmax_indices(ctx, &prim, &ib, &min, &max, 1); if ((int)(min + basevertex) < 0 || max + basevertex > ctx->Array.ArrayObj->_MaxElement) { diff --git a/mesalib/src/mesa/main/arrayobj.c b/mesalib/src/mesa/main/arrayobj.c index 4b3e07b85..29bfed8f5 100644 --- a/mesalib/src/mesa/main/arrayobj.c +++ b/mesalib/src/mesa/main/arrayobj.c @@ -303,7 +303,7 @@ _mesa_update_array_object_max_element(struct gl_context *ctx, GLuint min = ~0u; while (enabled) { - GLint attrib = _mesa_ffsll(enabled) - 1; + GLint attrib = ffsll(enabled) - 1; enabled &= ~BITFIELD64_BIT(attrib); min = update_min(min, &arrayObj->VertexAttrib[attrib]); } diff --git a/mesalib/src/mesa/main/bitset.h b/mesalib/src/mesa/main/bitset.h index c27b4c474..28b3c127e 100644 --- a/mesalib/src/mesa/main/bitset.h +++ b/mesalib/src/mesa/main/bitset.h @@ -88,7 +88,7 @@ __bitset_ffs(const BITSET_WORD *x, int n) for (i = 0; i < n; i++) { if (x[i]) - return _mesa_ffs(x[i]) + BITSET_WORDBITS * i; + return ffs(x[i]) + BITSET_WORDBITS * i; } return 0; diff --git a/mesalib/src/mesa/main/buffers.c b/mesalib/src/mesa/main/buffers.c index adea0f5f7..216b6ee87 100644 --- a/mesalib/src/mesa/main/buffers.c +++ b/mesalib/src/mesa/main/buffers.c @@ -35,6 +35,7 @@ #include "colormac.h" #include "context.h" #include "enums.h" +#include "fbobject.h" #include "mtypes.h" @@ -51,11 +52,12 @@ * \return bitmask of BUFFER_BIT_* flags */ static GLbitfield -supported_buffer_bitmask(const struct gl_context *ctx, const struct gl_framebuffer *fb) +supported_buffer_bitmask(const struct gl_context *ctx, + const struct gl_framebuffer *fb) { GLbitfield mask = 0x0; - if (fb->Name > 0) { + if (_mesa_is_user_fbo(fb)) { /* A user-created renderbuffer */ GLuint i; ASSERT(ctx->Extensions.EXT_framebuffer_object); @@ -242,7 +244,8 @@ _mesa_DrawBuffer(GLenum buffer) destMask = draw_buffer_enum_to_bitmask(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, + "glDrawBuffer(buffer=0x%x)", buffer); return; } destMask &= supportedMask; @@ -340,6 +343,7 @@ _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers) ctx->Driver.DrawBuffer(ctx, n > 0 ? buffers[0] : GL_NONE); } + /** * Performs necessary state updates when _mesa_drawbuffers makes an * actual change. @@ -354,13 +358,14 @@ updated_drawbuffers(struct gl_context *ctx) struct gl_framebuffer *fb = ctx->DrawBuffer; /* Flag the FBO as requiring validation. */ - if (fb->Name != 0) { + if (_mesa_is_user_fbo(fb)) { fb->_Status = 0; } } #endif } + /** * Helper function to set the GL_DRAW_BUFFER state in the context and * current FBO. Called via glDrawBuffer(), glDrawBuffersARB() @@ -402,7 +407,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers, if (n == 1) { GLuint count = 0, destMask0 = destMask[0]; while (destMask0) { - GLint bufIndex = _mesa_ffs(destMask0) - 1; + GLint bufIndex = ffs(destMask0) - 1; if (fb->_ColorDrawBufferIndexes[count] != bufIndex) { updated_drawbuffers(ctx); fb->_ColorDrawBufferIndexes[count] = bufIndex; @@ -417,7 +422,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers, GLuint count = 0; for (buf = 0; buf < n; buf++ ) { if (destMask[buf]) { - GLint bufIndex = _mesa_ffs(destMask[buf]) - 1; + GLint bufIndex = ffs(destMask[buf]) - 1; /* only one bit should be set in the destMask[buf] field */ ASSERT(_mesa_bitcount(destMask[buf]) == 1); if (fb->_ColorDrawBufferIndexes[buf] != bufIndex) { @@ -448,7 +453,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers, fb->ColorDrawBuffer[buf] = GL_NONE; } - if (fb->Name == 0) { + if (_mesa_is_winsys_fbo(fb)) { /* also set context drawbuffer state */ for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) { if (ctx->Color.DrawBuffer[buf] != fb->ColorDrawBuffer[buf]) { @@ -472,7 +477,7 @@ _mesa_update_draw_buffers(struct gl_context *ctx) GLuint i; /* should be a window system FBO */ - assert(ctx->DrawBuffer->Name == 0); + assert(_mesa_is_winsys_fbo(ctx->DrawBuffer)); for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) buffers[i] = ctx->Color.DrawBuffer[i]; @@ -493,7 +498,7 @@ _mesa_readbuffer(struct gl_context *ctx, GLenum buffer, GLint bufferIndex) { struct gl_framebuffer *fb = ctx->ReadBuffer; - if (fb->Name == 0) { + if (_mesa_is_winsys_fbo(fb)) { /* Only update the per-context READ_BUFFER state if we're bound to * a window-system framebuffer. */ @@ -529,7 +534,7 @@ _mesa_ReadBuffer(GLenum buffer) if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); - if (fb->Name > 0 && buffer == GL_NONE) { + if (_mesa_is_user_fbo(fb) && buffer == GL_NONE) { /* This is legal for user-created framebuffer objects */ srcBuffer = -1; } diff --git a/mesalib/src/mesa/main/clear.c b/mesalib/src/mesa/main/clear.c index bd5c01224..e4df120d6 100644 --- a/mesalib/src/mesa/main/clear.c +++ b/mesalib/src/mesa/main/clear.c @@ -338,7 +338,7 @@ _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) drawbuffer); return; } - else if (!ctx->RasterDiscard) { + else if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer && !ctx->RasterDiscard) { /* Save current stencil clear value, set to 'value', do the * stencil clear and restore the clear value. * XXX in the future we may have a new ctx->Driver.ClearBuffer() @@ -513,7 +513,7 @@ _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) drawbuffer); return; } - else if (!ctx->RasterDiscard) { + else if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer && !ctx->RasterDiscard) { /* Save current depth clear value, set to 'value', do the * depth clear and restore the clear value. * XXX in the future we may have a new ctx->Driver.ClearBuffer() @@ -592,6 +592,8 @@ _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { GET_CURRENT_CONTEXT(ctx); + GLbitfield mask = 0; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); FLUSH_CURRENT(ctx, 0); @@ -622,7 +624,12 @@ _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer, _mesa_update_state( ctx ); } - { + if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer) + mask |= BUFFER_BIT_DEPTH; + if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer) + mask |= BUFFER_BIT_STENCIL; + + if (mask) { /* save current clear values */ const GLclampd clearDepthSave = ctx->Depth.Clear; const GLuint clearStencilSave = ctx->Stencil.Clear; @@ -636,7 +643,7 @@ _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer, ctx->Driver.ClearStencil(ctx, stencil); /* clear buffers */ - ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL); + ctx->Driver.Clear(ctx, mask); /* restore */ ctx->Depth.Clear = clearDepthSave; diff --git a/mesalib/src/mesa/main/drawpix.c b/mesalib/src/mesa/main/drawpix.c index 9f5b0b36e..01983d945 100644 --- a/mesalib/src/mesa/main/drawpix.c +++ b/mesalib/src/mesa/main/drawpix.c @@ -203,6 +203,12 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, goto end; } + if (ctx->ReadBuffer->Name != 0 && ctx->ReadBuffer->Visual.samples > 0) { + _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION, + "glCopyPixels(multisample FBO)"); + goto end; + } + if (!_mesa_source_buffer_exists(ctx, type) || !_mesa_dest_buffer_exists(ctx, type)) { _mesa_error(ctx, GL_INVALID_OPERATION, diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index aefcaf350..052495907 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -79,26 +79,6 @@ static struct gl_renderbuffer DummyRenderbuffer; static struct gl_framebuffer IncompleteFramebuffer; -/** - * Is the given FBO a user-created FBO? - */ -static inline GLboolean -is_user_fbo(const struct gl_framebuffer *fb) -{ - return fb->Name != 0; -} - - -/** - * Is the given FBO a window system FBO (like an X window)? - */ -static inline GLboolean -is_winsys_fbo(const struct gl_framebuffer *fb) -{ - return fb->Name == 0; -} - - static void delete_dummy_renderbuffer(struct gl_renderbuffer *rb) { @@ -214,7 +194,7 @@ _mesa_get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb, { GLuint i; - assert(is_user_fbo(fb)); + assert(_mesa_is_user_fbo(fb)); switch (attachment) { case GL_COLOR_ATTACHMENT0_EXT: @@ -265,7 +245,7 @@ static struct gl_renderbuffer_attachment * _mesa_get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb, GLenum attachment) { - assert(is_winsys_fbo(fb)); + assert(_mesa_is_winsys_fbo(fb)); switch (attachment) { case GL_FRONT_LEFT: @@ -711,7 +691,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, GLint i; GLuint j; - assert(is_user_fbo(fb)); + assert(_mesa_is_user_fbo(fb)); numImages = 0; fb->Width = 0; @@ -1009,10 +989,10 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers) _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); } - if (is_user_fbo(ctx->DrawBuffer)) { + if (_mesa_is_user_fbo(ctx->DrawBuffer)) { detach_renderbuffer(ctx, ctx->DrawBuffer, rb); } - if (is_user_fbo(ctx->ReadBuffer) + if (_mesa_is_user_fbo(ctx->ReadBuffer) && ctx->ReadBuffer != ctx->DrawBuffer) { detach_renderbuffer(ctx, ctx->ReadBuffer, rb); } @@ -1318,7 +1298,7 @@ invalidate_rb(GLuint key, void *data, void *userData) struct gl_renderbuffer *rb = (struct gl_renderbuffer *) userData; /* If this is a user-created FBO */ - if (is_user_fbo(fb)) { + if (_mesa_is_user_fbo(fb)) { GLuint i; for (i = 0; i < BUFFER_COUNT; i++) { struct gl_renderbuffer_attachment *att = fb->Attachment + i; @@ -1395,7 +1375,8 @@ renderbuffer_storage(GLenum target, GLenum internalFormat, if (rb->InternalFormat == internalFormat && rb->Width == (GLuint) width && - rb->Height == (GLuint) height) { + rb->Height == (GLuint) height && + rb->NumSamples == samples) { /* no change in allocation needed */ return; } @@ -1609,7 +1590,7 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) GLuint i; ASSERT(ctx->Driver.RenderTexture); - if (is_winsys_fbo(fb)) + if (_mesa_is_winsys_fbo(fb)) return; /* can't render to texture with winsys framebuffers */ for (i = 0; i < BUFFER_COUNT; i++) { @@ -1629,7 +1610,7 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) static void check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) { - if (is_winsys_fbo(fb)) + if (_mesa_is_winsys_fbo(fb)) return; /* can't render to texture with winsys framebuffers */ if (ctx->Driver.FinishRenderTexture) { @@ -1882,7 +1863,7 @@ _mesa_CheckFramebufferStatusEXT(GLenum target) return 0; } - if (is_winsys_fbo(buffer)) { + if (_mesa_is_winsys_fbo(buffer)) { /* The window system / default framebuffer is always complete */ return GL_FRAMEBUFFER_COMPLETE_EXT; } @@ -1944,7 +1925,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, } /* check framebuffer binding */ - if (is_winsys_fbo(fb)) { + if (_mesa_is_winsys_fbo(fb)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferTexture%sEXT", caller); return; @@ -2204,7 +2185,7 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment, return; } - if (is_winsys_fbo(fb)) { + if (_mesa_is_winsys_fbo(fb)) { /* Can't attach new renderbuffers to a window system framebuffer */ _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT"); return; @@ -2285,7 +2266,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, return; } - if (is_winsys_fbo(buffer)) { + if (_mesa_is_winsys_fbo(buffer)) { /* Page 126 (page 136 of the PDF) of the OpenGL ES 2.0.25 spec * says: * @@ -2332,7 +2313,8 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, switch (pname) { case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT: - *params = is_winsys_fbo(buffer) ? GL_FRAMEBUFFER_DEFAULT : att->Type; + *params = _mesa_is_winsys_fbo(buffer) + ? GL_FRAMEBUFFER_DEFAULT : att->Type; return; case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT: if (att->Type == GL_RENDERBUFFER_EXT) { diff --git a/mesalib/src/mesa/main/fbobject.h b/mesalib/src/mesa/main/fbobject.h index 0a70a436d..3aee842f5 100644 --- a/mesalib/src/mesa/main/fbobject.h +++ b/mesalib/src/mesa/main/fbobject.h @@ -32,6 +32,28 @@ struct gl_context; struct gl_texture_object; + +/** + * Is the given FBO a user-created FBO? + */ +static inline GLboolean +_mesa_is_user_fbo(const struct gl_framebuffer *fb) +{ + return fb->Name != 0; +} + + +/** + * Is the given FBO a window system FBO (like an X window)? + */ +static inline GLboolean +_mesa_is_winsys_fbo(const struct gl_framebuffer *fb) +{ + return fb->Name == 0; +} + + + extern void _mesa_init_fbobjects(struct gl_context *ctx); diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp index 3e736fa15..afc17dc49 100644 --- a/mesalib/src/mesa/main/ff_fragment_shader.cpp +++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp @@ -42,6 +42,7 @@ extern "C" { #include "program/programopt.h" #include "texenvprogram.h" } +#include "main/uniforms.h" #include "../glsl/glsl_types.h" #include "../glsl/ir.h" #include "../glsl/glsl_symbol_table.h" @@ -294,7 +295,7 @@ need_saturate( GLuint mode ) static GLuint translate_tex_src_bit( GLbitfield bit ) { ASSERT(bit); - return _mesa_ffs(bit) - 1; + return ffs(bit) - 1; } @@ -527,7 +528,7 @@ struct texenv_fragment_program { */ /* Texcoord override from bumpmapping. */ - struct ir_variable *texcoord_tex[MAX_TEXTURE_COORD_UNITS]; + ir_variable *texcoord_tex[MAX_TEXTURE_COORD_UNITS]; /* Reg containing texcoord for a texture unit, * needed for bump mapping, else undef. @@ -1498,25 +1499,48 @@ create_new_program(struct gl_context *ctx, struct state_key *key) /* Set the sampler uniforms, and relink to get them into the linked * program. */ - struct gl_program *fp; - fp = p.shader_program->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program; + struct gl_shader *const fs = + p.shader_program->_LinkedShaders[MESA_SHADER_FRAGMENT]; + struct gl_program *const fp = fs->Program; + + _mesa_generate_parameters_list_for_uniforms(p.shader_program, fs, + fp->Parameters); + + _mesa_associate_uniform_storage(ctx, p.shader_program, fp->Parameters); for (unsigned int i = 0; i < MAX_TEXTURE_UNITS; i++) { - char *name = ralloc_asprintf(p.mem_ctx, "sampler_%d", i); + /* Enough space for 'sampler_999\0'. + */ + char name[12]; + + snprintf(name, sizeof(name), "sampler_%d", i); + int loc = _mesa_get_uniform_location(ctx, p.shader_program, name); if (loc != -1) { + unsigned base; + unsigned idx; + /* Avoid using _mesa_uniform() because it flags state * updates, so if we're generating this shader_program in a * state update, we end up recursing. Instead, just set the * value, which is picked up at re-link. */ - loc = (loc & 0xffff) + (loc >> 16); - int sampler = fp->Parameters->ParameterValues[loc][0].f; + _mesa_uniform_split_location_offset(loc, &base, &idx); + assert(idx == 0); - fp->SamplerUnits[sampler] = i; + struct gl_uniform_storage *const storage = + &p.shader_program->UniformStorage[base]; + + /* Update the storage, the SamplerUnits in the shader program, and + * the SamplerUnits in the assembly shader. + */ + storage->storage[idx].i = i; + fp->SamplerUnits[storage->sampler] = i; + p.shader_program->SamplerUnits[storage->sampler] = i; + _mesa_propagate_uniforms_to_driver_storage(storage, 0, 1); } } - _mesa_update_shader_textures_used(fp); + _mesa_update_shader_textures_used(p.shader_program, fp); (void) ctx->Driver.ProgramStringNotify(ctx, fp->Target, fp); if (!p.shader_program->LinkStatus) diff --git a/mesalib/src/mesa/main/ffvertex_prog.c b/mesalib/src/mesa/main/ffvertex_prog.c index 19d319a56..f1ab75333 100644 --- a/mesalib/src/mesa/main/ffvertex_prog.c +++ b/mesalib/src/mesa/main/ffvertex_prog.c @@ -378,7 +378,7 @@ static struct ureg swizzle1( struct ureg reg, int x ) static struct ureg get_temp( struct tnl_program *p ) { - int bit = _mesa_ffs( ~p->temp_in_use ); + int bit = ffs( ~p->temp_in_use ); if (!bit) { _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__); exit(1); diff --git a/mesalib/src/mesa/main/framebuffer.c b/mesalib/src/mesa/main/framebuffer.c index 730de6206..7c3c4e345 100644 --- a/mesalib/src/mesa/main/framebuffer.c +++ b/mesalib/src/mesa/main/framebuffer.c @@ -281,8 +281,8 @@ _mesa_resize_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb, * and return early. */ - /* For window system framebuffers, Name is zero */ - assert(fb->Name == 0); + /* Can only resize win-sys framebuffer objects */ + assert(_mesa_is_winsys_fbo(fb)); for (i = 0; i < BUFFER_COUNT; i++) { struct gl_renderbuffer_attachment *att = &fb->Attachment[i]; @@ -408,7 +408,7 @@ update_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb) GLuint i; /* user-created framebuffers only */ - assert(fb->Name); + assert(_mesa_is_user_fbo(fb)); for (i = 0; i < BUFFER_COUNT; i++) { struct gl_renderbuffer_attachment *att = &fb->Attachment[i]; @@ -687,7 +687,7 @@ update_color_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb) static void update_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) { - if (fb->Name == 0) { + if (_mesa_is_winsys_fbo(fb)) { /* This is a window-system framebuffer */ /* Need to update the FB's GL_DRAW_BUFFER state to match the * context state (GL_READ_BUFFER too). @@ -851,7 +851,6 @@ _mesa_source_buffer_exists(struct gl_context *ctx, GLenum format) /** * As above, but for drawing operations. - * XXX could do some code merging w/ above function. */ GLboolean _mesa_dest_buffer_exists(struct gl_context *ctx, GLenum format) diff --git a/mesalib/src/mesa/main/hash.c b/mesalib/src/mesa/main/hash.c index 4b250ad54..61c369a80 100644 --- a/mesalib/src/mesa/main/hash.c +++ b/mesalib/src/mesa/main/hash.c @@ -480,6 +480,26 @@ _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys) } +/** + * Return the number of entries in the hash table. + */ +GLuint +_mesa_HashNumEntries(const struct _mesa_HashTable *table) +{ + GLuint pos, count = 0; + + for (pos = 0; pos < TABLE_SIZE; pos++) { + const struct HashEntry *entry; + for (entry = table->Table[pos]; entry; entry = entry->Next) { + count++; + } + } + + return count; +} + + + #if 0 /* debug only */ /** diff --git a/mesalib/src/mesa/main/hash.h b/mesalib/src/mesa/main/hash.h index 4f916f9d0..e935f8d39 100644 --- a/mesalib/src/mesa/main/hash.h +++ b/mesalib/src/mesa/main/hash.h @@ -63,6 +63,9 @@ extern void _mesa_HashPrint(const struct _mesa_HashTable *table); extern GLuint _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys); +extern GLuint +_mesa_HashNumEntries(const struct _mesa_HashTable *table); + extern void _mesa_test_hash_functions(void); diff --git a/mesalib/src/mesa/main/imports.c b/mesalib/src/mesa/main/imports.c index 2469e4265..bbc6ac6e2 100644 --- a/mesalib/src/mesa/main/imports.c +++ b/mesalib/src/mesa/main/imports.c @@ -458,9 +458,8 @@ _mesa_inv_sqrtf(float n) * Find the first bit set in a word. */ int -_mesa_ffs(int32_t i) +ffs(int i) { -#if (defined(_WIN32) ) || defined(__IBMC__) || defined(__IBMCPP__) register int bit = 0; if (i != 0) { if ((i & 0xffff) == 0) { @@ -482,9 +481,6 @@ _mesa_ffs(int32_t i) bit++; } return bit; -#else - return ffs(i); -#endif } @@ -495,23 +491,24 @@ _mesa_ffs(int32_t i) * if no bits set. */ int -_mesa_ffsll(int64_t val) +ffsll(long long int val) { int bit; assert(sizeof(val) == 8); - bit = _mesa_ffs((int32_t)val); + bit = ffs((int) val); if (bit != 0) return bit; - bit = _mesa_ffs((int32_t)(val >> 32)); + bit = ffs((int) (val >> 32)); if (bit != 0) return 32 + bit; return 0; } -#endif +#endif /* __GNUC__ */ + #if !defined(__GNUC__) ||\ ((__GNUC__ * 100 + __GNUC_MINOR__) < 304) /* Not gcc 3.4 or later */ diff --git a/mesalib/src/mesa/main/imports.h b/mesalib/src/mesa/main/imports.h index b7e87439f..ce7b45d77 100644 --- a/mesalib/src/mesa/main/imports.h +++ b/mesalib/src/mesa/main/imports.h @@ -566,6 +566,9 @@ _mesa_inv_sqrtf(float x); extern void _mesa_init_sqrt_table(void); + +#ifndef FFS_DEFINED +#define FFS_DEFINED 1 #ifdef __GNUC__ #if defined(__MINGW32__) || defined(__CYGWIN__) || defined(ANDROID) || defined(__APPLE__) @@ -573,10 +576,16 @@ _mesa_init_sqrt_table(void); #define ffsll __builtin_ffsll #endif -#define _mesa_ffs(i) ffs(i) -#define _mesa_ffsll(i) ffsll(i) +#else + +extern int ffs(int i); +extern int ffsll(long long int i); + +#endif /*__ GNUC__ */ +#endif /* FFS_DEFINED */ -#if ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */ + +#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */ #define _mesa_bitcount(i) __builtin_popcount(i) #define _mesa_bitcount_64(i) __builtin_popcountll(i) #else @@ -586,16 +595,6 @@ extern unsigned int _mesa_bitcount_64(uint64_t n); #endif -#else -extern int -_mesa_ffs(int32_t i); - -extern int -_mesa_ffsll(int64_t i); - -extern unsigned int -_mesa_bitcount(unsigned int n); -#endif extern GLhalfARB _mesa_float_to_half(float f); diff --git a/mesalib/src/mesa/main/mipmap.c b/mesalib/src/mesa/main/mipmap.c index 867506c9f..03ce5361e 100644 --- a/mesalib/src/mesa/main/mipmap.c +++ b/mesalib/src/mesa/main/mipmap.c @@ -476,7 +476,7 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth, GLuint *dst = (GLuint *) dstRow; for (i = j = 0, k = k0; i < (GLuint) dstWidth; i++, j += colStride, k += colStride) { - dst[i] = (GLfloat)(rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4); + dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4; } } diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 64d8c8d3f..9fdabf98c 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1894,8 +1894,6 @@ struct gl_program /** Map from sampler unit to texture unit (set by glUniform1i()) */ GLubyte SamplerUnits[MAX_SAMPLERS]; - /** Which texture target is being sampled (TEXTURE_1D/2D/3D/etc_INDEX) */ - gl_texture_index SamplerTargets[MAX_SAMPLERS]; /** Bitmask of which register files are read/written with indirect * addressing. Mask of (1 << PROGRAM_x) bits. @@ -2185,9 +2183,17 @@ struct gl_shader unsigned Version; /**< GLSL version used for linking */ - unsigned num_samplers; /**< Number of samplers used by this shader. - * This field is only set post-linking. - */ + /** + * \name Sampler tracking + * + * \note Each of these fields is only set post-linking. + */ + /*@{*/ + unsigned num_samplers; /**< Number of samplers used by this shader. */ + GLbitfield active_samplers; /**< Bitfield of which samplers are used */ + GLbitfield shadow_samplers; /**< Samplers used for shadow sampling. */ + /*@}*/ + /** * Number of uniform components used by this shader. * @@ -2277,6 +2283,8 @@ struct gl_shader_program /** Vertex shader state - copied into gl_vertex_program at link time */ struct { GLboolean UsesClipDistance; /**< True if gl_ClipDistance is written to. */ + GLuint ClipDistanceArraySize; /**< Size of the gl_ClipDistance array, or + 0 if not present. */ } Vert; /* post-link info: */ @@ -2348,6 +2356,8 @@ struct gl_shader_state struct gl_shader_program *CurrentGeometryProgram; struct gl_shader_program *CurrentFragmentProgram; + struct gl_shader_program *_CurrentFragmentProgram; + /** * Program used by glUniform calls. * diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c index 0c0e5394d..c1489d211 100644 --- a/mesalib/src/mesa/main/readpix.c +++ b/mesalib/src/mesa/main/readpix.c @@ -782,6 +782,11 @@ _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height, return; } + if (ctx->ReadBuffer->Name != 0 && ctx->ReadBuffer->Visual.samples > 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)"); + return; + } + if (!_mesa_source_buffer_exists(ctx, format)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)"); return; diff --git a/mesalib/src/mesa/main/renderbuffer.c b/mesalib/src/mesa/main/renderbuffer.c index bb8f46d11..08e694673 100644 --- a/mesalib/src/mesa/main/renderbuffer.c +++ b/mesalib/src/mesa/main/renderbuffer.c @@ -132,7 +132,7 @@ _mesa_add_renderbuffer(struct gl_framebuffer *fb, fb->Attachment[bufferName].Renderbuffer == NULL); /* winsys vs. user-created buffer cross check */ - if (fb->Name) { + if (_mesa_is_user_fbo(fb)) { assert(rb->Name); } else { diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index 9372d6dec..0e655a0d8 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -45,6 +45,7 @@ #include "main/mtypes.h" #include "main/shaderapi.h" #include "main/shaderobj.h" +#include "main/uniforms.h" #include "program/program.h" #include "program/prog_parameter.h" #include "ralloc.h" @@ -124,6 +125,8 @@ _mesa_free_shader_state(struct gl_context *ctx) NULL); _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentFragmentProgram, NULL); + _mesa_reference_shader_program(ctx, &ctx->Shader._CurrentFragmentProgram, + NULL); _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL); } @@ -876,6 +879,33 @@ use_shader_program(struct gl_context *ctx, GLenum type, if (*target != shProg) { FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + + /* If the shader is also bound as the current rendering shader, unbind + * it from that binding point as well. This ensures that the correct + * semantics of glDeleteProgram are maintained. + */ + switch (type) { +#if FEATURE_ARB_vertex_shader + case GL_VERTEX_SHADER: + /* Empty for now. */ + break; +#endif +#if FEATURE_ARB_geometry_shader4 + case GL_GEOMETRY_SHADER_ARB: + /* Empty for now. */ + break; +#endif +#if FEATURE_ARB_fragment_shader + case GL_FRAGMENT_SHADER: + if (*target == ctx->Shader._CurrentFragmentProgram) { + _mesa_reference_shader_program(ctx, + &ctx->Shader._CurrentFragmentProgram, + NULL); + } + break; +#endif + } + _mesa_reference_shader_program(ctx, target, shProg); return true; } @@ -899,61 +929,6 @@ _mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg) } -/** - * Validate a program's samplers. - * Specifically, check that there aren't two samplers of different types - * pointing to the same texture unit. - * \return GL_TRUE if valid, GL_FALSE if invalid - */ -static GLboolean -validate_samplers(const struct gl_program *prog, char *errMsg) -{ - static const char *targetName[] = { - "TEXTURE_BUFFER", - "TEXTURE_2D_ARRAY", - "TEXTURE_1D_ARRAY", - "TEXTURE_EXTERNAL", - "TEXTURE_CUBE", - "TEXTURE_3D", - "TEXTURE_RECT", - "TEXTURE_2D", - "TEXTURE_1D", - }; - GLint targetUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; - GLbitfield samplersUsed = prog->SamplersUsed; - GLuint i; - - STATIC_ASSERT(Elements(targetName) == NUM_TEXTURE_TARGETS); - - if (samplersUsed == 0x0) - return GL_TRUE; - - for (i = 0; i < Elements(targetUsed); i++) - targetUsed[i] = -1; - - /* walk over bits which are set in 'samplers' */ - while (samplersUsed) { - GLuint unit; - gl_texture_index target; - GLint sampler = _mesa_ffs(samplersUsed) - 1; - assert(sampler >= 0); - assert(sampler < Elements(prog->SamplerUnits)); - unit = prog->SamplerUnits[sampler]; - target = prog->SamplerTargets[sampler]; - if (targetUsed[unit] != -1 && targetUsed[unit] != (int) target) { - _mesa_snprintf(errMsg, 100, - "Texture unit %d is accessed both as %s and %s", - unit, targetName[targetUsed[unit]], targetName[target]); - return GL_FALSE; - } - targetUsed[unit] = target; - samplersUsed ^= (1 << sampler); - } - - return GL_TRUE; -} - - /** * Do validation of the given shader program. * \param errMsg returns error message if validation fails. @@ -963,8 +938,6 @@ static GLboolean validate_shader_program(const struct gl_shader_program *shProg, char *errMsg) { - unsigned i; - if (!shProg->LinkStatus) { return GL_FALSE; } @@ -989,12 +962,8 @@ validate_shader_program(const struct gl_shader_program *shProg, * Check: any two active samplers in the current program object are of * different types, but refer to the same texture image unit, */ - for (i = 0; i < Elements(shProg->_LinkedShaders); i++) { - if (shProg->_LinkedShaders[i] - && !validate_samplers(shProg->_LinkedShaders[i]->Program, errMsg)) { - return GL_FALSE; - } - } + if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100)) + return GL_FALSE; return GL_TRUE; } diff --git a/mesalib/src/mesa/main/state.c b/mesalib/src/mesa/main/state.c index 7e43563bd..b910543e2 100644 --- a/mesalib/src/mesa/main/state.c +++ b/mesalib/src/mesa/main/state.c @@ -43,6 +43,7 @@ #include "pixel.h" #include "program/program.h" #include "program/prog_parameter.h" +#include "shaderobj.h" #include "state.h" #include "stencil.h" #include "texenvprogram.h" @@ -227,7 +228,7 @@ update_program(struct gl_context *ctx) { const struct gl_shader_program *vsProg = ctx->Shader.CurrentVertexProgram; const struct gl_shader_program *gsProg = ctx->Shader.CurrentGeometryProgram; - const struct gl_shader_program *fsProg = ctx->Shader.CurrentFragmentProgram; + struct gl_shader_program *fsProg = ctx->Shader.CurrentFragmentProgram; const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current; const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current; const struct gl_geometry_program *prevGP = ctx->GeometryProgram._Current; @@ -252,12 +253,18 @@ update_program(struct gl_context *ctx) if (fsProg && fsProg->LinkStatus && fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) { /* Use GLSL fragment shader */ + _mesa_reference_shader_program(ctx, + &ctx->Shader._CurrentFragmentProgram, + fsProg); _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, (struct gl_fragment_program *) fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program); } else if (ctx->FragmentProgram._Enabled) { /* Use user-defined fragment program */ + _mesa_reference_shader_program(ctx, + &ctx->Shader._CurrentFragmentProgram, + NULL); _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, ctx->FragmentProgram.Current); } @@ -265,6 +272,9 @@ update_program(struct gl_context *ctx) /* Use fragment program generated from fixed-function state */ struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx); + _mesa_reference_shader_program(ctx, + &ctx->Shader._CurrentFragmentProgram, + f); _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, (struct gl_fragment_program *) f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program); diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index 9475e84f5..39732522c 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -1900,7 +1900,7 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, } /* Check that the source buffer is complete */ - if (ctx->ReadBuffer->Name) { + if (_mesa_is_user_fbo(ctx->ReadBuffer)) { if (ctx->ReadBuffer->_Status == 0) { _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); } @@ -1909,6 +1909,13 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, "glCopyTexImage%dD(invalid readbuffer)", dimensions); return GL_TRUE; } + + if (ctx->ReadBuffer->Visual.samples > 0) { + _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION, + "glCopyTexImage%dD(multisample FBO)", + dimensions); + return GL_TRUE; + } } /* Check border */ @@ -1999,7 +2006,7 @@ copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions, GLenum target, GLint level) { /* Check that the source buffer is complete */ - if (ctx->ReadBuffer->Name) { + if (_mesa_is_user_fbo(ctx->ReadBuffer)) { if (ctx->ReadBuffer->_Status == 0) { _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); } @@ -2008,6 +2015,13 @@ copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions, "glCopyTexImage%dD(invalid readbuffer)", dimensions); return GL_TRUE; } + + if (ctx->ReadBuffer->Visual.samples > 0) { + _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION, + "glCopyTexSubImage%dD(multisample FBO)", + dimensions); + return GL_TRUE; + } } /* check target (proxies not allowed) */ @@ -2179,7 +2193,7 @@ check_rtt_cb(GLuint key, void *data, void *userData) const GLuint level = info->level, face = info->face; /* If this is a user-created FBO */ - if (fb->Name) { + if (_mesa_is_user_fbo(fb)) { GLuint i; /* check if any of the FBO's attachments point to 'texObj' */ for (i = 0; i < BUFFER_COUNT; i++) { diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c index 7ee200585..1b61d3a63 100644 --- a/mesalib/src/mesa/main/texobj.c +++ b/mesalib/src/mesa/main/texobj.c @@ -672,9 +672,11 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, return; } /* Don't support GL_DEPTH_COMPONENT for cube maps */ - if (t->Image[face][i]->_BaseFormat == GL_DEPTH_COMPONENT) { - incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex"); - return; + if (ctx->VersionMajor < 3 && !ctx->Extensions.EXT_gpu_shader4) { + if (t->Image[face][i]->_BaseFormat == GL_DEPTH_COMPONENT) { + incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex"); + return; + } } /* check that all six images have same size */ if (t->Image[face][i]->Width2 != width || @@ -891,7 +893,7 @@ unbind_texobj_from_fbo(struct gl_context *ctx, for (i = 0; i < n; i++) { struct gl_framebuffer *fb = (i == 0) ? ctx->DrawBuffer : ctx->ReadBuffer; - if (fb->Name) { + if (_mesa_is_user_fbo(fb)) { GLuint j; for (j = 0; j < BUFFER_COUNT; j++) { if (fb->Attachment[j].Type == GL_TEXTURE && diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index 512965fc3..a9c64cede 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -515,9 +515,9 @@ make_temp_uint_image(struct gl_context *ctx, GLuint dims, for (k = 0; k < texComponents; k++) { GLint j = map[k]; if (j == ZERO) - newImage[i * texComponents + k] = 0.0F; + newImage[i * texComponents + k] = 0; else if (j == ONE) - newImage[i * texComponents + k] = 1.0F; + newImage[i * texComponents + k] = 1; else newImage[i * texComponents + k] = tempImage[i * logComponents + j]; } @@ -4094,7 +4094,7 @@ _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS) _mesa_unpack_depth_span(ctx, srcWidth, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */ dstRow, /* dst addr */ - 1.0f, srcType, src, srcPacking); + ~0U, srcType, src, srcPacking); if (srcFormat != GL_DEPTH_COMPONENT) _mesa_unpack_stencil_span(ctx, srcWidth, diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp index f3d6a16ee..869f7d373 100644 --- a/mesalib/src/mesa/main/uniform_query.cpp +++ b/mesalib/src/mesa/main/uniform_query.cpp @@ -691,19 +691,16 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, bool flushed = false; for (i = 0; i < MESA_SHADER_TYPES; i++) { - struct gl_program *prog; - - if (shProg->_LinkedShaders[i] == NULL) - continue; - - prog = shProg->_LinkedShaders[i]->Program; + struct gl_shader *const sh = shProg->_LinkedShaders[i]; /* If the shader stage doesn't use any samplers, don't bother * checking if any samplers have changed. */ - if (prog->SamplersUsed == 0) + if (sh == NULL || sh->active_samplers == 0) continue; + struct gl_program *const prog = sh->Program; + assert(sizeof(prog->SamplerUnits) == sizeof(shProg->SamplerUnits)); /* Determine if any of the samplers used by this shader stage have @@ -711,7 +708,7 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, */ bool changed = false; for (unsigned j = 0; j < Elements(prog->SamplerUnits); j++) { - if ((prog->SamplersUsed & (1U << j)) != 0 + if ((sh->active_samplers & (1U << j)) != 0 && (prog->SamplerUnits[j] != shProg->SamplerUnits[j])) { changed = true; break; @@ -728,7 +725,7 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, shProg->SamplerUnits, sizeof(shProg->SamplerUnits)); - _mesa_update_shader_textures_used(prog); + _mesa_update_shader_textures_used(shProg, prog); (void) ctx->Driver.ProgramStringNotify(ctx, prog->Target, prog); } } @@ -933,3 +930,46 @@ _mesa_get_uniform_location(struct gl_context *ctx, return _mesa_uniform_merge_location_offset(location, offset); } + +extern "C" bool +_mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg, + char *errMsg, size_t errMsgLength) +{ + const glsl_type *unit_types[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; + + memset(unit_types, 0, sizeof(unit_types)); + + for (unsigned i = 0; i < shProg->NumUserUniformStorage; i++) { + const struct gl_uniform_storage *const storage = + &shProg->UniformStorage[i]; + const glsl_type *const t = (storage->type->is_array()) + ? storage->type->fields.array : storage->type; + + if (!t->is_sampler()) + continue; + + const unsigned count = MAX2(1, storage->type->array_size()); + for (unsigned j = 0; j < count; j++) { + const unsigned unit = storage->storage[j].i; + + /* The types of the samplers associated with a particular texture + * unit must be an exact match. Page 74 (page 89 of the PDF) of the + * OpenGL 3.3 core spec says: + * + * "It is not allowed to have variables of different sampler + * types pointing to the same texture image unit within a program + * object." + */ + if (unit_types[unit] == NULL) { + unit_types[unit] = t; + } else if (unit_types[unit] != t) { + _mesa_snprintf(errMsg, errMsgLength, + "Texture unit %d is accessed both as %s and %s", + unit, unit_types[unit]->name, t->name); + return false; + } + } + } + + return true; +} diff --git a/mesalib/src/mesa/main/uniforms.c b/mesalib/src/mesa/main/uniforms.c index 685c0f13f..e0214a88a 100644 --- a/mesalib/src/mesa/main/uniforms.c +++ b/mesalib/src/mesa/main/uniforms.c @@ -60,7 +60,8 @@ * We'll use that info for state validation before rendering. */ void -_mesa_update_shader_textures_used(struct gl_program *prog) +_mesa_update_shader_textures_used(struct gl_shader_program *shProg, + struct gl_program *prog) { GLuint s; @@ -68,8 +69,8 @@ _mesa_update_shader_textures_used(struct gl_program *prog) for (s = 0; s < MAX_SAMPLERS; s++) { if (prog->SamplersUsed & (1 << s)) { - GLuint unit = prog->SamplerUnits[s]; - GLuint tgt = prog->SamplerTargets[s]; + GLuint unit = shProg->SamplerUnits[s]; + GLuint tgt = shProg->SamplerTargets[s]; assert(unit < Elements(prog->TexturesUsed)); assert(tgt < NUM_TEXTURE_TARGETS); prog->TexturesUsed[unit] |= (1 << tgt); diff --git a/mesalib/src/mesa/main/uniforms.h b/mesalib/src/mesa/main/uniforms.h index 123d7b954..7b512a527 100644 --- a/mesalib/src/mesa/main/uniforms.h +++ b/mesalib/src/mesa/main/uniforms.h @@ -212,8 +212,12 @@ _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni, unsigned count); extern void -_mesa_update_shader_textures_used(struct gl_program *prog); +_mesa_update_shader_textures_used(struct gl_shader_program *shProg, + struct gl_program *prog); +extern bool +_mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg, + char *errMsg, size_t errMsgLength); extern void _mesa_init_shader_uniform_dispatch(struct _glapi_table *exec); diff --git a/mesalib/src/mesa/main/version.h b/mesalib/src/mesa/main/version.h index d288c4d55..8723c1f57 100644 --- a/mesalib/src/mesa/main/version.h +++ b/mesalib/src/mesa/main/version.h @@ -42,17 +42,6 @@ struct gl_context; #define MESA_VERSION_CODE MESA_VERSION(MESA_MAJOR, MESA_MINOR, MESA_PATCH) -/* OpenGL API version */ -#define OPENGL_MAJOR 2 -#define OPENGL_MINOR 1 -#define OPENGL_PATCH 0 -#define OPENGL_VERSION_STRING "2.1" - -/* To make version comparison easy */ -#define OPENGL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -#define OPENGL_VERSION_CODE OPENGL_VERSION(OPENGL_MAJOR, OPENGL_MINOR, OPENGL_PATCH) - - extern void _mesa_compute_version(struct gl_context *ctx); -- cgit v1.2.3