radeon: some more fbo work

This commit is contained in:
Dave Airlie 2009-03-20 22:07:05 +10:00
parent fabce837f9
commit 230abc06f8
3 changed files with 303 additions and 97 deletions

View file

@ -31,7 +31,8 @@ void radeonReadBuffer( GLcontext *ctx, GLenum mode );
void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height);
void radeon_fbo_init(struct radeon_context *radeon);
struct gl_renderbuffer *
radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv);
static inline struct radeon_renderbuffer *radeon_renderbuffer(struct gl_renderbuffer *rb)
{
struct radeon_renderbuffer *rrb = (struct radeon_renderbuffer *)rb;

View file

@ -38,6 +38,12 @@
#include "radeon_common.h"
#define FILE_DEBUG_FLAG DEBUG_TEXTURE
#define DBG(...) do { \
if (RADEON_DEBUG & FILE_DEBUG_FLAG) \
_mesa_printf(__VA_ARGS__); \
} while(0)
static struct gl_framebuffer *
radeon_new_framebuffer(GLcontext *ctx, GLuint name)
{
@ -60,13 +66,6 @@ radeon_delete_renderbuffer(struct gl_renderbuffer *rb)
_mesa_free(rrb);
}
static void
radeon_resize_buffers(GLcontext *ctx, struct gl_framebuffer *fb,
GLuint width, GLuint height)
{
}
static void *
radeon_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb,
GLint x, GLint y)
@ -89,18 +88,236 @@ radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
int cpp;
ASSERT(rb->Name != 0);
switch (internalFormat) {
case GL_R3_G3_B2:
case GL_RGB4:
case GL_RGB5:
rb->_ActualFormat = GL_RGB5;
rb->DataType = GL_UNSIGNED_BYTE;
rb->RedBits = 5;
rb->GreenBits = 6;
rb->BlueBits = 5;
cpp = 2;
break;
case GL_RGB:
case GL_RGB8:
case GL_RGB10:
case GL_RGB12:
case GL_RGB16:
rb->_ActualFormat = GL_RGB8;
rb->DataType = GL_UNSIGNED_BYTE;
rb->RedBits = 8;
rb->GreenBits = 8;
rb->BlueBits = 8;
rb->AlphaBits = 0;
cpp = 4;
break;
case GL_RGBA:
case GL_RGBA2:
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGBA8:
case GL_RGB10_A2:
case GL_RGBA12:
case GL_RGBA16:
rb->_ActualFormat = GL_RGBA8;
rb->DataType = GL_UNSIGNED_BYTE;
rb->RedBits = 8;
rb->GreenBits = 8;
rb->BlueBits = 8;
rb->AlphaBits = 8;
cpp = 4;
break;
case GL_STENCIL_INDEX:
case GL_STENCIL_INDEX1_EXT:
case GL_STENCIL_INDEX4_EXT:
case GL_STENCIL_INDEX8_EXT:
case GL_STENCIL_INDEX16_EXT:
/* alloc a depth+stencil buffer */
rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
rb->StencilBits = 8;
cpp = 4;
break;
case GL_DEPTH_COMPONENT16:
rb->_ActualFormat = GL_DEPTH_COMPONENT16;
rb->DataType = GL_UNSIGNED_SHORT;
rb->DepthBits = 16;
cpp = 2;
break;
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32:
rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
rb->DepthBits = 24;
cpp = 4;
break;
case GL_DEPTH_STENCIL_EXT:
case GL_DEPTH24_STENCIL8_EXT:
rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
rb->DepthBits = 24;
rb->StencilBits = 8;
cpp = 4;
break;
default:
_mesa_problem(ctx,
"Unexpected format in intel_alloc_renderbuffer_storage");
return GL_FALSE;
}
radeonFlush(ctx);
if (rrb->bo)
radeon_bo_unref(rrb->bo);
if (software_buffer) {
return _mesa_soft_renderbuffer_storage(ctx, rb, internalFormat,
width, height);
}
else {
/* TODO Alloc a BO */
// rrb->bo = radeon_bo_open();
rb->Width = width;
rb->Height = height;
return GL_TRUE;
}
}
/**
* Called for each hardware renderbuffer when a _window_ is resized.
* Just update fields.
* Not used for user-created renderbuffers!
*/
static GLboolean
radeon_alloc_window_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
GLenum internalFormat, GLuint width, GLuint height)
{
ASSERT(rb->Name == 0);
rb->Width = width;
rb->Height = height;
rb->_ActualFormat = internalFormat;
return GL_TRUE;
}
static void
radeon_resize_buffers(GLcontext *ctx, struct gl_framebuffer *fb,
GLuint width, GLuint height)
{
struct radeon_framebuffer *radeon_fb = (struct radeon_framebuffer*)fb;
int i;
_mesa_resize_framebuffer(ctx, fb, width, height);
fb->Initialized = GL_TRUE; /* XXX remove someday */
if (fb->Name != 0) {
return;
}
/* Make sure all window system renderbuffers are up to date */
for (i = 0; i < 2; i++) {
struct gl_renderbuffer *rb = &radeon_fb->color_rb[i]->base;
/* only resize if size is changing */
if (rb && (rb->Width != width || rb->Height != height)) {
rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height);
}
}
}
/** Dummy function for gl_renderbuffer::AllocStorage() */
static GLboolean
radeon_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
GLenum internalFormat, GLuint width, GLuint height)
{
_mesa_problem(ctx, "radeon_op_alloc_storage should never be called.");
return GL_FALSE;
}
struct gl_renderbuffer *
radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)
{
struct radeon_renderbuffer *rrb;
rrb = CALLOC_STRUCT(radeon_renderbuffer);
if (!rrb)
return NULL;
_mesa_init_renderbuffer(&rrb->base, 0);
rrb->base.ClassID = RADEON_RB_CLASS;
/* XXX format junk */
switch (format) {
case GL_RGB5:
rrb->base._ActualFormat = GL_RGB5;
rrb->base._BaseFormat = GL_RGBA;
rrb->base.RedBits = 5;
rrb->base.GreenBits = 6;
rrb->base.BlueBits = 5;
rrb->base.DataType = GL_UNSIGNED_BYTE;
break;
case GL_RGBA8:
rrb->base._ActualFormat = GL_RGBA8;
rrb->base._BaseFormat = GL_RGBA;
rrb->base.RedBits = 8;
rrb->base.GreenBits = 8;
rrb->base.BlueBits = 8;
rrb->base.AlphaBits = 8;
rrb->base.DataType = GL_UNSIGNED_BYTE;
break;
case GL_STENCIL_INDEX8_EXT:
rrb->base._ActualFormat = GL_STENCIL_INDEX8_EXT;
rrb->base._BaseFormat = GL_STENCIL_INDEX;
rrb->base.StencilBits = 8;
rrb->base.DataType = GL_UNSIGNED_BYTE;
break;
case GL_DEPTH_COMPONENT16:
rrb->base._ActualFormat = GL_DEPTH_COMPONENT16;
rrb->base._BaseFormat = GL_DEPTH_COMPONENT;
rrb->base.DepthBits = 16;
rrb->base.DataType = GL_UNSIGNED_SHORT;
break;
case GL_DEPTH_COMPONENT24:
rrb->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
rrb->base._BaseFormat = GL_DEPTH_COMPONENT;
rrb->base.DepthBits = 24;
rrb->base.DataType = GL_UNSIGNED_INT;
break;
case GL_DEPTH24_STENCIL8_EXT:
rrb->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
rrb->base._BaseFormat = GL_DEPTH_STENCIL_EXT;
rrb->base.DepthBits = 24;
rrb->base.StencilBits = 8;
rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
break;
default:
fprintf(stderr, "%s: Unknown format 0x%04x\n", __FUNCTION__, format);
_mesa_delete_renderbuffer(&rrb->base);
return NULL;
}
rrb->dPriv = driDrawPriv;
rrb->base.InternalFormat = format;
rrb->base.Delete = radeon_delete_renderbuffer;
rrb->base.AllocStorage = radeon_alloc_window_storage;
rrb->base.GetPointer = radeon_get_pointer;
radeonSetSpanFunctions(rrb);
rrb->bo = NULL;
return &rrb->base;
}
static struct gl_renderbuffer *
radeon_new_renderbuffer(GLcontext * ctx, GLuint name)
{
@ -120,6 +337,7 @@ radeon_new_renderbuffer(GLcontext * ctx, GLuint name)
return &rrb->base;
}
static void
radeon_bind_framebuffer(GLcontext * ctx, GLenum target,
struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
@ -144,10 +362,80 @@ radeon_framebuffer_renderbuffer(GLcontext * ctx,
radeon_draw_buffer(ctx, fb);
}
static GLboolean
radeon_update_wrapper(GLcontext *ctx, struct radeon_renderbuffer *rrb,
struct gl_texture_image *texImage)
{
if (texImage->TexFormat == &_mesa_texformat_argb8888) {
rrb->base._ActualFormat = GL_RGBA8;
rrb->base._BaseFormat = GL_RGBA;
rrb->base.DataType = GL_UNSIGNED_BYTE;
DBG("Render to RGBA8 texture OK\n");
}
else if (texImage->TexFormat == &_mesa_texformat_rgb565) {
rrb->base._ActualFormat = GL_RGB5;
rrb->base._BaseFormat = GL_RGB;
rrb->base.DataType = GL_UNSIGNED_SHORT;
DBG("Render to RGB5 texture OK\n");
}
else if (texImage->TexFormat == &_mesa_texformat_z16) {
rrb->base._ActualFormat = GL_DEPTH_COMPONENT16;
rrb->base._BaseFormat = GL_DEPTH_COMPONENT;
rrb->base.DataType = GL_UNSIGNED_SHORT;
DBG("Render to DEPTH16 texture OK\n");
}
else if (texImage->TexFormat == &_mesa_texformat_s8_z24) {
rrb->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
rrb->base._BaseFormat = GL_DEPTH_STENCIL_EXT;
rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
DBG("Render to DEPTH_STENCIL texture OK\n");
}
else {
DBG("Render to texture BAD FORMAT %d\n",
texImage->TexFormat->MesaFormat);
return GL_FALSE;
}
rrb->base.InternalFormat = rrb->base._ActualFormat;
rrb->base.Width = texImage->Width;
rrb->base.Height = texImage->Height;
rrb->base.RedBits = texImage->TexFormat->RedBits;
rrb->base.GreenBits = texImage->TexFormat->GreenBits;
rrb->base.BlueBits = texImage->TexFormat->BlueBits;
rrb->base.AlphaBits = texImage->TexFormat->AlphaBits;
rrb->base.DepthBits = texImage->TexFormat->DepthBits;
rrb->base.Delete = radeon_delete_renderbuffer;
rrb->base.AllocStorage = radeon_nop_alloc_storage;
return GL_TRUE;
}
static struct radeon_renderbuffer *
radeon_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage)
{
const GLuint name = ~0; /* not significant, but distinct for debugging */
struct radeon_renderbuffer *rrb;
/* make an radeon_renderbuffer to wrap the texture image */
rrb = CALLOC_STRUCT(radeon_renderbuffer);
if (!rrb) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture");
return NULL;
}
_mesa_init_renderbuffer(&rrb->base, name);
rrb->base.ClassID = RADEON_RB_CLASS;
if (!radeon_update_wrapper(ctx, rrb, texImage)) {
_mesa_free(rrb);
return NULL;
}
return rrb;
}
static void
radeon_render_texture(GLcontext * ctx,

View file

@ -1175,90 +1175,7 @@ radeonInitDriver( __DRIscreenPrivate *sPriv )
return GL_TRUE;
}
static GLboolean
radeon_alloc_window_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
GLenum intFormat, GLuint w, GLuint h)
{
rb->Width = w;
rb->Height = h;
rb->_ActualFormat = intFormat;
return GL_TRUE;
}
static struct radeon_renderbuffer *
radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)
{
struct radeon_renderbuffer *ret;
ret = CALLOC_STRUCT(radeon_renderbuffer);
if (!ret)
return NULL;
_mesa_init_renderbuffer(&ret->base, 0);
ret->base.ClassID = RADEON_RB_CLASS;
/* XXX format junk */
switch (format) {
case GL_RGB5:
ret->base._ActualFormat = GL_RGB5;
ret->base._BaseFormat = GL_RGBA;
ret->base.RedBits = 5;
ret->base.GreenBits = 6;
ret->base.BlueBits = 5;
ret->base.DataType = GL_UNSIGNED_BYTE;
break;
case GL_RGBA8:
ret->base._ActualFormat = GL_RGBA8;
ret->base._BaseFormat = GL_RGBA;
ret->base.RedBits = 8;
ret->base.GreenBits = 8;
ret->base.BlueBits = 8;
ret->base.AlphaBits = 8;
ret->base.DataType = GL_UNSIGNED_BYTE;
break;
case GL_STENCIL_INDEX8_EXT:
ret->base._ActualFormat = GL_STENCIL_INDEX8_EXT;
ret->base._BaseFormat = GL_STENCIL_INDEX;
ret->base.StencilBits = 8;
ret->base.DataType = GL_UNSIGNED_BYTE;
break;
case GL_DEPTH_COMPONENT16:
ret->base._ActualFormat = GL_DEPTH_COMPONENT16;
ret->base._BaseFormat = GL_DEPTH_COMPONENT;
ret->base.DepthBits = 16;
ret->base.DataType = GL_UNSIGNED_SHORT;
break;
case GL_DEPTH_COMPONENT24:
ret->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
ret->base._BaseFormat = GL_DEPTH_COMPONENT;
ret->base.DepthBits = 24;
ret->base.DataType = GL_UNSIGNED_INT;
break;
case GL_DEPTH24_STENCIL8_EXT:
ret->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
ret->base._BaseFormat = GL_DEPTH_STENCIL_EXT;
ret->base.DepthBits = 24;
ret->base.StencilBits = 8;
ret->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
break;
default:
fprintf(stderr, "%s: Unknown format 0x%04x\n", __FUNCTION__, format);
_mesa_delete_renderbuffer(&ret->base);
return NULL;
}
ret->dPriv = driDrawPriv;
ret->base.InternalFormat = format;
ret->base.AllocStorage = radeon_alloc_window_storage;
radeonSetSpanFunctions(ret);
ret->bo = NULL;
return ret;
}
/**
* Create the Mesa framebuffer and renderbuffers for a given window/drawable.
@ -1298,29 +1215,29 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
depthFormat = GL_DEPTH_COMPONENT24;
/* front color renderbuffer */
rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
rfb->color_rb[0] = radeon_renderbuffer(radeon_create_renderbuffer(rgbFormat, driDrawPriv));
_mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base);
rfb->color_rb[0]->has_surface = 1;
/* back color renderbuffer */
if (mesaVis->doubleBufferMode) {
rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
rfb->color_rb[1] = radeon_renderbuffer(radeon_create_renderbuffer(rgbFormat, driDrawPriv));
_mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base);
rfb->color_rb[1]->has_surface = 1;
}
/* depth renderbuffer */
if (depthFormat != GL_NONE) {
struct radeon_renderbuffer *depth =
radeon_create_renderbuffer(depthFormat, driDrawPriv);
struct radeon_renderbuffer *depth = radeon_renderbuffer(
radeon_create_renderbuffer(depthFormat, driDrawPriv));
_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
depth->has_surface = screen->depthHasSurface;
}
/* stencil renderbuffer */
if (mesaVis->stencilBits > 0 && !swStencil) {
struct radeon_renderbuffer *stencil =
radeon_create_renderbuffer(GL_STENCIL_INDEX8_EXT, driDrawPriv);
struct radeon_renderbuffer *stencil = radeon_renderbuffer(
radeon_create_renderbuffer(GL_STENCIL_INDEX8_EXT, driDrawPriv));
_mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &stencil->base);
stencil->has_surface = screen->depthHasSurface;
}