Implement rendering to textures for any mipmap level, any cube face, any

3D texture slice.
Added draw_offset to intel_region struct.
This commit is contained in:
Brian Paul 2006-03-25 16:20:27 +00:00
parent 3e980901b0
commit e1998baef8
4 changed files with 57 additions and 48 deletions

View file

@ -247,12 +247,14 @@ static void i915_emit_state( struct intel_context *intel )
BEGIN_BATCH(I915_DEST_SETUP_SIZE+2, 0);
OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]);
OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]);
OUT_RELOC(state->draw_region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0);
OUT_RELOC(state->draw_region->buffer, DRM_MM_TT|DRM_MM_WRITE,
state->draw_region->draw_offset);
if (state->depth_region) {
OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]);
OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]);
OUT_RELOC(state->depth_region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0);
OUT_RELOC(state->depth_region->buffer, DRM_MM_TT|DRM_MM_WRITE,
state->depth_region->draw_offset);
}
OUT_BATCH(state->Buffer[I915_DESTREG_DV0]);

View file

@ -420,7 +420,8 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield mask, GLboolean all,
OUT_BATCH( BR13 );
OUT_BATCH( (b.y1 << 16) | b.x1 );
OUT_BATCH( (b.y2 << 16) | b.x2 );
OUT_RELOC( irb->region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0 );
OUT_RELOC( irb->region->buffer, DRM_MM_TT|DRM_MM_WRITE,
irb->region->draw_offset );
OUT_BATCH( clearVal );
ADVANCE_BATCH();
clearMask &= ~bufBit; /* turn off bit, for faster loop exit */

View file

@ -470,8 +470,10 @@ intel_framebuffer_renderbuffer(GLcontext *ctx,
GLenum attachment,
struct gl_renderbuffer *rb)
{
/*
_mesa_debug(ctx, "Intel FramebufferRenderbuffer %u %u\n",
fb->Name, rb ? rb->Name : 0);
*/
intelFlush(ctx);
@ -488,7 +490,7 @@ intel_framebuffer_renderbuffer(GLcontext *ctx,
static struct intel_renderbuffer *
intel_wrap_texture(GLcontext *ctx, struct gl_texture_image *texImage)
{
const GLuint name = ~0; /* XXX OK? */
const GLuint name = ~0; /* not significant, but distinct for debugging */
struct intel_renderbuffer *irb;
/* make an intel_renderbuffer to wrap the texture image */
@ -553,11 +555,10 @@ intel_renderbuffer_texture(GLcontext *ctx,
{
struct gl_texture_image *newImage
= att->Texture->Image[att->CubeMapFace][att->TextureLevel];
struct intel_renderbuffer *irb
= intel_renderbuffer(att->Renderbuffer);
struct intel_texture_image *intel_image;
GLuint imageOffset;
(void) fb;
@ -565,33 +566,45 @@ intel_renderbuffer_texture(GLcontext *ctx,
if (!irb) {
irb = intel_wrap_texture(ctx, newImage);
if (irb) {
/* bind the wrapper to the attachment point */
att->Renderbuffer = &irb->Base;
}
else {
/* fallback to software rendering */
_mesa_problem(ctx, "Render to texture - unsupported hw format");
_mesa_renderbuffer_texture(ctx, fb, att);
/* XXX FBO: Need to map the buffer (or in intelSpanRenderStart???) */
return;
}
}
if (irb) {
/* hardware rendering to texture */
irb->Base.RefCount++;
/*
_mesa_debug(ctx, "Begin render texture tex=%u w=%d h=%d refcount=%d\n",
att->Texture->Name, newImage->Width, newImage->Height,
irb->Base.RefCount);
*/
/*
_mesa_debug(ctx, "Begin render texture (tid %u) tex %u\n",
_glthread_GetID(), att->Texture->Name);
*/
/* point the renderbufer's region to the texture image region */
intel_image = intel_texture_image(newImage);
if (irb->region != intel_image->mt->region)
intel_region_reference(&irb->region, intel_image->mt->region);
/* hook into the region */
/* XXX mipmap level / cube face */
intel_image = intel_texture_image(newImage);
if (irb->region != intel_image->mt->region)
intel_region_reference(&irb->region, intel_image->mt->region);
att->Renderbuffer = &irb->Base;
intel_draw_buffer(ctx, fb);
}
else {
/* fallback to software rendering */
_mesa_problem(ctx, "Render to texture - unsupported hw format");
_mesa_renderbuffer_texture(ctx, fb, att);
/* XXX FBO: Need to map the buffer (or in intelSpanRenderStart???) */
/* compute offset of the particular 2D image within the texture region */
imageOffset = intel_miptree_image_offset(intel_image->mt,
att->CubeMapFace,
att->TextureLevel);
if (att->Texture->Target == GL_TEXTURE_3D) {
GLuint imgStride = intel_miptree_depth_image_stride(intel_image->mt,
att->CubeMapFace,
att->TextureLevel);
imageOffset += imgStride * att->Zoffset;
}
/* store that offset in the region */
intel_image->mt->region->draw_offset = imageOffset;
/* update drawing region, etc */
intel_draw_buffer(ctx, fb);
}
@ -612,21 +625,11 @@ intel_finish_render_texture(GLcontext *ctx,
*/
if (irb) {
/* hardware */
/* just release the region */
intel_region_release(intel, &irb->region);
irb->Base.RefCount--;
/*
_mesa_debug(ctx, "intel_finish_render_texture, refcount=%d\n",
irb->Base.RefCount);
*/
/* should never hit zero here */
assert(irb->Base.RefCount > 0);
}
else {
/* software */
else if (att->Renderbuffer) {
/* software fallback */
_mesa_finish_render_texture(ctx, att);
/* XXX FBO: Need to unmap the buffer (or in intelSpanRenderStart???) */
}

View file

@ -41,15 +41,18 @@ struct intel_context;
* - Blitter commands for copying 2D regions between buffers. (really???)
*/
struct intel_region {
GLuint buffer; /* buffer manager's buffer ID */
GLuint refcount;
GLuint cpp; /* bytes per pixel */
GLuint pitch; /* in pixels */
GLuint height; /* in pixels */
GLubyte *map; /* only non-NULL when region is actually mapped */
GLuint map_refcount;
GLuint buffer; /**< buffer manager's buffer ID */
GLuint refcount; /**< Reference count for region */
GLuint cpp; /**< bytes per pixel */
GLuint pitch; /**< in pixels */
GLuint height; /**< in pixels */
GLubyte *map; /**< only non-NULL when region is actually mapped */
GLuint map_refcount; /**< Reference count for mapping */
GLuint draw_offset; /**< Offset of drawing address within the region */
};
/* Allocate a refcounted region. Pointers to regions should only be
* copied by calling intel_reference_region().
*/