void GLAPIENTRY _mesa_VDPAUMapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces) { GET_CURRENT_CONTEXT(ctx); int i; if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) { _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUUnmapSurfacesNV"); return; } for (i = 0; i < numSurfaces; ++i) { struct vdp_surface *surf = (struct vdp_surface *)surfaces[i]; if (!_mesa_set_search(ctx->vdpSurfaces, surf)) { _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUSurfaceAccessNV"); return; } if (surf->state == GL_SURFACE_MAPPED_NV) { _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUSurfaceAccessNV"); return; } } for (i = 0; i < numSurfaces; ++i) { struct vdp_surface *surf = (struct vdp_surface *)surfaces[i]; unsigned numTextureNames = surf->output ? 1 : 4; unsigned j; for (j = 0; j < numTextureNames; ++j) { struct gl_texture_object *tex = surf->textures[j]; struct gl_texture_image *image; _mesa_lock_texture(ctx, tex); image = _mesa_get_tex_image(ctx, tex, surf->target, 0); if (!image) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "VDPAUMapSurfacesNV"); _mesa_unlock_texture(ctx, tex); return; } ctx->Driver.FreeTextureImageBuffer(ctx, image); ctx->Driver.VDPAUMapSurface(ctx, surf->target, surf->access, surf->output, tex, image, surf->vdpSurface, j); _mesa_unlock_texture(ctx, tex); } surf->state = GL_SURFACE_MAPPED_NV; } }
void GLAPIENTRY _mesa_GenerateMipmapEXT(GLenum target) { struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, _NEW_BUFFERS); switch (target) { case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_3D: case GL_TEXTURE_CUBE_MAP: /* OK, legal value */ break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target)"); return; } texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); /* XXX this might not handle cube maps correctly */ _mesa_lock_texture(ctx, texObj); _mesa_generate_mipmap(ctx, target, texUnit, texObj); _mesa_unlock_texture(ctx, texObj); }
void GLAPIENTRY _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img) { struct gl_texture_object *texObj; struct gl_texture_image *texImage; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (getcompressedteximage_error_check(ctx, target, level, img)) { return; } if (_mesa_is_bufferobj(ctx->Pack.BufferObj) && !img) { /* not an error, do nothing */ return; } texObj = _mesa_get_current_tex_object(ctx, target); texImage = _mesa_select_tex_image(ctx, texObj, target, level); if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) { _mesa_debug(ctx, "glGetCompressedTexImage(tex %u) format = %s, w=%d, h=%d\n", texObj->Name, _mesa_get_format_name(texImage->TexFormat), texImage->Width, texImage->Height); } _mesa_lock_texture(ctx, texObj); { ctx->Driver.GetCompressedTexImage(ctx, target, level, img, texObj, texImage); } _mesa_unlock_texture(ctx, texObj); }
static GLboolean intel_bind_renderbuffer_tex_image(struct gl_context *ctx, struct gl_renderbuffer *rb, struct gl_texture_image *image) { struct intel_renderbuffer *irb = intel_renderbuffer(rb); struct intel_texture_image *intel_image = intel_texture_image(image); struct gl_texture_object *texobj = image->TexObject; struct intel_texture_object *intel_texobj = intel_texture_object(texobj); /* We can only handle RB allocated with AllocRenderbufferStorage, or * window-system renderbuffers. */ assert(!rb->TexImage); if (!irb->mt) return false; _mesa_lock_texture(ctx, texobj); _mesa_init_teximage_fields(ctx, image, rb->Width, rb->Height, 1, 0, rb->InternalFormat, rb->Format); image->NumSamples = rb->NumSamples; intel_miptree_reference(&intel_image->mt, irb->mt); /* Immediately validate the image to the object. */ intel_miptree_reference(&intel_texobj->mt, intel_image->mt); intel_texobj->needs_validate = true; _mesa_unlock_texture(ctx, texobj); return true; }
void intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint texture_format, __DRIdrawable *dPriv) { struct gl_framebuffer *fb = dPriv->driverPrivate; struct brw_context *brw = pDRICtx->driverPrivate; struct gl_context *ctx = &brw->ctx; struct intel_renderbuffer *rb; struct gl_texture_object *texObj; struct gl_texture_image *texImage; int level = 0, internalFormat = 0; mesa_format texFormat = MESA_FORMAT_NONE; texObj = _mesa_get_current_tex_object(ctx, target); if (!texObj) return; if (dPriv->lastStamp != dPriv->dri2.stamp || !pDRICtx->driScreenPriv->dri2.useInvalidate) intel_update_renderbuffers(pDRICtx, dPriv); rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); /* If the miptree isn't set, then intel_update_renderbuffers was unable * to get the BO for the drawable from the window system. */ if (!rb || !rb->mt) return; if (rb->mt->cpp == 4) { if (texture_format == __DRI_TEXTURE_FORMAT_RGB) { internalFormat = GL_RGB; texFormat = MESA_FORMAT_B8G8R8X8_UNORM; } else { internalFormat = GL_RGBA; texFormat = MESA_FORMAT_B8G8R8A8_UNORM; } } else if (rb->mt->cpp == 2) { internalFormat = GL_RGB; texFormat = MESA_FORMAT_B5G6R5_UNORM; } _mesa_lock_texture(&brw->ctx, texObj); texImage = _mesa_get_tex_image(ctx, texObj, target, level); intel_miptree_make_shareable(brw, rb->mt); intel_set_texture_image_bo(ctx, texImage, rb->mt->bo, target, internalFormat, texFormat, 0, rb->Base.Base.Width, rb->Base.Base.Height, rb->mt->pitch, 0, 0, 0); _mesa_unlock_texture(&brw->ctx, texObj); }
void intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint texture_format, __DRIdrawable *dPriv) { struct gl_framebuffer *fb = dPriv->driverPrivate; struct intel_context *intel = pDRICtx->driverPrivate; struct gl_context *ctx = &intel->ctx; struct intel_texture_object *intelObj; struct intel_renderbuffer *rb; struct gl_texture_object *texObj; struct gl_texture_image *texImage; int level = 0, internalFormat = 0; gl_format texFormat = MESA_FORMAT_NONE; texObj = _mesa_get_current_tex_object(ctx, target); intelObj = intel_texture_object(texObj); if (!intelObj) return; if (dPriv->lastStamp != dPriv->dri2.stamp || !pDRICtx->driScreenPriv->dri2.useInvalidate) intel_update_renderbuffers(pDRICtx, dPriv); rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); /* If the region isn't set, then intel_update_renderbuffers was unable * to get the buffers for the drawable. */ if (!rb || !rb->mt) return; if (rb->mt->cpp == 4) { if (texture_format == __DRI_TEXTURE_FORMAT_RGB) { internalFormat = GL_RGB; texFormat = MESA_FORMAT_XRGB8888; } else { internalFormat = GL_RGBA; texFormat = MESA_FORMAT_ARGB8888; } } else if (rb->mt->cpp == 2) { internalFormat = GL_RGB; texFormat = MESA_FORMAT_RGB565; } _mesa_lock_texture(&intel->ctx, texObj); texImage = _mesa_get_tex_image(ctx, texObj, target, level); intel_set_texture_image_region(ctx, texImage, rb->mt->region, target, internalFormat, texFormat, 0, rb->mt->region->width, rb->mt->region->height, 0, 0); _mesa_unlock_texture(&intel->ctx, texObj); }
/** * Bind a pipe surface to a texture object. After the call, * the texture object is marked dirty and will be (re-)validated. * * If this is the first surface bound, the texture object is said to * switch from normal to surface based. It will be cleared first in * this case. * * \param ps pipe surface to be unbound * \param target texture target * \param level image level * \param format internal format of the texture */ int st_bind_texture_surface(struct pipe_surface *ps, int target, int level, enum pipe_format format) { GET_CURRENT_CONTEXT(ctx); const GLuint unit = ctx->Texture.CurrentUnit; struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; struct gl_texture_object *texObj; struct gl_texture_image *texImage; struct st_texture_object *stObj; struct st_texture_image *stImage; GLenum internalFormat; switch (target) { case ST_TEXTURE_2D: target = GL_TEXTURE_2D; break; case ST_TEXTURE_RECT: target = GL_TEXTURE_RECTANGLE_ARB; break; default: return 0; } /* map pipe format to base format for now */ if (pf_get_component_bits(format, PIPE_FORMAT_COMP_A) > 0) internalFormat = GL_RGBA; else internalFormat = GL_RGB; texObj = _mesa_select_tex_object(ctx, texUnit, target); _mesa_lock_texture(ctx, texObj); stObj = st_texture_object(texObj); /* switch to surface based */ if (!stObj->surface_based) { _mesa_clear_texture_object(ctx, texObj); stObj->surface_based = GL_TRUE; } texImage = _mesa_get_tex_image(ctx, texObj, target, level); stImage = st_texture_image(texImage); _mesa_init_teximage_fields(ctx, target, texImage, ps->width, ps->height, 1, 0, internalFormat); texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat, GL_RGBA, GL_UNSIGNED_BYTE); _mesa_set_fetch_functions(texImage, 2); pipe_texture_reference(&stImage->pt, ps->texture); _mesa_dirty_texobj(ctx, texObj, GL_TRUE); _mesa_unlock_texture(ctx, texObj); return 1; }
static bool intel_copy_texsubimage(struct brw_context *brw, struct intel_texture_image *intelImage, GLint dstx, GLint dsty, GLint slice, struct intel_renderbuffer *irb, GLint x, GLint y, GLsizei width, GLsizei height) { const GLenum internalFormat = intelImage->base.Base.InternalFormat; bool ret; /* No pixel transfer operations (zoom, bias, mapping), just a blit */ if (brw->ctx._ImageTransferState) return false; intel_prepare_render(brw); /* glCopyTexSubImage() can be called on a multisampled renderbuffer (if * that renderbuffer is associated with the window system framebuffer), * however the hardware blitter can't handle this case, so fall back to * meta (which can, since it uses ReadPixels). */ if (irb->Base.Base.NumSamples != 0) return false; /* glCopyTexSubImage() can't be called on a multisampled texture. */ assert(intelImage->base.Base.NumSamples == 0); if (!intelImage->mt || !irb || !irb->mt) { if (unlikely(INTEL_DEBUG & DEBUG_PERF)) fprintf(stderr, "%s fail %p %p (0x%08x)\n", __func__, intelImage->mt, irb, internalFormat); return false; } /* account for view parameters and face index */ int dst_level = intelImage->base.Base.Level + intelImage->base.Base.TexObject->MinLevel; int dst_slice = slice + intelImage->base.Base.Face + intelImage->base.Base.TexObject->MinLayer; _mesa_unlock_texture(&brw->ctx, intelImage->base.Base.TexObject); /* blit from src buffer to texture */ ret = intel_miptree_blit(brw, irb->mt, irb->mt_level, irb->mt_layer, x, y, irb->Base.Base.Name == 0, intelImage->mt, dst_level, dst_slice, dstx, dsty, false, width, height, GL_COPY); _mesa_lock_texture(&brw->ctx, intelImage->base.Base.TexObject); return ret; }
/** * Delete named textures. * * \param n number of textures to be deleted. * \param textures array of texture IDs to be deleted. * * \sa glDeleteTextures(). * * If we're about to delete a texture that's currently bound to any * texture unit, unbind the texture first. Decrement the reference * count on the texture object and delete it if it's zero. * Recall that texture objects can be shared among several rendering * contexts. */ void GLAPIENTRY _mesa_DeleteTextures( GLsizei n, const GLuint *textures) { GET_CURRENT_CONTEXT(ctx); GLint i; if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) _mesa_debug(ctx, "glDeleteTextures %d\n", n); FLUSH_VERTICES(ctx, 0); /* too complex */ if (!textures) return; for (i = 0; i < n; i++) { if (textures[i] > 0) { struct gl_texture_object *delObj = _mesa_lookup_texture(ctx, textures[i]); if (delObj) { _mesa_lock_texture(ctx, delObj); /* Check if texture is bound to any framebuffer objects. * If so, unbind. * See section 4.4.2.3 of GL_EXT_framebuffer_object. */ unbind_texobj_from_fbo(ctx, delObj); /* Check if this texture is currently bound to any texture units. * If so, unbind it. */ unbind_texobj_from_texunits(ctx, delObj); _mesa_unlock_texture(ctx, delObj); ctx->NewState |= _NEW_TEXTURE; /* The texture _name_ is now free for re-use. * Remove it from the hash table now. */ _glthread_LOCK_MUTEX(ctx->Shared->Mutex); _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name); _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); /* Unreference the texobj. If refcount hits zero, the texture * will be deleted. */ _mesa_reference_texobj(&delObj, NULL); } } } }
/** * This is the implementation for glGetnTexImageARB, glGetTextureImage, * and glGetTexImage. * * Requires caller to pass in texImage object because _mesa_GetTextureImage * must handle the GL_TEXTURE_CUBE_MAP target. * * \param target texture target. * \param level image level. * \param format pixel data format for returned image. * \param type pixel data type for returned image. * \param bufSize size of the pixels data buffer. * \param pixels returned pixel data. * \param dsa True when the caller is an ARB_direct_state_access function, * false otherwise */ void _mesa_get_texture_image(struct gl_context *ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage, GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *pixels, bool dsa) { assert(texObj); assert(texImage); FLUSH_VERTICES(ctx, 0); /* * Legal target checking has been moved up to GetnTexImage and * GetTextureImage so that it can be caught before receiving a NULL * texImage object and exiting. */ if (getteximage_error_check(ctx, texImage, target, level, format, type, bufSize, pixels, dsa)) { return; } if (!_mesa_is_bufferobj(ctx->Pack.BufferObj) && !pixels) { /* not an error, do nothing */ return; } if (_mesa_is_zero_size_texture(texImage)) return; if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) { _mesa_debug(ctx, "glGetTex%sImage(tex %u) format = %s, w=%d, h=%d," " dstFmt=0x%x, dstType=0x%x\n", dsa ? "ture": "", texObj->Name, _mesa_get_format_name(texImage->TexFormat), texImage->Width, texImage->Height, format, type); } _mesa_lock_texture(ctx, texObj); { ctx->Driver.GetTexImage(ctx, format, type, pixels, texImage); } _mesa_unlock_texture(ctx, texObj); }
/** * Unbind a pipe surface from a texture object. After the call, * the texture object is marked dirty and will be (re-)validated. * * \param ps pipe surface to be unbound * \param target texture target * \param level image level */ int st_unbind_texture_surface(struct pipe_surface *ps, int target, int level) { GET_CURRENT_CONTEXT(ctx); const GLuint unit = ctx->Texture.CurrentUnit; struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; struct gl_texture_object *texObj; struct gl_texture_image *texImage; struct st_texture_object *stObj; struct st_texture_image *stImage; switch (target) { case ST_TEXTURE_2D: target = GL_TEXTURE_2D; break; case ST_TEXTURE_RECT: target = GL_TEXTURE_RECTANGLE_ARB; break; default: return 0; } texObj = _mesa_select_tex_object(ctx, texUnit, target); _mesa_lock_texture(ctx, texObj); texImage = _mesa_get_tex_image(ctx, texObj, target, level); stObj = st_texture_object(texObj); stImage = st_texture_image(texImage); /* Make sure the pipe surface is still bound. The texture object is still * considered surface based even if this is the last bound surface. */ if (stImage->pt == ps->texture) { pipe_texture_reference(&stImage->pt, NULL); _mesa_clear_texture_image(ctx, texImage); _mesa_dirty_texobj(ctx, texObj, GL_TRUE); } _mesa_unlock_texture(ctx, texObj); return 1; }
/** * Delete named textures. * * \param n number of textures to be deleted. * \param textures array of texture IDs to be deleted. * * \sa glDeleteTextures(). * * If we're about to delete a texture that's currently bound to any * texture unit, unbind the texture first. Decrement the reference * count on the texture object and delete it if it's zero. * Recall that texture objects can be shared among several rendering * contexts. */ void GLAPIENTRY _mesa_DeleteTextures( GLsizei n, const GLuint *textures) { GET_CURRENT_CONTEXT(ctx); GLint i; ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */ if (!textures) return; for (i = 0; i < n; i++) { if (textures[i] > 0) { struct gl_texture_object *delObj = _mesa_lookup_texture(ctx, textures[i]); if (delObj) { _mesa_lock_texture(ctx, delObj); /* Check if this texture is currently bound to any texture units. * If so, unbind it. */ unbind_texobj_from_texunits(ctx, delObj); _mesa_unlock_texture(ctx, delObj); ctx->NewState |= _NEW_TEXTURE; /* The texture _name_ is now free for re-use. * Remove it from the hash table now. */ _glthread_LOCK_MUTEX(ctx->Shared->Mutex); _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name); _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); /* Unreference the texobj. If refcount hits zero, the texture * will be deleted. */ _mesa_reference_texobj(&delObj, NULL); } } } }
/** * Get texture image. Called by glGetTexImage. * * \param target texture target. * \param level image level. * \param format pixel data format for returned image. * \param type pixel data type for returned image. * \param bufSize size of the pixels data buffer. * \param pixels returned pixel data. */ void GLAPIENTRY _mesa_GetnTexImageARB( GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *pixels ) { struct gl_texture_object *texObj; struct gl_texture_image *texImage; GET_CURRENT_CONTEXT(ctx); FLUSH_VERTICES(ctx, 0); if (getteximage_error_check(ctx, target, level, format, type, bufSize, pixels)) { return; } if (!_mesa_is_bufferobj(ctx->Pack.BufferObj) && !pixels) { /* not an error, do nothing */ return; } texObj = _mesa_get_current_tex_object(ctx, target); texImage = _mesa_select_tex_image(ctx, texObj, target, level); if (_mesa_is_zero_size_texture(texImage)) return; if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) { _mesa_debug(ctx, "glGetTexImage(tex %u) format = %s, w=%d, h=%d," " dstFmt=0x%x, dstType=0x%x\n", texObj->Name, _mesa_get_format_name(texImage->TexFormat), texImage->Width, texImage->Height, format, type); } _mesa_lock_texture(ctx, texObj); { ctx->Driver.GetTexImage(ctx, format, type, pixels, texImage); } _mesa_unlock_texture(ctx, texObj); }
/** Implements glGetnCompressedTexImageARB, glGetCompressedTexImage, and * glGetCompressedTextureImage. * * texImage must be passed in because glGetCompressedTexImage must handle the * target GL_TEXTURE_CUBE_MAP. */ void _mesa_get_compressed_texture_image(struct gl_context *ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage, GLenum target, GLint level, GLsizei bufSize, GLvoid *pixels, bool dsa) { assert(texObj); assert(texImage); FLUSH_VERTICES(ctx, 0); if (getcompressedteximage_error_check(ctx, texImage, target, level, bufSize, pixels, dsa)) { return; } if (!_mesa_is_bufferobj(ctx->Pack.BufferObj) && !pixels) { /* not an error, do nothing */ return; } if (_mesa_is_zero_size_texture(texImage)) return; if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) { _mesa_debug(ctx, "glGetCompressedTex%sImage(tex %u) format = %s, w=%d, h=%d\n", dsa ? "ture" : "", texObj->Name, _mesa_get_format_name(texImage->TexFormat), texImage->Width, texImage->Height); } _mesa_lock_texture(ctx, texObj); { ctx->Driver.GetCompressedTexImage(ctx, texImage, pixels); } _mesa_unlock_texture(ctx, texObj); }
static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint texture_format, __DRIdrawable *dPriv) { struct dri_context *dri_ctx; int x, y, w, h; __DRIscreen *sPriv = dPriv->driScreenPriv; struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; struct swrast_texture_image *swImage; uint32_t internalFormat; gl_format texFormat; dri_ctx = pDRICtx->driverPrivate; internalFormat = (texture_format == __DRI_TEXTURE_FORMAT_RGB ? 3 : 4); texUnit = _mesa_get_current_tex_unit(&dri_ctx->Base); texObj = _mesa_select_tex_object(&dri_ctx->Base, texUnit, target); texImage = _mesa_get_tex_image(&dri_ctx->Base, texObj, target, 0); swImage = swrast_texture_image(texImage); _mesa_lock_texture(&dri_ctx->Base, texObj); sPriv->swrast_loader->getDrawableInfo(dPriv, &x, &y, &w, &h, dPriv->loaderPrivate); if (texture_format == __DRI_TEXTURE_FORMAT_RGB) texFormat = MESA_FORMAT_XRGB8888; else texFormat = MESA_FORMAT_ARGB8888; _mesa_init_teximage_fields(&dri_ctx->Base, texImage, w, h, 1, 0, internalFormat, texFormat); sPriv->swrast_loader->getImage(dPriv, x, y, w, h, (char *)swImage->Buffer, dPriv->loaderPrivate); _mesa_unlock_texture(&dri_ctx->Base, texObj); }
void GLAPIENTRY _mesa_GenerateMipmapEXT(GLenum target) { struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, _NEW_BUFFERS); switch (target) { case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_3D: case GL_TEXTURE_CUBE_MAP: /* OK, legal value */ break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target)"); return; } texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); _mesa_lock_texture(ctx, texObj); if (target == GL_TEXTURE_CUBE_MAP) { int face; for (face = 0; face < 6; face++) ctx->Driver.GenerateMipmap(ctx, GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + face, texObj); } else { ctx->Driver.GenerateMipmap(ctx, target, texObj); } _mesa_unlock_texture(ctx, texObj); }
/** * Generate all the mipmap levels below the base level. * Note: this GL function would be more useful if one could specify a * cube face, a set of array slices, etc. */ void GLAPIENTRY _mesa_GenerateMipmap(GLenum target) { struct gl_texture_image *srcImage; struct gl_texture_object *texObj; GLboolean error; GET_CURRENT_CONTEXT(ctx); FLUSH_VERTICES(ctx, 0); switch (target) { case GL_TEXTURE_1D: error = _mesa_is_gles(ctx); break; case GL_TEXTURE_2D: error = GL_FALSE; break; case GL_TEXTURE_3D: error = ctx->API == API_OPENGLES; break; case GL_TEXTURE_CUBE_MAP: error = !ctx->Extensions.ARB_texture_cube_map; break; case GL_TEXTURE_1D_ARRAY: error = _mesa_is_gles(ctx) || !ctx->Extensions.EXT_texture_array; break; case GL_TEXTURE_2D_ARRAY: error = (_mesa_is_gles(ctx) && ctx->Version < 30) || !ctx->Extensions.EXT_texture_array; break; case GL_TEXTURE_CUBE_MAP_ARRAY: error = _mesa_is_gles(ctx) || !ctx->Extensions.ARB_texture_cube_map_array; break; default: error = GL_TRUE; } if (error) { _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target=%s)", _mesa_lookup_enum_by_nr(target)); return; } texObj = _mesa_get_current_tex_object(ctx, target); if (texObj->BaseLevel >= texObj->MaxLevel) { /* nothing to do */ 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); srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel); if (!srcImage) { _mesa_unlock_texture(ctx, texObj); _mesa_error(ctx, GL_INVALID_OPERATION, "glGenerateMipmap(zero size base image)"); return; } if (_mesa_is_enum_format_integer(srcImage->InternalFormat) || _mesa_is_depthstencil_format(srcImage->InternalFormat) || _mesa_is_stencil_format(srcImage->InternalFormat)) { _mesa_unlock_texture(ctx, texObj); _mesa_error(ctx, GL_INVALID_OPERATION, "glGenerateMipmap(invalid internal format)"); return; } if (target == GL_TEXTURE_CUBE_MAP) { GLuint face; for (face = 0; face < 6; face++) ctx->Driver.GenerateMipmap(ctx, GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + face, texObj); } else { ctx->Driver.GenerateMipmap(ctx, target, texObj); } _mesa_unlock_texture(ctx, texObj); }
static GLintptr register_surface(struct gl_context *ctx, GLboolean isOutput, const GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames) { struct vdp_surface *surf; int i; if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) { _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAURegisterSurfaceNV"); return (GLintptr)NULL; } if (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE) { _mesa_error(ctx, GL_INVALID_ENUM, "VDPAURegisterSurfaceNV"); return (GLintptr)NULL; } if (target == GL_TEXTURE_RECTANGLE && !ctx->Extensions.NV_texture_rectangle) { _mesa_error(ctx, GL_INVALID_ENUM, "VDPAURegisterSurfaceNV"); return (GLintptr)NULL; } surf = CALLOC_STRUCT( vdp_surface ); if (surf == NULL) { _mesa_error_no_memory("VDPAURegisterSurfaceNV"); return (GLintptr)NULL; } surf->vdpSurface = vdpSurface; surf->target = target; surf->access = GL_READ_WRITE; surf->state = GL_SURFACE_REGISTERED_NV; surf->output = isOutput; for (i = 0; i < numTextureNames; ++i) { struct gl_texture_object *tex; tex = _mesa_lookup_texture(ctx, textureNames[i]); if (tex == NULL) { free(surf); _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAURegisterSurfaceNV(texture ID not found)"); return (GLintptr)NULL; } _mesa_lock_texture(ctx, tex); if (tex->Immutable) { _mesa_unlock_texture(ctx, tex); free(surf); _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAURegisterSurfaceNV(texture is immutable)"); return (GLintptr)NULL; } if (tex->Target == 0) tex->Target = target; else if (tex->Target != target) { _mesa_unlock_texture(ctx, tex); free(surf); _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAURegisterSurfaceNV(target mismatch)"); return (GLintptr)NULL; } /* This will disallow respecifying the storage. */ tex->Immutable = GL_TRUE; _mesa_unlock_texture(ctx, tex); _mesa_reference_texobj(&surf->textures[i], tex); } _mesa_set_add(ctx->vdpSurfaces, surf); return (GLintptr)surf; }
/** * Called via ctx->Driver.GenerateMipmap() * Note: We don't yet support 3D textures, or texture borders. */ void _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, struct gl_texture_object *texObj) { struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; struct vertex verts[4]; const GLuint baseLevel = texObj->BaseLevel; const GLuint maxLevel = texObj->MaxLevel; const GLint maxLevelSave = texObj->MaxLevel; const GLboolean genMipmapSave = texObj->GenerateMipmap; const GLboolean use_glsl_version = ctx->Extensions.ARB_vertex_shader && ctx->Extensions.ARB_fragment_shader; GLenum faceTarget; GLuint dstLevel; struct gl_sampler_object *samp_obj_save = NULL; GLint swizzle[4]; GLboolean swizzleSaved = GL_FALSE; /* GLint so the compiler won't complain about type signedness mismatch in * the calls to _mesa_texture_parameteriv below. */ static const GLint always_false = GL_FALSE; static const GLint always_true = GL_TRUE; if (fallback_required(ctx, target, texObj)) { _mesa_generate_mipmap(ctx, target, texObj); return; } if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) { faceTarget = target; target = GL_TEXTURE_CUBE_MAP; } else { faceTarget = target; } _mesa_meta_begin(ctx, MESA_META_ALL & ~MESA_META_DRAW_BUFFERS); _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); /* Choose between glsl version and fixed function version of * GenerateMipmap function. */ if (use_glsl_version) { _mesa_meta_setup_vertex_objects(ctx, &mipmap->VAO, &mipmap->buf_obj, true, 2, 4, 0); _mesa_meta_setup_blit_shader(ctx, target, false, &mipmap->shaders); } else { _mesa_meta_setup_ff_tnl_for_blit(ctx, &mipmap->VAO, &mipmap->buf_obj, 3); _mesa_set_enable(ctx, target, GL_TRUE); } _mesa_reference_sampler_object(ctx, &samp_obj_save, ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler); /* We may have been called from glGenerateTextureMipmap with CurrentUnit * still set to 0, so we don't know when we can skip binding the texture. * Assume that _mesa_BindTexture will be fast if we're rebinding the same * texture. */ _mesa_BindTexture(target, texObj->Name); if (mipmap->samp_obj == NULL) { mipmap->samp_obj = ctx->Driver.NewSamplerObject(ctx, 0xDEADBEEF); if (mipmap->samp_obj == NULL) { /* This is a bit lazy. Flag out of memory, and then don't bother to * clean up. Once out of memory is flagged, the only realistic next * move is to destroy the context. That will trigger all the right * clean up. */ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenerateMipmap"); return; } _mesa_set_sampler_filters(ctx, mipmap->samp_obj, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR); _mesa_set_sampler_wrap(ctx, mipmap->samp_obj, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); /* We don't want to encode or decode sRGB values; treat them as linear. */ _mesa_set_sampler_srgb_decode(ctx, mipmap->samp_obj, GL_SKIP_DECODE_EXT); } _mesa_bind_sampler(ctx, ctx->Texture.CurrentUnit, mipmap->samp_obj); assert(mipmap->fb != NULL); _mesa_bind_framebuffers(ctx, mipmap->fb, mipmap->fb); _mesa_texture_parameteriv(ctx, texObj, GL_GENERATE_MIPMAP, &always_false, false); if (texObj->_Swizzle != SWIZZLE_NOOP) { static const GLint swizzleNoop[4] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; memcpy(swizzle, texObj->Swizzle, sizeof(swizzle)); swizzleSaved = GL_TRUE; _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_SWIZZLE_RGBA, swizzleNoop, false); } /* Silence valgrind warnings about reading uninitialized stack. */ memset(verts, 0, sizeof(verts)); /* setup vertex positions */ verts[0].x = -1.0F; verts[0].y = -1.0F; verts[1].x = 1.0F; verts[1].y = -1.0F; verts[2].x = 1.0F; verts[2].y = 1.0F; verts[3].x = -1.0F; verts[3].y = 1.0F; /* texture is already locked, unlock now */ _mesa_unlock_texture(ctx, texObj); _mesa_prepare_mipmap_levels(ctx, texObj, baseLevel, maxLevel); for (dstLevel = baseLevel + 1; dstLevel <= maxLevel; dstLevel++) { const struct gl_texture_image *srcImage; struct gl_texture_image *dstImage; const GLuint srcLevel = dstLevel - 1; GLuint layer; GLsizei srcWidth, srcHeight, srcDepth; GLsizei dstWidth, dstHeight, dstDepth; srcImage = _mesa_select_tex_image(texObj, faceTarget, srcLevel); assert(srcImage->Border == 0); /* src size */ srcWidth = srcImage->Width; if (target == GL_TEXTURE_1D_ARRAY) { srcHeight = 1; srcDepth = srcImage->Height; } else { srcHeight = srcImage->Height; srcDepth = srcImage->Depth; } /* new dst size */ dstWidth = minify(srcWidth, 1); dstHeight = minify(srcHeight, 1); dstDepth = target == GL_TEXTURE_3D ? minify(srcDepth, 1) : srcDepth; if (dstWidth == srcWidth && dstHeight == srcHeight && dstDepth == srcDepth) { /* all done */ break; } /* Allocate storage for the destination mipmap image(s) */ /* Set MaxLevel large enough to hold the new level when we allocate it */ _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_MAX_LEVEL, (GLint *) &dstLevel, false); dstImage = _mesa_select_tex_image(texObj, faceTarget, dstLevel); /* All done. We either ran out of memory or we would go beyond the last * valid level of an immutable texture if we continued. */ if (dstImage == NULL) break; /* limit minification to src level */ _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_MAX_LEVEL, (GLint *) &srcLevel, false); /* setup viewport */ _mesa_set_viewport(ctx, 0, 0, 0, dstWidth, dstHeight); _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0); for (layer = 0; layer < dstDepth; ++layer) { /* Setup texture coordinates */ _mesa_meta_setup_texture_coords(faceTarget, layer, 0, 0, /* xoffset, yoffset */ srcWidth, srcHeight, /* img size */ srcWidth, srcHeight, srcDepth, verts[0].tex, verts[1].tex, verts[2].tex, verts[3].tex); /* upload vertex data */ _mesa_buffer_data(ctx, mipmap->buf_obj, GL_NONE, sizeof(verts), verts, GL_DYNAMIC_DRAW, __func__); _mesa_meta_framebuffer_texture_image(ctx, ctx->DrawBuffer, GL_COLOR_ATTACHMENT0, dstImage, layer); /* sanity check */ if (_mesa_check_framebuffer_status(ctx, ctx->DrawBuffer) != GL_FRAMEBUFFER_COMPLETE) { _mesa_problem(ctx, "Unexpected incomplete framebuffer in " "_mesa_meta_GenerateMipmap()"); break; } assert(dstWidth == ctx->DrawBuffer->Width); if (target == GL_TEXTURE_1D_ARRAY) { assert(dstHeight == 1); } else { assert(dstHeight == ctx->DrawBuffer->Height); } _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); } } _mesa_lock_texture(ctx, texObj); /* relock */ _mesa_bind_sampler(ctx, ctx->Texture.CurrentUnit, samp_obj_save); _mesa_reference_sampler_object(ctx, &samp_obj_save, NULL); _mesa_meta_end(ctx); _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_MAX_LEVEL, &maxLevelSave, false); if (genMipmapSave) _mesa_texture_parameteriv(ctx, texObj, GL_GENERATE_MIPMAP, &always_true, false); if (swizzleSaved) _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_SWIZZLE_RGBA, swizzle, false); }
/** * Called via ctx->Driver.GenerateMipmap() * Note: We don't yet support 3D textures, 1D/2D array textures or texture * borders. */ void _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, struct gl_texture_object *texObj) { struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; struct vertex verts[4]; const GLuint baseLevel = texObj->BaseLevel; const GLuint maxLevel = texObj->MaxLevel; const GLint maxLevelSave = texObj->MaxLevel; const GLboolean genMipmapSave = texObj->GenerateMipmap; const GLuint currentTexUnitSave = ctx->Texture.CurrentUnit; const GLboolean use_glsl_version = ctx->Extensions.ARB_vertex_shader && ctx->Extensions.ARB_fragment_shader; GLenum faceTarget; GLuint dstLevel; GLuint samplerSave; GLint swizzle[4]; GLboolean swizzleSaved = GL_FALSE; if (fallback_required(ctx, target, texObj)) { _mesa_generate_mipmap(ctx, target, texObj); return; } if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) { faceTarget = target; target = GL_TEXTURE_CUBE_MAP; } else { faceTarget = target; } _mesa_meta_begin(ctx, MESA_META_ALL & ~MESA_META_DRAW_BUFFERS); /* Choose between glsl version and fixed function version of * GenerateMipmap function. */ if (use_glsl_version) { _mesa_meta_setup_vertex_objects(&mipmap->VAO, &mipmap->VBO, true, 2, 4, 0); _mesa_meta_setup_blit_shader(ctx, target, false, &mipmap->shaders); } else { _mesa_meta_setup_ff_tnl_for_blit(&mipmap->VAO, &mipmap->VBO, 3); _mesa_set_enable(ctx, target, GL_TRUE); } samplerSave = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; if (currentTexUnitSave != 0) glBindTexture(target, texObj->Name); if (!mipmap->Sampler) { glGenSamplers(1, &mipmap->Sampler); glBindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); glSamplerParameteri(mipmap->Sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glSamplerParameteri(mipmap->Sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glSamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glSamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); /* We don't want to encode or decode sRGB values; treat them as linear. * This is not technically correct for GLES3 but we don't get any API * error at the moment. */ if (ctx->Extensions.EXT_texture_sRGB_decode) { glSamplerParameteri(mipmap->Sampler, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); } } else { glBindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); } assert(mipmap->FBO != 0); glBindFramebuffer(GL_FRAMEBUFFER, mipmap->FBO); glTexParameteri(target, GL_GENERATE_MIPMAP, GL_FALSE); // if (texObj->_Swizzle != SWIZZLE_NOOP) { // static const GLint swizzleNoop[4] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; // memcpy(swizzle, texObj->Swizzle, sizeof(swizzle)); // swizzleSaved = GL_TRUE; // glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzleNoop); // } /* Silence valgrind warnings about reading uninitialized stack. */ memset(verts, 0, sizeof(verts)); /* setup vertex positions */ verts[0].x = -1.0F; verts[0].y = -1.0F; verts[1].x = 1.0F; verts[1].y = -1.0F; verts[2].x = 1.0F; verts[2].y = 1.0F; verts[3].x = -1.0F; verts[3].y = 1.0F; /* texture is already locked, unlock now */ _mesa_unlock_texture(ctx, texObj); for (dstLevel = baseLevel + 1; dstLevel <= maxLevel; dstLevel++) { const struct gl_texture_image *srcImage; struct gl_texture_image *dstImage; const GLuint srcLevel = dstLevel - 1; GLuint layer; GLsizei srcWidth, srcHeight, srcDepth; GLsizei dstWidth, dstHeight, dstDepth; srcImage = _mesa_select_tex_image(texObj, faceTarget, srcLevel); assert(srcImage->Border == 0); /* src size */ srcWidth = srcImage->Width; if (target == GL_TEXTURE_1D_ARRAY) { srcHeight = 1; srcDepth = srcImage->Height; } else { srcHeight = srcImage->Height; srcDepth = srcImage->Depth; } /* new dst size */ dstWidth = minify(srcWidth, 1); dstHeight = minify(srcHeight, 1); // dstDepth = target == GL_TEXTURE_3D ? minify(srcDepth, 1) : srcDepth; dstDepth = srcDepth; if (dstWidth == srcWidth && dstHeight == srcHeight && dstDepth == srcDepth) { /* all done */ break; } /* Allocate storage for the destination mipmap image(s) */ /* Set MaxLevel large enough to hold the new level when we allocate it */ glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, dstLevel); if (!prepare_mipmap_level(ctx, texObj, dstLevel, dstWidth, dstHeight, dstDepth, srcImage->InternalFormat, srcImage->TexFormat)) { /* All done. We either ran out of memory or we would go beyond the * last valid level of an immutable texture if we continued. */ break; } dstImage = _mesa_select_tex_image(texObj, faceTarget, dstLevel); /* limit minification to src level */ glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel); /* setup viewport */ _mesa_set_viewport(ctx, 0, 0, 0, dstWidth, dstHeight); glDrawBuffer(GL_COLOR_ATTACHMENT0); for (layer = 0; layer < dstDepth; ++layer) { /* Setup texture coordinates */ _mesa_meta_setup_texture_coords(faceTarget, layer, 0, 0, 1, /* width, height never used here */ verts[0].tex, verts[1].tex, verts[2].tex, verts[3].tex); /* upload vertex data */ glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_DYNAMIC_DRAW); _mesa_meta_bind_fbo_image(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dstImage, layer); /* sanity check */ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { _mesa_problem(ctx, "Unexpected incomplete framebuffer in " "_mesa_meta_GenerateMipmap()"); break; } assert(dstWidth == ctx->DrawBuffer->Width); if (target == GL_TEXTURE_1D_ARRAY) { assert(dstHeight == 1); } else { assert(dstHeight == ctx->DrawBuffer->Height); } glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } } _mesa_lock_texture(ctx, texObj); /* relock */ glBindSampler(ctx->Texture.CurrentUnit, samplerSave); _mesa_meta_end(ctx); glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave); if (genMipmapSave) glTexParameteri(target, GL_GENERATE_MIPMAP, genMipmapSave); // if (swizzleSaved) // glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle); }
void GLAPIENTRY _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) { struct gl_texture_unit *texUnit; struct gl_texture_object *obj; GLboolean error = GL_FALSE; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexParameterfv(current unit)"); return; } texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; obj = _mesa_select_tex_object(ctx, texUnit, target); if (!obj) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)"); return; } _mesa_lock_texture(ctx, obj); switch (pname) { case GL_TEXTURE_MAG_FILTER: *params = ENUM_TO_FLOAT(obj->MagFilter); break; case GL_TEXTURE_MIN_FILTER: *params = ENUM_TO_FLOAT(obj->MinFilter); break; case GL_TEXTURE_WRAP_S: *params = ENUM_TO_FLOAT(obj->WrapS); break; case GL_TEXTURE_WRAP_T: *params = ENUM_TO_FLOAT(obj->WrapT); break; case GL_TEXTURE_WRAP_R: *params = ENUM_TO_FLOAT(obj->WrapR); break; case GL_TEXTURE_BORDER_COLOR: params[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F); params[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F); params[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F); params[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F); break; case GL_TEXTURE_RESIDENT: { GLboolean resident; if (ctx->Driver.IsTextureResident) resident = ctx->Driver.IsTextureResident(ctx, obj); else resident = GL_TRUE; *params = ENUM_TO_FLOAT(resident); } break; case GL_TEXTURE_PRIORITY: *params = obj->Priority; break; case GL_TEXTURE_MIN_LOD: *params = obj->MinLod; break; case GL_TEXTURE_MAX_LOD: *params = obj->MaxLod; break; case GL_TEXTURE_BASE_LEVEL: *params = (GLfloat) obj->BaseLevel; break; case GL_TEXTURE_MAX_LEVEL: *params = (GLfloat) obj->MaxLevel; break; case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (ctx->Extensions.EXT_texture_filter_anisotropic) { *params = obj->MaxAnisotropy; } else error = 1; break; case GL_TEXTURE_COMPARE_SGIX: if (ctx->Extensions.SGIX_shadow) { *params = (GLfloat) obj->CompareFlag; } else error = 1; break; case GL_TEXTURE_COMPARE_OPERATOR_SGIX: if (ctx->Extensions.SGIX_shadow) { *params = (GLfloat) obj->CompareOperator; } else error = 1; break; case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */ if (ctx->Extensions.SGIX_shadow_ambient) { *params = obj->ShadowAmbient; } else error = 1; break; case GL_GENERATE_MIPMAP_SGIS: if (ctx->Extensions.SGIS_generate_mipmap) { *params = (GLfloat) obj->GenerateMipmap; } else error = 1; break; case GL_TEXTURE_COMPARE_MODE_ARB: if (ctx->Extensions.ARB_shadow) { *params = (GLfloat) obj->CompareMode; } else error = 1; break; case GL_TEXTURE_COMPARE_FUNC_ARB: if (ctx->Extensions.ARB_shadow) { *params = (GLfloat) obj->CompareFunc; } else error = 1; break; case GL_DEPTH_TEXTURE_MODE_ARB: if (ctx->Extensions.ARB_depth_texture) { *params = (GLfloat) obj->DepthMode; } else error = 1; break; case GL_TEXTURE_LOD_BIAS: if (ctx->Extensions.EXT_texture_lod_bias) { *params = obj->LodBias; } else error = 1; break; #ifdef FEATURE_OES_draw_texture case GL_TEXTURE_CROP_RECT_OES: params[0] = obj->CropRect[0]; params[1] = obj->CropRect[1]; params[2] = obj->CropRect[2]; params[3] = obj->CropRect[3]; break; #endif default: error = 1; break; } if (error) _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", pname); _mesa_unlock_texture(ctx, obj); }
void GLAPIENTRY _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) { struct gl_texture_object *obj; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); obj = get_texobj(ctx, target, GL_TRUE); if (!obj) return; _mesa_lock_texture(ctx, obj); switch (pname) { case GL_TEXTURE_MAG_FILTER: *params = (GLint) obj->Sampler.MagFilter; break;; case GL_TEXTURE_MIN_FILTER: *params = (GLint) obj->Sampler.MinFilter; break;; case GL_TEXTURE_WRAP_S: *params = (GLint) obj->Sampler.WrapS; break;; case GL_TEXTURE_WRAP_T: *params = (GLint) obj->Sampler.WrapT; break;; case GL_TEXTURE_WRAP_R: *params = (GLint) obj->Sampler.WrapR; break;; case GL_TEXTURE_BORDER_COLOR: { GLfloat b[4]; b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F); b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F); b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F); b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F); params[0] = FLOAT_TO_INT(b[0]); params[1] = FLOAT_TO_INT(b[1]); params[2] = FLOAT_TO_INT(b[2]); params[3] = FLOAT_TO_INT(b[3]); } break;; case GL_TEXTURE_RESIDENT: *params = 1; break;; case GL_TEXTURE_PRIORITY: *params = FLOAT_TO_INT(obj->Priority); break; case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (!ctx->Extensions.EXT_texture_filter_anisotropic) goto invalid_pname; *params = (GLint) obj->Sampler.MaxAnisotropy; break; case GL_TEXTURE_IMMUTABLE_FORMAT: if (!ctx->Extensions.ARB_texture_storage) goto invalid_pname; *params = (GLint) obj->Immutable; break; default: goto invalid_pname; } /* no error if we get here */ _mesa_unlock_texture(ctx, obj); return; invalid_pname: _mesa_unlock_texture(ctx, obj); _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname); }
void GLAPIENTRY _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) { struct gl_texture_object *obj; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); obj = get_texobj(ctx, target, GL_TRUE); if (!obj) return; _mesa_lock_texture(ctx, obj); switch (pname) { case GL_TEXTURE_MAG_FILTER: *params = ENUM_TO_FLOAT(obj->Sampler.MagFilter); break; case GL_TEXTURE_MIN_FILTER: *params = ENUM_TO_FLOAT(obj->Sampler.MinFilter); break; case GL_TEXTURE_WRAP_S: *params = ENUM_TO_FLOAT(obj->Sampler.WrapS); break; case GL_TEXTURE_WRAP_T: *params = ENUM_TO_FLOAT(obj->Sampler.WrapT); break; case GL_TEXTURE_WRAP_R: *params = ENUM_TO_FLOAT(obj->Sampler.WrapR); break; case GL_TEXTURE_BORDER_COLOR: if (ctx->NewState & _NEW_BUFFERS) _mesa_update_state_locked(ctx); params[0] = obj->Sampler.BorderColor.f[0]; params[1] = obj->Sampler.BorderColor.f[1]; params[2] = obj->Sampler.BorderColor.f[2]; params[3] = obj->Sampler.BorderColor.f[3]; break; case GL_TEXTURE_RESIDENT: *params = 1.0F; break; case GL_TEXTURE_PRIORITY: *params = obj->Priority; break; case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (!ctx->Extensions.EXT_texture_filter_anisotropic) goto invalid_pname; *params = obj->Sampler.MaxAnisotropy; break; case GL_TEXTURE_IMMUTABLE_FORMAT: if (!ctx->Extensions.ARB_texture_storage) goto invalid_pname; *params = (GLfloat) obj->Immutable; break; default: goto invalid_pname; } /* no error if we get here */ _mesa_unlock_texture(ctx, obj); return; invalid_pname: _mesa_unlock_texture(ctx, obj); _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", pname); }
void GLAPIENTRY _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) { struct gl_texture_object *obj; GLboolean error = GL_FALSE; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); obj = get_texobj(ctx, target, GL_TRUE); if (!obj) return; _mesa_lock_texture(ctx, obj); switch (pname) { case GL_TEXTURE_MAG_FILTER: *params = (GLint) obj->Sampler.MagFilter; break;; case GL_TEXTURE_MIN_FILTER: *params = (GLint) obj->Sampler.MinFilter; break;; case GL_TEXTURE_WRAP_S: *params = (GLint) obj->Sampler.WrapS; break;; case GL_TEXTURE_WRAP_T: *params = (GLint) obj->Sampler.WrapT; break;; case GL_TEXTURE_WRAP_R: *params = (GLint) obj->Sampler.WrapR; break;; case GL_TEXTURE_BORDER_COLOR: { GLfloat b[4]; b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F); b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F); b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F); b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F); params[0] = FLOAT_TO_INT(b[0]); params[1] = FLOAT_TO_INT(b[1]); params[2] = FLOAT_TO_INT(b[2]); params[3] = FLOAT_TO_INT(b[3]); } break;; case GL_TEXTURE_RESIDENT: { GLboolean resident; if (ctx->Driver.IsTextureResident) resident = ctx->Driver.IsTextureResident(ctx, obj); else resident = GL_TRUE; *params = (GLint) resident; } break;; case GL_TEXTURE_PRIORITY: *params = FLOAT_TO_INT(obj->Priority); break;; case GL_TEXTURE_MIN_LOD: *params = (GLint) obj->Sampler.MinLod; break;; case GL_TEXTURE_MAX_LOD: *params = (GLint) obj->Sampler.MaxLod; break;; case GL_TEXTURE_BASE_LEVEL: *params = obj->BaseLevel; break;; case GL_TEXTURE_MAX_LEVEL: *params = obj->MaxLevel; break;; case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (ctx->Extensions.EXT_texture_filter_anisotropic) { *params = (GLint) obj->Sampler.MaxAnisotropy; } else { error = GL_TRUE; } break; case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: if (ctx->Extensions.ARB_shadow_ambient) { *params = (GLint) FLOAT_TO_INT(obj->Sampler.CompareFailValue); } else { error = GL_TRUE; } break; case GL_GENERATE_MIPMAP_SGIS: *params = (GLint) obj->GenerateMipmap; break; case GL_TEXTURE_COMPARE_MODE_ARB: if (ctx->Extensions.ARB_shadow) { *params = (GLint) obj->Sampler.CompareMode; } else { error = GL_TRUE; } break; case GL_TEXTURE_COMPARE_FUNC_ARB: if (ctx->Extensions.ARB_shadow) { *params = (GLint) obj->Sampler.CompareFunc; } else { error = GL_TRUE; } break; case GL_DEPTH_TEXTURE_MODE_ARB: if (ctx->Extensions.ARB_depth_texture) { *params = (GLint) obj->Sampler.DepthMode; } else { error = GL_TRUE; } break; case GL_TEXTURE_LOD_BIAS: if (ctx->Extensions.EXT_texture_lod_bias) { *params = (GLint) obj->Sampler.LodBias; } else { error = GL_TRUE; } break; #if FEATURE_OES_draw_texture case GL_TEXTURE_CROP_RECT_OES: params[0] = obj->CropRect[0]; params[1] = obj->CropRect[1]; params[2] = obj->CropRect[2]; params[3] = obj->CropRect[3]; break; #endif case GL_TEXTURE_SWIZZLE_R_EXT: case GL_TEXTURE_SWIZZLE_G_EXT: case GL_TEXTURE_SWIZZLE_B_EXT: case GL_TEXTURE_SWIZZLE_A_EXT: if (ctx->Extensions.EXT_texture_swizzle) { GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT; *params = obj->Swizzle[comp]; } else { error = GL_TRUE; } break; case GL_TEXTURE_SWIZZLE_RGBA_EXT: if (ctx->Extensions.EXT_texture_swizzle) { COPY_4V(params, obj->Swizzle); } else { error = GL_TRUE; } break; case GL_TEXTURE_CUBE_MAP_SEAMLESS: if (ctx->Extensions.AMD_seamless_cubemap_per_texture) { *params = (GLint) obj->Sampler.CubeMapSeamless; } else { error = GL_TRUE; } break; default: ; /* silence warnings */ } if (error) _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname); _mesa_unlock_texture(ctx, obj); }
void r300SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_format, __DRIdrawable *dPriv) { struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; struct radeon_renderbuffer *rb; radeon_texture_image *rImage; radeonContextPtr radeon; r300ContextPtr rmesa; struct radeon_framebuffer *rfb; radeonTexObjPtr t; uint32_t pitch_val; uint32_t internalFormat, type, format; type = GL_BGRA; format = GL_UNSIGNED_BYTE; internalFormat = (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT ? 3 : 4); radeon = pDRICtx->driverPrivate; rmesa = pDRICtx->driverPrivate; rfb = dPriv->driverPrivate; texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target); texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0); rImage = get_radeon_texture_image(texImage); t = radeon_tex_obj(texObj); if (t == NULL) { return; } radeon_update_renderbuffers(pDRICtx, dPriv); /* back & depth buffer are useless free them right away */ rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } rb = rfb->color_rb[0]; if (rb->bo == NULL) { /* Failed to BO for the buffer */ return; } _mesa_lock_texture(radeon->glCtx, texObj); if (t->bo) { radeon_bo_unref(t->bo); t->bo = NULL; } if (rImage->bo) { radeon_bo_unref(rImage->bo); rImage->bo = NULL; } radeon_miptree_unreference(&t->mt); radeon_miptree_unreference(&rImage->mt); _mesa_init_teximage_fields(radeon->glCtx, target, texImage, rb->base.Width, rb->base.Height, 1, 0, rb->cpp); texImage->RowStride = rb->pitch / rb->cpp; rImage->bo = rb->bo; radeon_bo_ref(rImage->bo); t->bo = rb->bo; radeon_bo_ref(t->bo); t->tile_bits = 0; t->image_override = GL_TRUE; t->override_offset = 0; t->pp_txpitch &= (1 << 13) -1; pitch_val = rb->pitch; switch (rb->cpp) { case 4: if (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT) t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8); else t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); t->pp_txfilter |= tx_table[2].filter; pitch_val /= 4; break; case 3: default: t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8); t->pp_txfilter |= tx_table[4].filter; pitch_val /= 4; break; case 2: t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5); t->pp_txfilter |= tx_table[5].filter; pitch_val /= 2; break; } pitch_val--; t->pp_txsize = (((R300_TX_WIDTHMASK_MASK & ((rb->base.Width - 1) << R300_TX_WIDTHMASK_SHIFT))) | ((R300_TX_HEIGHTMASK_MASK & ((rb->base.Height - 1) << R300_TX_HEIGHTMASK_SHIFT)))); t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN; t->pp_txpitch |= pitch_val; if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { if (rb->base.Width > 2048) t->pp_txpitch |= R500_TXWIDTH_BIT11; else t->pp_txpitch &= ~R500_TXWIDTH_BIT11; if (rb->base.Height > 2048) t->pp_txpitch |= R500_TXHEIGHT_BIT11; else t->pp_txpitch &= ~R500_TXHEIGHT_BIT11; } t->validated = GL_TRUE; _mesa_unlock_texture(radeon->glCtx, texObj); return; }
void GLAPIENTRY _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) { struct gl_texture_object *obj; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); obj = get_texobj(ctx, target, GL_TRUE); if (!obj) return; _mesa_lock_texture(ctx, obj); switch (pname) { case GL_TEXTURE_MAG_FILTER: *params = (GLint) obj->Sampler.MagFilter; break; case GL_TEXTURE_MIN_FILTER: *params = (GLint) obj->Sampler.MinFilter; break; case GL_TEXTURE_WRAP_S: *params = (GLint) obj->Sampler.WrapS; break; case GL_TEXTURE_WRAP_T: *params = (GLint) obj->Sampler.WrapT; break; case GL_TEXTURE_WRAP_R: *params = (GLint) obj->Sampler.WrapR; break; case GL_TEXTURE_BORDER_COLOR: { GLfloat b[4]; b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F); b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F); b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F); b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F); params[0] = FLOAT_TO_INT(b[0]); params[1] = FLOAT_TO_INT(b[1]); params[2] = FLOAT_TO_INT(b[2]); params[3] = FLOAT_TO_INT(b[3]); } break; case GL_TEXTURE_RESIDENT: *params = 1; break; case GL_TEXTURE_PRIORITY: *params = FLOAT_TO_INT(obj->Priority); break; case GL_TEXTURE_MIN_LOD: *params = (GLint) obj->Sampler.MinLod; break; case GL_TEXTURE_MAX_LOD: *params = (GLint) obj->Sampler.MaxLod; break; case GL_TEXTURE_BASE_LEVEL: *params = obj->BaseLevel; break; case GL_TEXTURE_MAX_LEVEL: *params = obj->MaxLevel; break; case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (!ctx->Extensions.EXT_texture_filter_anisotropic) goto invalid_pname; *params = (GLint) obj->Sampler.MaxAnisotropy; break; case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: if (!ctx->Extensions.ARB_shadow_ambient) goto invalid_pname; *params = (GLint) FLOAT_TO_INT(obj->Sampler.CompareFailValue); break; case GL_GENERATE_MIPMAP_SGIS: *params = (GLint) obj->GenerateMipmap; break; case GL_TEXTURE_COMPARE_MODE_ARB: if (!ctx->Extensions.ARB_shadow) goto invalid_pname; *params = (GLint) obj->Sampler.CompareMode; break; case GL_TEXTURE_COMPARE_FUNC_ARB: if (!ctx->Extensions.ARB_shadow) goto invalid_pname; *params = (GLint) obj->Sampler.CompareFunc; break; case GL_DEPTH_TEXTURE_MODE_ARB: if (!ctx->Extensions.ARB_depth_texture) goto invalid_pname; *params = (GLint) obj->DepthMode; break; case GL_TEXTURE_LOD_BIAS: *params = (GLint) obj->Sampler.LodBias; break; #if FEATURE_OES_draw_texture case GL_TEXTURE_CROP_RECT_OES: params[0] = obj->CropRect[0]; params[1] = obj->CropRect[1]; params[2] = obj->CropRect[2]; params[3] = obj->CropRect[3]; break; #endif case GL_TEXTURE_SWIZZLE_R_EXT: case GL_TEXTURE_SWIZZLE_G_EXT: case GL_TEXTURE_SWIZZLE_B_EXT: case GL_TEXTURE_SWIZZLE_A_EXT: if (!ctx->Extensions.EXT_texture_swizzle) goto invalid_pname; *params = obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT]; break; case GL_TEXTURE_SWIZZLE_RGBA_EXT: if (!ctx->Extensions.EXT_texture_swizzle) goto invalid_pname; COPY_4V(params, obj->Swizzle); break; case GL_TEXTURE_CUBE_MAP_SEAMLESS: if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) goto invalid_pname; *params = (GLint) obj->Sampler.CubeMapSeamless; break; case GL_TEXTURE_IMMUTABLE_FORMAT: if (!ctx->Extensions.ARB_texture_storage) goto invalid_pname; *params = (GLint) obj->Immutable; break; case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: if (!ctx->Extensions.OES_EGL_image_external) goto invalid_pname; *params = obj->RequiredTextureImageUnits; break; default: goto invalid_pname; } /* no error if we get here */ _mesa_unlock_texture(ctx, obj); return; invalid_pname: _mesa_unlock_texture(ctx, obj); _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname); }
static boolean st_context_teximage(struct st_context_iface *stctxi, enum st_texture_type tex_type, int level, enum pipe_format pipe_format, struct pipe_resource *tex, boolean mipmap) { struct st_context *st = (struct st_context *) stctxi; struct gl_context *ctx = st->ctx; struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); struct gl_texture_object *texObj; struct gl_texture_image *texImage; struct st_texture_object *stObj; struct st_texture_image *stImage; GLenum internalFormat; GLuint width, height, depth; GLenum target; switch (tex_type) { case ST_TEXTURE_1D: target = GL_TEXTURE_1D; break; case ST_TEXTURE_2D: target = GL_TEXTURE_2D; break; case ST_TEXTURE_3D: target = GL_TEXTURE_3D; break; case ST_TEXTURE_RECT: target = GL_TEXTURE_RECTANGLE_ARB; break; default: return FALSE; } texObj = _mesa_select_tex_object(ctx, texUnit, target); _mesa_lock_texture(ctx, texObj); stObj = st_texture_object(texObj); /* switch to surface based */ if (!stObj->surface_based) { _mesa_clear_texture_object(ctx, texObj); stObj->surface_based = GL_TRUE; } texImage = _mesa_get_tex_image(ctx, texObj, target, level); stImage = st_texture_image(texImage); if (tex) { gl_format texFormat = st_pipe_format_to_mesa_format(pipe_format); if (util_format_has_alpha(tex->format)) internalFormat = GL_RGBA; else internalFormat = GL_RGB; _mesa_init_teximage_fields(ctx, texImage, tex->width0, tex->height0, 1, 0, internalFormat, texFormat); width = tex->width0; height = tex->height0; depth = tex->depth0; /* grow the image size until we hit level = 0 */ while (level > 0) { if (width != 1) width <<= 1; if (height != 1) height <<= 1; if (depth != 1) depth <<= 1; level--; } } else { _mesa_clear_texture_image(ctx, texImage); width = height = depth = 0; } pipe_resource_reference(&stImage->pt, tex); stObj->width0 = width; stObj->height0 = height; stObj->depth0 = depth; stObj->surface_format = pipe_format; _mesa_dirty_texobj(ctx, texObj, GL_TRUE); _mesa_unlock_texture(ctx, texObj); return TRUE; }
void GLAPIENTRY _mesa_GetTexLevelParameteriv( GLenum target, GLint level, GLenum pname, GLint *params ) { const struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; const struct gl_texture_image *img = NULL; GLuint dimensions; GLboolean isProxy; GLint maxLevels; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexLevelParameteriv(current unit)"); return; } texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; /* this will catch bad target values */ dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */ if (dimensions == 0) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)"); return; } maxLevels = _mesa_max_texture_levels(ctx, target); if (maxLevels == 0) { /* should not happen since <target> was just checked above */ _mesa_problem(ctx, "maxLevels=0 in _mesa_GetTexLevelParameter"); return; } if (level < 0 || level >= maxLevels) { _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" ); return; } texObj = _mesa_select_tex_object(ctx, texUnit, target); _mesa_lock_texture(ctx, texObj); img = _mesa_select_tex_image(ctx, texObj, target, level); if (!img || !img->TexFormat) { /* undefined texture image */ if (pname == GL_TEXTURE_COMPONENTS) *params = 1; else *params = 0; goto out; } isProxy = _mesa_is_proxy_texture(target); switch (pname) { case GL_TEXTURE_WIDTH: *params = img->Width; break; case GL_TEXTURE_HEIGHT: *params = img->Height; break; case GL_TEXTURE_DEPTH: *params = img->Depth; break; case GL_TEXTURE_INTERNAL_FORMAT: *params = img->InternalFormat; break; case GL_TEXTURE_BORDER: *params = img->Border; break; case GL_TEXTURE_RED_SIZE: if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->RedBits; else *params = 0; break; case GL_TEXTURE_GREEN_SIZE: if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->GreenBits; else *params = 0; break; case GL_TEXTURE_BLUE_SIZE: if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->BlueBits; else *params = 0; break; case GL_TEXTURE_ALPHA_SIZE: if (img->_BaseFormat == GL_ALPHA || img->_BaseFormat == GL_LUMINANCE_ALPHA || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->AlphaBits; else *params = 0; break; case GL_TEXTURE_INTENSITY_SIZE: if (img->_BaseFormat != GL_INTENSITY) *params = 0; else if (img->TexFormat->IntensityBits > 0) *params = img->TexFormat->IntensityBits; else /* intensity probably stored as rgb texture */ *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits); break; case GL_TEXTURE_LUMINANCE_SIZE: if (img->_BaseFormat != GL_LUMINANCE && img->_BaseFormat != GL_LUMINANCE_ALPHA) *params = 0; else if (img->TexFormat->LuminanceBits > 0) *params = img->TexFormat->LuminanceBits; else /* luminance probably stored as rgb texture */ *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits); break; case GL_TEXTURE_INDEX_SIZE_EXT: if (img->_BaseFormat == GL_COLOR_INDEX) *params = img->TexFormat->IndexBits; else *params = 0; break; case GL_TEXTURE_DEPTH_SIZE_ARB: if (ctx->Extensions.ARB_depth_texture) *params = img->TexFormat->DepthBits; else _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); break; case GL_TEXTURE_STENCIL_SIZE_EXT: if (ctx->Extensions.EXT_packed_depth_stencil) { *params = img->TexFormat->StencilBits; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; /* GL_ARB_texture_compression */ case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: if (ctx->Extensions.ARB_texture_compression) { if (img->IsCompressed && !isProxy) { /* Don't use ctx->Driver.CompressedTextureSize() since that * may returned a padded hardware size. */ *params = _mesa_compressed_texture_size(ctx, img->Width, img->Height, img->Depth, img->TexFormat->MesaFormat); } else { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexLevelParameter[if]v(pname)"); } } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; case GL_TEXTURE_COMPRESSED: if (ctx->Extensions.ARB_texture_compression) { *params = (GLint) img->IsCompressed; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; /* GL_ARB_texture_float */ case GL_TEXTURE_RED_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->RedBits ? img->TexFormat->DataType : GL_NONE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; case GL_TEXTURE_GREEN_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->GreenBits ? img->TexFormat->DataType : GL_NONE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; case GL_TEXTURE_BLUE_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->BlueBits ? img->TexFormat->DataType : GL_NONE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; case GL_TEXTURE_ALPHA_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->AlphaBits ? img->TexFormat->DataType : GL_NONE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; case GL_TEXTURE_LUMINANCE_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->LuminanceBits ? img->TexFormat->DataType : GL_NONE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; case GL_TEXTURE_INTENSITY_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->IntensityBits ? img->TexFormat->DataType : GL_NONE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; case GL_TEXTURE_DEPTH_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->DepthBits ? img->TexFormat->DataType : GL_NONE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } out: _mesa_unlock_texture(ctx, texObj); }
static boolean st_context_teximage(struct st_context_iface *stctxi, enum st_texture_type target, int level, enum pipe_format internal_format, struct pipe_resource *tex, boolean mipmap) { struct st_context *st = (struct st_context *) stctxi; struct gl_context *ctx = st->ctx; struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); struct gl_texture_object *texObj; struct gl_texture_image *texImage; struct st_texture_object *stObj; struct st_texture_image *stImage; GLenum internalFormat; GLuint width, height, depth; switch (target) { case ST_TEXTURE_1D: target = GL_TEXTURE_1D; break; case ST_TEXTURE_2D: target = GL_TEXTURE_2D; break; case ST_TEXTURE_3D: target = GL_TEXTURE_3D; break; case ST_TEXTURE_RECT: target = GL_TEXTURE_RECTANGLE_ARB; break; default: return FALSE; break; } texObj = _mesa_select_tex_object(ctx, texUnit, target); _mesa_lock_texture(ctx, texObj); stObj = st_texture_object(texObj); /* switch to surface based */ if (!stObj->surface_based) { _mesa_clear_texture_object(ctx, texObj); stObj->surface_based = GL_TRUE; } texImage = _mesa_get_tex_image(ctx, texObj, target, level); stImage = st_texture_image(texImage); if (tex) { gl_format texFormat; /* * XXX When internal_format and tex->format differ, st_finalize_texture * needs to allocate a new texture with internal_format and copy the * texture here into the new one. It will result in surface_copy being * called on surfaces whose formats differ. * * To avoid that, internal_format is (wrongly) ignored here. A sane fix * is to use a sampler view. */ if (!st_sampler_compat_formats(tex->format, internal_format)) internal_format = tex->format; if (util_format_get_component_bits(internal_format, UTIL_FORMAT_COLORSPACE_RGB, 3) > 0) internalFormat = GL_RGBA; else internalFormat = GL_RGB; texFormat = st_ChooseTextureFormat(ctx, internalFormat, GL_BGRA, GL_UNSIGNED_BYTE); _mesa_init_teximage_fields(ctx, texImage, tex->width0, tex->height0, 1, 0, internalFormat, texFormat); width = tex->width0; height = tex->height0; depth = tex->depth0; /* grow the image size until we hit level = 0 */ while (level > 0) { if (width != 1) width <<= 1; if (height != 1) height <<= 1; if (depth != 1) depth <<= 1; level--; } } else { _mesa_clear_texture_image(ctx, texImage); width = height = depth = 0; } pipe_resource_reference(&stImage->pt, tex); stObj->width0 = width; stObj->height0 = height; stObj->depth0 = depth; _mesa_dirty_texobj(ctx, texObj, GL_TRUE); _mesa_unlock_texture(ctx, texObj); return TRUE; }
/** * Helper for _mesa_meta_CopyTexSubImage1/2/3D() functions. * Have to be careful with locking and meta state for pixel transfer. */ static void copy_tex_sub_image(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage, GLint xoffset, GLint yoffset, GLint zoffset, struct gl_renderbuffer *rb, GLint x, GLint y, GLsizei width, GLsizei height) { struct gl_texture_object *texObj = texImage->TexObject; const GLenum target = texObj->Target; GLenum format, type; GLint bpp; void *buf; /* Choose format/type for temporary image buffer */ format = _mesa_get_format_base_format(texImage->TexFormat); if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA || format == GL_INTENSITY) { /* We don't want to use GL_LUMINANCE, GL_INTENSITY, etc. for the * temp image buffer because glReadPixels will do L=R+G+B which is * not what we want (should be L=R). */ format = GL_RGBA; } if (_mesa_is_format_integer_color(texImage->TexFormat)) { _mesa_problem(ctx, "unsupported integer color copyteximage"); return; } type = get_temp_image_type(ctx, format); bpp = _mesa_bytes_per_pixel(format, type); if (bpp <= 0) { _mesa_problem(ctx, "Bad bpp in meta copy_tex_sub_image()"); return; } /* * Alloc image buffer (XXX could use a PBO) */ buf = malloc(width * height * bpp); if (!buf) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage%uD", dims); return; } _mesa_unlock_texture(ctx, texObj); /* need to unlock first */ /* * Read image from framebuffer (disable pixel transfer ops) */ _mesa_meta_begin(ctx, MESA_META_PIXEL_STORE | MESA_META_PIXEL_TRANSFER); ctx->Driver.ReadPixels(ctx, x, y, width, height, format, type, &ctx->Pack, buf); _mesa_meta_end(ctx); _mesa_update_state(ctx); /* to update pixel transfer state */ /* * Store texture data (with pixel transfer ops) */ _mesa_meta_begin(ctx, MESA_META_PIXEL_STORE); if (target == GL_TEXTURE_1D) { ctx->Driver.TexSubImage1D(ctx, texImage, xoffset, width, format, type, buf, &ctx->Unpack); } else { ctx->Driver.TexSubImage2D(ctx, texImage, xoffset, yoffset, width, height, format, type, buf, &ctx->Unpack); } _mesa_meta_end(ctx); _mesa_lock_texture(ctx, texObj); /* re-lock */ free(buf); }