mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-26 10:40:11 +01:00
Implement software fallback for render-to-texture when the texture format
can't be rendered by the hardware.
This commit is contained in:
parent
460a375d85
commit
d65cda4ce3
3 changed files with 64 additions and 27 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue