mesa: add support for GL_DEPTH_STENCIL_ATTACHMENT point.
Used to set both the depth and stencil attachment points to one renderbuffer of texture.
This commit is contained in:
@@ -128,6 +128,8 @@ _mesa_lookup_framebuffer(GLcontext *ctx, GLuint id)
|
|||||||
/**
|
/**
|
||||||
* Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding
|
* Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding
|
||||||
* gl_renderbuffer_attachment object.
|
* gl_renderbuffer_attachment object.
|
||||||
|
* If \p attachment is GL_DEPTH_STENCIL_ATTACHMENT, return a pointer to
|
||||||
|
* the depth buffer attachment point.
|
||||||
*/
|
*/
|
||||||
struct gl_renderbuffer_attachment *
|
struct gl_renderbuffer_attachment *
|
||||||
_mesa_get_attachment(GLcontext *ctx, struct gl_framebuffer *fb,
|
_mesa_get_attachment(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||||
@@ -157,6 +159,8 @@ _mesa_get_attachment(GLcontext *ctx, struct gl_framebuffer *fb,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return &fb->Attachment[BUFFER_COLOR0 + i];
|
return &fb->Attachment[BUFFER_COLOR0 + i];
|
||||||
|
case GL_DEPTH_STENCIL_ATTACHMENT:
|
||||||
|
/* fall-through */
|
||||||
case GL_DEPTH_ATTACHMENT_EXT:
|
case GL_DEPTH_ATTACHMENT_EXT:
|
||||||
return &fb->Attachment[BUFFER_DEPTH];
|
return &fb->Attachment[BUFFER_DEPTH];
|
||||||
case GL_STENCIL_ATTACHMENT_EXT:
|
case GL_STENCIL_ATTACHMENT_EXT:
|
||||||
@@ -267,6 +271,12 @@ _mesa_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
|||||||
ASSERT(att);
|
ASSERT(att);
|
||||||
if (rb) {
|
if (rb) {
|
||||||
_mesa_set_renderbuffer_attachment(ctx, att, rb);
|
_mesa_set_renderbuffer_attachment(ctx, att, rb);
|
||||||
|
if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
|
||||||
|
/* do stencil attachment here (depth already done above) */
|
||||||
|
att = _mesa_get_attachment(ctx, fb, GL_STENCIL_ATTACHMENT_EXT);
|
||||||
|
assert(att);
|
||||||
|
_mesa_set_renderbuffer_attachment(ctx, att, rb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_mesa_remove_attachment(ctx, att);
|
_mesa_remove_attachment(ctx, att);
|
||||||
@@ -1361,7 +1371,6 @@ framebuffer_texture(GLcontext *ctx, const char *caller, GLenum target,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((level < 0) ||
|
if ((level < 0) ||
|
||||||
(level >= _mesa_max_texture_levels(ctx, texObj->Target))) {
|
(level >= _mesa_max_texture_levels(ctx, texObj->Target))) {
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||||
@@ -1377,6 +1386,18 @@ framebuffer_texture(GLcontext *ctx, const char *caller, GLenum target,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (texObj && attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
|
||||||
|
/* the texture format must be depth+stencil */
|
||||||
|
const struct gl_texture_image *texImg;
|
||||||
|
texImg = texObj->Image[0][texObj->BaseLevel];
|
||||||
|
if (!texImg || texImg->_BaseFormat != GL_DEPTH_STENCIL) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||||
|
"glFramebufferTexture%sEXT(texture is not"
|
||||||
|
" DEPTH_STENCIL format)", caller);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
||||||
/* The above doesn't fully flush the drivers in the way that a
|
/* The above doesn't fully flush the drivers in the way that a
|
||||||
* glFlush does, but that is required here:
|
* glFlush does, but that is required here:
|
||||||
@@ -1535,6 +1556,17 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
|
|||||||
rb = NULL;
|
rb = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
|
||||||
|
/* make sure the renderbuffer is a depth/stencil format */
|
||||||
|
if (rb->_BaseFormat != GL_DEPTH_STENCIL) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||||
|
"glFramebufferRenderbufferEXT(renderbuffer"
|
||||||
|
" is not DEPTH_STENCIL format)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
||||||
/* The above doesn't fully flush the drivers in the way that a
|
/* The above doesn't fully flush the drivers in the way that a
|
||||||
* glFlush does, but that is required here:
|
* glFlush does, but that is required here:
|
||||||
@@ -1603,6 +1635,19 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
|
||||||
|
/* the depth and stencil attachments must point to the same buffer */
|
||||||
|
const struct gl_renderbuffer_attachment *depthAtt, *stencilAtt;
|
||||||
|
depthAtt = _mesa_get_attachment(ctx, buffer, GL_DEPTH_ATTACHMENT);
|
||||||
|
stencilAtt = _mesa_get_attachment(ctx, buffer, GL_STENCIL_ATTACHMENT);
|
||||||
|
if (depthAtt->Renderbuffer != stencilAtt->Renderbuffer) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||||
|
"glGetFramebufferAttachmentParameterivEXT(DEPTH/STENCIL"
|
||||||
|
" attachments differ)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
|
||||||
/* The above doesn't fully flush the drivers in the way that a
|
/* The above doesn't fully flush the drivers in the way that a
|
||||||
* glFlush does, but that is required here:
|
* glFlush does, but that is required here:
|
||||||
|
Reference in New Issue
Block a user