mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-09 14:50:11 +01:00
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:
parent
3e980901b0
commit
e1998baef8
4 changed files with 57 additions and 48 deletions
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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???) */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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().
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue