X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fintel_fbo.c;h=64d57e8bc897b558e6d4cad138da249f0f588f5e;hb=9b387b5d3f4103c51079ea5298d33086af6da433;hp=c70b1bf36b2806854673c57b874598a86a9012c7;hpb=98328e4c193c90bc9945531f82595f09410b1a3b;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/intel_fbo.c b/src/mesa/drivers/dri/i965/intel_fbo.c index c70b1bf36b2..64d57e8bc89 100644 --- a/src/mesa/drivers/dri/i965/intel_fbo.c +++ b/src/mesa/drivers/dri/i965/intel_fbo.c @@ -36,8 +36,9 @@ #include "main/context.h" #include "main/teximage.h" #include "main/image.h" -#include "main/hash_table.h" -#include "main/set.h" +#include "main/condrender.h" +#include "util/hash_table.h" +#include "util/set.h" #include "swrast/swrast.h" #include "drivers/common/meta.h" @@ -47,7 +48,7 @@ #include "intel_blit.h" #include "intel_fbo.h" #include "intel_mipmap_tree.h" -#include "intel_regions.h" +#include "intel_image.h" #include "intel_screen.h" #include "intel_tex.h" #include "brw_context.h" @@ -73,7 +74,7 @@ intel_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb) { struct intel_renderbuffer *irb = intel_renderbuffer(rb); - ASSERT(irb); + assert(irb); intel_miptree_release(&irb->mt); intel_miptree_release(&irb->singlesample_mt); @@ -126,7 +127,7 @@ intel_map_renderbuffer(struct gl_context *ctx, struct intel_renderbuffer *irb = intel_renderbuffer(rb); struct intel_mipmap_tree *mt; void *map; - int stride; + ptrdiff_t stride; if (srb->Buffer) { /* this is a malloc'd renderbuffer (accum buffer), not an irb */ @@ -188,8 +189,8 @@ intel_map_renderbuffer(struct gl_context *ctx, stride = -stride; } - DBG("%s: rb %d (%s) mt mapped: (%d, %d) (%dx%d) -> %p/%d\n", - __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format), + DBG("%s: rb %d (%s) mt mapped: (%d, %d) (%dx%d) -> %p/%"PRIdPTR"\n", + __func__, rb->Name, _mesa_get_format_name(rb->Format), x, y, w, h, map, stride); *out_map = map; @@ -213,7 +214,7 @@ intel_unmap_renderbuffer(struct gl_context *ctx, struct intel_renderbuffer *irb = intel_renderbuffer(rb); struct intel_mipmap_tree *mt; - DBG("%s: rb %d (%s)\n", __FUNCTION__, + DBG("%s: rb %d (%s)\n", __func__, rb->Name, _mesa_get_format_name(rb->Format)); if (srb->Buffer) { @@ -259,20 +260,10 @@ intel_quantize_num_samples(struct intel_screen *intel, unsigned num_samples) return quantized_samples; } - -/** - * Called via glRenderbufferStorageEXT() to set the format and allocate - * storage for a user-created renderbuffer. - */ -static GLboolean -intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, - GLenum internalFormat, - GLuint width, GLuint height) +static mesa_format +intel_renderbuffer_format(struct gl_context * ctx, GLenum internalFormat) { struct brw_context *brw = brw_context(ctx); - struct intel_screen *screen = brw->intelScreen; - struct intel_renderbuffer *irb = intel_renderbuffer(rb); - rb->NumSamples = intel_quantize_num_samples(screen, rb->NumSamples); switch (internalFormat) { default: @@ -281,9 +272,9 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer * except they're less useful because you can't texture with * them. */ - rb->Format = ctx->Driver.ChooseTextureFormat(ctx, GL_TEXTURE_2D, - internalFormat, - GL_NONE, GL_NONE); + return ctx->Driver.ChooseTextureFormat(ctx, GL_TEXTURE_2D, + internalFormat, + GL_NONE, GL_NONE); break; case GL_STENCIL_INDEX: case GL_STENCIL_INDEX1_EXT: @@ -292,22 +283,34 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer case GL_STENCIL_INDEX16_EXT: /* These aren't actual texture formats, so force them here. */ if (brw->has_separate_stencil) { - rb->Format = MESA_FORMAT_S_UINT8; + return MESA_FORMAT_S_UINT8; } else { assert(!brw->must_use_separate_stencil); - rb->Format = MESA_FORMAT_Z24_UNORM_S8_UINT; + return MESA_FORMAT_Z24_UNORM_S8_UINT; } - break; } +} + +static GLboolean +intel_alloc_private_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + struct brw_context *brw = brw_context(ctx); + struct intel_screen *screen = brw->intelScreen; + struct intel_renderbuffer *irb = intel_renderbuffer(rb); + + assert(rb->Format != MESA_FORMAT_NONE); + rb->NumSamples = intel_quantize_num_samples(screen, rb->NumSamples); rb->Width = width; rb->Height = height; rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); intel_miptree_release(&irb->mt); - DBG("%s: %s: %s (%dx%d)\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(internalFormat), + DBG("%s: %s: %s (%dx%d)\n", __func__, + _mesa_enum_to_string(internalFormat), _mesa_get_format_name(rb->Format), width, height); if (width == 0 || height == 0) @@ -324,6 +327,18 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer return true; } +/** + * Called via glRenderbufferStorageEXT() to set the format and allocate + * storage for a user-created renderbuffer. + */ +static GLboolean +intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + rb->Format = intel_renderbuffer_format(ctx, internalFormat); + return intel_alloc_private_renderbuffer_storage(ctx, rb, internalFormat, width, height); +} static void intel_image_target_renderbuffer_storage(struct gl_context *ctx, @@ -348,13 +363,6 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx, return; } - /* Buffers originating from outside are for read-only. */ - if (image->dma_buf_imported) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glEGLImageTargetRenderbufferStorage(dma buffers are read-only)"); - return; - } - /* __DRIimage is opaque to the core so it has to be checked here */ switch (image->format) { case MESA_FORMAT_R8G8B8A8_UNORM: @@ -368,22 +376,29 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx, irb = intel_renderbuffer(rb); intel_miptree_release(&irb->mt); + + /* Disable creation of the miptree's aux buffers because the driver exposes + * no EGL API to manage them. That is, there is no API for resolving the aux + * buffer's content to the main buffer nor for invalidating the aux buffer's + * content. + */ irb->mt = intel_miptree_create_for_bo(brw, - image->region->bo, + image->bo, image->format, image->offset, - image->region->width, - image->region->height, - image->region->pitch, - image->region->tiling); + image->width, + image->height, + 1, + image->pitch, + MIPTREE_LAYOUT_DISABLE_AUX); if (!irb->mt) return; rb->InternalFormat = image->internal_format; - rb->Width = image->region->width; - rb->Height = image->region->height; + rb->Width = image->width; + rb->Height = image->height; rb->Format = image->format; - rb->_BaseFormat = _mesa_base_fbo_format(ctx, image->internal_format); + rb->_BaseFormat = _mesa_get_format_base_format(image->format); rb->NeedsFinishRenderTexture = true; irb->layer_count = 1; } @@ -400,7 +415,7 @@ static GLboolean intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) { - ASSERT(rb->Name == 0); + assert(rb->Name == 0); rb->Width = width; rb->Height = height; rb->InternalFormat = internalFormat; @@ -413,7 +428,7 @@ static GLboolean 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."); + _mesa_problem(ctx, "intel_nop_alloc_storage should never be called."); return false; } @@ -468,7 +483,7 @@ intel_create_private_renderbuffer(mesa_format format, unsigned num_samples) struct intel_renderbuffer *irb; irb = intel_create_renderbuffer(format, num_samples); - irb->Base.Base.AllocStorage = intel_alloc_renderbuffer_storage; + irb->Base.Base.AllocStorage = intel_alloc_private_renderbuffer_storage; return irb; } @@ -536,19 +551,21 @@ intel_renderbuffer_update_wrapper(struct brw_context *brw, irb->mt_layer = layer_multiplier * layer; - if (layered) { - irb->layer_count = image->TexObject->NumLayers ?: mt->level[level].depth / layer_multiplier; - } else { + if (!layered) { irb->layer_count = 1; + } else if (image->TexObject->NumLayers > 0) { + irb->layer_count = image->TexObject->NumLayers; + } else { + irb->layer_count = mt->level[level].depth / layer_multiplier; } intel_miptree_reference(&irb->mt, mt); intel_renderbuffer_set_draw_offset(irb); - if (mt->hiz_mt == NULL && brw_is_hiz_depth_format(brw, rb->Format)) { + if (intel_miptree_wants_hiz_buffer(brw, mt)) { intel_miptree_alloc_hiz(brw, mt); - if (!mt->hiz_mt) + if (!mt->hiz_buf) return false; } @@ -624,6 +641,7 @@ intel_render_texture(struct gl_context * ctx, static GLuint msg_id = 0; \ if (unlikely(ctx->Const.ContextFlags & GL_CONTEXT_FLAG_DEBUG_BIT)) { \ _mesa_gl_debug(ctx, &msg_id, \ + MESA_DEBUG_SOURCE_API, \ MESA_DEBUG_TYPE_OTHER, \ MESA_DEBUG_SEVERITY_MEDIUM, \ __VA_ARGS__); \ @@ -644,9 +662,9 @@ intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) struct intel_renderbuffer *stencilRb = intel_get_renderbuffer(fb, BUFFER_STENCIL); struct intel_mipmap_tree *depth_mt = NULL, *stencil_mt = NULL; - int i; + unsigned i; - DBG("%s() on fb %p (%s)\n", __FUNCTION__, + DBG("%s() on fb %p (%s)\n", __func__, fb, (fb == ctx->DrawBuffer ? "drawbuffer" : (fb == ctx->ReadBuffer ? "readbuffer" : "other buffer"))); @@ -659,9 +677,9 @@ intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) } if (depth_mt && stencil_mt) { - if (brw->gen >= 7) { - /* For gen >= 7, we are using the lod/minimum-array-element fields - * and supportting layered rendering. This means that we must restrict + if (brw->gen >= 6) { + /* For gen >= 6, we are using the lod/minimum-array-element fields + * and supporting layered rendering. This means that we must restrict * the depth & stencil attachments to match in various more retrictive * ways. (width, height, depth, LOD and layer) */ @@ -713,7 +731,7 @@ intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) } } - for (i = 0; i < Elements(fb->Attachment); i++) { + for (i = 0; i < ARRAY_SIZE(fb->Attachment); i++) { struct gl_renderbuffer *rb; struct intel_renderbuffer *irb; @@ -763,6 +781,8 @@ intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) */ static GLbitfield intel_blit_framebuffer_with_blitter(struct gl_context *ctx, + const struct gl_framebuffer *readFb, + const struct gl_framebuffer *drawFb, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, @@ -777,9 +797,7 @@ intel_blit_framebuffer_with_blitter(struct gl_context *ctx, intel_prepare_render(brw); if (mask & GL_COLOR_BUFFER_BIT) { - GLint i; - const struct gl_framebuffer *drawFb = ctx->DrawBuffer; - const struct gl_framebuffer *readFb = ctx->ReadBuffer; + unsigned i; struct gl_renderbuffer *src_rb = readFb->_ColorReadBuffer; struct intel_renderbuffer *src_irb = intel_renderbuffer(src_rb); @@ -815,8 +833,8 @@ intel_blit_framebuffer_with_blitter(struct gl_context *ctx, * results are undefined if any destination pixels have a dependency on * source pixels. */ - for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { - struct gl_renderbuffer *dst_rb = ctx->DrawBuffer->_ColorDrawBuffers[i]; + for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) { + struct gl_renderbuffer *dst_rb = drawFb->_ColorDrawBuffers[i]; struct intel_renderbuffer *dst_irb = intel_renderbuffer(dst_rb); if (!dst_irb) { @@ -847,30 +865,101 @@ intel_blit_framebuffer_with_blitter(struct gl_context *ctx, static void intel_blit_framebuffer(struct gl_context *ctx, + struct gl_framebuffer *readFb, + struct gl_framebuffer *drawFb, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - mask = brw_blorp_framebuffer(brw_context(ctx), + struct brw_context *brw = brw_context(ctx); + + /* Page 679 of OpenGL 4.4 spec says: + * "Added BlitFramebuffer to commands affected by conditional rendering in + * section 10.10 (Bug 9562)." + */ + if (!_mesa_check_conditional_render(ctx)) + return; + + mask = brw_blorp_framebuffer(brw, readFb, drawFb, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); if (mask == 0x0) return; + mask = _mesa_meta_BlitFramebuffer(ctx, readFb, drawFb, + srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, + mask, filter); + if (mask == 0x0) + return; + + if (brw->gen >= 8 && (mask & GL_STENCIL_BUFFER_BIT)) { + brw_meta_fbo_stencil_blit(brw_context(ctx), readFb, drawFb, + srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1); + mask &= ~GL_STENCIL_BUFFER_BIT; + if (mask == 0x0) + return; + } + /* Try using the BLT engine. */ - mask = intel_blit_framebuffer_with_blitter(ctx, + mask = intel_blit_framebuffer_with_blitter(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); if (mask == 0x0) return; + _swrast_BlitFramebuffer(ctx, readFb, drawFb, + srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, + mask, filter); +} - _mesa_meta_BlitFramebuffer(ctx, - srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, - mask, filter); +/** + * Gen4-5 implementation of glBlitFrameBuffer(). + * + * Tries BLT, Meta, then swrast. + * + * Gen4-5 have a single ring for both 3D and BLT operations, so there's no + * inter-ring synchronization issues like on Gen6+. It is apparently faster + * than using the 3D pipeline. Original Gen4 also has to rebase and copy + * miptree slices in order to render to unaligned locations. + */ +static void +gen4_blit_framebuffer(struct gl_context *ctx, + struct gl_framebuffer *readFb, + struct gl_framebuffer *drawFb, + GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) +{ + /* Page 679 of OpenGL 4.4 spec says: + * "Added BlitFramebuffer to commands affected by conditional rendering in + * section 10.10 (Bug 9562)." + */ + if (!_mesa_check_conditional_render(ctx)) + return; + + mask = intel_blit_framebuffer_with_blitter(ctx, readFb, drawFb, + srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, + mask, filter); + if (mask == 0x0) + return; + + mask = _mesa_meta_BlitFramebuffer(ctx, readFb, drawFb, + srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, + mask, filter); + if (mask == 0x0) + return; + + _swrast_BlitFramebuffer(ctx, readFb, drawFb, + srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, + mask, filter); } /** @@ -879,7 +968,7 @@ intel_blit_framebuffer(struct gl_context *ctx, bool intel_renderbuffer_has_hiz(struct intel_renderbuffer *irb) { - return intel_miptree_slice_has_hiz(irb->mt, irb->mt_level, irb->mt_layer); + return intel_miptree_level_has_hiz(irb->mt, irb->mt_level); } bool @@ -933,6 +1022,9 @@ intel_renderbuffer_move_to_temp(struct brw_context *brw, struct intel_mipmap_tree *new_mt; int width, height, depth; + uint32_t layout_flags = MIPTREE_LAYOUT_ACCELERATED_UPLOAD | + MIPTREE_LAYOUT_TILING_ANY; + intel_miptree_get_dimensions_for_image(rb->TexImage, &width, &height, &depth); new_mt = intel_miptree_create(brw, rb->TexImage->TexObject->Target, @@ -940,11 +1032,10 @@ intel_renderbuffer_move_to_temp(struct brw_context *brw, intel_image->base.Base.Level, intel_image->base.Base.Level, width, height, depth, - true, irb->mt->num_samples, - INTEL_MIPTREE_TILING_ANY); + layout_flags); - if (brw_is_hiz_depth_format(brw, new_mt->format)) { + if (intel_miptree_wants_hiz_buffer(brw, new_mt)) { intel_miptree_alloc_hiz(brw, new_mt); } @@ -968,7 +1059,7 @@ brw_render_cache_set_clear(struct brw_context *brw) void brw_render_cache_set_add_bo(struct brw_context *brw, drm_intel_bo *bo) { - _mesa_set_add(brw->render_cache, _mesa_hash_pointer(bo), bo); + _mesa_set_add(brw->render_cache, bo); } /** @@ -986,10 +1077,10 @@ brw_render_cache_set_add_bo(struct brw_context *brw, drm_intel_bo *bo) void brw_render_cache_set_check_flush(struct brw_context *brw, drm_intel_bo *bo) { - if (!_mesa_set_search(brw->render_cache, _mesa_hash_pointer(bo), bo)) + if (!_mesa_set_search(brw->render_cache, bo)) return; - intel_batchbuffer_emit_mi_flush(brw); + brw_emit_mi_flush(brw); } /** @@ -1006,9 +1097,13 @@ intel_fbo_init(struct brw_context *brw) dd->UnmapRenderbuffer = intel_unmap_renderbuffer; dd->RenderTexture = intel_render_texture; dd->ValidateFramebuffer = intel_validate_framebuffer; - dd->BlitFramebuffer = intel_blit_framebuffer; + if (brw->gen >= 6) + dd->BlitFramebuffer = intel_blit_framebuffer; + else + dd->BlitFramebuffer = gen4_blit_framebuffer; dd->EGLImageTargetRenderbufferStorage = intel_image_target_renderbuffer_storage; - brw->render_cache = _mesa_set_create(brw, _mesa_key_pointer_equal); + brw->render_cache = _mesa_set_create(brw, _mesa_hash_pointer, + _mesa_key_pointer_equal); }