#include "main/texrender.h"
#include "radeon_common.h"
+#include "radeon_mipmap_tree.h"
#define FILE_DEBUG_FLAG DEBUG_TEXTURE
#define DBG(...) do { \
static void
radeon_delete_renderbuffer(struct gl_renderbuffer *rb)
{
- GET_CURRENT_CONTEXT(ctx);
struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
ASSERT(rrb);
if (rrb && rrb->bo) {
radeon_bo_unref(rrb->bo);
}
-
-
_mesa_free(rrb);
}
width, height);
}
else {
- /* TODO Alloc a BO */
-
- // rrb->bo = radeon_bo_open();
+ uint32_t size = width * height * cpp;
+ uint32_t pitch = ((cpp * width + 63) & ~63) / cpp;
+
+ fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width,
+ height, pitch);
+
+ rrb->pitch = pitch * cpp;
+ rrb->cpp = cpp;
+ rrb->bo = radeon_bo_open(radeon->radeonScreen->bom,
+ 0,
+ size,
+ 0,
+ RADEON_GEM_DOMAIN_VRAM,
+ 0);
rb->Width = width;
rb->Height = height;
return GL_TRUE;
return GL_FALSE;
}
-struct gl_renderbuffer *
+struct radeon_renderbuffer *
radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)
{
struct radeon_renderbuffer *rrb;
rrb->base.AllocStorage = radeon_alloc_window_storage;
rrb->base.GetPointer = radeon_get_pointer;
- radeonSetSpanFunctions(rrb);
-
rrb->bo = NULL;
- return &rrb->base;
+ return rrb;
}
static struct gl_renderbuffer *
return &rrb->base;
}
-
static void
radeon_bind_framebuffer(GLcontext * ctx, GLenum target,
struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
struct gl_texture_image *texImage)
{
if (texImage->TexFormat == &_mesa_texformat_argb8888) {
+ rrb->cpp = 4;
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->cpp = 2;
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->cpp = 2;
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->cpp = 4;
rrb->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
rrb->base._BaseFormat = GL_DEPTH_STENCIL_EXT;
rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
return GL_FALSE;
}
+ rrb->pitch = texImage->Width * rrb->cpp;
rrb->base.InternalFormat = rrb->base._ActualFormat;
rrb->base.Width = texImage->Width;
rrb->base.Height = texImage->Height;
struct gl_framebuffer *fb,
struct gl_renderbuffer_attachment *att)
{
+ struct gl_texture_image *newImage
+ = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
+ struct radeon_renderbuffer *rrb = radeon_renderbuffer(att->Renderbuffer);
+ radeon_texture_image *radeon_image;
+ GLuint imageOffset;
+
+ (void) fb;
+
+ ASSERT(newImage);
+
+ if (newImage->Border != 0) {
+ /* Fallback on drawing to a texture with a border, which won't have a
+ * miptree.
+ */
+ _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
+ _mesa_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);
+ }
+ else {
+ /* fallback to software rendering */
+ _mesa_render_texture(ctx, fb, att);
+ return;
+ }
+ }
+
+ if (!radeon_update_wrapper(ctx, rrb, newImage)) {
+ _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
+ _mesa_render_texture(ctx, fb, att);
+ return;
+ }
+
+ DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n",
+ _glthread_GetID(),
+ att->Texture->Name, newImage->Width, newImage->Height,
+ rrb->base.RefCount);
+
+ /* point the renderbufer's region to the texture image region */
+ radeon_image = (radeon_texture_image *)newImage;
+ if (rrb->bo != radeon_image->mt->bo) {
+ if (rrb->bo)
+ radeon_bo_unref(rrb->bo);
+ rrb->bo = radeon_image->mt->bo;
+ radeon_bo_ref(rrb->bo);
+ }
+
+ /* compute offset of the particular 2D image within the texture region */
+ imageOffset = radeon_miptree_image_offset(radeon_image->mt,
+ att->CubeMapFace,
+ att->TextureLevel);
+
+ if (att->Texture->Target == GL_TEXTURE_3D) {
+ const GLuint *offsets = radeon_miptree_depth_offsets(radeon_image->mt,
+ att->TextureLevel);
+ imageOffset += offsets[att->Zoffset];
+ }
+ /* store that offset in the region */
+ rrb->draw_offset = imageOffset;
+
+ /* update drawing region, etc */
+ radeon_draw_buffer(ctx, fb);
}
static void
}
-
+void radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb,
+ struct radeon_bo *bo)
+{
+ struct radeon_bo *old;
+ old = rb->bo;
+ rb->bo = bo;
+ radeon_bo_ref(bo);
+ if (old)
+ radeon_bo_unref(old);
+}