summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2006-03-25 17:56:49 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>2006-03-25 17:56:49 +0000
commitd65cda4ce3173e4e57752eb99ba8b413c8b7db24 (patch)
treea9e2234980bab37a0164a3992697d0d31d1ceed6
parent460a375d854133814a0c141724cbe3b866186624 (diff)
Implement software fallback for render-to-texture when the texture format
can't be rendered by the hardware.
-rw-r--r--src/mesa/drivers/dri/i915/intel_buffers.c21
-rw-r--r--src/mesa/drivers/dri/i915/intel_fbo.c22
-rw-r--r--src/mesa/drivers/dri/i915/intel_span.c48
3 files changed, 64 insertions, 27 deletions
diff --git a/src/mesa/drivers/dri/i915/intel_buffers.c b/src/mesa/drivers/dri/i915/intel_buffers.c
index 4f4731b6140..223b9c6ee21 100644
--- a/src/mesa/drivers/dri/i915/intel_buffers.c
+++ b/src/mesa/drivers/dri/i915/intel_buffers.c
@@ -384,11 +384,11 @@ static void intelClear(GLcontext *ctx,
GLbitfield tri_mask = 0;
GLbitfield blit_mask = 0;
GLbitfield swrast_mask = 0;
+ GLuint i;
if (0)
fprintf(stderr, "%s\n", __FUNCTION__);
-
/* HW color buffers (front, back, aux, generic FBO, etc) */
if (colorMask == ~0) {
/* clear all R,G,B,A */
@@ -429,6 +429,18 @@ static void intelClear(GLcontext *ctx,
/* SW fallback clearing */
swrast_mask = mask & ~tri_mask & ~blit_mask;
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ GLuint bufBit = 1 << i;
+ if ((blit_mask | tri_mask) & bufBit) {
+ if (!ctx->DrawBuffer->Attachment[i].Renderbuffer->ClassID) {
+ blit_mask &= ~bufBit;
+ tri_mask &= ~bufBit;
+ swrast_mask |= bufBit;
+ }
+ }
+ }
+
+
intelFlush( ctx ); /* XXX intelClearWithBlit also does this */
if (blit_mask)
@@ -603,6 +615,13 @@ intel_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
colorRegion = (irb && irb->region) ? irb->region : NULL;
}
+ if (!colorRegion) {
+ FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE );
+ }
+ else {
+ FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE );
+ }
+
/***
*** Get depth buffer region and check if we need a software fallback.
*** Note that the depth buffer is usually a DEPTH_STENCIL buffer.
diff --git a/src/mesa/drivers/dri/i915/intel_fbo.c b/src/mesa/drivers/dri/i915/intel_fbo.c
index dc882dd4cb3..fbd23ee773e 100644
--- a/src/mesa/drivers/dri/i915/intel_fbo.c
+++ b/src/mesa/drivers/dri/i915/intel_fbo.c
@@ -120,29 +120,15 @@ intel_delete_renderbuffer(struct gl_renderbuffer *rb)
/**
* Return a pointer to a specific pixel in a renderbuffer.
- * Note: y=0=bottom.
- * Called via gl_renderbuffer::GetPointer().
*/
static void *
intel_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb,
GLint x, GLint y)
{
- struct intel_renderbuffer *irb = intel_renderbuffer(rb);
-
- /* Actually, we could _always_ return NULL from this function and
- * be OK. The swrast code would just use the Get/Put routines as needed.
- * But by really implementing this function there's a chance for better
- * performance.
+ /* By returning NULL we force all software rendering to go through
+ * the span routines.
*/
- if (irb->region && irb->region->map) {
- int offset;
- y = irb->region->height - y - 1;
- offset = (y * irb->region->pitch + x) * irb->region->cpp;
- return (void *) (irb->region->map + offset);
- }
- else {
- return NULL;
- }
+ return NULL;
}
@@ -572,9 +558,7 @@ intel_renderbuffer_texture(GLcontext *ctx,
}
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;
}
}
diff --git a/src/mesa/drivers/dri/i915/intel_span.c b/src/mesa/drivers/dri/i915/intel_span.c
index cd4b30d2178..24eac0dce21 100644
--- a/src/mesa/drivers/dri/i915/intel_span.c
+++ b/src/mesa/drivers/dri/i915/intel_span.c
@@ -172,6 +172,11 @@
* XXX in the future, we could probably convey extra information to
* reduce the number of mappings needed. I.e. if doing a glReadPixels
* from the depth buffer, we really only need one mapping.
+ *
+ * XXX Rewrite this function someday.
+ * We can probably just loop over all the renderbuffer attachments,
+ * map/unmap all of them, and not worry about the _ColorDrawBuffers
+ * _ColorReadBuffer, _DepthBuffer or _StencilBuffer fields.
*/
static void
intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
@@ -185,9 +190,8 @@ intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers[i]; j++) {
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i][j];
irb = intel_renderbuffer(rb);
- /* XXX FBO: check irb != NULL to catch software RBs??? */
- ASSERT(irb);
- if (irb->Base.Name != 0) { /* XXX FBO temporary test */
+ if (irb && irb->Base.Name != 0) { /* XXX FBO temporary test */
+ /* this is a user-created intel_renderbuffer */
if (irb->region) {
if (map)
intel_region_map(intel, irb->region);
@@ -200,6 +204,24 @@ intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
}
}
+ /* check for render to textures */
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment + i;
+ struct gl_texture_object *tex = att->Texture;
+ if (tex) {
+ /* render to texture */
+ ASSERT(att->Renderbuffer);
+ if (map) {
+ struct gl_texture_image *texImg;
+ texImg = tex->Image[att->CubeMapFace][att->TextureLevel];
+ intel_tex_map_images(intel, intel_texture_object(tex));
+ }
+ else {
+ intel_tex_unmap_images(intel, intel_texture_object(tex));
+ }
+ }
+ }
+
/* color read buffers */
irb = intel_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
if (irb && irb->region && irb->Base.Name != 0) {
@@ -242,10 +264,16 @@ intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
if (ctx->DrawBuffer->_DepthBuffer) {
irb = intel_renderbuffer(ctx->DrawBuffer->_DepthBuffer->Wrapped);
if (irb && irb->region && irb->Base.Name != 0) {
- if (map)
+ if (map) {
intel_region_map(intel, irb->region);
- else
+ irb->pfMap = irb->region->map;
+ irb->pfPitch = irb->region->pitch;
+ }
+ else {
intel_region_unmap(intel, irb->region);
+ irb->pfMap = NULL;
+ irb->pfPitch = 0;
+ }
}
}
@@ -253,10 +281,16 @@ intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
if (ctx->DrawBuffer->_StencilBuffer) {
irb = intel_renderbuffer(ctx->DrawBuffer->_StencilBuffer->Wrapped);
if (irb && irb->region && irb->Base.Name != 0) {
- if (map)
+ if (map) {
intel_region_map(intel, irb->region);
- else
+ irb->pfMap = irb->region->map;
+ irb->pfPitch = irb->region->pitch;
+ }
+ else {
intel_region_unmap(intel, irb->region);
+ irb->pfMap = NULL;
+ irb->pfPitch = 0;
+ }
}
}
}