merge from texman branch
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
#include "renderbuffer.h"
|
||||
#include "state.h"
|
||||
#include "teximage.h"
|
||||
#include "texobj.h"
|
||||
#include "texstore.h"
|
||||
|
||||
|
||||
@@ -66,8 +67,8 @@ static struct gl_renderbuffer DummyRenderbuffer;
|
||||
/**
|
||||
* Helper routine for getting a gl_renderbuffer.
|
||||
*/
|
||||
static struct gl_renderbuffer *
|
||||
lookup_renderbuffer(GLcontext *ctx, GLuint id)
|
||||
struct gl_renderbuffer *
|
||||
_mesa_lookup_renderbuffer(GLcontext *ctx, GLuint id)
|
||||
{
|
||||
struct gl_renderbuffer *rb;
|
||||
|
||||
@@ -83,8 +84,8 @@ lookup_renderbuffer(GLcontext *ctx, GLuint id)
|
||||
/**
|
||||
* Helper routine for getting a gl_framebuffer.
|
||||
*/
|
||||
static struct gl_framebuffer *
|
||||
lookup_framebuffer(GLcontext *ctx, GLuint id)
|
||||
struct gl_framebuffer *
|
||||
_mesa_lookup_framebuffer(GLcontext *ctx, GLuint id)
|
||||
{
|
||||
struct gl_framebuffer *fb;
|
||||
|
||||
@@ -209,7 +210,7 @@ _mesa_set_texture_attachment(GLcontext *ctx,
|
||||
att->Complete = GL_FALSE;
|
||||
|
||||
if (att->Texture->Image[att->CubeMapFace][att->TextureLevel]) {
|
||||
ctx->Driver.RenderbufferTexture(ctx, fb, att);
|
||||
ctx->Driver.RenderTexture(ctx, fb, att);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,6 +224,7 @@ _mesa_set_renderbuffer_attachment(GLcontext *ctx,
|
||||
struct gl_renderbuffer_attachment *att,
|
||||
struct gl_renderbuffer *rb)
|
||||
{
|
||||
/* XXX check if re-doing same attachment, exit early */
|
||||
_mesa_remove_attachment(ctx, att);
|
||||
att->Type = GL_RENDERBUFFER_EXT;
|
||||
att->Renderbuffer = rb;
|
||||
@@ -242,6 +244,10 @@ _mesa_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
{
|
||||
struct gl_renderbuffer_attachment *att;
|
||||
|
||||
_glthread_LOCK_MUTEX(fb->Mutex);
|
||||
if (rb)
|
||||
_glthread_LOCK_MUTEX(rb->Mutex);
|
||||
|
||||
att = _mesa_get_attachment(ctx, fb, attachment);
|
||||
ASSERT(att);
|
||||
|
||||
@@ -251,6 +257,10 @@ _mesa_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
else {
|
||||
_mesa_remove_attachment(ctx, att);
|
||||
}
|
||||
|
||||
if (rb)
|
||||
_glthread_UNLOCK_MUTEX(rb->Mutex);
|
||||
_glthread_UNLOCK_MUTEX(fb->Mutex);
|
||||
}
|
||||
|
||||
|
||||
@@ -554,7 +564,7 @@ _mesa_IsRenderbufferEXT(GLuint renderbuffer)
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
|
||||
if (renderbuffer) {
|
||||
struct gl_renderbuffer *rb = lookup_renderbuffer(ctx, renderbuffer);
|
||||
struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
|
||||
if (rb != NULL && rb != &DummyRenderbuffer)
|
||||
return GL_TRUE;
|
||||
}
|
||||
@@ -579,7 +589,7 @@ _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
|
||||
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
||||
|
||||
if (renderbuffer) {
|
||||
newRb = lookup_renderbuffer(ctx, renderbuffer);
|
||||
newRb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
|
||||
if (newRb == &DummyRenderbuffer) {
|
||||
/* ID was reserved, but no real renderbuffer object made yet */
|
||||
newRb = NULL;
|
||||
@@ -626,7 +636,7 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
|
||||
for (i = 0; i < n; i++) {
|
||||
if (renderbuffers[i] > 0) {
|
||||
struct gl_renderbuffer *rb;
|
||||
rb = lookup_renderbuffer(ctx, renderbuffers[i]);
|
||||
rb = _mesa_lookup_renderbuffer(ctx, renderbuffers[i]);
|
||||
if (rb) {
|
||||
/* check if deleting currently bound renderbuffer object */
|
||||
if (rb == ctx->CurrentRenderbuffer) {
|
||||
@@ -786,15 +796,26 @@ _mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
|
||||
return;
|
||||
}
|
||||
|
||||
/* These MUST get set by the AllocStorage func */
|
||||
rb->_ActualFormat = 0;
|
||||
rb->RedBits =
|
||||
rb->GreenBits =
|
||||
rb->BlueBits =
|
||||
rb->AlphaBits =
|
||||
rb->IndexBits =
|
||||
rb->DepthBits =
|
||||
rb->StencilBits = 0;
|
||||
|
||||
/* Now allocate the storage */
|
||||
ASSERT(rb->AllocStorage);
|
||||
if (rb->AllocStorage(ctx, rb, internalFormat, width, height)) {
|
||||
/* No error - check/set fields now */
|
||||
assert(rb->_ActualFormat);
|
||||
assert(rb->Width == width);
|
||||
assert(rb->Height == height);
|
||||
assert(rb->InternalFormat);
|
||||
assert(rb->RedBits || rb->GreenBits || rb->BlueBits || rb->AlphaBits ||
|
||||
rb->DepthBits || rb->StencilBits || rb->IndexBits);
|
||||
rb->InternalFormat = internalFormat;
|
||||
rb->_BaseFormat = baseFormat;
|
||||
}
|
||||
else {
|
||||
@@ -802,6 +823,7 @@ _mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
|
||||
rb->Width = 0;
|
||||
rb->Height = 0;
|
||||
rb->InternalFormat = GL_NONE;
|
||||
rb->_ActualFormat = GL_NONE;
|
||||
rb->_BaseFormat = GL_NONE;
|
||||
rb->RedBits =
|
||||
rb->GreenBits =
|
||||
@@ -884,7 +906,7 @@ _mesa_IsFramebufferEXT(GLuint framebuffer)
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
|
||||
if (framebuffer) {
|
||||
struct gl_framebuffer *rb = lookup_framebuffer(ctx, framebuffer);
|
||||
struct gl_framebuffer *rb = _mesa_lookup_framebuffer(ctx, framebuffer);
|
||||
if (rb != NULL && rb != &DummyFramebuffer)
|
||||
return GL_TRUE;
|
||||
}
|
||||
@@ -892,13 +914,28 @@ _mesa_IsFramebufferEXT(GLuint framebuffer)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
check_begin_texture_render(GLcontext *ctx, struct gl_framebuffer *fb)
|
||||
{
|
||||
GLuint i;
|
||||
ASSERT(ctx->Driver.RenderTexture);
|
||||
for (i = 0; i < BUFFER_COUNT; i++) {
|
||||
struct gl_renderbuffer_attachment *att = fb->Attachment + i;
|
||||
struct gl_texture_object *texObj = att->Texture;
|
||||
if (texObj) {
|
||||
ctx->Driver.RenderTexture(ctx, fb, att);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Examine all the framebuffer's attachments to see if any are textures.
|
||||
* If so, call ctx->Driver.FinishRenderTexture() for each texture to
|
||||
* notify the device driver that the texture image may have changed.
|
||||
*/
|
||||
static void
|
||||
check_texture_render(GLcontext *ctx, struct gl_framebuffer *fb)
|
||||
check_end_texture_render(GLcontext *ctx, struct gl_framebuffer *fb)
|
||||
{
|
||||
if (ctx->Driver.FinishRenderTexture) {
|
||||
GLuint i;
|
||||
@@ -922,6 +959,12 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
|
||||
|
||||
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
||||
|
||||
if (!ctx->Extensions.EXT_framebuffer_object) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glBindFramebufferEXT(unsupported)");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (target) {
|
||||
#if FEATURE_EXT_framebuffer_blit
|
||||
case GL_DRAW_FRAMEBUFFER_EXT:
|
||||
@@ -954,7 +997,7 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
|
||||
|
||||
if (framebuffer) {
|
||||
/* Binding a user-created framebuffer object */
|
||||
newFb = lookup_framebuffer(ctx, framebuffer);
|
||||
newFb = _mesa_lookup_framebuffer(ctx, framebuffer);
|
||||
if (newFb == &DummyFramebuffer) {
|
||||
/* ID was reserved, but no real framebuffer object made yet */
|
||||
newFb = NULL;
|
||||
@@ -968,10 +1011,12 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
|
||||
}
|
||||
_mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newFb);
|
||||
}
|
||||
_glthread_LOCK_MUTEX(newFb->Mutex);
|
||||
if (bindReadBuf)
|
||||
newFb->RefCount++;
|
||||
if (bindDrawBuf)
|
||||
newFb->RefCount++;
|
||||
_glthread_UNLOCK_MUTEX(newFb->Mutex);
|
||||
}
|
||||
else {
|
||||
/* Binding the window system framebuffer (which was originally set
|
||||
@@ -980,12 +1025,19 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
|
||||
newFb = ctx->WinSysDrawBuffer;
|
||||
}
|
||||
|
||||
ASSERT(newFb);
|
||||
ASSERT(newFb != &DummyFramebuffer);
|
||||
|
||||
/*
|
||||
* XXX check if re-binding same buffer and skip some of this code.
|
||||
*/
|
||||
|
||||
if (bindReadBuf) {
|
||||
oldFb = ctx->ReadBuffer;
|
||||
if (oldFb && oldFb->Name != 0) {
|
||||
_glthread_LOCK_MUTEX(oldFb->Mutex);
|
||||
oldFb->RefCount--;
|
||||
_glthread_UNLOCK_MUTEX(oldFb->Mutex);
|
||||
if (oldFb->RefCount == 0) {
|
||||
oldFb->Delete(oldFb);
|
||||
}
|
||||
@@ -997,16 +1049,20 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
|
||||
oldFb = ctx->DrawBuffer;
|
||||
if (oldFb && oldFb->Name != 0) {
|
||||
/* check if old FB had any texture attachments */
|
||||
if (ctx->Driver.FinishRenderTexture) {
|
||||
check_texture_render(ctx, oldFb);
|
||||
}
|
||||
check_end_texture_render(ctx, oldFb);
|
||||
/* check if time to delete this framebuffer */
|
||||
_glthread_LOCK_MUTEX(oldFb->Mutex);
|
||||
oldFb->RefCount--;
|
||||
if (oldFb->RefCount == 0) {
|
||||
oldFb->Delete(oldFb);
|
||||
}
|
||||
_glthread_UNLOCK_MUTEX(oldFb->Mutex);
|
||||
}
|
||||
ctx->DrawBuffer = newFb;
|
||||
if (newFb->Name != 0) {
|
||||
/* check if newly bound framebuffer has any texture attachments */
|
||||
check_begin_texture_render(ctx, newFb);
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->Driver.BindFramebuffer) {
|
||||
@@ -1027,7 +1083,7 @@ _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
|
||||
for (i = 0; i < n; i++) {
|
||||
if (framebuffers[i] > 0) {
|
||||
struct gl_framebuffer *fb;
|
||||
fb = lookup_framebuffer(ctx, framebuffers[i]);
|
||||
fb = _mesa_lookup_framebuffer(ctx, framebuffers[i]);
|
||||
if (fb) {
|
||||
ASSERT(fb == &DummyFramebuffer || fb->Name == framebuffers[i]);
|
||||
|
||||
@@ -1045,7 +1101,9 @@ _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
|
||||
/* But the object will not be freed until it's no longer
|
||||
* bound in any context.
|
||||
*/
|
||||
_glthread_LOCK_MUTEX(fb->Mutex);
|
||||
fb->RefCount--;
|
||||
_glthread_UNLOCK_MUTEX(fb->Mutex);
|
||||
if (fb->RefCount == 0) {
|
||||
fb->Delete(fb);
|
||||
}
|
||||
@@ -1134,100 +1192,134 @@ _mesa_CheckFramebufferStatusEXT(GLenum target)
|
||||
|
||||
|
||||
/**
|
||||
* Do error checking common to glFramebufferTexture1D/2D/3DEXT.
|
||||
* \return GL_TRUE if any error, GL_FALSE otherwise
|
||||
* Common code called by glFramebufferTexture1D/2D/3DEXT().
|
||||
*/
|
||||
static GLboolean
|
||||
error_check_framebuffer_texture(GLcontext *ctx, GLuint dims,
|
||||
GLenum target, GLenum attachment,
|
||||
GLenum textarget, GLuint texture, GLint level)
|
||||
{
|
||||
ASSERT(dims >= 1 && dims <= 3);
|
||||
|
||||
if (target != GL_FRAMEBUFFER_EXT) {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||
"glFramebufferTexture%dDEXT(target)", dims);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* check framebuffer binding */
|
||||
if (ctx->DrawBuffer->Name == 0) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glFramebufferTexture%dDEXT", dims);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* only check textarget, level if texture ID is non-zero */
|
||||
if (texture) {
|
||||
if ((dims == 1 && textarget != GL_TEXTURE_1D) ||
|
||||
(dims == 3 && textarget != GL_TEXTURE_3D) ||
|
||||
(dims == 2 && textarget != GL_TEXTURE_2D &&
|
||||
textarget != GL_TEXTURE_RECTANGLE_ARB &&
|
||||
!IS_CUBE_FACE(textarget))) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glFramebufferTexture%dDEXT(textarget)", dims);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
if ((level < 0) || level >= _mesa_max_texture_levels(ctx, textarget)) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glFramebufferTexture%dDEXT(level)", dims);
|
||||
return GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* XXX The code in _mesa_FramebufferTexture1/2/3DEXT could be probably
|
||||
* be combined into one function.
|
||||
*/
|
||||
void GLAPIENTRY
|
||||
_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
|
||||
GLenum textarget, GLuint texture, GLint level)
|
||||
static void
|
||||
framebuffer_texture(GLuint dims, GLenum target, GLenum attachment,
|
||||
GLenum textarget, GLuint texture,
|
||||
GLint level, GLint zoffset)
|
||||
{
|
||||
struct gl_renderbuffer_attachment *att;
|
||||
struct gl_texture_object *texObj = NULL;
|
||||
struct gl_framebuffer *fb;
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
|
||||
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
||||
|
||||
if (error_check_framebuffer_texture(ctx, 1, target, attachment,
|
||||
textarget, texture, level))
|
||||
if (target != GL_FRAMEBUFFER_EXT) {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||
"glFramebufferTexture%dDEXT(target)", dims);
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(textarget == GL_TEXTURE_1D);
|
||||
fb = ctx->DrawBuffer;
|
||||
ASSERT(fb);
|
||||
|
||||
/* XXX read blit */
|
||||
att = _mesa_get_attachment(ctx, ctx->DrawBuffer, attachment);
|
||||
/* check framebuffer binding */
|
||||
if (fb->Name == 0) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glFramebufferTexture%dDEXT", dims);
|
||||
return;
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
texObj = _mesa_lookup_texture(ctx, texture);
|
||||
}
|
||||
|
||||
/* Check dimension-dependent things */
|
||||
switch (dims) {
|
||||
case 1:
|
||||
if (textarget != GL_TEXTURE_1D) {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||
"glFramebufferTexture1DEXT(textarget)");
|
||||
return;
|
||||
}
|
||||
if (texObj && texObj->Target != GL_TEXTURE_1D) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glFramebufferTexture1DEXT(texture target mismatch)");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (textarget != GL_TEXTURE_2D &&
|
||||
textarget != GL_TEXTURE_RECTANGLE_ARB &&
|
||||
!IS_CUBE_FACE(textarget)) {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||
"glFramebufferTexture2DEXT(textarget)");
|
||||
return;
|
||||
}
|
||||
if (texObj) {
|
||||
if ((texObj->Target == GL_TEXTURE_2D && textarget != GL_TEXTURE_2D) ||
|
||||
(texObj->Target == GL_TEXTURE_RECTANGLE_ARB
|
||||
&& textarget != GL_TEXTURE_RECTANGLE_ARB) ||
|
||||
(texObj->Target == GL_TEXTURE_CUBE_MAP
|
||||
&& !IS_CUBE_FACE(textarget))) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glFramebufferTexture1DEXT(texture target mismatch)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (textarget != GL_TEXTURE_3D) {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||
"glFramebufferTexture3DEXT(textarget)");
|
||||
return;
|
||||
}
|
||||
if (texObj && texObj->Target != GL_TEXTURE_3D) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glFramebufferTexture3DEXT(texture target mismatch)");
|
||||
return;
|
||||
}
|
||||
{
|
||||
const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
|
||||
if (zoffset < 0 || zoffset >= maxSize) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glFramebufferTexture3DEXT(zoffset)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(ctx, "Unexpected dims in error_check_framebuffer_texture");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((level < 0) || level >= _mesa_max_texture_levels(ctx, textarget)) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glFramebufferTexture%dDEXT(level)", dims);
|
||||
return;
|
||||
}
|
||||
|
||||
att = _mesa_get_attachment(ctx, fb, attachment);
|
||||
if (att == NULL) {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||
"glFramebufferTexture1DEXT(attachment)");
|
||||
"glFramebufferTexture%dDEXT(attachment)", dims);
|
||||
return;
|
||||
}
|
||||
|
||||
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
||||
|
||||
if (texture) {
|
||||
struct gl_texture_object *texObj = (struct gl_texture_object *)
|
||||
_mesa_HashLookup(ctx->Shared->TexObjects, texture);
|
||||
if (!texObj) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glFramebufferTexture1DEXT(texture)");
|
||||
return;
|
||||
}
|
||||
if (texObj->Target != textarget) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION, /* XXX correct error? */
|
||||
"glFramebufferTexture1DEXT(texture target)");
|
||||
return;
|
||||
}
|
||||
_mesa_set_texture_attachment(ctx, ctx->DrawBuffer, att,
|
||||
texObj, textarget, level, 0);
|
||||
_glthread_LOCK_MUTEX(fb->Mutex);
|
||||
if (texObj) {
|
||||
_mesa_set_texture_attachment(ctx, fb, att, texObj, textarget,
|
||||
level, zoffset);
|
||||
}
|
||||
else {
|
||||
_mesa_remove_attachment(ctx, att);
|
||||
}
|
||||
_glthread_UNLOCK_MUTEX(fb->Mutex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
|
||||
GLenum textarget, GLuint texture, GLint level)
|
||||
{
|
||||
const GLint zoffset = 0;
|
||||
framebuffer_texture(1, target, attachment, textarget, texture,
|
||||
level, zoffset);
|
||||
}
|
||||
|
||||
|
||||
@@ -1235,51 +1327,9 @@ void GLAPIENTRY
|
||||
_mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
|
||||
GLenum textarget, GLuint texture, GLint level)
|
||||
{
|
||||
struct gl_renderbuffer_attachment *att;
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
|
||||
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
||||
|
||||
if (error_check_framebuffer_texture(ctx, 2, target, attachment,
|
||||
textarget, texture, level))
|
||||
return;
|
||||
|
||||
ASSERT(textarget == GL_TEXTURE_2D ||
|
||||
textarget == GL_TEXTURE_RECTANGLE_ARB ||
|
||||
IS_CUBE_FACE(textarget));
|
||||
|
||||
att = _mesa_get_attachment(ctx, ctx->DrawBuffer, attachment);
|
||||
if (att == NULL) {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||
"glFramebufferTexture2DEXT(attachment)");
|
||||
return;
|
||||
}
|
||||
|
||||
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
||||
|
||||
if (texture) {
|
||||
struct gl_texture_object *texObj = (struct gl_texture_object *)
|
||||
_mesa_HashLookup(ctx->Shared->TexObjects, texture);
|
||||
if (!texObj) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glFramebufferTexture2DEXT(texture)");
|
||||
return;
|
||||
}
|
||||
if ((texObj->Target == GL_TEXTURE_2D && textarget != GL_TEXTURE_2D) ||
|
||||
(texObj->Target == GL_TEXTURE_RECTANGLE_ARB
|
||||
&& textarget != GL_TEXTURE_RECTANGLE_ARB) ||
|
||||
(texObj->Target == GL_TEXTURE_CUBE_MAP
|
||||
&& !IS_CUBE_FACE(textarget))) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION, /* XXX correct error? */
|
||||
"glFramebufferTexture2DEXT(texture target)");
|
||||
return;
|
||||
}
|
||||
_mesa_set_texture_attachment(ctx, ctx->DrawBuffer, att,
|
||||
texObj, textarget, level, 0);
|
||||
}
|
||||
else {
|
||||
_mesa_remove_attachment(ctx, att);
|
||||
}
|
||||
const GLint zoffset = 0;
|
||||
framebuffer_texture(2, target, attachment, textarget, texture,
|
||||
level, zoffset);
|
||||
}
|
||||
|
||||
|
||||
@@ -1288,54 +1338,12 @@ _mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
|
||||
GLenum textarget, GLuint texture,
|
||||
GLint level, GLint zoffset)
|
||||
{
|
||||
struct gl_renderbuffer_attachment *att;
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
|
||||
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
||||
|
||||
if (error_check_framebuffer_texture(ctx, 3, target, attachment,
|
||||
textarget, texture, level))
|
||||
return;
|
||||
|
||||
ASSERT(textarget == GL_TEXTURE_3D);
|
||||
|
||||
att = _mesa_get_attachment(ctx, ctx->DrawBuffer, attachment);
|
||||
if (att == NULL) {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM,
|
||||
"glFramebufferTexture1DEXT(attachment)");
|
||||
return;
|
||||
}
|
||||
|
||||
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
||||
|
||||
if (texture) {
|
||||
const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
|
||||
struct gl_texture_object *texObj = (struct gl_texture_object *)
|
||||
_mesa_HashLookup(ctx->Shared->TexObjects, texture);
|
||||
if (!texObj) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glFramebufferTexture3DEXT(texture)");
|
||||
return;
|
||||
}
|
||||
if (texObj->Target != textarget) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION, /* XXX correct error? */
|
||||
"glFramebufferTexture3DEXT(texture target)");
|
||||
return;
|
||||
}
|
||||
if (zoffset < 0 || zoffset >= maxSize) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glFramebufferTexture3DEXT(zoffset)");
|
||||
return;
|
||||
}
|
||||
_mesa_set_texture_attachment(ctx, ctx->DrawBuffer, att,
|
||||
texObj, textarget, level,zoffset);
|
||||
}
|
||||
else {
|
||||
_mesa_remove_attachment(ctx, att);
|
||||
}
|
||||
framebuffer_texture(3, target, attachment, textarget, texture,
|
||||
level, zoffset);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
|
||||
GLenum renderbufferTarget,
|
||||
@@ -1396,7 +1404,7 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
|
||||
}
|
||||
|
||||
if (renderbuffer) {
|
||||
rb = lookup_renderbuffer(ctx, renderbuffer);
|
||||
rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
|
||||
if (!rb) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glFramebufferRenderbufferEXT(renderbuffer)");
|
||||
|
Reference in New Issue
Block a user