X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fintel%2Fintel_fbo.c;h=4537f1fb97b1b1ce0a6e6ca4d4ac00ae8b12280e;hb=66389bb99d86c8d96c2a7dbd83a5227c0e13e767;hp=f48703e155cb43a1dafcc548b403918d43600007;hpb=3db27d4a4aee9f311a447778ce94007415f2637f;p=mesa.git diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index f48703e155c..4537f1fb97b 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -70,24 +70,15 @@ intel_new_framebuffer(struct gl_context * ctx, GLuint name) static void intel_delete_renderbuffer(struct gl_renderbuffer *rb) { - GET_CURRENT_CONTEXT(ctx); - struct intel_context *intel = intel_context(ctx); struct intel_renderbuffer *irb = intel_renderbuffer(rb); ASSERT(irb); - if (intel && irb->region) { - intel_region_release(&irb->region); - } - if (intel && irb->hiz_region) { - intel_region_release(&irb->hiz_region); - } - if (intel && irb->wrapped_depth) { - _mesa_reference_renderbuffer(&irb->wrapped_depth, NULL); - } - if (intel && irb->wrapped_stencil) { - _mesa_reference_renderbuffer(&irb->wrapped_stencil, NULL); - } + intel_region_release(&irb->region); + intel_region_release(&irb->hiz_region); + + _mesa_reference_renderbuffer(&irb->wrapped_depth, NULL); + _mesa_reference_renderbuffer(&irb->wrapped_stencil, NULL); free(irb); } @@ -107,17 +98,11 @@ intel_get_pointer(struct gl_context * ctx, struct gl_renderbuffer *rb, } -static struct gl_renderbuffer* -intel_create_wrapped_renderbuffer(struct gl_context * ctx, - struct gl_renderbuffer *wrapper, - gl_format format); - - /** * Called via glRenderbufferStorageEXT() to set the format and allocate * storage for a user-created renderbuffer. */ -static GLboolean +GLboolean intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) @@ -188,6 +173,9 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer if (irb->Base.Format == MESA_FORMAT_S8) { /* + * The stencil buffer is W tiled. However, we request from the kernel a + * non-tiled buffer because the GTT is incapable of W fencing. + * * The stencil buffer has quirky pitch requirements. From Vol 2a, * 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch": * The pitch must be set to 2x the value computed based on width, as @@ -195,15 +183,14 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer * To accomplish this, we resort to the nasty hack of doubling the drm * region's cpp and halving its height. * - * If we neglect to double the pitch, then drm_intel_gem_bo_map_gtt() - * maps the memory incorrectly. + * If we neglect to double the pitch, then render corruption occurs. */ irb->region = intel_region_alloc(intel->intelScreen, - I915_TILING_Y, + I915_TILING_NONE, cpp * 2, - width, - height / 2, - GL_TRUE); + ALIGN(width, 64), + ALIGN((height + 1) / 2, 64), + true); if (!irb->region) return false; @@ -214,9 +201,9 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer struct gl_renderbuffer *depth_rb; struct gl_renderbuffer *stencil_rb; - depth_rb = intel_create_wrapped_renderbuffer(ctx, rb, + depth_rb = intel_create_wrapped_renderbuffer(ctx, width, height, MESA_FORMAT_X8_Z24); - stencil_rb = intel_create_wrapped_renderbuffer(ctx, rb, + stencil_rb = intel_create_wrapped_renderbuffer(ctx, width, height, MESA_FORMAT_S8); ok = depth_rb && stencil_rb; ok = ok && intel_alloc_renderbuffer_storage(ctx, depth_rb, @@ -236,12 +223,14 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer return false; } + depth_rb->Wrapped = rb; + stencil_rb->Wrapped = rb; _mesa_reference_renderbuffer(&irb->wrapped_depth, depth_rb); _mesa_reference_renderbuffer(&irb->wrapped_stencil, stencil_rb); } else { irb->region = intel_region_alloc(intel->intelScreen, tiling, cpp, - width, height, GL_TRUE); + width, height, true); if (!irb->region) return false; @@ -251,7 +240,7 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer irb->region->cpp, irb->region->width, irb->region->height, - GL_TRUE); + true); if (!irb->hiz_region) { intel_region_release(&irb->region); return false; @@ -259,7 +248,7 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer } } - return GL_TRUE; + return true; } @@ -280,9 +269,18 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx, if (image == NULL) return; + /* __DRIimage is opaque to the core so it has to be checked here */ + switch (image->format) { + case MESA_FORMAT_RGBA8888_REV: + _mesa_error(&intel->ctx, GL_INVALID_OPERATION, + "glEGLImageTargetRenderbufferStorage(unsupported image format"); + return; + break; + default: + break; + } + irb = intel_renderbuffer(rb); - if (irb->region) - intel_region_release(&irb->region); intel_region_reference(&irb->region, image->region); rb->InternalFormat = image->internal_format; @@ -309,7 +307,7 @@ intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, rb->Height = height; rb->InternalFormat = internalFormat; - return GL_TRUE; + return true; } @@ -321,7 +319,7 @@ intel_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb, _mesa_resize_framebuffer(ctx, fb, width, height); - fb->Initialized = GL_TRUE; /* XXX remove someday */ + fb->Initialized = true; /* XXX remove someday */ if (fb->Name != 0) { return; @@ -346,36 +344,9 @@ intel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) { _mesa_problem(ctx, "intel_op_alloc_storage should never be called."); - return GL_FALSE; -} - - -void -intel_renderbuffer_set_region(struct intel_context *intel, - struct intel_renderbuffer *rb, - struct intel_region *region) -{ - struct intel_region *old; - - old = rb->region; - rb->region = NULL; - intel_region_reference(&rb->region, region); - intel_region_release(&old); + return false; } - -void -intel_renderbuffer_set_hiz_region(struct intel_context *intel, - struct intel_renderbuffer *rb, - struct intel_region *region) -{ - struct intel_region *old = rb->hiz_region; - rb->hiz_region = NULL; - intel_region_reference(&rb->hiz_region, region); - intel_region_release(&old); -} - - /** * Create a new intel_renderbuffer which corresponds to an on-screen window, * not a user-created renderbuffer. @@ -409,9 +380,9 @@ intel_create_renderbuffer(gl_format format) } -static struct gl_renderbuffer * +struct gl_renderbuffer* intel_create_wrapped_renderbuffer(struct gl_context * ctx, - struct gl_renderbuffer *wrapper, + int width, int height, gl_format format) { /* @@ -433,18 +404,8 @@ intel_create_wrapped_renderbuffer(struct gl_context * ctx, rb->Format = format; rb->InternalFormat = rb->_BaseFormat; rb->DataType = intel_mesa_format_to_rb_datatype(format); - rb->Width = wrapper->Width; - rb->Height = wrapper->Height; - - rb->AllocStorage = intel_nop_alloc_storage; - rb->Delete = intel_delete_renderbuffer; - rb->GetPointer = intel_get_pointer; - - /* - * A refcount here would cause a cyclic reference. The wrapper references - * the unwrapper. - */ - rb->Wrapped = wrapper; + rb->Width = width; + rb->Height = height; return rb; } @@ -487,7 +448,7 @@ intel_bind_framebuffer(struct gl_context * ctx, GLenum target, struct gl_framebuffer *fb, struct gl_framebuffer *fbread) { if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { - intel_draw_buffer(ctx, fb); + intel_draw_buffer(ctx); } else { /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */ @@ -508,62 +469,105 @@ intel_framebuffer_renderbuffer(struct gl_context * ctx, intel_flush(ctx); _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); - intel_draw_buffer(ctx, fb); + intel_draw_buffer(ctx); } +static bool +intel_update_tex_wrapper_regions(struct intel_context *intel, + struct intel_renderbuffer *irb, + struct intel_texture_image *intel_image); -static GLboolean +static bool intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb, struct gl_texture_image *texImage) { struct intel_context *intel = intel_context(ctx); struct intel_texture_image *intel_image = intel_texture_image(texImage); + int width, height, depth; if (!intel_span_supports_format(texImage->TexFormat)) { DBG("Render to texture BAD FORMAT %s\n", _mesa_get_format_name(texImage->TexFormat)); - return GL_FALSE; + return false; } else { DBG("Render to texture %s\n", _mesa_get_format_name(texImage->TexFormat)); } + intel_miptree_get_dimensions_for_image(texImage, &width, &height, &depth); + irb->Base.Format = texImage->TexFormat; irb->Base.DataType = intel_mesa_format_to_rb_datatype(texImage->TexFormat); irb->Base.InternalFormat = texImage->InternalFormat; irb->Base._BaseFormat = _mesa_base_tex_format(ctx, irb->Base.InternalFormat); - irb->Base.Width = texImage->Width; - irb->Base.Height = texImage->Height; + irb->Base.Width = width; + irb->Base.Height = height; irb->Base.Delete = intel_delete_renderbuffer; irb->Base.AllocStorage = intel_nop_alloc_storage; + if (intel_image->stencil_rb) { + /* The tex image has packed depth/stencil format, but is using separate + * stencil. */ + + bool ok; + struct intel_renderbuffer *depth_irb = + intel_renderbuffer(intel_image->depth_rb); + + /* Update the hiz region if necessary. */ + ok = intel_update_tex_wrapper_regions(intel, depth_irb, intel_image); + if (!ok) { + return false; + } + + /* The tex image shares its embedded depth and stencil renderbuffers with + * the renderbuffer wrapper. */ + _mesa_reference_renderbuffer(&irb->wrapped_depth, + intel_image->depth_rb); + _mesa_reference_renderbuffer(&irb->wrapped_stencil, + intel_image->stencil_rb); + + return true; + } else { + return intel_update_tex_wrapper_regions(intel, irb, intel_image); + } +} + +/** + * FIXME: The handling of the hiz region is broken for mipmapped depth textures + * FIXME: because intel_finalize_mipmap_tree is unaware of it. + */ +static bool +intel_update_tex_wrapper_regions(struct intel_context *intel, + struct intel_renderbuffer *irb, + struct intel_texture_image *intel_image) +{ + struct gl_renderbuffer *rb = &irb->Base; + /* Point the renderbuffer's region to the texture's region. */ if (irb->region != intel_image->mt->region) { - intel_region_release(&irb->region); intel_region_reference(&irb->region, intel_image->mt->region); } /* Allocate the texture's hiz region if necessary. */ - if (intel->vtbl.is_hiz_depth_format(intel, texImage->TexFormat) + if (intel->vtbl.is_hiz_depth_format(intel, rb->Format) && !intel_image->mt->hiz_region) { intel_image->mt->hiz_region = intel_region_alloc(intel->intelScreen, I915_TILING_Y, - _mesa_get_format_bytes(texImage->TexFormat), - texImage->Width, - texImage->Height, - GL_TRUE); + _mesa_get_format_bytes(rb->Format), + rb->Width, + rb->Height, + true); if (!intel_image->mt->hiz_region) - return GL_FALSE; + return false; } /* Point the renderbuffer's hiz region to the texture's hiz region. */ if (irb->hiz_region != intel_image->mt->hiz_region) { - intel_region_release(&irb->hiz_region); intel_region_reference(&irb->hiz_region, intel_image->mt->hiz_region); } - return GL_TRUE; + return true; } @@ -596,22 +600,20 @@ intel_wrap_texture(struct gl_context * ctx, struct gl_texture_image *texImage) return irb; } -static void +void intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb, struct intel_texture_image *intel_image, int zoffset) { - struct intel_mipmap_tree *mt = intel_image->mt; unsigned int dst_x, dst_y; /* compute offset of the particular 2D image within the texture region */ intel_miptree_get_image_offset(intel_image->mt, - intel_image->level, - intel_image->face, + intel_image->base.Base.Level, + intel_image->base.Base.Face, zoffset, &dst_x, &dst_y); - irb->draw_offset = (dst_y * mt->region->pitch + dst_x) * mt->cpp; irb->draw_x = dst_x; irb->draw_y = dst_y; } @@ -652,6 +654,22 @@ intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb, } } +#ifndef I915 +static bool +need_tile_offset_workaround(struct brw_context *brw, + struct intel_renderbuffer *irb) +{ + uint32_t tile_x, tile_y; + + if (brw->has_surface_tile_offset) + return false; + + intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y); + + return tile_x != 0 || tile_y != 0; +} +#endif + /** * Called by glFramebufferTexture[123]DEXT() (and other places) to * prepare for rendering into texture memory. This might be called @@ -702,11 +720,10 @@ intel_render_texture(struct gl_context * ctx, irb->Base.RefCount); intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset); - intel_image->used_as_render_target = GL_TRUE; + intel_image->used_as_render_target = true; #ifndef I915 - if (!brw_context(ctx)->has_surface_tile_offset && - (irb->draw_offset & 4095) != 0) { + if (need_tile_offset_workaround(brw_context(ctx), irb)) { /* Original gen4 hardware couldn't draw to a non-tile-aligned * destination in a miptree unless you actually setup your * renderbuffer as a miptree and used the fragile @@ -715,34 +732,27 @@ intel_render_texture(struct gl_context * ctx, * into that. */ struct intel_context *intel = intel_context(ctx); - struct intel_mipmap_tree *old_mt = intel_image->mt; struct intel_mipmap_tree *new_mt; + int width, height, depth; + + intel_miptree_get_dimensions_for_image(image, &width, &height, &depth); new_mt = intel_miptree_create(intel, image->TexObject->Target, - intel_image->base.TexFormat, - intel_image->level, - intel_image->level, - intel_image->base.Width, - intel_image->base.Height, - intel_image->base.Depth, - GL_TRUE); - - intel_miptree_image_copy(intel, - new_mt, - intel_image->face, - intel_image->level, - old_mt); - - intel_miptree_release(intel, &intel_image->mt); - intel_image->mt = new_mt; + intel_image->base.Base.TexFormat, + intel_image->base.Base.Level, + intel_image->base.Base.Level, + width, height, depth, + true); + + intel_miptree_copy_teximage(intel, intel_image, new_mt); intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset); - intel_region_release(&irb->region); intel_region_reference(&irb->region, intel_image->mt->region); + intel_miptree_release(&new_mt); } #endif /* update drawing region, etc */ - intel_draw_buffer(ctx, fb); + intel_draw_buffer(ctx); } @@ -764,7 +774,7 @@ intel_finish_render_texture(struct gl_context * ctx, /* Flag that this image may now be validated into the object's miptree. */ if (intel_image) - intel_image->used_as_render_target = GL_FALSE; + intel_image->used_as_render_target = false; /* Since we've (probably) rendered to the texture and will (likely) use * it in the texture domain later on in this batchbuffer, flush the @@ -791,29 +801,21 @@ intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) * The depth and stencil renderbuffers are the same renderbuffer or wrap * the same texture. */ - bool depth_stencil_are_same; - if (depthRb && stencilRb && depthRb == stencilRb) - depth_stencil_are_same = true; - else if (depthRb && stencilRb && depthRb != stencilRb - && (fb->Attachment[BUFFER_DEPTH].Type == GL_TEXTURE) - && (fb->Attachment[BUFFER_STENCIL].Type == GL_TEXTURE) - && (fb->Attachment[BUFFER_DEPTH].Texture->Name - == fb->Attachment[BUFFER_STENCIL].Texture->Name)) - depth_stencil_are_same = true; - else - depth_stencil_are_same = false; - - bool fb_has_combined_depth_stencil_format = - (depthRb && depthRb->Base.Format == MESA_FORMAT_S8_Z24) || - (stencilRb && stencilRb->Base.Format == MESA_FORMAT_S8_Z24); - - bool fb_has_hiz = intel_framebuffer_has_hiz(fb); - - if ((intel->must_use_separate_stencil || fb_has_hiz) - && (depth_stencil_are_same || fb_has_combined_depth_stencil_format)) { - fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; - } else if (!intel->has_separate_stencil && depthRb && stencilRb && !depth_stencil_are_same) { - fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + if (depthRb && stencilRb) { + bool depth_stencil_are_same; + if (depthRb == stencilRb) + depth_stencil_are_same = true; + else if ((fb->Attachment[BUFFER_DEPTH].Type == GL_TEXTURE) && + (fb->Attachment[BUFFER_STENCIL].Type == GL_TEXTURE) && + (fb->Attachment[BUFFER_DEPTH].Texture->Name == + fb->Attachment[BUFFER_STENCIL].Texture->Name)) + depth_stencil_are_same = true; + else + depth_stencil_are_same = false; + + if (!intel->has_separate_stencil && !depth_stencil_are_same) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + } } for (i = 0; i < Elements(fb->Attachment); i++) { @@ -893,11 +895,9 @@ intel_blit_framebuffer_copy_tex_sub_image(struct gl_context *ctx, struct gl_texture_image *texImage = _mesa_select_tex_image(ctx, texObj, target, dstLevel); - GLenum internalFormat = texImage->InternalFormat; - if (intel_copy_texsubimage(intel_context(ctx), target, + if (intel_copy_texsubimage(intel_context(ctx), intel_texture_image(texImage), - internalFormat, dstX0, dstY0, srcX0, srcY0, srcX1 - srcX0, /* width */