diff options
Diffstat (limited to 'src/mesa/main')
32 files changed, 1198 insertions, 1344 deletions
diff --git a/src/mesa/main/APIspec.xml b/src/mesa/main/APIspec.xml index 4dc0b0d4851..16d0c9413d0 100644 --- a/src/mesa/main/APIspec.xml +++ b/src/mesa/main/APIspec.xml @@ -3536,7 +3536,7 @@ <api name="mesa" implementation="true"> <category name="MESA"/> - <function name="Color4f" default_prefix="_vbo_" template="Color" gltype="GLfloat" vector_size="4" expand_vector="true"/> + <function name="Color4f" default_prefix="_es_" template="Color" gltype="GLfloat" vector_size="4" expand_vector="true"/> <function name="ClipPlane" template="ClipPlane" gltype="GLdouble"/> <function name="CullFace" template="CullFace"/> @@ -3554,8 +3554,8 @@ <function name="LineWidth" template="LineWidth" gltype="GLfloat"/> - <function name="Materialf" default_prefix="_vbo_" template="Material" gltype="GLfloat" expand_vector="true"/> - <function name="Materialfv" default_prefix="_vbo_" template="Material" gltype="GLfloat"/> + <function name="Materialf" default_prefix="_es_" template="Material" gltype="GLfloat" expand_vector="true"/> + <function name="Materialfv" default_prefix="_es_" template="Material" gltype="GLfloat"/> <function name="PointSize" template="PointSize" gltype="GLfloat"/> <function name="PointSizePointer" template="PointSizePointer"/> @@ -3650,7 +3650,7 @@ <function name="EnableClientState" template="EnableClientState"/> <function name="GetPointerv" template="GetPointer"/> - <function name="Normal3f" default_prefix="_vbo_" template="Normal" gltype="GLfloat" expand_vector="true"/> + <function name="Normal3f" default_prefix="_es_" template="Normal" gltype="GLfloat" expand_vector="true"/> <function name="NormalPointer" template="NormalPointer"/> <function name="TexCoordPointer" template="TexCoordPointer"/> <function name="VertexPointer" template="VertexPointer"/> @@ -3679,7 +3679,7 @@ <function name="ActiveTextureARB" template="ActiveTexture"/> <function name="ClientActiveTextureARB" template="ClientActiveTexture"/> - <function name="MultiTexCoord4f" default_prefix="_vbo_" template="MultiTexCoord" gltype="GLfloat" vector_size="4" expand_vector="true"/> + <function name="MultiTexCoord4f" default_prefix="_es_" template="MultiTexCoord" gltype="GLfloat" vector_size="4" expand_vector="true"/> <function name="SampleCoverageARB" template="SampleCoverage" gltype="GLclampf"/> @@ -3691,14 +3691,14 @@ <function name="PointParameterf" template="PointParameter" gltype="GLfloat" expand_vector="true"/> <function name="PointParameterfv" template="PointParameter" gltype="GLfloat"/> - <function name="VertexAttrib1f" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="1" expand_vector="true"/> - <function name="VertexAttrib2f" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="2" expand_vector="true"/> - <function name="VertexAttrib3f" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="3" expand_vector="true"/> - <function name="VertexAttrib4f" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="4" expand_vector="true"/> - <function name="VertexAttrib1fv" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="1"/> - <function name="VertexAttrib2fv" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="2"/> - <function name="VertexAttrib3fv" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="3"/> - <function name="VertexAttrib4fv" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="4"/> + <function name="VertexAttrib1f" default_prefix="_es_" template="VertexAttrib" gltype="GLfloat" vector_size="1" expand_vector="true"/> + <function name="VertexAttrib2f" default_prefix="_es_" template="VertexAttrib" gltype="GLfloat" vector_size="2" expand_vector="true"/> + <function name="VertexAttrib3f" default_prefix="_es_" template="VertexAttrib" gltype="GLfloat" vector_size="3" expand_vector="true"/> + <function name="VertexAttrib4f" default_prefix="_es_" template="VertexAttrib" gltype="GLfloat" vector_size="4" expand_vector="true"/> + <function name="VertexAttrib1fv" default_prefix="_es_" template="VertexAttrib" gltype="GLfloat" vector_size="1"/> + <function name="VertexAttrib2fv" default_prefix="_es_" template="VertexAttrib" gltype="GLfloat" vector_size="2"/> + <function name="VertexAttrib3fv" default_prefix="_es_" template="VertexAttrib" gltype="GLfloat" vector_size="3"/> + <function name="VertexAttrib4fv" default_prefix="_es_" template="VertexAttrib" gltype="GLfloat" vector_size="4"/> <function name="VertexAttribPointerARB" template="VertexAttribPointer"/> <function name="EnableVertexAttribArrayARB" template="EnableVertexAttribArray"/> @@ -3850,7 +3850,7 @@ <category name="OES_matrix_palette"/> - <function name="Color4f" template="Color" gltype="GLfloat" vector_size="4" expand_vector="true"/> + <function name="Color4f" external="true" template="Color" gltype="GLfloat" vector_size="4" expand_vector="true"/> <function name="Color4ub" template="Color" gltype="GLubyte" vector_size="4" expand_vector="true"/> <function name="Color4x" template="Color" gltype="GLfixed" vector_size="4" expand_vector="true"/> @@ -3880,8 +3880,8 @@ <function name="LineWidth" template="LineWidth" gltype="GLfloat"/> <function name="LineWidthx" template="LineWidth" gltype="GLfixed"/> - <function name="Materialf" template="Material" gltype="GLfloat" expand_vector="true"/> - <function name="Materialfv" template="Material" gltype="GLfloat"/> + <function name="Materialf" external="true" template="Material" gltype="GLfloat" expand_vector="true"/> + <function name="Materialfv" external="true" template="Material" gltype="GLfloat"/> <function name="Materialx" template="Material" gltype="GLfixed" expand_vector="true"/> <function name="Materialxv" template="Material" gltype="GLfixed"/> @@ -4012,7 +4012,7 @@ <function name="GetPointerv" template="GetPointer"/> - <function name="Normal3f" template="Normal" gltype="GLfloat" expand_vector="true"/> + <function name="Normal3f" external="true" template="Normal" gltype="GLfloat" expand_vector="true"/> <function name="Normal3x" template="Normal" gltype="GLfixed" expand_vector="true"/> <function name="NormalPointer" template="NormalPointer"/> <function name="TexCoordPointer" template="TexCoordPointer"/> @@ -4039,7 +4039,7 @@ <function name="ActiveTexture" template="ActiveTexture"/> <function name="ClientActiveTexture" template="ClientActiveTexture"/> - <function name="MultiTexCoord4f" template="MultiTexCoord" gltype="GLfloat" vector_size="4" expand_vector="true"/> + <function name="MultiTexCoord4f" external="true" template="MultiTexCoord" gltype="GLfloat" vector_size="4" expand_vector="true"/> <function name="SampleCoverage" template="SampleCoverage" gltype="GLclampf"/> <function name="SampleCoveragex" template="SampleCoverage" gltype="GLclampx"/> @@ -4227,14 +4227,14 @@ <function name="BlendFuncSeparate" template="BlendFuncSeparate"/> - <function name="VertexAttrib1f" template="VertexAttrib" gltype="GLfloat" vector_size="1" expand_vector="true"/> - <function name="VertexAttrib2f" template="VertexAttrib" gltype="GLfloat" vector_size="2" expand_vector="true"/> - <function name="VertexAttrib3f" template="VertexAttrib" gltype="GLfloat" vector_size="3" expand_vector="true"/> - <function name="VertexAttrib4f" template="VertexAttrib" gltype="GLfloat" vector_size="4" expand_vector="true"/> - <function name="VertexAttrib1fv" template="VertexAttrib" gltype="GLfloat" vector_size="1"/> - <function name="VertexAttrib2fv" template="VertexAttrib" gltype="GLfloat" vector_size="2"/> - <function name="VertexAttrib3fv" template="VertexAttrib" gltype="GLfloat" vector_size="3"/> - <function name="VertexAttrib4fv" template="VertexAttrib" gltype="GLfloat" vector_size="4"/> + <function name="VertexAttrib1f" external="true" template="VertexAttrib" gltype="GLfloat" vector_size="1" expand_vector="true"/> + <function name="VertexAttrib2f" external="true" template="VertexAttrib" gltype="GLfloat" vector_size="2" expand_vector="true"/> + <function name="VertexAttrib3f" external="true" template="VertexAttrib" gltype="GLfloat" vector_size="3" expand_vector="true"/> + <function name="VertexAttrib4f" external="true" template="VertexAttrib" gltype="GLfloat" vector_size="4" expand_vector="true"/> + <function name="VertexAttrib1fv" external="true" template="VertexAttrib" gltype="GLfloat" vector_size="1"/> + <function name="VertexAttrib2fv" external="true" template="VertexAttrib" gltype="GLfloat" vector_size="2"/> + <function name="VertexAttrib3fv" external="true" template="VertexAttrib" gltype="GLfloat" vector_size="3"/> + <function name="VertexAttrib4fv" external="true" template="VertexAttrib" gltype="GLfloat" vector_size="4"/> <function name="VertexAttribPointer" template="VertexAttribPointer"/> diff --git a/src/mesa/main/compiler.h b/src/mesa/main/compiler.h index 800eb839005..5557a3b5cb5 100644 --- a/src/mesa/main/compiler.h +++ b/src/mesa/main/compiler.h @@ -358,6 +358,10 @@ static INLINE GLuint CPU_TO_LE32(GLuint x) #define M_E (2.7182818284590452354) #endif +#ifndef M_LOG2E +#define M_LOG2E (1.4426950408889634074) +#endif + #ifndef ONE_DIV_LN2 #define ONE_DIV_LN2 (1.442695040888963456) #endif diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index 0f2d1a8f8da..fffb1a7d2ec 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -97,17 +97,20 @@ /** Max texture palette / color table size */ #define MAX_COLOR_TABLE_SIZE 256 +/** Max memory to allow for a single texture image (in megabytes) */ +#define MAX_TEXTURE_MBYTES 1024 + /** Number of 1D/2D texture mipmap levels */ -#define MAX_TEXTURE_LEVELS 13 +#define MAX_TEXTURE_LEVELS 15 /** Number of 3D texture mipmap levels */ -#define MAX_3D_TEXTURE_LEVELS 9 +#define MAX_3D_TEXTURE_LEVELS 15 /** Number of cube texture mipmap levels - GL_ARB_texture_cube_map */ -#define MAX_CUBE_TEXTURE_LEVELS 13 +#define MAX_CUBE_TEXTURE_LEVELS 15 /** Maximum rectangular texture size - GL_NV_texture_rectangle */ -#define MAX_TEXTURE_RECT_SIZE 4096 +#define MAX_TEXTURE_RECT_SIZE 16384 /** Maximum number of layers in a 1D or 2D array texture - GL_MESA_texture_array */ #define MAX_ARRAY_TEXTURE_LAYERS 64 @@ -140,11 +143,28 @@ */ #ifndef MAX_WIDTH -# define MAX_WIDTH 4096 +# define MAX_WIDTH 16384 #endif /** Maximum viewport/image height */ #ifndef MAX_HEIGHT -# define MAX_HEIGHT 4096 +# define MAX_HEIGHT 16384 +#endif + +/* XXX: hack to prevent stack overflow on windows until all temporary arrays + * [MAX_WIDTH] are allocated from the heap */ +#ifdef WIN32 +#undef MAX_TEXTURE_LEVELS +#undef MAX_3D_TEXTURE_LEVELS +#undef MAX_CUBE_TEXTURE_LEVELS +#undef MAX_TEXTURE_RECT_SIZE +#undef MAX_WIDTH +#undef MAX_HEIGHT +#define MAX_TEXTURE_LEVELS 13 +#define MAX_3D_TEXTURE_LEVELS 9 +#define MAX_CUBE_TEXTURE_LEVELS 13 +#define MAX_TEXTURE_RECT_SIZE 4096 +#define MAX_WIDTH 4096 +#define MAX_HEIGHT 4096 #endif /** Maxmimum size for CVA. May be overridden by the drivers. */ @@ -168,7 +188,7 @@ #define MAX_TEXTURE_MAX_ANISOTROPY 16.0 /** For GL_EXT_texture_lod_bias (typically MAX_TEXTURE_LEVELS - 1) */ -#define MAX_TEXTURE_LOD_BIAS 12.0 +#define MAX_TEXTURE_LOD_BIAS 14.0 /** For any program target/extension */ /*@{*/ diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index b132030b9b1..f42a566c302 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -535,6 +535,7 @@ _mesa_init_constants(struct gl_context *ctx) assert(ctx); /* Constants, may be overriden (usually only reduced) by device drivers */ + ctx->Const.MaxTextureMbytes = MAX_TEXTURE_MBYTES; ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS; ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS; ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS; @@ -1399,6 +1400,8 @@ _mesa_make_current( struct gl_context *newCtx, struct gl_framebuffer *drawBuffer, struct gl_framebuffer *readBuffer ) { + GET_CURRENT_CONTEXT(curCtx); + if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(newCtx, "_mesa_make_current()\n"); @@ -1419,6 +1422,11 @@ _mesa_make_current( struct gl_context *newCtx, } } + if (curCtx && + (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) && /* make sure this context is valid for flushing */ + curCtx != newCtx) + _mesa_flush(curCtx); + /* We used to call _glapi_check_multithread() here. Now do it in drivers */ _glapi_set_context((void *) newCtx); ASSERT(_mesa_get_current_context() == newCtx); @@ -1822,7 +1830,7 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where) #ifdef DEBUG if (ctx->Shader.Flags & GLSL_LOG) { struct gl_shader_program *shProg[MESA_SHADER_TYPES]; - unsigned i; + gl_shader_type i; shProg[MESA_SHADER_VERTEX] = ctx->Shader.CurrentVertexProgram; shProg[MESA_SHADER_GEOMETRY] = ctx->Shader.CurrentGeometryProgram; diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 3d5830c01cc..b71afdd61f3 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -873,8 +873,12 @@ make_extension_string_es2(const struct gl_context *ctx, GLubyte *str) if (ctx->Extensions.ARB_vertex_buffer_object) len += append_extension(&str, "GL_OES_mapbuffer"); +#if 0 + /* disabled because of missing GLSL support */ if (ctx->Extensions.EXT_texture3D) len += append_extension(&str, "GL_OES_texture_3D"); +#endif + if (ctx->Extensions.ARB_texture_non_power_of_two) len += append_extension(&str, "GL_OES_texture_npot"); if (ctx->Extensions.EXT_texture_filter_anisotropic) diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 7c3357043fa..975063d0d78 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -2014,7 +2014,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, switch (pname) { case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT: - *params = att->Type; + *params = buffer->Name == 0 ? GL_FRAMEBUFFER_DEFAULT : att->Type; return; case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT: if (att->Type == GL_RENDERBUFFER_EXT) { @@ -2024,8 +2024,8 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, *params = att->Texture->Name; } else { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetFramebufferAttachmentParameterivEXT(pname)"); + assert(att->Type == GL_NONE); + *params = 0; } return; case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT: @@ -2146,6 +2146,7 @@ _mesa_GenerateMipmapEXT(GLenum target) /* OK, legal value */ break; default: + /* XXX need to implement GL_TEXTURE_1D_ARRAY and GL_TEXTURE_2D_ARRAY */ _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target)"); return; } @@ -2157,6 +2158,13 @@ _mesa_GenerateMipmapEXT(GLenum target) return; } + if (texObj->Target == GL_TEXTURE_CUBE_MAP && + !_mesa_cube_complete(texObj)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGenerateMipmap(incomplete cube map)"); + return; + } + _mesa_lock_texture(ctx, texObj); if (target == GL_TEXTURE_CUBE_MAP) { GLuint face; diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c index 88a04e888e4..cd9eb81852f 100644 --- a/src/mesa/main/formats.c +++ b/src/mesa/main/formats.c @@ -1057,11 +1057,12 @@ _mesa_format_image_size(gl_format format, GLsizei width, const struct gl_format_info *info = _mesa_get_format_info(format); /* Strictly speaking, a conditional isn't needed here */ if (info->BlockWidth > 1 || info->BlockHeight > 1) { - /* compressed format */ + /* compressed format (2D only for now) */ const GLuint bw = info->BlockWidth, bh = info->BlockHeight; const GLuint wblocks = (width + bw - 1) / bw; const GLuint hblocks = (height + bh - 1) / bh; const GLuint sz = wblocks * hblocks * info->BytesPerBlock; + assert(depth == 1); return sz; } else { @@ -1072,6 +1073,36 @@ _mesa_format_image_size(gl_format format, GLsizei width, } +/** + * Same as _mesa_format_image_size() but returns a 64-bit value to + * accomodate very large textures. + */ +uint64_t +_mesa_format_image_size64(gl_format format, GLsizei width, + GLsizei height, GLsizei depth) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + /* Strictly speaking, a conditional isn't needed here */ + if (info->BlockWidth > 1 || info->BlockHeight > 1) { + /* compressed format (2D only for now) */ + const uint64_t bw = info->BlockWidth, bh = info->BlockHeight; + const uint64_t wblocks = (width + bw - 1) / bw; + const uint64_t hblocks = (height + bh - 1) / bh; + const uint64_t sz = wblocks * hblocks * info->BytesPerBlock; + assert(depth == 1); + return sz; + } + else { + /* non-compressed */ + const uint64_t sz = ((uint64_t) width * + (uint64_t) height * + (uint64_t) depth * + info->BytesPerBlock); + return sz; + } +} + + GLint _mesa_format_row_stride(gl_format format, GLsizei width) diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h index eeb460dabe7..997229bf9f4 100644 --- a/src/mesa/main/formats.h +++ b/src/mesa/main/formats.h @@ -209,6 +209,10 @@ extern GLuint _mesa_format_image_size(gl_format format, GLsizei width, GLsizei height, GLsizei depth); +extern uint64_t +_mesa_format_image_size64(gl_format format, GLsizei width, + GLsizei height, GLsizei depth); + extern GLint _mesa_format_row_stride(gl_format format, GLsizei width); diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index b54af6ee86b..5ae35b868e3 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -314,6 +314,7 @@ EXTRA_EXT2(ARB_vertex_program, NV_vertex_program); EXTRA_EXT2(ARB_vertex_program, ARB_fragment_program); EXTRA_EXT(ARB_vertex_buffer_object); EXTRA_EXT(ARB_geometry_shader4); +EXTRA_EXT(ARB_copy_buffer); static const int extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program[] = { @@ -469,6 +470,10 @@ static const struct value_desc values[] = { { GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, 0, extra_ARB_vertex_buffer_object }, + /* GL_ARB_copy_buffer */ + { GL_COPY_READ_BUFFER, LOC_CUSTOM, TYPE_INT, 0, extra_ARB_copy_buffer }, + { GL_COPY_WRITE_BUFFER, LOC_CUSTOM, TYPE_INT, 0, extra_ARB_copy_buffer }, + /* GL_OES_read_format */ { GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, LOC_CUSTOM, TYPE_INT, 0, extra_new_buffers_OES_read_format }, @@ -700,12 +705,9 @@ static const struct value_desc values[] = { #if FEATURE_ES2 /* Enums unique to OpenGL ES 2.0 */ { 0, 0, TYPE_API_MASK, API_OPENGLES2_BIT, NO_EXTRA }, - { GL_MAX_FRAGMENT_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, - offsetof(struct gl_context, Const.FragmentProgram.MaxUniformComponents), NO_EXTRA }, - { GL_MAX_VARYING_VECTORS, LOC_CUSTOM, TYPE_INT, - offsetof(struct gl_context, Const.MaxVarying), NO_EXTRA }, - { GL_MAX_VERTEX_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, - offsetof(struct gl_context, Const.VertexProgram.MaxUniformComponents), NO_EXTRA }, + { GL_MAX_FRAGMENT_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA }, + { GL_MAX_VARYING_VECTORS, CONTEXT_INT(Const.MaxVarying), NO_EXTRA }, + { GL_MAX_VERTEX_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA }, { GL_SHADER_COMPILER, CONST(1), NO_EXTRA }, /* OES_get_program_binary */ { GL_NUM_SHADER_BINARY_FORMATS, CONST(0), NO_EXTRA }, @@ -1112,6 +1114,14 @@ static const struct value_desc values[] = { extra_valid_draw_buffer }, { GL_DRAW_BUFFER3_ARB, BUFFER_ENUM(ColorDrawBuffer[3]), extra_valid_draw_buffer }, + { GL_DRAW_BUFFER4_ARB, BUFFER_ENUM(ColorDrawBuffer[4]), + extra_valid_draw_buffer }, + { GL_DRAW_BUFFER5_ARB, BUFFER_ENUM(ColorDrawBuffer[5]), + extra_valid_draw_buffer }, + { GL_DRAW_BUFFER6_ARB, BUFFER_ENUM(ColorDrawBuffer[6]), + extra_valid_draw_buffer }, + { GL_DRAW_BUFFER7_ARB, BUFFER_ENUM(ColorDrawBuffer[7]), + extra_valid_draw_buffer }, /* GL_ATI_fragment_shader */ { GL_NUM_FRAGMENT_REGISTERS_ATI, CONST(6), extra_ATI_fragment_shader }, @@ -1564,6 +1574,14 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu v->value_int = ctx->Array.ElementArrayBufferObj->Name; break; + /* ARB_copy_buffer */ + case GL_COPY_READ_BUFFER: + v->value_int = ctx->CopyReadBuffer->Name; + break; + case GL_COPY_WRITE_BUFFER: + v->value_int = ctx->CopyWriteBuffer->Name; + break; + case GL_FRAGMENT_PROGRAM_BINDING_NV: v->value_int = ctx->FragmentProgram.Current ? ctx->FragmentProgram.Current->Base.Id : 0; @@ -1604,6 +1622,14 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: v->value_int = ctx->Array.ArrayObj->PointSize.BufferObj->Name; break; + + case GL_MAX_VERTEX_UNIFORM_VECTORS: + v->value_int = ctx->Const.VertexProgram.MaxUniformComponents / 4; + break; + + case GL_MAX_FRAGMENT_UNIFORM_VECTORS: + v->value_int = ctx->Const.FragmentProgram.MaxUniformComponents / 4; + break; } } @@ -1733,16 +1759,18 @@ find_value(const char *func, GLenum pname, void **p, union value *v) hash = (pname * prime_factor); while (1) { d = &values[table[hash & mask]]; - if (likely(d->pname == pname)) - break; /* If the enum isn't valid, the hash walk ends with index 0, * which is the API mask entry at the beginning of values[]. */ - if (d->type == TYPE_API_MASK) { + if (unlikely(d->type == TYPE_API_MASK)) { _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func, _mesa_lookup_enum_by_nr(pname)); return &error_value; } + + if (likely(d->pname == pname)) + break; + hash += prime_step; } diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index df1527b47f1..f9f2ed73077 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -154,6 +154,8 @@ _mesa_sizeof_type( GLenum type ) return sizeof(GLdouble); case GL_HALF_FLOAT_ARB: return sizeof(GLhalfARB); + case GL_FIXED: + return sizeof(GLfixed); default: return -1; } diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c index bcca4edc1aa..cefbf4d8c98 100644 --- a/src/mesa/main/imports.c +++ b/src/mesa/main/imports.c @@ -88,7 +88,8 @@ _mesa_align_malloc(size_t bytes, unsigned long alignment) #if defined(HAVE_POSIX_MEMALIGN) void *mem; int err = posix_memalign(& mem, alignment, bytes); - (void) err; + if (err) + return NULL; return mem; #elif defined(_WIN32) && defined(_MSC_VER) return _aligned_malloc(bytes, alignment); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 87b96489dbf..1c549a8e247 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -41,14 +41,6 @@ #include "math/m_matrix.h" /* GLmatrix */ #include "main/simple_list.h" /* struct simple_node */ -/* Shader stages. Note that these will become 5 with tessellation. - * These MUST have the same values as PIPE_SHADER_* - */ -#define MESA_SHADER_VERTEX 0 -#define MESA_SHADER_FRAGMENT 1 -#define MESA_SHADER_GEOMETRY 2 -#define MESA_SHADER_TYPES 3 - /** * Color channel data type. @@ -130,6 +122,20 @@ struct st_context; /** + * Shader stages. Note that these will become 5 with tessellation. + * These MUST have the same values as gallium's PIPE_SHADER_* + */ +typedef enum +{ + MESA_SHADER_VERTEX = 0, + MESA_SHADER_FRAGMENT = 1, + MESA_SHADER_GEOMETRY = 2, + MESA_SHADER_TYPES = 3 +} gl_shader_type; + + + +/** * Indexes for vertex program attributes. * GL_NV_vertex_program aliases generic attributes over the conventional * attributes. In GL_ARB_vertex_program shader the aliasing is optional. @@ -2191,6 +2197,7 @@ struct gl_shader_compiler_options GLboolean EmitNoCont; /**< Emit CONT opcode? */ GLboolean EmitNoMainReturn; /**< Emit CONT/RET opcodes? */ GLboolean EmitNoNoise; /**< Emit NOISE opcodes? */ + GLboolean EmitNoPow; /**< Emit POW opcodes? */ /** * \name Forms of indirect addressing the driver cannot do. @@ -2560,6 +2567,7 @@ struct gl_program_constants */ struct gl_constants { + GLint MaxTextureMbytes; /**< Max memory per image, in MB */ GLint MaxTextureLevels; /**< Max mipmap levels. */ GLint Max3DTextureLevels; /**< Max mipmap levels for 3D textures */ GLint MaxCubeTextureLevels; /**< Max mipmap levels for cube textures */ diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c index fdb647c7ea8..6d524e64908 100644 --- a/src/mesa/main/pack.c +++ b/src/mesa/main/pack.c @@ -484,11 +484,25 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], const struct gl_pixelstore_attrib *dstPacking, GLbitfield transferOps) { - GLfloat luminance[MAX_WIDTH]; + GLfloat *luminance; const GLint comps = _mesa_components_in_format(dstFormat); const GLboolean intDstFormat = _mesa_is_integer_format(dstFormat); GLuint i; + if (dstFormat == GL_LUMINANCE || + dstFormat == GL_LUMINANCE_ALPHA || + dstFormat == GL_LUMINANCE_INTEGER_EXT || + dstFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT) { + luminance = (GLfloat *) malloc(n * sizeof(GLfloat)); + if (!luminance) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing"); + return; + } + } + else { + luminance = NULL; + } + /* XXX * This test should probably go away. Have the caller set/clear the * IMAGE_CLAMP_BIT as needed. @@ -1907,6 +1921,8 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], } } } + + free(luminance); } @@ -3462,7 +3478,12 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx, { GLint dstComponents; GLint rDst, gDst, bDst, aDst, lDst, iDst; - GLfloat rgba[MAX_WIDTH][4]; + GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat)); + + if (!rgba) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); + return; + } dstComponents = _mesa_components_in_format( dstFormat ); /* source & dest image formats should have been error checked by now */ @@ -3471,9 +3492,14 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx, /* * Extract image data and convert to RGBA floats */ - assert(n <= MAX_WIDTH); if (srcFormat == GL_COLOR_INDEX) { - GLuint indexes[MAX_WIDTH]; + GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint)); + + if (!indexes) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); + return; + } + extract_uint_indexes(n, indexes, srcFormat, srcType, source, srcPacking); @@ -3484,6 +3510,8 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx, for (i = 0; i < n; i++) { dest[i] = (GLchan) (indexes[i] & 0xff); } + free(indexes); + free(rgba); return; } else { @@ -3498,6 +3526,8 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx, * with color indexes. */ transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT); + + free(indexes); } else { /* non-color index data */ @@ -3575,6 +3605,8 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx, dst += dstComponents; } } + + free(rgba); } } @@ -3652,7 +3684,12 @@ _mesa_unpack_color_span_float( struct gl_context *ctx, { GLint dstComponents; GLint rDst, gDst, bDst, aDst, lDst, iDst; - GLfloat rgba[MAX_WIDTH][4]; + GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat)); + + if (!rgba) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); + return; + } dstComponents = _mesa_components_in_format( dstFormat ); /* source & dest image formats should have been error checked by now */ @@ -3661,9 +3698,15 @@ _mesa_unpack_color_span_float( struct gl_context *ctx, /* * Extract image data and convert to RGBA floats */ - assert(n <= MAX_WIDTH); if (srcFormat == GL_COLOR_INDEX) { - GLuint indexes[MAX_WIDTH]; + GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint)); + + if (!indexes) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); + free(rgba); + return; + } + extract_uint_indexes(n, indexes, srcFormat, srcType, source, srcPacking); @@ -3674,6 +3717,8 @@ _mesa_unpack_color_span_float( struct gl_context *ctx, for (i = 0; i < n; i++) { dest[i] = (GLchan) (indexes[i] & 0xff); } + free(indexes); + free(rgba); return; } else { @@ -3688,6 +3733,8 @@ _mesa_unpack_color_span_float( struct gl_context *ctx, * with color indexes. */ transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT); + + free(indexes); } else { /* non-color index data */ @@ -3760,6 +3807,8 @@ _mesa_unpack_color_span_float( struct gl_context *ctx, dst += dstComponents; } } + + free(rgba); } } @@ -3776,9 +3825,12 @@ _mesa_unpack_color_span_uint(struct gl_context *ctx, const GLvoid *source, const struct gl_pixelstore_attrib *srcPacking) { - GLuint rgba[MAX_WIDTH][4]; + GLuint (*rgba)[4] = (GLuint (*)[4]) malloc(n * 4 * sizeof(GLfloat)); - ASSERT(n <= MAX_WIDTH); + if (!rgba) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); + return; + } ASSERT(dstFormat == GL_ALPHA || dstFormat == GL_LUMINANCE || @@ -3912,6 +3964,8 @@ _mesa_unpack_color_span_uint(struct gl_context *ctx, } } } + + free(rgba); } @@ -3943,9 +3997,14 @@ _mesa_unpack_dudv_span_byte( struct gl_context *ctx, /* general solution */ { GLint dstComponents; - GLfloat rgba[MAX_WIDTH][4]; GLbyte *dst = dest; GLuint i; + GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat)); + + if (!rgba) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); + return; + } dstComponents = _mesa_components_in_format( dstFormat ); /* source & dest image formats should have been error checked by now */ @@ -3954,7 +4013,6 @@ _mesa_unpack_dudv_span_byte( struct gl_context *ctx, /* * Extract image data and convert to RGBA floats */ - assert(n <= MAX_WIDTH); extract_float_rgba(n, rgba, srcFormat, srcType, source, srcPacking->SwapBytes); @@ -3970,6 +4028,8 @@ _mesa_unpack_dudv_span_byte( struct gl_context *ctx, dst[1] = FLOAT_TO_BYTE(rgba[i][GCOMP]); dst += dstComponents; } + + free(rgba); } } @@ -3988,7 +4048,7 @@ _mesa_unpack_dudv_span_byte( struct gl_context *ctx, * transferOps - the pixel transfer operations to apply */ void -_mesa_unpack_index_span( const struct gl_context *ctx, GLuint n, +_mesa_unpack_index_span( struct gl_context *ctx, GLuint n, GLenum dstType, GLvoid *dest, GLenum srcType, const GLvoid *source, const struct gl_pixelstore_attrib *srcPacking, @@ -4026,8 +4086,12 @@ _mesa_unpack_index_span( const struct gl_context *ctx, GLuint n, /* * general solution */ - GLuint indexes[MAX_WIDTH]; - assert(n <= MAX_WIDTH); + GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint)); + + if (!indexes) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); + return; + } extract_uint_indexes(n, indexes, GL_COLOR_INDEX, srcType, source, srcPacking); @@ -4061,19 +4125,24 @@ _mesa_unpack_index_span( const struct gl_context *ctx, GLuint n, default: _mesa_problem(ctx, "bad dstType in _mesa_unpack_index_span"); } + + free(indexes); } } void -_mesa_pack_index_span( const struct gl_context *ctx, GLuint n, +_mesa_pack_index_span( struct gl_context *ctx, GLuint n, GLenum dstType, GLvoid *dest, const GLuint *source, const struct gl_pixelstore_attrib *dstPacking, GLbitfield transferOps ) { - GLuint indexes[MAX_WIDTH]; + GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint)); - ASSERT(n <= MAX_WIDTH); + if (!indexes) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing"); + return; + } transferOps &= (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT); @@ -4178,6 +4247,8 @@ _mesa_pack_index_span( const struct gl_context *ctx, GLuint n, default: _mesa_problem(ctx, "bad type in _mesa_pack_index_span"); } + + free(indexes); } @@ -4196,7 +4267,7 @@ _mesa_pack_index_span( const struct gl_context *ctx, GLuint n, * transferOps - apply offset/bias/lookup ops? */ void -_mesa_unpack_stencil_span( const struct gl_context *ctx, GLuint n, +_mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n, GLenum dstType, GLvoid *dest, GLenum srcType, const GLvoid *source, const struct gl_pixelstore_attrib *srcPacking, @@ -4240,8 +4311,12 @@ _mesa_unpack_stencil_span( const struct gl_context *ctx, GLuint n, /* * general solution */ - GLuint indexes[MAX_WIDTH]; - assert(n <= MAX_WIDTH); + GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint)); + + if (!indexes) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil unpacking"); + return; + } extract_uint_indexes(n, indexes, GL_STENCIL_INDEX, srcType, source, srcPacking); @@ -4286,18 +4361,23 @@ _mesa_unpack_stencil_span( const struct gl_context *ctx, GLuint n, default: _mesa_problem(ctx, "bad dstType in _mesa_unpack_stencil_span"); } + + free(indexes); } } void -_mesa_pack_stencil_span( const struct gl_context *ctx, GLuint n, +_mesa_pack_stencil_span( struct gl_context *ctx, GLuint n, GLenum dstType, GLvoid *dest, const GLstencil *source, const struct gl_pixelstore_attrib *dstPacking ) { - GLstencil stencil[MAX_WIDTH]; + GLstencil *stencil = (GLstencil *) malloc(n * sizeof(GLstencil)); - ASSERT(n <= MAX_WIDTH); + if (!stencil) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil packing"); + return; + } if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag) { @@ -4436,6 +4516,8 @@ _mesa_pack_stencil_span( const struct gl_context *ctx, GLuint n, default: _mesa_problem(ctx, "bad type in _mesa_pack_index_span"); } + + free(stencil); } #define DEPTH_VALUES(GLTYPE, GLTYPE2FLOAT) \ @@ -4466,12 +4548,12 @@ _mesa_pack_stencil_span( const struct gl_context *ctx, GLuint n, * (ignored for GLfloat). */ void -_mesa_unpack_depth_span( const struct gl_context *ctx, GLuint n, +_mesa_unpack_depth_span( struct gl_context *ctx, GLuint n, GLenum dstType, GLvoid *dest, GLuint depthMax, GLenum srcType, const GLvoid *source, const struct gl_pixelstore_attrib *srcPacking ) { - GLfloat depthTemp[MAX_WIDTH], *depthValues; + GLfloat *depthTemp, *depthValues; GLboolean needClamp = GL_FALSE; /* Look for special cases first. @@ -4517,6 +4599,12 @@ _mesa_unpack_depth_span( const struct gl_context *ctx, GLuint n, /* general case path follows */ + depthTemp = (GLfloat *) malloc(n * sizeof(GLfloat)); + if (!depthTemp) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); + return; + } + if (dstType == GL_FLOAT) { depthValues = (GLfloat *) dest; } @@ -4599,6 +4687,7 @@ _mesa_unpack_depth_span( const struct gl_context *ctx, GLuint n, break; default: _mesa_problem(NULL, "bad type in _mesa_unpack_depth_span()"); + free(depthTemp); return; } @@ -4658,6 +4747,8 @@ _mesa_unpack_depth_span( const struct gl_context *ctx, GLuint n, ASSERT(dstType == GL_FLOAT); /*ASSERT(depthMax == 1.0F);*/ } + + free(depthTemp); } @@ -4665,13 +4756,15 @@ _mesa_unpack_depth_span( const struct gl_context *ctx, GLuint n, * Pack an array of depth values. The values are floats in [0,1]. */ void -_mesa_pack_depth_span( const struct gl_context *ctx, GLuint n, GLvoid *dest, +_mesa_pack_depth_span( struct gl_context *ctx, GLuint n, GLvoid *dest, GLenum dstType, const GLfloat *depthSpan, const struct gl_pixelstore_attrib *dstPacking ) { - GLfloat depthCopy[MAX_WIDTH]; - - ASSERT(n <= MAX_WIDTH); + GLfloat *depthCopy = (GLfloat *) malloc(n * sizeof(GLfloat)); + if (!depthCopy) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing"); + return; + } if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) { memcpy(depthCopy, depthSpan, n * sizeof(GLfloat)); @@ -4773,6 +4866,8 @@ _mesa_pack_depth_span( const struct gl_context *ctx, GLuint n, GLvoid *dest, default: _mesa_problem(ctx, "bad type in _mesa_pack_depth_span"); } + + free(depthCopy); } @@ -4781,16 +4876,21 @@ _mesa_pack_depth_span( const struct gl_context *ctx, GLuint n, GLvoid *dest, * Pack depth and stencil values as GL_DEPTH_STENCIL/GL_UNSIGNED_INT_24_8. */ void -_mesa_pack_depth_stencil_span(const struct gl_context *ctx, GLuint n, GLuint *dest, +_mesa_pack_depth_stencil_span(struct gl_context *ctx, GLuint n, GLuint *dest, const GLfloat *depthVals, const GLstencil *stencilVals, const struct gl_pixelstore_attrib *dstPacking) { - GLfloat depthCopy[MAX_WIDTH]; - GLstencil stencilCopy[MAX_WIDTH]; + GLfloat *depthCopy = (GLfloat *) malloc(n * sizeof(GLfloat)); + GLstencil *stencilCopy = (GLstencil *) malloc(n * sizeof(GLstencil)); GLuint i; - ASSERT(n <= MAX_WIDTH); + if (!depthCopy || !stencilCopy) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing"); + free(depthCopy); + free(stencilCopy); + return; + } if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) { memcpy(depthCopy, depthVals, n * sizeof(GLfloat)); @@ -4814,6 +4914,9 @@ _mesa_pack_depth_stencil_span(const struct gl_context *ctx, GLuint n, GLuint *de if (dstPacking->SwapBytes) { _mesa_swap4(dest, n); } + + free(depthCopy); + free(stencilCopy); } diff --git a/src/mesa/main/pack.h b/src/mesa/main/pack.h index 65d3f7a0fb2..78238ea5839 100644 --- a/src/mesa/main/pack.h +++ b/src/mesa/main/pack.h @@ -90,7 +90,7 @@ _mesa_unpack_dudv_span_byte(struct gl_context *ctx, GLbitfield transferOps); extern void -_mesa_unpack_index_span(const struct gl_context *ctx, GLuint n, +_mesa_unpack_index_span(struct gl_context *ctx, GLuint n, GLenum dstType, GLvoid *dest, GLenum srcType, const GLvoid *source, const struct gl_pixelstore_attrib *srcPacking, @@ -98,39 +98,39 @@ _mesa_unpack_index_span(const struct gl_context *ctx, GLuint n, extern void -_mesa_pack_index_span(const struct gl_context *ctx, GLuint n, +_mesa_pack_index_span(struct gl_context *ctx, GLuint n, GLenum dstType, GLvoid *dest, const GLuint *source, const struct gl_pixelstore_attrib *dstPacking, GLbitfield transferOps); extern void -_mesa_unpack_stencil_span(const struct gl_context *ctx, GLuint n, +_mesa_unpack_stencil_span(struct gl_context *ctx, GLuint n, GLenum dstType, GLvoid *dest, GLenum srcType, const GLvoid *source, const struct gl_pixelstore_attrib *srcPacking, GLbitfield transferOps); extern void -_mesa_pack_stencil_span(const struct gl_context *ctx, GLuint n, +_mesa_pack_stencil_span(struct gl_context *ctx, GLuint n, GLenum dstType, GLvoid *dest, const GLstencil *source, const struct gl_pixelstore_attrib *dstPacking); extern void -_mesa_unpack_depth_span(const struct gl_context *ctx, GLuint n, +_mesa_unpack_depth_span(struct gl_context *ctx, GLuint n, GLenum dstType, GLvoid *dest, GLuint depthMax, GLenum srcType, const GLvoid *source, const struct gl_pixelstore_attrib *srcPacking); extern void -_mesa_pack_depth_span(const struct gl_context *ctx, GLuint n, GLvoid *dest, +_mesa_pack_depth_span(struct gl_context *ctx, GLuint n, GLvoid *dest, GLenum dstType, const GLfloat *depthSpan, const struct gl_pixelstore_attrib *dstPacking); extern void -_mesa_pack_depth_stencil_span(const struct gl_context *ctx, +_mesa_pack_depth_stencil_span(struct gl_context *ctx, GLuint n, GLuint *dest, const GLfloat *depthVals, const GLstencil *stencilVals, diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 030236e7350..96df58d35c2 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -95,7 +95,7 @@ _mesa_init_shader_state(struct gl_context *ctx) * are generated by the GLSL compiler. */ struct gl_shader_compiler_options options; - GLuint i; + gl_shader_type sh; memset(&options, 0, sizeof(options)); options.MaxUnrollIterations = 32; @@ -103,8 +103,8 @@ _mesa_init_shader_state(struct gl_context *ctx) /* Default pragma settings */ options.DefaultPragmas.Optimize = GL_TRUE; - for(i = 0; i < MESA_SHADER_TYPES; ++i) - memcpy(&ctx->ShaderCompilerOptions[i], &options, sizeof(options)); + for (sh = 0; sh < MESA_SHADER_TYPES; ++sh) + memcpy(&ctx->ShaderCompilerOptions[sh], &options, sizeof(options)); ctx->Shader.Flags = get_shader_flags(); } diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c index b6594cbe6f0..216bbce0032 100644 --- a/src/mesa/main/shaderobj.c +++ b/src/mesa/main/shaderobj.c @@ -291,6 +291,7 @@ _mesa_free_shader_program_data(struct gl_context *ctx, struct gl_shader_program *shProg) { GLuint i; + gl_shader_type sh; assert(shProg->Type == GL_SHADER_PROGRAM_MESA); @@ -326,10 +327,10 @@ _mesa_free_shader_program_data(struct gl_context *ctx, shProg->TransformFeedback.NumVarying = 0; - for (i = 0; i < MESA_SHADER_TYPES; i++) { - if (shProg->_LinkedShaders[i] != NULL) { - ctx->Driver.DeleteShader(ctx, shProg->_LinkedShaders[i]); - shProg->_LinkedShaders[i] = NULL; + for (sh = 0; sh < MESA_SHADER_TYPES; sh++) { + if (shProg->_LinkedShaders[sh] != NULL) { + ctx->Driver.DeleteShader(ctx, shProg->_LinkedShaders[sh]); + shProg->_LinkedShaders[sh] = NULL; } } } diff --git a/src/mesa/main/shaderobj.h b/src/mesa/main/shaderobj.h index 346a5b75175..de7c998cf0e 100644 --- a/src/mesa/main/shaderobj.h +++ b/src/mesa/main/shaderobj.h @@ -98,7 +98,7 @@ extern void _mesa_free_shader_state(struct gl_context *ctx); -static INLINE GLuint +static INLINE gl_shader_type _mesa_shader_type_to_index(GLenum v) { switch (v) { @@ -110,7 +110,7 @@ _mesa_shader_type_to_index(GLenum v) return MESA_SHADER_GEOMETRY; default: ASSERT(0 && "bad value in _mesa_shader_type_to_index()"); - return ~0; + return MESA_SHADER_TYPES; } } diff --git a/src/mesa/main/syncobj.h b/src/mesa/main/syncobj.h index f3c0046cf3d..51de9bf4809 100644 --- a/src/mesa/main/syncobj.h +++ b/src/mesa/main/syncobj.h @@ -31,9 +31,13 @@ #ifndef SYNCOBJ_H #define SYNCOBJ_H -#include "main/mtypes.h" +#include "glheader.h" +#include "mfeatures.h" +struct _glapi_table; struct dd_function_table; +struct gl_context; +struct gl_sync_object; #if FEATURE_ARB_sync diff --git a/src/mesa/main/texcompress.h b/src/mesa/main/texcompress.h index 83856429c54..19b08bbadf6 100644 --- a/src/mesa/main/texcompress.h +++ b/src/mesa/main/texcompress.h @@ -25,8 +25,11 @@ #ifndef TEXCOMPRESS_H #define TEXCOMPRESS_H -#include "mtypes.h" #include "formats.h" +#include "glheader.h" +#include "mfeatures.h" + +struct gl_context; #if _HAVE_FULL_GL diff --git a/src/mesa/main/texcompress_s3tc.h b/src/mesa/main/texcompress_s3tc.h index d0a5b186b71..74a0343b9b9 100644 --- a/src/mesa/main/texcompress_s3tc.h +++ b/src/mesa/main/texcompress_s3tc.h @@ -25,9 +25,13 @@ #ifndef TEXCOMPRESS_S3TC_H #define TEXCOMPRESS_S3TC_H -#include "main/mtypes.h" +#include "compiler.h" +#include "glheader.h" +#include "mfeatures.h" #include "texstore.h" +struct gl_context; +struct gl_texture_image; #if FEATURE_texture_s3tc diff --git a/src/mesa/main/texenvprogram.h b/src/mesa/main/texenvprogram.h index abfb916d21b..22e30a51943 100644 --- a/src/mesa/main/texenvprogram.h +++ b/src/mesa/main/texenvprogram.h @@ -27,7 +27,7 @@ #define TEXENVPROGRAM_H -#include "mtypes.h" +struct gl_context; extern struct gl_fragment_program * _mesa_get_fixed_func_fragment_program(struct gl_context *ctx); diff --git a/src/mesa/main/texformat.h b/src/mesa/main/texformat.h index 8bd15076753..3cf09213ac4 100644 --- a/src/mesa/main/texformat.h +++ b/src/mesa/main/texformat.h @@ -27,9 +27,9 @@ #define TEXFORMAT_H -#include "mtypes.h" #include "formats.h" +struct gl_context; extern gl_format _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat, diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c index 879ac529a01..c94f88e16e6 100644 --- a/src/mesa/main/texgetimage.c +++ b/src/mesa/main/texgetimage.c @@ -120,10 +120,15 @@ get_tex_depth(struct gl_context *ctx, GLuint dimensions, const GLint height = texImage->Height; const GLint depth = texImage->Depth; GLint img, row, col; + GLfloat *depthRow = (GLfloat *) malloc(width * sizeof(GLfloat)); + + if (!depthRow) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); + return; + } for (img = 0; img < depth; img++) { for (row = 0; row < height; row++) { - GLfloat depthRow[MAX_WIDTH]; void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, width, height, format, type, img, row, 0); @@ -135,6 +140,8 @@ get_tex_depth(struct gl_context *ctx, GLuint dimensions, _mesa_pack_depth_span(ctx, width, dest, type, depthRow, &ctx->Pack); } } + + free(depthRow); } @@ -244,6 +251,12 @@ get_tex_srgb(struct gl_context *ctx, GLuint dimensions, const GLint depth = texImage->Depth; const GLbitfield transferOps = 0x0; GLint img, row; + GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat)); + + if (!rgba) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); + return; + } for (img = 0; img < depth; img++) { for (row = 0; row < height; row++) { @@ -251,7 +264,6 @@ get_tex_srgb(struct gl_context *ctx, GLuint dimensions, width, height, format, type, img, row, 0); - GLfloat rgba[MAX_WIDTH][4]; GLint col; /* convert row to RGBA format */ @@ -279,6 +291,8 @@ get_tex_srgb(struct gl_context *ctx, GLuint dimensions, &ctx->Pack, transferOps); } } + + free(rgba); } @@ -314,13 +328,18 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions, */ GLbitfield transferOps = 0x0; GLint img, row; + GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat)); + + if (!rgba) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); + return; + } for (img = 0; img < depth; img++) { for (row = 0; row < height; row++) { void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, width, height, format, type, img, row, 0); - GLfloat rgba[MAX_WIDTH][4]; GLint col; GLenum dataType = _mesa_get_format_datatype(texImage->TexFormat); @@ -364,6 +383,8 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions, &ctx->Pack, transferOps); } } + + free(rgba); } diff --git a/src/mesa/main/texgetimage.h b/src/mesa/main/texgetimage.h index 81a3bbbd9a7..ef420ddabf5 100644 --- a/src/mesa/main/texgetimage.h +++ b/src/mesa/main/texgetimage.h @@ -27,7 +27,11 @@ #ifndef TEXGETIMAGE_H #define TEXGETIMAGE_H -#include "mtypes.h" +#include "glheader.h" + +struct gl_context; +struct gl_texture_image; +struct gl_texture_object; extern void _mesa_get_teximage(struct gl_context *ctx, GLenum target, GLint level, diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 060f34b7f97..c5ae63052a7 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -636,6 +636,47 @@ _mesa_is_proxy_texture(GLenum target) /** + * Return the proxy target which corresponds to the given texture target + */ +static GLenum +get_proxy_target(GLenum target) +{ + switch (target) { + case GL_TEXTURE_1D: + case GL_PROXY_TEXTURE_1D: + return GL_PROXY_TEXTURE_1D; + case GL_TEXTURE_2D: + case GL_PROXY_TEXTURE_2D: + return GL_PROXY_TEXTURE_2D; + case GL_TEXTURE_3D: + case GL_PROXY_TEXTURE_3D: + return GL_PROXY_TEXTURE_3D; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_ARB: + case GL_PROXY_TEXTURE_CUBE_MAP_ARB: + return GL_PROXY_TEXTURE_CUBE_MAP_ARB; + case GL_TEXTURE_RECTANGLE_NV: + case GL_PROXY_TEXTURE_RECTANGLE_NV: + return GL_PROXY_TEXTURE_RECTANGLE_NV; + case GL_TEXTURE_1D_ARRAY_EXT: + case GL_PROXY_TEXTURE_1D_ARRAY_EXT: + return GL_PROXY_TEXTURE_1D_ARRAY_EXT; + case GL_TEXTURE_2D_ARRAY_EXT: + case GL_PROXY_TEXTURE_2D_ARRAY_EXT: + return GL_PROXY_TEXTURE_2D_ARRAY_EXT; + default: + _mesa_problem(NULL, "unexpected target in get_proxy_target()"); + return 0; + } +} + + +/** * Get the texture object that corresponds to the target of the given * texture unit. * @@ -1178,94 +1219,110 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level, switch (target) { case GL_PROXY_TEXTURE_1D: maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); - if (width < 2 * border || width > 2 + maxSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && - width >0 && !_mesa_is_pow_two(width - 2 * border)) || - level >= ctx->Const.MaxTextureLevels) { - /* bad width or level */ + if (width < 2 * border || width > 2 + maxSize) return GL_FALSE; + if (level >= ctx->Const.MaxTextureLevels) + return GL_FALSE; + if (!ctx->Extensions.ARB_texture_non_power_of_two) { + if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) + return GL_FALSE; } return GL_TRUE; + case GL_PROXY_TEXTURE_2D: maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); - if (width < 2 * border || width > 2 + maxSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && - width > 0 && !_mesa_is_pow_two(width - 2 * border)) || - height < 2 * border || height > 2 + maxSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && - height > 0 && !_mesa_is_pow_two(height - 2 * border)) || - level >= ctx->Const.MaxTextureLevels) { - /* bad width or height or level */ + if (width < 2 * border || width > 2 + maxSize) + return GL_FALSE; + if (height < 2 * border || height > 2 + maxSize) + return GL_FALSE; + if (level >= ctx->Const.MaxTextureLevels) return GL_FALSE; + if (!ctx->Extensions.ARB_texture_non_power_of_two) { + if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) + return GL_FALSE; + if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) + return GL_FALSE; } return GL_TRUE; + case GL_PROXY_TEXTURE_3D: maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); - if (width < 2 * border || width > 2 + maxSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && - width > 0 && !_mesa_is_pow_two(width - 2 * border)) || - height < 2 * border || height > 2 + maxSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && - height > 0 && !_mesa_is_pow_two(height - 2 * border)) || - depth < 2 * border || depth > 2 + maxSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && - depth > 0 && !_mesa_is_pow_two(depth - 2 * border)) || - level >= ctx->Const.Max3DTextureLevels) { - /* bad width or height or depth or level */ + if (width < 2 * border || width > 2 + maxSize) + return GL_FALSE; + if (height < 2 * border || height > 2 + maxSize) + return GL_FALSE; + if (depth < 2 * border || depth > 2 + maxSize) return GL_FALSE; + if (level >= ctx->Const.Max3DTextureLevels) + return GL_FALSE; + if (!ctx->Extensions.ARB_texture_non_power_of_two) { + if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) + return GL_FALSE; + if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) + return GL_FALSE; + if (depth > 0 && !_mesa_is_pow_two(depth - 2 * border)) + return GL_FALSE; } return GL_TRUE; + case GL_PROXY_TEXTURE_RECTANGLE_NV: - if (width < 0 || width > ctx->Const.MaxTextureRectSize || - height < 0 || height > ctx->Const.MaxTextureRectSize || - level != 0) { - /* bad width or height or level */ + maxSize = ctx->Const.MaxTextureRectSize; + if (width < 0 || width > maxSize) + return GL_FALSE; + if (height < 0 || height > maxSize) + return GL_FALSE; + if (level != 0) return GL_FALSE; - } return GL_TRUE; + case GL_PROXY_TEXTURE_CUBE_MAP_ARB: maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1); - if (width < 2 * border || width > 2 + maxSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && - width > 0 && !_mesa_is_pow_two(width - 2 * border)) || - height < 2 * border || height > 2 + maxSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && - height > 0 && !_mesa_is_pow_two(height - 2 * border)) || - level >= ctx->Const.MaxCubeTextureLevels) { - /* bad width or height */ + if (width < 2 * border || width > 2 + maxSize) + return GL_FALSE; + if (height < 2 * border || height > 2 + maxSize) return GL_FALSE; + if (level >= ctx->Const.MaxCubeTextureLevels) + return GL_FALSE; + if (!ctx->Extensions.ARB_texture_non_power_of_two) { + if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) + return GL_FALSE; + if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) + return GL_FALSE; } return GL_TRUE; + case GL_PROXY_TEXTURE_1D_ARRAY_EXT: maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); - if (width < 2 * border || width > 2 + maxSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && - width > 0 && !_mesa_is_pow_two(width - 2 * border)) || - level >= ctx->Const.MaxTextureLevels) { - /* bad width or level */ + if (width < 2 * border || width > 2 + maxSize) return GL_FALSE; - } - - if (height < 1 || height > ctx->Const.MaxArrayTextureLayers) { + if (height < 1 || height > ctx->Const.MaxArrayTextureLayers) + return GL_FALSE; + if (level >= ctx->Const.MaxTextureLevels) return GL_FALSE; + if (!ctx->Extensions.ARB_texture_non_power_of_two) { + if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) + return GL_FALSE; } return GL_TRUE; + case GL_PROXY_TEXTURE_2D_ARRAY_EXT: maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); - if (width < 2 * border || width > 2 + maxSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && - width > 0 && !_mesa_is_pow_two(width - 2 * border)) || - height < 2 * border || height > 2 + maxSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && - height > 0 && !_mesa_is_pow_two(height - 2 * border)) || - level >= ctx->Const.MaxTextureLevels) { - /* bad width or height or level */ + if (width < 2 * border || width > 2 + maxSize) return GL_FALSE; - } - if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers) { + if (height < 2 * border || height > 2 + maxSize) + return GL_FALSE; + if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers) + return GL_FALSE; + if (level >= ctx->Const.MaxTextureLevels) return GL_FALSE; + if (!ctx->Extensions.ARB_texture_non_power_of_two) { + if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) + return GL_FALSE; + if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) + return GL_FALSE; } return GL_TRUE; + default: _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage"); return GL_FALSE; @@ -1274,15 +1331,37 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level, /** - * Helper function to determine whether a target supports compressed textures + * Check if the memory used by the texture would exceed the driver's limit. + * This lets us support a max 3D texture size of 8K (for example) but + * prevents allocating a full 8K x 8K x 8K texture. + * XXX this could be rolled into the proxy texture size test (above) but + * we don't have the actual texture internal format at that point. + */ +static GLboolean +legal_texture_size(struct gl_context *ctx, gl_format format, + GLint width, GLint height, GLint depth) +{ + uint64_t bytes = _mesa_format_image_size64(format, width, height, depth); + uint64_t mbytes = bytes / (1024 * 1024); /* convert to MB */ + return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes; +} + + + +/** + * Helper function to determine whether a target and specific compression + * format are supported. */ static GLboolean -target_can_be_compressed(struct gl_context *ctx, GLenum target) +target_can_be_compressed(const struct gl_context *ctx, GLenum target, + GLenum intFormat) { + (void) intFormat; /* not used yet */ + switch (target) { case GL_TEXTURE_2D: case GL_PROXY_TEXTURE_2D: - return GL_TRUE; + return GL_TRUE; /* true for any compressed format so far */ case GL_PROXY_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: @@ -1301,6 +1380,109 @@ target_can_be_compressed(struct gl_context *ctx, GLenum target) /** + * Check if the given texture target value is legal for a + * glTexImage1/2/3D call. + */ +static GLboolean +legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target) +{ + switch (dims) { + case 1: + switch (target) { + case GL_TEXTURE_1D: + case GL_PROXY_TEXTURE_1D: + return GL_TRUE; + default: + return GL_FALSE; + } + case 2: + switch (target) { + case GL_TEXTURE_2D: + case GL_PROXY_TEXTURE_2D: + return GL_TRUE; + case GL_PROXY_TEXTURE_CUBE_MAP: + 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: + return ctx->Extensions.ARB_texture_cube_map; + case GL_TEXTURE_RECTANGLE_NV: + case GL_PROXY_TEXTURE_RECTANGLE_NV: + return ctx->Extensions.NV_texture_rectangle; + case GL_TEXTURE_1D_ARRAY_EXT: + case GL_PROXY_TEXTURE_1D_ARRAY_EXT: + return ctx->Extensions.MESA_texture_array; + default: + return GL_FALSE; + } + case 3: + switch (target) { + case GL_TEXTURE_3D: + case GL_PROXY_TEXTURE_3D: + return GL_TRUE; + case GL_TEXTURE_2D_ARRAY_EXT: + case GL_PROXY_TEXTURE_2D_ARRAY_EXT: + return ctx->Extensions.MESA_texture_array; + default: + return GL_FALSE; + } + default: + _mesa_problem(ctx, "invalid dims=%u in legal_teximage_target()", dims); + return GL_FALSE; + } +} + + +/** + * Check if the given texture target value is legal for a + * glTexSubImage, glCopyTexSubImage or glCopyTexImage call. + * The difference compared to legal_teximage_target() above is that + * proxy targets are not supported. + */ +static GLboolean +legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target) +{ + switch (dims) { + case 1: + return target == GL_TEXTURE_1D; + case 2: + switch (target) { + case GL_TEXTURE_2D: + return GL_TRUE; + 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: + return ctx->Extensions.ARB_texture_cube_map; + case GL_TEXTURE_RECTANGLE_NV: + return ctx->Extensions.NV_texture_rectangle; + case GL_TEXTURE_1D_ARRAY_EXT: + return ctx->Extensions.MESA_texture_array; + default: + return GL_FALSE; + } + case 3: + switch (target) { + case GL_TEXTURE_3D: + return GL_TRUE; + case GL_TEXTURE_2D_ARRAY_EXT: + return ctx->Extensions.MESA_texture_array; + default: + return GL_FALSE; + } + default: + _mesa_problem(ctx, "invalid dims=%u in legal_texsubimage_target()", + dims); + return GL_FALSE; + } +} + + +/** * Test the glTexImage[123]D() parameters for errors. * * \param ctx GL context. @@ -1329,10 +1511,10 @@ texture_error_check( struct gl_context *ctx, GLint width, GLint height, GLint depth, GLint border ) { - const GLboolean isProxy = _mesa_is_proxy_texture(target); + const GLenum proxyTarget = get_proxy_target(target); + const GLboolean isProxy = target == proxyTarget; GLboolean sizeOK = GL_TRUE; GLboolean colorFormat, indexFormat; - GLenum proxy_target; /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */ if (level < 0 || level >= MAX_TEXTURE_LEVELS) { @@ -1362,71 +1544,16 @@ texture_error_check( struct gl_context *ctx, return GL_TRUE; } - /* Check target and call ctx->Driver.TestProxyTexImage() to check the - * level, width, height and depth. - */ - if (dimensions == 1) { - if (target == GL_PROXY_TEXTURE_1D || target == GL_TEXTURE_1D) { - proxy_target = GL_PROXY_TEXTURE_1D; - height = 1; - depth = 1; - } - else { - _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" ); - return GL_TRUE; - } - } - else if (dimensions == 2) { - depth = 1; - if (target == GL_PROXY_TEXTURE_2D || target == GL_TEXTURE_2D) { - proxy_target = GL_PROXY_TEXTURE_2D; - } - else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB || - (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && - target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); - return GL_TRUE; - } - proxy_target = GL_PROXY_TEXTURE_CUBE_MAP_ARB; - sizeOK = (width == height); - } - else if (target == GL_PROXY_TEXTURE_RECTANGLE_NV || - target == GL_TEXTURE_RECTANGLE_NV) { - if (!ctx->Extensions.NV_texture_rectangle) { - _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); - return GL_TRUE; - } - proxy_target = GL_PROXY_TEXTURE_RECTANGLE_NV; - } - else if (target == GL_PROXY_TEXTURE_1D_ARRAY_EXT || - target == GL_TEXTURE_1D_ARRAY_EXT) { - proxy_target = GL_PROXY_TEXTURE_1D_ARRAY_EXT; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); - return GL_TRUE; - } - } - else if (dimensions == 3) { - if (target == GL_PROXY_TEXTURE_3D || target == GL_TEXTURE_3D) { - proxy_target = GL_PROXY_TEXTURE_3D; - } - else if (target == GL_PROXY_TEXTURE_2D_ARRAY_EXT || - target == GL_TEXTURE_2D_ARRAY_EXT) { - proxy_target = GL_PROXY_TEXTURE_2D_ARRAY_EXT; - } - else { - _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" ); - return GL_TRUE; - } - } - else { - _mesa_problem( ctx, "bad dims in texture_error_check" ); - return GL_TRUE; + /* Do this simple check before calling the TestProxyTexImage() function */ + if (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { + sizeOK = (width == height); } - sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxy_target, level, + /* + * Use the proxy texture driver hook to see if the size/level/etc are + * legal. + */ + sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level, internalFormat, format, type, width, height, depth, border); @@ -1531,9 +1658,10 @@ texture_error_check( struct gl_context *ctx, /* additional checks for compressed textures */ if (_mesa_is_compressed_format(ctx, internalFormat)) { - if (!target_can_be_compressed(ctx, target) && !isProxy) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glTexImage%dD(target)", dimensions); + if (!target_can_be_compressed(ctx, target, internalFormat)) { + if (!isProxy) + _mesa_error(ctx, GL_INVALID_ENUM, + "glTexImage%dD(target)", dimensions); return GL_TRUE; } if (border != 0) { @@ -1591,61 +1719,13 @@ subtexture_error_check( struct gl_context *ctx, GLuint dimensions, GLint width, GLint height, GLint depth, GLenum format, GLenum type ) { - /* Check target */ - if (dimensions == 1) { - if (target != GL_TEXTURE_1D) { - _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" ); - return GL_TRUE; - } - } - else if (dimensions == 2) { - if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && - target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); - return GL_TRUE; - } - } - else if (target == GL_TEXTURE_RECTANGLE_NV) { - if (!ctx->Extensions.NV_texture_rectangle) { - _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); - return GL_TRUE; - } - } - else if (target == GL_TEXTURE_1D_ARRAY_EXT) { - if (!ctx->Extensions.MESA_texture_array) { - _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); - return GL_TRUE; - } - } - else if (target != GL_TEXTURE_2D) { - _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); - return GL_TRUE; - } - } - else if (dimensions == 3) { - if (target == GL_TEXTURE_2D_ARRAY_EXT) { - if (!ctx->Extensions.MESA_texture_array) { - _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" ); - return GL_TRUE; - } - } - else if (target != GL_TEXTURE_3D) { - _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" ); - return GL_TRUE; - } - } - else { - _mesa_problem( ctx, "invalid dims in texture_error_check" ); - return GL_TRUE; - } - /* Basic level check */ if (level < 0 || level >= MAX_TEXTURE_LEVELS) { _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level); return GL_TRUE; } + /* Check for negative sizes */ if (width < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(width=%d)", dimensions, width); @@ -1732,13 +1812,6 @@ subtexture_error_check2( struct gl_context *ctx, GLuint dimensions, if (_mesa_is_format_compressed(destTex->TexFormat)) { GLuint bw, bh; - if (!target_can_be_compressed(ctx, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glTexSubImage%dD(target=%s)", dimensions, - _mesa_lookup_enum_by_nr(target)); - return GL_TRUE; - } - /* do tests which depend on compression block size */ _mesa_get_format_block_size(destTex->TexFormat, &bw, &bh); @@ -1789,10 +1862,18 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border ) { - GLenum type; + const GLenum proxyTarget = get_proxy_target(target); + const GLenum type = GL_FLOAT; GLboolean sizeOK; GLint format; + /* check target */ + if (!legal_texsubimage_target(ctx, dimensions, target)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)", + dimensions, _mesa_lookup_enum_by_nr(target)); + return GL_TRUE; + } + /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */ if (level < 0 || level >= MAX_TEXTURE_LEVELS) { _mesa_error(ctx, GL_INVALID_VALUE, @@ -1830,75 +1911,14 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, return GL_TRUE; } - /* NOTE: the format and type aren't really significant for - * TestProxyTexImage(). Only the internalformat really matters. - */ - type = GL_FLOAT; + /* Do size, level checking */ + sizeOK = (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) + ? (width == height) : 1; - /* Check target and call ctx->Driver.TestProxyTexImage() to check the - * level, width, height and depth. - */ - if (dimensions == 1) { - if (target == GL_TEXTURE_1D) { - sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_1D, - level, internalFormat, - format, type, - width, 1, 1, border); - } - else { - _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" ); - return GL_TRUE; - } - } - else if (dimensions == 2) { - if (target == GL_TEXTURE_2D) { - sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_2D, - level, internalFormat, - format, type, - width, height, 1, border); - } - else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && - target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); - return GL_TRUE; - } - sizeOK = (width == height) && - ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_CUBE_MAP_ARB, - level, internalFormat, format, type, - width, height, 1, border); - } - else if (target == GL_TEXTURE_RECTANGLE_NV) { - if (!ctx->Extensions.NV_texture_rectangle) { - _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); - return GL_TRUE; - } - sizeOK = ctx->Driver.TestProxyTexImage(ctx, - GL_PROXY_TEXTURE_RECTANGLE_NV, - level, internalFormat, - format, type, - width, height, 1, border); - } - else if (target == GL_TEXTURE_1D_ARRAY_EXT) { - if (!ctx->Extensions.MESA_texture_array) { - _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)"); - return GL_TRUE; - } - sizeOK = ctx->Driver.TestProxyTexImage(ctx, - GL_PROXY_TEXTURE_1D_ARRAY_EXT, - level, internalFormat, - format, type, - width, height, 1, border); - } - else { - _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); - return GL_TRUE; - } - } - else { - _mesa_problem(ctx, "invalid dimensions in copytexture_error_check"); - return GL_TRUE; - } + sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level, + internalFormat, format, + type, width, height, + 1, border); if (!sizeOK) { if (dimensions == 1) { @@ -1914,7 +1934,7 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, } if (_mesa_is_compressed_format(ctx, internalFormat)) { - if (!target_can_be_compressed(ctx, target)) { + if (!target_can_be_compressed(ctx, target, internalFormat)) { _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%dD(target)", dimensions); return GL_TRUE; @@ -1973,45 +1993,11 @@ copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions, } } - /* Check target */ - if (dimensions == 1) { - if (target != GL_TEXTURE_1D) { - _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" ); - return GL_TRUE; - } - } - else if (dimensions == 2) { - if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && - target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); - return GL_TRUE; - } - } - else if (target == GL_TEXTURE_RECTANGLE_NV) { - if (!ctx->Extensions.NV_texture_rectangle) { - _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); - return GL_TRUE; - } - } - else if (target == GL_TEXTURE_1D_ARRAY_EXT) { - if (!ctx->Extensions.MESA_texture_array) { - _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); - return GL_TRUE; - } - } - else if (target != GL_TEXTURE_2D) { - _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); - return GL_TRUE; - } - } - else if (dimensions == 3) { - if (((target != GL_TEXTURE_2D_ARRAY_EXT) || - (!ctx->Extensions.MESA_texture_array)) - && (target != GL_TEXTURE_3D)) { - _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" ); - return GL_TRUE; - } + /* check target (proxies not allowed) */ + if (!legal_texsubimage_target(ctx, dimensions, target)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%uD(target=%s)", + dimensions, _mesa_lookup_enum_by_nr(target)); + return GL_TRUE; } /* Check level */ @@ -2100,11 +2086,6 @@ copytexsubimage_error_check2( struct gl_context *ctx, GLuint dimensions, } if (_mesa_is_format_compressed(teximage->TexFormat)) { - if (!target_can_be_compressed(ctx, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glCopyTexSubImage%dD(target)", dimensions); - return GL_TRUE; - } /* offset must be multiple of 4 */ if ((xoffset & 3) || (yoffset & 3)) { _mesa_error(ctx, GL_INVALID_VALUE, @@ -2337,89 +2318,48 @@ _mesa_choose_texture_format(struct gl_context *ctx, } - -/* - * Called from the API. Note that width includes the border. +/** + * Common code to implement all the glTexImage1D/2D/3D functions. */ -void GLAPIENTRY -_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, - GLsizei width, GLint border, GLenum format, - GLenum type, const GLvoid *pixels ) +static void +teximage(struct gl_context *ctx, GLuint dims, + GLenum target, GLint level, GLint internalFormat, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum format, GLenum type, + const GLvoid *pixels) { - GET_CURRENT_CONTEXT(ctx); + GLboolean error; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glTexImage1D %s %d %s %d %d %s %s %p\n", + _mesa_debug(ctx, "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n", + dims, _mesa_lookup_enum_by_nr(target), level, - _mesa_lookup_enum_by_nr(internalFormat), width, border, + _mesa_lookup_enum_by_nr(internalFormat), + width, height, depth, border, _mesa_lookup_enum_by_nr(format), _mesa_lookup_enum_by_nr(type), pixels); - internalFormat = override_internal_format(internalFormat, width, 1); - - if (target == GL_TEXTURE_1D) { - /* non-proxy target */ - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; - const GLuint face = _mesa_tex_target_to_face(target); - - if (texture_error_check(ctx, 1, target, level, internalFormat, - format, type, width, 1, 1, border)) { - return; /* error was recorded */ - } - - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) - _mesa_update_state(ctx); - - texObj = _mesa_get_current_tex_object(ctx, target); - _mesa_lock_texture(ctx, texObj); - { - texImage = _mesa_get_tex_image(ctx, texObj, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); - } - else { - gl_format texFormat; - - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - - ASSERT(texImage->Data == NULL); - - texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, - internalFormat, format, - type); - - _mesa_init_teximage_fields(ctx, target, texImage, - width, 1, 1, - border, internalFormat, - texFormat); + internalFormat = override_internal_format(internalFormat, width, height); - /* Give the texture to the driver. <pixels> may be null. */ - ASSERT(ctx->Driver.TexImage1D); - ctx->Driver.TexImage1D(ctx, target, level, internalFormat, - width, border, format, type, pixels, - &ctx->Unpack, texObj, texImage); + /* target error checking */ + if (!legal_teximage_target(ctx, dims, target)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%uD(target=%s)", + dims, _mesa_lookup_enum_by_nr(target)); + return; + } - check_gen_mipmap(ctx, target, texObj, level); + /* general error checking */ + error = texture_error_check(ctx, dims, target, level, internalFormat, + format, type, width, height, depth, border); - update_fbo_texture(ctx, texObj, face, level); + if (_mesa_is_proxy_texture(target)) { + /* Proxy texture: just clear or set state depending on error checking */ + struct gl_texture_image *texImage = + _mesa_get_proxy_tex_image(ctx, target, level); - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; - } - } - _mesa_unlock_texture(ctx, texObj); - } - else if (target == GL_PROXY_TEXTURE_1D) { - /* Proxy texture: check for errors and update proxy state */ - struct gl_texture_image *texImage; - texImage = _mesa_get_proxy_tex_image(ctx, target, level); - if (texture_error_check(ctx, 1, target, level, internalFormat, - format, type, width, 1, 1, border)) { + if (error) { /* when error, clear all proxy texture image parameters */ if (texImage) clear_teximage_fields(texImage); @@ -2428,54 +2368,28 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, /* no error, set the tex image parameters */ struct gl_texture_object *texObj = _mesa_get_current_tex_object(ctx, target); - gl_format texFormat = _mesa_choose_texture_format(ctx, texObj, target, - level, + gl_format texFormat = _mesa_choose_texture_format(ctx, texObj, + target, level, internalFormat, format, type); - _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, - border, internalFormat, texFormat); + + if (legal_texture_size(ctx, texFormat, width, height, depth)) { + _mesa_init_teximage_fields(ctx, target, texImage, width, height, + depth, border, internalFormat, + texFormat); + } + else if (texImage) { + clear_teximage_fields(texImage); + } } } else { - _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" ); - return; - } -} - - -void GLAPIENTRY -_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, - GLsizei width, GLsizei height, GLint border, - GLenum format, GLenum type, - const GLvoid *pixels ) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glTexImage2D %s %d %s %d %d %d %s %s %p\n", - _mesa_lookup_enum_by_nr(target), level, - _mesa_lookup_enum_by_nr(internalFormat), width, height, - border, _mesa_lookup_enum_by_nr(format), - _mesa_lookup_enum_by_nr(type), pixels); - - internalFormat = override_internal_format(internalFormat, width, height); - - if (target == GL_TEXTURE_2D || - (ctx->Extensions.ARB_texture_cube_map && - target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && - target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) || - (ctx->Extensions.NV_texture_rectangle && - target == GL_TEXTURE_RECTANGLE_NV) || - (ctx->Extensions.MESA_texture_array && - target == GL_TEXTURE_1D_ARRAY_EXT)) { /* non-proxy target */ + const GLuint face = _mesa_tex_target_to_face(target); struct gl_texture_object *texObj; struct gl_texture_image *texImage; - const GLuint face = _mesa_tex_target_to_face(target); - if (texture_error_check(ctx, 2, target, level, internalFormat, - format, type, width, height, 1, border)) { + if (error) { return; /* error was recorded */ } @@ -2483,11 +2397,13 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, _mesa_update_state(ctx); texObj = _mesa_get_current_tex_object(ctx, target); + _mesa_lock_texture(ctx, texObj); { texImage = _mesa_get_tex_image(ctx, texObj, target, level); + if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims); } else { gl_format texFormat; @@ -2497,63 +2413,81 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, } ASSERT(texImage->Data == NULL); - texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, internalFormat, format, type); - _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, - border, internalFormat, texFormat); - - /* Give the texture to the driver. <pixels> may be null. */ - ASSERT(ctx->Driver.TexImage2D); - ctx->Driver.TexImage2D(ctx, target, level, internalFormat, - width, height, border, format, type, - pixels, &ctx->Unpack, texObj, texImage); + if (legal_texture_size(ctx, texFormat, width, height, depth)) { + _mesa_init_teximage_fields(ctx, target, texImage, + width, height, depth, + border, internalFormat, texFormat); + + /* Give the texture to the driver. <pixels> may be null. */ + ASSERT(ctx->Driver.TexImage3D); + switch (dims) { + case 1: + ctx->Driver.TexImage1D(ctx, target, level, internalFormat, + width, border, format, + type, pixels, &ctx->Unpack, texObj, + texImage); + break; + case 2: + ctx->Driver.TexImage2D(ctx, target, level, internalFormat, + width, height, border, format, + type, pixels, &ctx->Unpack, texObj, + texImage); + break; + case 3: + ctx->Driver.TexImage3D(ctx, target, level, internalFormat, + width, height, depth, border, format, + type, pixels, &ctx->Unpack, texObj, + texImage); + break; + default: + _mesa_problem(ctx, "invalid dims=%u in teximage()", dims); + } - check_gen_mipmap(ctx, target, texObj, level); + check_gen_mipmap(ctx, target, texObj, level); - update_fbo_texture(ctx, texObj, face, level); + update_fbo_texture(ctx, texObj, face, level); - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + /* state update */ + texObj->_Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + else { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims); + } } } _mesa_unlock_texture(ctx, texObj); } - else if (target == GL_PROXY_TEXTURE_2D || - (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB && - ctx->Extensions.ARB_texture_cube_map) || - (target == GL_PROXY_TEXTURE_RECTANGLE_NV && - ctx->Extensions.NV_texture_rectangle) || - (ctx->Extensions.MESA_texture_array && - target == GL_PROXY_TEXTURE_1D_ARRAY_EXT)) { - /* Proxy texture: check for errors and update proxy state */ - struct gl_texture_image *texImage; - texImage = _mesa_get_proxy_tex_image(ctx, target, level); - if (texture_error_check(ctx, 2, target, level, internalFormat, - format, type, width, height, 1, border)) { - /* when error, clear all proxy texture image parameters */ - if (texImage) - clear_teximage_fields(texImage); - } - else { - /* no error, set the tex image parameters */ - struct gl_texture_object *texObj = - _mesa_get_current_tex_object(ctx, target); - gl_format texFormat = _mesa_choose_texture_format(ctx, texObj, - target, level, - internalFormat, - format, type); - _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, - border, internalFormat, texFormat); - } - } - else { - _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" ); - return; - } +} + + +/* + * Called from the API. Note that width includes the border. + */ +void GLAPIENTRY +_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, + GLsizei width, GLint border, GLenum format, + GLenum type, const GLvoid *pixels ) +{ + GET_CURRENT_CONTEXT(ctx); + teximage(ctx, 1, target, level, internalFormat, width, 1, 1, + border, format, type, pixels); +} + + +void GLAPIENTRY +_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, + GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels ) +{ + GET_CURRENT_CONTEXT(ctx); + teximage(ctx, 2, target, level, internalFormat, width, height, 1, + border, format, type, pixels); } @@ -2568,100 +2502,8 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, const GLvoid *pixels ) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glTexImage3D %s %d %s %d %d %d %d %s %s %p\n", - _mesa_lookup_enum_by_nr(target), level, - _mesa_lookup_enum_by_nr(internalFormat), width, height, - depth, border, _mesa_lookup_enum_by_nr(format), - _mesa_lookup_enum_by_nr(type), pixels); - - internalFormat = override_internal_format(internalFormat, width, height); - - if (target == GL_TEXTURE_3D || - (ctx->Extensions.MESA_texture_array && - target == GL_TEXTURE_2D_ARRAY_EXT)) { - /* non-proxy target */ - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; - const GLuint face = _mesa_tex_target_to_face(target); - - if (texture_error_check(ctx, 3, target, level, (GLint) internalFormat, - format, type, width, height, depth, border)) { - return; /* error was recorded */ - } - - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) - _mesa_update_state(ctx); - - texObj = _mesa_get_current_tex_object(ctx, target); - _mesa_lock_texture(ctx, texObj); - { - texImage = _mesa_get_tex_image(ctx, texObj, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); - } - else { - gl_format texFormat; - - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - - ASSERT(texImage->Data == NULL); - texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, - internalFormat, format, - type); - _mesa_init_teximage_fields(ctx, target, texImage, - width, height, depth, - border, internalFormat, texFormat); - - /* Give the texture to the driver. <pixels> may be null. */ - ASSERT(ctx->Driver.TexImage3D); - ctx->Driver.TexImage3D(ctx, target, level, internalFormat, - width, height, depth, border, format, type, - pixels, &ctx->Unpack, texObj, texImage); - - check_gen_mipmap(ctx, target, texObj, level); - - update_fbo_texture(ctx, texObj, face, level); - - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; - } - } - _mesa_unlock_texture(ctx, texObj); - } - else if (target == GL_PROXY_TEXTURE_3D || - (ctx->Extensions.MESA_texture_array && - target == GL_PROXY_TEXTURE_2D_ARRAY_EXT)) { - /* Proxy texture: check for errors and update proxy state */ - struct gl_texture_image *texImage; - texImage = _mesa_get_proxy_tex_image(ctx, target, level); - if (texture_error_check(ctx, 3, target, level, internalFormat, - format, type, width, height, depth, border)) { - /* when error, clear all proxy texture image parameters */ - if (texImage) - clear_teximage_fields(texImage); - } - else { - /* no error, set the tex image parameters */ - struct gl_texture_object *texObj = - _mesa_get_current_tex_object(ctx, target); - gl_format texFormat = _mesa_choose_texture_format(ctx, texObj, - target, level, - internalFormat, - format, type); - _mesa_init_teximage_fields(ctx, target, texImage, width, height, - depth, border, internalFormat, texFormat); - } - } - else { - _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" ); - return; - } + teximage(ctx, 3, target, level, internalFormat, width, height, depth, + border, format, type, pixels); } @@ -2724,51 +2566,92 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) #endif -void GLAPIENTRY -_mesa_TexSubImage1D( GLenum target, GLint level, - GLint xoffset, GLsizei width, - GLenum format, GLenum type, - const GLvoid *pixels ) + +/** + * Implement all the glTexSubImage1/2/3D() functions. + */ +static void +texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels ) { struct gl_texture_object *texObj; struct gl_texture_image *texImage; - GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glTexSubImage1D %s %d %d %d %s %s %p\n", + _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n", + dims, _mesa_lookup_enum_by_nr(target), level, - xoffset, width, _mesa_lookup_enum_by_nr(format), + xoffset, yoffset, zoffset, width, height, depth, + _mesa_lookup_enum_by_nr(format), _mesa_lookup_enum_by_nr(type), pixels); + /* check target (proxies not allowed) */ + if (!legal_texsubimage_target(ctx, dims, target)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)", + dims, _mesa_lookup_enum_by_nr(target)); + return; + } + if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) _mesa_update_state(ctx); - if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0, - width, 1, 1, format, type)) { + if (subtexture_error_check(ctx, dims, target, level, xoffset, yoffset, zoffset, + width, height, depth, format, type)) { return; /* error was detected */ } - texObj = _mesa_get_current_tex_object(ctx, target); - assert(texObj); _mesa_lock_texture(ctx, texObj); { texImage = _mesa_select_tex_image(ctx, texObj, target, level); - if (subtexture_error_check2(ctx, 1, target, level, xoffset, 0, 0, - width, 1, 1, format, type, texImage)) { + if (subtexture_error_check2(ctx, dims, target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, type, texImage)) { /* error was recorded */ } - else if (width > 0) { - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; + else if (width > 0 && height > 0 && height > 0) { + /* If we have a border, offset=-1 is legal. Bias by border width. */ + switch (dims) { + case 3: + zoffset += texImage->Border; + /* fall-through */ + case 2: + yoffset += texImage->Border; + /* fall-through */ + case 1: + xoffset += texImage->Border; + } - ASSERT(ctx->Driver.TexSubImage1D); - ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width, - format, type, pixels, &ctx->Unpack, - texObj, texImage); + switch (dims) { + case 1: + ctx->Driver.TexSubImage1D(ctx, target, level, + xoffset, width, + format, type, pixels, + &ctx->Unpack, texObj, texImage ); + break; + case 2: + ctx->Driver.TexSubImage2D(ctx, target, level, + xoffset, yoffset, width, height, + format, type, pixels, + &ctx->Unpack, texObj, texImage ); + break; + case 3: + ctx->Driver.TexSubImage3D(ctx, target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, type, pixels, + &ctx->Unpack, texObj, texImage ); + break; + default: + _mesa_problem(ctx, "unexpected dims in subteximage()"); + } check_gen_mipmap(ctx, target, texObj, level); @@ -2780,58 +2663,31 @@ _mesa_TexSubImage1D( GLenum target, GLint level, void GLAPIENTRY +_mesa_TexSubImage1D( GLenum target, GLint level, + GLint xoffset, GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels ) +{ + GET_CURRENT_CONTEXT(ctx); + texsubimage(ctx, 1, target, level, + xoffset, 0, 0, + width, 1, 1, + format, type, pixels); +} + + +void GLAPIENTRY _mesa_TexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels ) { - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glTexSubImage2D %s %d %d %d %d %d %s %s %p\n", - _mesa_lookup_enum_by_nr(target), level, - xoffset, yoffset, width, height, - _mesa_lookup_enum_by_nr(format), - _mesa_lookup_enum_by_nr(type), pixels); - - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) - _mesa_update_state(ctx); - - if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0, - width, height, 1, format, type)) { - return; /* error was detected */ - } - - texObj = _mesa_get_current_tex_object(ctx, target); - - _mesa_lock_texture(ctx, texObj); - { - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - - if (subtexture_error_check2(ctx, 2, target, level, xoffset, yoffset, 0, - width, height, 1, format, type, texImage)) { - /* error was recorded */ - } - else if (width > 0 && height >= 0) { - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; - yoffset += texImage->Border; - - ASSERT(ctx->Driver.TexSubImage2D); - ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset, - width, height, format, type, pixels, - &ctx->Unpack, texObj, texImage); - - check_gen_mipmap(ctx, target, texObj, level); - - ctx->NewState |= _NEW_TEXTURE; - } - } - _mesa_unlock_texture(ctx, texObj); + texsubimage(ctx, 2, target, level, + xoffset, yoffset, 0, + width, height, 1, + format, type, pixels); } @@ -2843,84 +2699,41 @@ _mesa_TexSubImage3D( GLenum target, GLint level, GLenum format, GLenum type, const GLvoid *pixels ) { - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glTexSubImage3D %s %d %d %d %d %d %d %d %s %s %p\n", - _mesa_lookup_enum_by_nr(target), level, - xoffset, yoffset, zoffset, width, height, depth, - _mesa_lookup_enum_by_nr(format), - _mesa_lookup_enum_by_nr(type), pixels); - - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) - _mesa_update_state(ctx); - - if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset, - width, height, depth, format, type)) { - return; /* error was detected */ - } - - texObj = _mesa_get_current_tex_object(ctx, target); - - _mesa_lock_texture(ctx, texObj); - { - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - - if (subtexture_error_check2(ctx, 3, target, level, - xoffset, yoffset, zoffset, - width, height, depth, - format, type, texImage)) { - /* error was recorded */ - } - else if (width > 0 && height > 0 && height > 0) { - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; - yoffset += texImage->Border; - zoffset += texImage->Border; - - ASSERT(ctx->Driver.TexSubImage3D); - ctx->Driver.TexSubImage3D(ctx, target, level, - xoffset, yoffset, zoffset, - width, height, depth, - format, type, pixels, - &ctx->Unpack, texObj, texImage ); - - check_gen_mipmap(ctx, target, texObj, level); - - ctx->NewState |= _NEW_TEXTURE; - } - } - _mesa_unlock_texture(ctx, texObj); + texsubimage(ctx, 3, target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, type, pixels); } -void GLAPIENTRY -_mesa_CopyTexImage1D( GLenum target, GLint level, - GLenum internalFormat, - GLint x, GLint y, - GLsizei width, GLint border ) +/** + * Implement the glCopyTexImage1/2D() functions. + */ +static void +copyteximage(struct gl_context *ctx, GLuint dims, + GLenum target, GLint level, GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, GLint border ) { struct gl_texture_object *texObj; struct gl_texture_image *texImage; const GLuint face = _mesa_tex_target_to_face(target); - GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glCopyTexImage1D %s %d %s %d %d %d %d\n", + _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n", + dims, _mesa_lookup_enum_by_nr(target), level, _mesa_lookup_enum_by_nr(internalFormat), - x, y, width, border); + x, y, width, height, border); if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); - if (copytexture_error_check(ctx, 1, target, level, internalFormat, - width, 1, border)) + if (copytexture_error_check(ctx, dims, target, level, internalFormat, + width, height, border)) return; texObj = _mesa_get_current_tex_object(ctx, target); @@ -2928,8 +2741,9 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, _mesa_lock_texture(ctx, texObj); { texImage = _mesa_get_tex_image(ctx, texObj, target, level); + if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims); } else { gl_format texFormat; @@ -2944,20 +2758,29 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, internalFormat, GL_NONE, GL_NONE); - _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, - border, internalFormat, texFormat); + if (legal_texture_size(ctx, texFormat, width, height, 1)) { + _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, + border, internalFormat, texFormat); - ASSERT(ctx->Driver.CopyTexImage1D); - ctx->Driver.CopyTexImage1D(ctx, target, level, internalFormat, - x, y, width, border); + ASSERT(ctx->Driver.CopyTexImage2D); + if (dims == 1) + ctx->Driver.CopyTexImage1D(ctx, target, level, internalFormat, + x, y, width, border); + else + ctx->Driver.CopyTexImage2D(ctx, target, level, internalFormat, + x, y, width, height, border); - check_gen_mipmap(ctx, target, texObj, level); + check_gen_mipmap(ctx, target, texObj, level); - update_fbo_texture(ctx, texObj, face, level); + update_fbo_texture(ctx, texObj, face, level); - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + /* state update */ + texObj->_Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + else { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims); + } } } _mesa_unlock_texture(ctx, texObj); @@ -2966,92 +2789,52 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, void GLAPIENTRY -_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, - GLint x, GLint y, GLsizei width, GLsizei height, - GLint border ) +_mesa_CopyTexImage1D( GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, + GLsizei width, GLint border ) { - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; - const GLuint face = _mesa_tex_target_to_face(target); GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glCopyTexImage2D %s %d %s %d %d %d %d %d\n", - _mesa_lookup_enum_by_nr(target), level, - _mesa_lookup_enum_by_nr(internalFormat), - x, y, width, height, border); - - if (ctx->NewState & NEW_COPY_TEX_STATE) - _mesa_update_state(ctx); - - if (copytexture_error_check(ctx, 2, target, level, internalFormat, - width, height, border)) - return; - - texObj = _mesa_get_current_tex_object(ctx, target); - - _mesa_lock_texture(ctx, texObj); - { - texImage = _mesa_get_tex_image(ctx, texObj, target, level); - - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); - } - else { - gl_format texFormat; - - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - - ASSERT(texImage->Data == NULL); - - texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, - internalFormat, GL_NONE, - GL_NONE); - - _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, - border, internalFormat, texFormat); + copyteximage(ctx, 1, target, level, internalFormat, x, y, width, 1, border); +} - ASSERT(ctx->Driver.CopyTexImage2D); - ctx->Driver.CopyTexImage2D(ctx, target, level, internalFormat, - x, y, width, height, border); - check_gen_mipmap(ctx, target, texObj, level); - update_fbo_texture(ctx, texObj, face, level); - - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; - } - } - _mesa_unlock_texture(ctx, texObj); +void GLAPIENTRY +_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border ) +{ + GET_CURRENT_CONTEXT(ctx); + copyteximage(ctx, 2, target, level, internalFormat, + x, y, width, height, border); } -void GLAPIENTRY -_mesa_CopyTexSubImage1D( GLenum target, GLint level, - GLint xoffset, GLint x, GLint y, GLsizei width ) + +/** + * Implementation for glCopyTexSubImage1/2/3D() functions. + */ +static void +copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height) { struct gl_texture_object *texObj; struct gl_texture_image *texImage; - GLint yoffset = 0; - GLsizei height = 1; - GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glCopyTexSubImage1D %s %d %d %d %d %d\n", + _mesa_debug(ctx, "glCopyTexSubImage%uD %s %d %d %d %d %d %d %d %d\n", + dims, _mesa_lookup_enum_by_nr(target), - level, xoffset, x, y, width); + level, xoffset, yoffset, zoffset, x, y, width, height); if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); - if (copytexsubimage_error_check1(ctx, 1, target, level)) + if (copytexsubimage_error_check1(ctx, dims, target, level)) return; texObj = _mesa_get_current_tex_object(ctx, target); @@ -3060,19 +2843,43 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, { texImage = _mesa_select_tex_image(ctx, texObj, target, level); - if (copytexsubimage_error_check2(ctx, 1, target, level, - xoffset, 0, 0, width, 1, texImage)) { - /* error was recorded */ + if (copytexsubimage_error_check2(ctx, dims, target, level, xoffset, yoffset, + zoffset, width, height, texImage)) { + /* error was recored */ } else { - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; + /* If we have a border, offset=-1 is legal. Bias by border width. */ + switch (dims) { + case 3: + zoffset += texImage->Border; + /* fall-through */ + case 2: + yoffset += texImage->Border; + /* fall-through */ + case 1: + xoffset += texImage->Border; + } if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, &width, &height)) { - ASSERT(ctx->Driver.CopyTexSubImage1D); - ctx->Driver.CopyTexSubImage1D(ctx, target, level, - xoffset, x, y, width); + switch (dims) { + case 1: + ctx->Driver.CopyTexSubImage1D(ctx, target, level, + xoffset, x, y, width); + break; + case 2: + ctx->Driver.CopyTexSubImage2D(ctx, target, level, + xoffset, yoffset, + x, y, width, height); + break; + case 3: + ctx->Driver.CopyTexSubImage3D(ctx, target, level, + xoffset, yoffset, zoffset, + x, y, width, height); + break; + default: + _mesa_problem(ctx, "bad dims in copytexsubimage()"); + } check_gen_mipmap(ctx, target, texObj, level); @@ -3084,57 +2891,24 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, } +void GLAPIENTRY +_mesa_CopyTexSubImage1D( GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width ) +{ + GET_CURRENT_CONTEXT(ctx); + copytexsubimage(ctx, 1, target, level, xoffset, 0, 0, x, y, width, 1); +} + + void GLAPIENTRY _mesa_CopyTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height ) { - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glCopyTexSubImage2D %s %d %d %d %d %d %d %d\n", - _mesa_lookup_enum_by_nr(target), - level, xoffset, yoffset, x, y, width, height); - - if (ctx->NewState & NEW_COPY_TEX_STATE) - _mesa_update_state(ctx); - - if (copytexsubimage_error_check1(ctx, 2, target, level)) - return; - - texObj = _mesa_get_current_tex_object(ctx, target); - - _mesa_lock_texture(ctx, texObj); - { - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - - if (copytexsubimage_error_check2(ctx, 2, target, level, - xoffset, yoffset, 0, - width, height, texImage)) { - /* error was recorded */ - } - else { - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; - yoffset += texImage->Border; - - if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, - &width, &height)) { - ASSERT(ctx->Driver.CopyTexSubImage2D); - ctx->Driver.CopyTexSubImage2D(ctx, target, level, xoffset, yoffset, - x, y, width, height); - - check_gen_mipmap(ctx, target, texObj, level); - - ctx->NewState |= _NEW_TEXTURE; - } - } - } - _mesa_unlock_texture(ctx, texObj); + copytexsubimage(ctx, 2, target, level, xoffset, yoffset, 0, x, y, + width, height); } @@ -3144,52 +2918,9 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ) { - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glCopyTexSubImage3D %s %d %d %d %d %d %d %d %d\n", - _mesa_lookup_enum_by_nr(target), - level, xoffset, yoffset, zoffset, x, y, width, height); - - if (ctx->NewState & NEW_COPY_TEX_STATE) - _mesa_update_state(ctx); - - if (copytexsubimage_error_check1(ctx, 3, target, level)) - return; - - texObj = _mesa_get_current_tex_object(ctx, target); - - _mesa_lock_texture(ctx, texObj); - { - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - - if (copytexsubimage_error_check2(ctx, 3, target, level, xoffset, yoffset, - zoffset, width, height, texImage)) { - /* error was recored */ - } - else { - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; - yoffset += texImage->Border; - zoffset += texImage->Border; - - if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, - &width, &height)) { - ASSERT(ctx->Driver.CopyTexSubImage3D); - ctx->Driver.CopyTexSubImage3D(ctx, target, level, - xoffset, yoffset, zoffset, - x, y, width, height); - - check_gen_mipmap(ctx, target, texObj, level); - - ctx->NewState |= _NEW_TEXTURE; - } - } - } - _mesa_unlock_texture(ctx, texObj); + copytexsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, + x, y, width, height); } @@ -3234,45 +2965,18 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize) { - GLint expectedSize, maxLevels = 0, maxTextureSize; + const GLenum proxyTarget = get_proxy_target(target); + const GLint maxLevels = _mesa_max_texture_levels(ctx, target); + GLint expectedSize; - if (dimensions == 1) { - /* 1D compressed textures not allowed */ - return GL_INVALID_ENUM; - } - else if (dimensions == 2) { - if (target == GL_PROXY_TEXTURE_2D) { - maxLevels = ctx->Const.MaxTextureLevels; - } - else if (target == GL_TEXTURE_2D) { - maxLevels = ctx->Const.MaxTextureLevels; - } - else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { - if (!ctx->Extensions.ARB_texture_cube_map) - return GL_INVALID_ENUM; /*target*/ - maxLevels = ctx->Const.MaxCubeTextureLevels; - } - else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && - target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { - if (!ctx->Extensions.ARB_texture_cube_map) - return GL_INVALID_ENUM; /*target*/ - maxLevels = ctx->Const.MaxCubeTextureLevels; - } - else { - return GL_INVALID_ENUM; /*target*/ - } - } - else if (dimensions == 3) { - /* 3D compressed textures not allowed */ - return GL_INVALID_ENUM; - } - else { - assert(0); + /* check level */ + if (level < 0 || level >= maxLevels) + return GL_INVALID_VALUE; + + if (!target_can_be_compressed(ctx, target, internalFormat)) { return GL_INVALID_ENUM; } - maxTextureSize = 1 << (maxLevels - 1); - /* This will detect any invalid internalFormat value */ if (!_mesa_is_compressed_format(ctx, internalFormat)) return GL_INVALID_ENUM; @@ -3281,47 +2985,51 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, if (_mesa_base_tex_format(ctx, internalFormat) < 0) return GL_INVALID_ENUM; + /* No compressed formats support borders at this time */ if (border != 0) return GL_INVALID_VALUE; - /* - * XXX We should probably use the proxy texture error check function here. - */ - if (width < 1 || width > maxTextureSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(width))) - return GL_INVALID_VALUE; - - if ((height < 1 || height > maxTextureSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(height))) - && dimensions > 1) - return GL_INVALID_VALUE; - - if ((depth < 1 || depth > maxTextureSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(depth))) - && dimensions > 2) - return GL_INVALID_VALUE; - /* For cube map, width must equal height */ if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB && width != height) return GL_INVALID_VALUE; - if (level < 0 || level >= maxLevels) - return GL_INVALID_VALUE; + /* check image size against compression block size */ + { + gl_format texFormat = + ctx->Driver.ChooseTextureFormat(ctx, internalFormat, + GL_NONE, GL_NONE); + GLuint bw, bh; - expectedSize = compressed_tex_size(width, height, depth, internalFormat); - if (expectedSize != imageSize) - return GL_INVALID_VALUE; + _mesa_get_format_block_size(texFormat, &bw, &bh); + if ((width > bw && width % bw > 0) || + (height > bh && height % bh > 0)) { + /* + * Per GL_ARB_texture_compression: GL_INVALID_OPERATION is + * generated [...] if any parameter combinations are not + * supported by the specific compressed internal format. + */ + return GL_INVALID_OPERATION; + } + } -#if FEATURE_EXT_texture_sRGB - if ((internalFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT || - internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT || - internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT || - internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT) - && border != 0) { + /* check image sizes */ + if (!ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level, + internalFormat, GL_NONE, GL_NONE, + width, height, depth, border)) { + /* See error comment above */ return GL_INVALID_OPERATION; } -#endif + + /* check image size in bytes */ + expectedSize = compressed_tex_size(width, height, depth, internalFormat); + if (expectedSize != imageSize) { + /* Per GL_ARB_texture_compression: GL_INVALID_VALUE is generated [...] + * if <imageSize> is not consistent with the format, dimensions, and + * contents of the specified image. + */ + return GL_INVALID_VALUE; + } return GL_NO_ERROR; } @@ -3463,159 +3171,101 @@ compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims, } - -void GLAPIENTRY -_mesa_CompressedTexImage1DARB(GLenum target, GLint level, - GLenum internalFormat, GLsizei width, - GLint border, GLsizei imageSize, - const GLvoid *data) +/** + * Implementation of the glCompressedTexImage1/2/3D() functions. + */ +static void +compressedteximage(struct gl_context *ctx, GLuint dims, + GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLsizei imageSize, const GLvoid *data) { - GET_CURRENT_CONTEXT(ctx); + GLenum error; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glCompressedTexImage1DARB %s %d %s %d %d %d %p\n", + _mesa_debug(ctx, + "glCompressedTexImage%uDARB %s %d %s %d %d %d %d %d %p\n", + dims, _mesa_lookup_enum_by_nr(target), level, _mesa_lookup_enum_by_nr(internalFormat), - width, border, imageSize, data); - - if (target == GL_TEXTURE_1D) { - /* non-proxy target */ - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; - GLenum error = compressed_texture_error_check(ctx, 1, target, level, - internalFormat, width, 1, 1, border, imageSize); - if (error) { - _mesa_error(ctx, error, "glCompressedTexImage1D"); - return; - } - - texObj = _mesa_get_current_tex_object(ctx, target); - - _mesa_lock_texture(ctx, texObj); - { - texImage = _mesa_get_tex_image(ctx, texObj, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D"); - } - else { - gl_format texFormat; - - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); - - texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, - internalFormat, GL_NONE, - GL_NONE); + width, height, depth, border, imageSize, data); - _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, - border, internalFormat, texFormat); + /* check target */ + if (!legal_teximage_target(ctx, dims, target)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage%uD(target=%s)", + dims, _mesa_lookup_enum_by_nr(target)); + return; + } - ASSERT(ctx->Driver.CompressedTexImage1D); - ctx->Driver.CompressedTexImage1D(ctx, target, level, - internalFormat, width, border, - imageSize, data, - texObj, texImage); + error = compressed_texture_error_check(ctx, dims, target, level, + internalFormat, width, height, depth, + border, imageSize); - check_gen_mipmap(ctx, target, texObj, level); +#if FEATURE_ES + /* XXX this is kind of a hack */ + if (error) { + _mesa_error(ctx, error, "glTexImage2D"); + return; + } - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; - } + if (dims == 2) { + switch (internalFormat) { + case GL_PALETTE4_RGB8_OES: + case GL_PALETTE4_RGBA8_OES: + case GL_PALETTE4_R5_G6_B5_OES: + case GL_PALETTE4_RGBA4_OES: + case GL_PALETTE4_RGB5_A1_OES: + case GL_PALETTE8_RGB8_OES: + case GL_PALETTE8_RGBA8_OES: + case GL_PALETTE8_R5_G6_B5_OES: + case GL_PALETTE8_RGBA4_OES: + case GL_PALETTE8_RGB5_A1_OES: + _mesa_cpal_compressed_teximage2d(target, level, internalFormat, + width, height, imageSize, data); + return; } - _mesa_unlock_texture(ctx, texObj); } - else if (target == GL_PROXY_TEXTURE_1D) { - /* Proxy texture: check for errors and update proxy state */ - GLenum error = compressed_texture_error_check(ctx, 1, target, level, - internalFormat, width, 1, 1, border, imageSize); +#endif + + if (_mesa_is_proxy_texture(target)) { + /* Proxy texture: just check for errors and update proxy state */ + struct gl_texture_image *texImage; + if (!error) { - ASSERT(ctx->Driver.TestProxyTexImage); - error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, - internalFormat, GL_NONE, GL_NONE, - width, 1, 1, border); - } - if (error) { - /* if error, clear all proxy texture image parameters */ - struct gl_texture_image *texImage; - texImage = _mesa_get_proxy_tex_image(ctx, target, level); - if (texImage) - clear_teximage_fields(texImage); + struct gl_texture_object *texObj = + _mesa_get_current_tex_object(ctx, target); + gl_format texFormat = + _mesa_choose_texture_format(ctx, texObj, target, level, + internalFormat, GL_NONE, GL_NONE); + if (!legal_texture_size(ctx, texFormat, width, height, depth)) { + error = GL_OUT_OF_MEMORY; + } } - else { - /* store the teximage parameters */ - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; - gl_format texFormat; - texObj = _mesa_get_current_tex_object(ctx, target); - - _mesa_lock_texture(ctx, texObj); - { - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, - internalFormat, GL_NONE, - GL_NONE); - _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, - border, internalFormat, texFormat); - } - _mesa_unlock_texture(ctx, texObj); + texImage = _mesa_get_proxy_tex_image(ctx, target, level); + if (texImage) { + if (error) { + /* if error, clear all proxy texture image parameters */ + clear_teximage_fields(texImage); + } + else { + /* no error: store the teximage parameters */ + _mesa_init_teximage_fields(ctx, target, texImage, width, height, + depth, border, internalFormat, + MESA_FORMAT_NONE); + } } } else { - _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1D(target)"); - return; - } -} - -void GLAPIENTRY -_mesa_CompressedTexImage2DARB(GLenum target, GLint level, - GLenum internalFormat, GLsizei width, - GLsizei height, GLint border, GLsizei imageSize, - const GLvoid *data) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glCompressedTexImage2DARB %s %d %s %d %d %d %d %p\n", - _mesa_lookup_enum_by_nr(target), level, - _mesa_lookup_enum_by_nr(internalFormat), - width, height, border, imageSize, data); - -#if FEATURE_ES - switch (internalFormat) { - case GL_PALETTE4_RGB8_OES: - case GL_PALETTE4_RGBA8_OES: - case GL_PALETTE4_R5_G6_B5_OES: - case GL_PALETTE4_RGBA4_OES: - case GL_PALETTE4_RGB5_A1_OES: - case GL_PALETTE8_RGB8_OES: - case GL_PALETTE8_RGBA8_OES: - case GL_PALETTE8_R5_G6_B5_OES: - case GL_PALETTE8_RGBA4_OES: - case GL_PALETTE8_RGB5_A1_OES: - _mesa_cpal_compressed_teximage2d(target, level, internalFormat, - width, height, imageSize, data); - return; - } -#endif - - if (target == GL_TEXTURE_2D || - (ctx->Extensions.ARB_texture_cube_map && - target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && - target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { /* non-proxy target */ struct gl_texture_object *texObj; struct gl_texture_image *texImage; - GLenum error = compressed_texture_error_check(ctx, 2, target, level, - internalFormat, width, height, 1, border, imageSize); if (error) { - _mesa_error(ctx, error, "glCompressedTexImage2D"); + _mesa_error(ctx, error, "glCompressedTexImage%uD", dims); return; } @@ -3625,7 +3275,8 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, { texImage = _mesa_get_tex_image(ctx, texObj, target, level); if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); + _mesa_error(ctx, GL_OUT_OF_MEMORY, + "glCompressedTexImage%uD", dims); } else { gl_format texFormat; @@ -3639,67 +3290,78 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, internalFormat, GL_NONE, GL_NONE); - _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, - border, internalFormat, texFormat); - - ASSERT(ctx->Driver.CompressedTexImage2D); - ctx->Driver.CompressedTexImage2D(ctx, target, level, - internalFormat, width, height, - border, imageSize, data, - texObj, texImage); + if (legal_texture_size(ctx, texFormat, width, height, depth)) { + _mesa_init_teximage_fields(ctx, target, texImage, + width, height, depth, + border, internalFormat, texFormat); + + switch (dims) { + case 1: + ASSERT(ctx->Driver.CompressedTexImage1D); + ctx->Driver.CompressedTexImage1D(ctx, target, level, + internalFormat, + width, + border, imageSize, data, + texObj, texImage); + break; + case 2: + ASSERT(ctx->Driver.CompressedTexImage2D); + ctx->Driver.CompressedTexImage2D(ctx, target, level, + internalFormat, + width, height, + border, imageSize, data, + texObj, texImage); + break; + case 3: + ASSERT(ctx->Driver.CompressedTexImage3D); + ctx->Driver.CompressedTexImage3D(ctx, target, level, + internalFormat, + width, height, depth, + border, imageSize, data, + texObj, texImage); + break; + default: + _mesa_problem(ctx, "bad dims in compressedteximage"); + } - check_gen_mipmap(ctx, target, texObj, level); + check_gen_mipmap(ctx, target, texObj, level); - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + /* state update */ + texObj->_Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + else { + _mesa_error(ctx, GL_OUT_OF_MEMORY, + "glCompressedTexImage%uD", dims); + } } } _mesa_unlock_texture(ctx, texObj); } - else if (target == GL_PROXY_TEXTURE_2D || - (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB && - ctx->Extensions.ARB_texture_cube_map)) { - /* Proxy texture: check for errors and update proxy state */ - GLenum error = compressed_texture_error_check(ctx, 2, target, level, - internalFormat, width, height, 1, border, imageSize); - if (!error) { - ASSERT(ctx->Driver.TestProxyTexImage); - error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, - internalFormat, GL_NONE, GL_NONE, - width, height, 1, border); - } - if (error) { - /* if error, clear all proxy texture image parameters */ - struct gl_texture_image *texImage; - texImage = _mesa_get_proxy_tex_image(ctx, target, level); - if (texImage) - clear_teximage_fields(texImage); - } - else { - /* store the teximage parameters */ - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; - gl_format texFormat; +} - texObj = _mesa_get_current_tex_object(ctx, target); - _mesa_lock_texture(ctx, texObj); - { - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, - internalFormat, GL_NONE, - GL_NONE); - _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, - border, internalFormat, texFormat); - } - _mesa_unlock_texture(ctx, texObj); - } - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(target)"); - return; - } +void GLAPIENTRY +_mesa_CompressedTexImage1DARB(GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLint border, GLsizei imageSize, + const GLvoid *data) +{ + GET_CURRENT_CONTEXT(ctx); + compressedteximage(ctx, 1, target, level, internalFormat, + width, 1, 1, border, imageSize, data); +} + + +void GLAPIENTRY +_mesa_CompressedTexImage2DARB(GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize, + const GLvoid *data) +{ + GET_CURRENT_CONTEXT(ctx); + compressedteximage(ctx, 2, target, level, internalFormat, + width, height, 1, border, imageSize, data); } @@ -3710,107 +3372,8 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, GLsizei imageSize, const GLvoid *data) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glCompressedTexImage3DARB %s %d %s %d %d %d %d %d %p\n", - _mesa_lookup_enum_by_nr(target), level, - _mesa_lookup_enum_by_nr(internalFormat), - width, height, depth, border, imageSize, data); - - if (target == GL_TEXTURE_3D) { - /* non-proxy target */ - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; - GLenum error = compressed_texture_error_check(ctx, 3, target, level, - internalFormat, width, height, depth, border, imageSize); - if (error) { - _mesa_error(ctx, error, "glCompressedTexImage3D"); - return; - } - - texObj = _mesa_get_current_tex_object(ctx, target); - - _mesa_lock_texture(ctx, texObj); - { - texImage = _mesa_get_tex_image(ctx, texObj, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D"); - } - else { - gl_format texFormat; - - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); - - texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, - internalFormat, GL_NONE, - GL_NONE); - - _mesa_init_teximage_fields(ctx, target, texImage, - width, height, depth, - border, internalFormat, texFormat); - - ASSERT(ctx->Driver.CompressedTexImage3D); - ctx->Driver.CompressedTexImage3D(ctx, target, level, - internalFormat, - width, height, depth, - border, imageSize, data, - texObj, texImage); - - check_gen_mipmap(ctx, target, texObj, level); - - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; - } - } - _mesa_unlock_texture(ctx, texObj); - } - else if (target == GL_PROXY_TEXTURE_3D) { - /* Proxy texture: check for errors and update proxy state */ - GLenum error = compressed_texture_error_check(ctx, 3, target, level, - internalFormat, width, height, depth, border, imageSize); - if (!error) { - ASSERT(ctx->Driver.TestProxyTexImage); - error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, - internalFormat, GL_NONE, GL_NONE, - width, height, depth, border); - } - if (error) { - /* if error, clear all proxy texture image parameters */ - struct gl_texture_image *texImage; - texImage = _mesa_get_proxy_tex_image(ctx, target, level); - if (texImage) - clear_teximage_fields(texImage); - } - else { - /* store the teximage parameters */ - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; - gl_format texFormat; - - texObj = _mesa_get_current_tex_object(ctx, target); - - _mesa_lock_texture(ctx, texObj); - { - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, - internalFormat, GL_NONE, - GL_NONE); - _mesa_init_teximage_fields(ctx, target, texImage, width, height, - depth, border, internalFormat, - texFormat); - } - _mesa_unlock_texture(ctx, texObj); - } - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3D(target)"); - return; - } + compressedteximage(ctx, 3, target, level, internalFormat, + width, height, depth, border, imageSize, data); } diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index 72dbf10cc4b..5bc5639dbf7 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -372,15 +372,12 @@ _mesa_reference_texobj(struct gl_texture_object **ptr, /** - * Report why a texture object is incomplete. - * - * \param t texture object. - * \param why string describing why it's incomplete. - * - * \note For debug purposes only. + * Mark a texture object as incomplete. + * \param t texture object + * \param fmt... string describing why it's incomplete (for debugging). */ static void -incomplete(const struct gl_texture_object *t, const char *fmt, ...) +incomplete(struct gl_texture_object *t, const char *fmt, ...) { #if 0 va_list args; @@ -392,6 +389,7 @@ incomplete(const struct gl_texture_object *t, const char *fmt, ...) printf("Texture Obj %d incomplete because: %s\n", t->Name, s); #endif + t->_Complete = GL_FALSE; } @@ -421,14 +419,12 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, */ if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) { incomplete(t, "base level = %d is invalid", baseLevel); - t->_Complete = GL_FALSE; return; } /* Always need the base level image */ if (!t->Image[0][baseLevel]) { incomplete(t, "Image[baseLevel=%d] == NULL", baseLevel); - t->_Complete = GL_FALSE; return; } @@ -437,7 +433,6 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, t->Image[0][baseLevel]->Height == 0 || t->Image[0][baseLevel]->Depth == 0) { incomplete(t, "texture width = 0"); - t->_Complete = GL_FALSE; return; } @@ -491,7 +486,6 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, if (t->Image[face][baseLevel] == NULL || t->Image[face][baseLevel]->Width2 != w || t->Image[face][baseLevel]->Height2 != h) { - t->_Complete = GL_FALSE; incomplete(t, "Cube face missing or mismatched size"); return; } @@ -508,7 +502,6 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, GLint maxLevel = t->_MaxLevel; if (minLevel > maxLevel) { - t->_Complete = GL_FALSE; incomplete(t, "minLevel > maxLevel"); return; } @@ -517,12 +510,10 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, for (i = minLevel; i <= maxLevel; i++) { if (t->Image[0][i]) { if (t->Image[0][i]->TexFormat != t->Image[0][baseLevel]->TexFormat) { - t->_Complete = GL_FALSE; incomplete(t, "Format[i] != Format[baseLevel]"); return; } if (t->Image[0][i]->Border != t->Image[0][baseLevel]->Border) { - t->_Complete = GL_FALSE; incomplete(t, "Border[i] != Border[baseLevel]"); return; } @@ -540,12 +531,10 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, } if (i >= minLevel && i <= maxLevel) { if (!t->Image[0][i]) { - t->_Complete = GL_FALSE; incomplete(t, "1D Image[0][i] == NULL"); return; } if (t->Image[0][i]->Width2 != width ) { - t->_Complete = GL_FALSE; incomplete(t, "1D Image[0][i] bad width"); return; } @@ -569,17 +558,14 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, } if (i >= minLevel && i <= maxLevel) { if (!t->Image[0][i]) { - t->_Complete = GL_FALSE; incomplete(t, "2D Image[0][i] == NULL"); return; } if (t->Image[0][i]->Width2 != width) { - t->_Complete = GL_FALSE; incomplete(t, "2D Image[0][i] bad width"); return; } if (t->Image[0][i]->Height2 != height) { - t->_Complete = GL_FALSE; incomplete(t, "2D Image[0][i] bad height"); return; } @@ -607,26 +593,21 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, if (i >= minLevel && i <= maxLevel) { if (!t->Image[0][i]) { incomplete(t, "3D Image[0][i] == NULL"); - t->_Complete = GL_FALSE; return; } if (t->Image[0][i]->_BaseFormat == GL_DEPTH_COMPONENT) { - t->_Complete = GL_FALSE; incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex"); return; } if (t->Image[0][i]->Width2 != width) { - t->_Complete = GL_FALSE; incomplete(t, "3D Image[0][i] bad width"); return; } if (t->Image[0][i]->Height2 != height) { - t->_Complete = GL_FALSE; incomplete(t, "3D Image[0][i] bad height"); return; } if (t->Image[0][i]->Depth2 != depth) { - t->_Complete = GL_FALSE; incomplete(t, "3D Image[0][i] bad depth"); return; } @@ -652,20 +633,17 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, for (face = 0; face < 6; face++) { /* check that we have images defined */ if (!t->Image[face][i]) { - t->_Complete = GL_FALSE; incomplete(t, "CubeMap Image[n][i] == NULL"); return; } /* Don't support GL_DEPTH_COMPONENT for cube maps */ if (t->Image[face][i]->_BaseFormat == GL_DEPTH_COMPONENT) { - t->_Complete = GL_FALSE; 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 || t->Image[face][i]->Height2 != height) { - t->_Complete = GL_FALSE; incomplete(t, "CubeMap Image[n][i] bad size"); return; } @@ -688,6 +666,44 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, /** + * Check if the given cube map texture is "cube complete" as defined in + * the OpenGL specification. + */ +GLboolean +_mesa_cube_complete(const struct gl_texture_object *texObj) +{ + const GLint baseLevel = texObj->BaseLevel; + const struct gl_texture_image *img0, *img; + GLuint face; + + if (texObj->Target != GL_TEXTURE_CUBE_MAP) + return GL_FALSE; + + if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) + return GL_FALSE; + + /* check first face */ + img0 = texObj->Image[0][baseLevel]; + if (!img0 || + img0->Width < 1 || + img0->Width != img0->Height) + return GL_FALSE; + + /* check remaining faces vs. first face */ + for (face = 1; face < 6; face++) { + img = texObj->Image[face][baseLevel]; + if (!img || + img->Width != img0->Width || + img->Height != img0->Height || + img->TexFormat != img0->TexFormat) + return GL_FALSE; + } + + return GL_TRUE; +} + + +/** * Mark a texture object dirty. It forces the object to be incomplete * and optionally forces the context to re-validate its state. * diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h index 821b35caa36..2461b063efd 100644 --- a/src/mesa/main/texobj.h +++ b/src/mesa/main/texobj.h @@ -32,8 +32,9 @@ #define TEXTOBJ_H -#include "mtypes.h" +#include "glheader.h" +struct gl_context; /** * \name Internal functions @@ -68,6 +69,9 @@ extern void _mesa_test_texobj_completeness( const struct gl_context *ctx, struct gl_texture_object *obj ); +extern GLboolean +_mesa_cube_complete(const struct gl_texture_object *texObj); + extern void _mesa_dirty_texobj(struct gl_context *ctx, struct gl_texture_object *texObj, GLboolean invalidate_state); diff --git a/src/mesa/main/texrender.h b/src/mesa/main/texrender.h index 5e68fb03b57..cacd091160e 100644 --- a/src/mesa/main/texrender.h +++ b/src/mesa/main/texrender.h @@ -1,7 +1,9 @@ #ifndef TEXRENDER_H #define TEXRENDER_H -#include "mtypes.h" +struct gl_context; +struct gl_framebuffer; +struct gl_renderbuffer_attachment; extern void _mesa_render_texture(struct gl_context *ctx, diff --git a/src/mesa/main/transformfeedback.h b/src/mesa/main/transformfeedback.h index 752cd4e201f..b0d5b70f2b7 100644 --- a/src/mesa/main/transformfeedback.h +++ b/src/mesa/main/transformfeedback.h @@ -25,8 +25,13 @@ #ifndef TRANSFORM_FEEDBACK_H #define TRANSFORM_FEEDBACK_H -#include "main/mtypes.h" +#include "compiler.h" +#include "glheader.h" +#include "mfeatures.h" +struct _glapi_table; +struct dd_function_table; +struct gl_context; extern void _mesa_init_transform_feedback(struct gl_context *ctx); diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 340c3fe1d39..32bf95e3ed1 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -127,8 +127,8 @@ update_array(struct gl_context *ctx, GLsizei elementSize; GLenum format = GL_RGBA; - if (ctx->API != API_OPENGLES) { - /* fixed point arrays / data is only allowed with OpenGL ES 1.x */ + if (ctx->API != API_OPENGLES && ctx->API != API_OPENGLES2) { + /* fixed point arrays / data is only allowed with OpenGL ES 1.x/2.0 */ legalTypesMask &= ~FIXED_BIT; } @@ -297,7 +297,8 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) { GLbitfield legalTypes = (SHORT_BIT | INT_BIT | - HALF_BIT | FLOAT_BIT | DOUBLE_BIT); + HALF_BIT | FLOAT_BIT | DOUBLE_BIT | + FIXED_BIT); GET_CURRENT_CONTEXT(ctx); const GLuint unit = ctx->Array.ActiveTexture; ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h index fb96478cfc3..af9324134ec 100644 --- a/src/mesa/main/varray.h +++ b/src/mesa/main/varray.h @@ -28,7 +28,11 @@ #define VARRAY_H -#include "mtypes.h" +#include "glheader.h" +#include "mfeatures.h" + +struct gl_client_array; +struct gl_context; #if _HAVE_FULL_GL diff --git a/src/mesa/main/viewport.h b/src/mesa/main/viewport.h index ccfa37588b8..909ff92eee5 100644 --- a/src/mesa/main/viewport.h +++ b/src/mesa/main/viewport.h @@ -28,7 +28,8 @@ #define VIEWPORT_H #include "glheader.h" -#include "mtypes.h" + +struct gl_context; extern void GLAPIENTRY _mesa_Viewport(GLint x, GLint y, GLsizei width, GLsizei height); |