mesa: Make core Mesa allocate the texture renderbuffer wrapper.
Every driver did the same thing. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
@@ -606,28 +606,13 @@ intel_render_texture(struct gl_context * ctx,
|
||||
/* Fallback on drawing to a texture that doesn't have a miptree
|
||||
* (has a border, width/height 0, etc.)
|
||||
*/
|
||||
_mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
|
||||
_swrast_render_texture(ctx, fb, att);
|
||||
return;
|
||||
}
|
||||
else if (!irb) {
|
||||
intel_miptree_check_level_layer(mt, att->TextureLevel, layer);
|
||||
|
||||
irb = (struct intel_renderbuffer *)intel_new_renderbuffer(ctx, ~0);
|
||||
|
||||
if (irb) {
|
||||
/* bind the wrapper to the attachment point */
|
||||
_mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base.Base);
|
||||
}
|
||||
else {
|
||||
/* fallback to software rendering */
|
||||
_swrast_render_texture(ctx, fb, att);
|
||||
return;
|
||||
}
|
||||
}
|
||||
intel_miptree_check_level_layer(mt, att->TextureLevel, layer);
|
||||
|
||||
if (!intel_renderbuffer_update_wrapper(intel, irb, image, layer)) {
|
||||
_mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
|
||||
_swrast_render_texture(ctx, fb, att);
|
||||
return;
|
||||
}
|
||||
|
@@ -270,16 +270,6 @@ nouveau_render_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
|
||||
struct gl_texture_image *ti =
|
||||
att->Texture->Image[att->CubeMapFace][att->TextureLevel];
|
||||
|
||||
/* Allocate a renderbuffer object for the texture if we
|
||||
* haven't already done so. */
|
||||
if (!rb) {
|
||||
rb = nouveau_renderbuffer_new(ctx, ~0);
|
||||
assert(rb);
|
||||
|
||||
rb->AllocStorage = NULL;
|
||||
_mesa_reference_renderbuffer(&att->Renderbuffer, rb);
|
||||
}
|
||||
|
||||
/* Update the renderbuffer fields from the texture. */
|
||||
set_renderbuffer_format(rb, get_tex_format(ti));
|
||||
rb->Width = ti->Width;
|
||||
|
@@ -835,25 +835,11 @@ radeon_render_texture(struct gl_context * ctx,
|
||||
if (!radeon_image->mt) {
|
||||
/* Fallback on drawing to a texture without a miptree.
|
||||
*/
|
||||
_mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
|
||||
_swrast_render_texture(ctx, fb, att);
|
||||
return;
|
||||
}
|
||||
else if (!rrb) {
|
||||
rrb = radeon_wrap_texture(ctx, newImage);
|
||||
if (rrb) {
|
||||
/* bind the wrapper to the attachment point */
|
||||
_mesa_reference_renderbuffer(&att->Renderbuffer, &rrb->base.Base);
|
||||
}
|
||||
else {
|
||||
/* fallback to software rendering */
|
||||
_swrast_render_texture(ctx, fb, att);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!radeon_update_wrapper(ctx, rrb, newImage)) {
|
||||
_mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
|
||||
_swrast_render_texture(ctx, fb, att);
|
||||
return;
|
||||
}
|
||||
|
@@ -341,6 +341,47 @@ _mesa_remove_attachment(struct gl_context *ctx,
|
||||
att->Complete = GL_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a renderbuffer which will be set up by the driver to wrap the
|
||||
* texture image slice.
|
||||
*
|
||||
* By using a gl_renderbuffer (like user-allocated renderbuffers), drivers get
|
||||
* to share most of their framebuffer rendering code between winsys,
|
||||
* renderbuffer, and texture attachments.
|
||||
*
|
||||
* The allocated renderbuffer uses a non-zero Name so that drivers can check
|
||||
* it for determining vertical orientation, but we use ~0 to make it fairly
|
||||
* unambiguous with actual user (non-texture) renderbuffers.
|
||||
*/
|
||||
void
|
||||
_mesa_update_texture_renderbuffer(struct gl_context *ctx,
|
||||
struct gl_framebuffer *fb,
|
||||
struct gl_renderbuffer_attachment *att)
|
||||
{
|
||||
struct gl_texture_image *texImage;
|
||||
struct gl_renderbuffer *rb;
|
||||
|
||||
texImage = _mesa_get_attachment_teximage(att);
|
||||
if (!texImage)
|
||||
return;
|
||||
|
||||
rb = att->Renderbuffer;
|
||||
if (!rb) {
|
||||
rb = ctx->Driver.NewRenderbuffer(ctx, ~0);
|
||||
if (!rb) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture()");
|
||||
return;
|
||||
}
|
||||
_mesa_reference_renderbuffer(&att->Renderbuffer, rb);
|
||||
|
||||
/* This can't get called on a texture renderbuffer, so set it to NULL
|
||||
* for clarity compared to user renderbuffers.
|
||||
*/
|
||||
rb->AllocStorage = NULL;
|
||||
}
|
||||
|
||||
ctx->Driver.RenderTexture(ctx, fb, att);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind a texture object to an attachment point.
|
||||
@@ -369,6 +410,7 @@ _mesa_set_texture_attachment(struct gl_context *ctx,
|
||||
assert(!att->Texture);
|
||||
_mesa_reference_texobj(&att->Texture, texObj);
|
||||
}
|
||||
invalidate_framebuffer(fb);
|
||||
|
||||
/* always update these fields */
|
||||
att->TextureLevel = level;
|
||||
@@ -377,11 +419,7 @@ _mesa_set_texture_attachment(struct gl_context *ctx,
|
||||
att->Layered = layered;
|
||||
att->Complete = GL_FALSE;
|
||||
|
||||
if (_mesa_get_attachment_teximage(att)) {
|
||||
ctx->Driver.RenderTexture(ctx, fb, att);
|
||||
}
|
||||
|
||||
invalidate_framebuffer(fb);
|
||||
_mesa_update_texture_renderbuffer(ctx, fb, att);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -107,6 +107,11 @@ _mesa_set_renderbuffer_attachment(struct gl_context *ctx,
|
||||
struct gl_renderbuffer_attachment *att,
|
||||
struct gl_renderbuffer *rb);
|
||||
|
||||
void
|
||||
_mesa_update_texture_renderbuffer(struct gl_context *ctx,
|
||||
struct gl_framebuffer *fb,
|
||||
struct gl_renderbuffer_attachment *att);
|
||||
|
||||
extern void
|
||||
_mesa_framebuffer_renderbuffer(struct gl_context *ctx,
|
||||
struct gl_framebuffer *fb,
|
||||
|
@@ -2760,8 +2760,7 @@ check_rtt_cb(GLuint key, void *data, void *userData)
|
||||
att->TextureLevel == level &&
|
||||
att->CubeMapFace == face) {
|
||||
ASSERT(_mesa_get_attachment_teximage(att));
|
||||
/* Tell driver about the new renderbuffer texture */
|
||||
ctx->Driver.RenderTexture(ctx, ctx->DrawBuffer, att);
|
||||
_mesa_update_texture_renderbuffer(ctx, ctx->DrawBuffer, att);
|
||||
/* Mark fb status as indeterminate to force re-validation */
|
||||
fb->_Status = 0;
|
||||
}
|
||||
|
@@ -390,8 +390,8 @@ st_render_texture(struct gl_context *ctx,
|
||||
{
|
||||
struct st_context *st = st_context(ctx);
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
struct st_renderbuffer *strb;
|
||||
struct gl_renderbuffer *rb;
|
||||
struct gl_renderbuffer *rb = att->Renderbuffer;
|
||||
struct st_renderbuffer *strb = st_renderbuffer(rb);
|
||||
struct pipe_resource *pt;
|
||||
struct st_texture_object *stObj;
|
||||
const struct gl_texture_image *texImage;
|
||||
@@ -406,24 +406,6 @@ st_render_texture(struct gl_context *ctx,
|
||||
/* get pointer to texture image we're rendeing to */
|
||||
texImage = _mesa_get_attachment_teximage(att);
|
||||
|
||||
/* create new renderbuffer which wraps the texture image.
|
||||
* Use the texture's name as the renderbuffer's name so that we have
|
||||
* something that's non-zero (to determine vertical orientation) and
|
||||
* possibly helpful for debugging.
|
||||
*/
|
||||
rb = st_new_renderbuffer(ctx, att->Texture->Name);
|
||||
if (!rb) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture()");
|
||||
return;
|
||||
}
|
||||
|
||||
_mesa_reference_renderbuffer(&att->Renderbuffer, rb);
|
||||
assert(rb->RefCount == 1);
|
||||
rb->AllocStorage = NULL; /* should not get called */
|
||||
strb = st_renderbuffer(rb);
|
||||
|
||||
assert(strb->Base.RefCount > 0);
|
||||
|
||||
/* get the texture for the texture object */
|
||||
stObj = st_texture_object(att->Texture);
|
||||
|
||||
|
@@ -22,37 +22,6 @@ delete_texture_wrapper(struct gl_context *ctx, struct gl_renderbuffer *rb)
|
||||
free(rb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function creates a renderbuffer object which wraps a texture image.
|
||||
* The new renderbuffer is plugged into the given attachment point.
|
||||
* This allows rendering into the texture as if it were a renderbuffer.
|
||||
*/
|
||||
static void
|
||||
wrap_texture(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
|
||||
{
|
||||
struct gl_renderbuffer *rb;
|
||||
const GLuint name = 0;
|
||||
|
||||
ASSERT(att->Type == GL_TEXTURE);
|
||||
ASSERT(att->Renderbuffer == NULL);
|
||||
|
||||
rb = ctx->Driver.NewRenderbuffer(ctx, name);
|
||||
if (!rb) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "wrap_texture");
|
||||
return;
|
||||
}
|
||||
|
||||
/* init base gl_renderbuffer fields */
|
||||
_mesa_init_renderbuffer(rb, name);
|
||||
/* plug in our texture_renderbuffer-specific functions */
|
||||
rb->Delete = delete_texture_wrapper;
|
||||
rb->AllocStorage = NULL; /* illegal! */
|
||||
|
||||
/* update attachment point */
|
||||
_mesa_reference_renderbuffer(&att->Renderbuffer, rb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the renderbuffer wrapper for rendering to a texture.
|
||||
* For example, update the width, height of the RB based on the texture size,
|
||||
@@ -116,11 +85,12 @@ _swrast_render_texture(struct gl_context *ctx,
|
||||
struct gl_framebuffer *fb,
|
||||
struct gl_renderbuffer_attachment *att)
|
||||
{
|
||||
struct gl_renderbuffer *rb = att->Renderbuffer;
|
||||
(void) fb;
|
||||
|
||||
if (!att->Renderbuffer) {
|
||||
wrap_texture(ctx, att);
|
||||
}
|
||||
/* plug in our texture_renderbuffer-specific functions */
|
||||
rb->Delete = delete_texture_wrapper;
|
||||
|
||||
update_wrapper(ctx, att);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user