diff options
author | Brian Paul <brian.paul@tungstengraphics.com> | 2006-03-25 17:56:49 +0000 |
---|---|---|
committer | Brian Paul <brian.paul@tungstengraphics.com> | 2006-03-25 17:56:49 +0000 |
commit | d65cda4ce3173e4e57752eb99ba8b413c8b7db24 (patch) | |
tree | a9e2234980bab37a0164a3992697d0d31d1ceed6 | |
parent | 460a375d854133814a0c141724cbe3b866186624 (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.c | 21 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_fbo.c | 22 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_span.c | 48 |
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 4f4731b614..223b9c6ee2 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 dc882dd4cb..fbd23ee773 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 cd4b30d217..24eac0dce2 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; + } } } } |