diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_draw.c | 51 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_misc_state.c | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_fbo.c | 19 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_fbo.h | 24 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_mipmap_tree.h | 7 |
7 files changed, 99 insertions, 11 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 9e0e2423dae..d1309ac4837 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -408,6 +408,56 @@ brw_postdraw_set_buffers_need_resolve(struct brw_context *brw) } } +static void +intel_renderbuffer_move_temp_back(struct brw_context *brw, + struct intel_renderbuffer *irb) +{ + if (irb->align_wa_mt == NULL) + return; + + brw_render_cache_set_check_flush(brw, irb->align_wa_mt->bo); + + intel_miptree_copy_slice(brw, irb->align_wa_mt, 0, 0, + irb->mt, + irb->Base.Base.TexImage->Level, irb->mt_layer); + + intel_miptree_reference(&irb->align_wa_mt, NULL); + + /* Finally restore the x,y to correspond to full miptree. */ + intel_renderbuffer_set_draw_offset(irb); + + /* Make sure render surface state gets re-emitted with updated miptree. */ + brw->NewGLState |= _NEW_BUFFERS; +} + +static void +brw_postdraw_reconcile_align_wa_slices(struct brw_context *brw) +{ + struct gl_context *ctx = &brw->ctx; + struct gl_framebuffer *fb = ctx->DrawBuffer; + + struct intel_renderbuffer *depth_irb = + intel_get_renderbuffer(fb, BUFFER_DEPTH); + struct intel_renderbuffer *stencil_irb = + intel_get_renderbuffer(fb, BUFFER_STENCIL); + + if (depth_irb && depth_irb->align_wa_mt) + intel_renderbuffer_move_temp_back(brw, depth_irb); + + if (stencil_irb && stencil_irb->align_wa_mt) + intel_renderbuffer_move_temp_back(brw, stencil_irb); + + for (unsigned i = 0; i < fb->_NumColorDrawBuffers; i++) { + struct intel_renderbuffer *irb = + intel_renderbuffer(fb->_ColorDrawBuffers[i]); + + if (!irb || irb->align_wa_mt == NULL) + continue; + + intel_renderbuffer_move_temp_back(brw, irb); + } +} + /* May fail if out of video memory for texture or vbo upload, or on * fallback conditions. */ @@ -605,6 +655,7 @@ retry: intel_batchbuffer_flush(brw); brw_program_cache_check_size(brw); + brw_postdraw_reconcile_align_wa_slices(brw); brw_postdraw_set_buffers_need_resolve(brw); return; diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c index a1022e9da17..d242aa49918 100644 --- a/src/mesa/drivers/dri/i965/brw_misc_state.c +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c @@ -133,7 +133,7 @@ get_stencil_miptree(struct intel_renderbuffer *irb) return NULL; if (irb->mt->stencil_mt) return irb->mt->stencil_mt; - return irb->mt; + return intel_renderbuffer_get_mt(irb); } static bool @@ -262,7 +262,7 @@ brw_emit_depthbuffer(struct brw_context *brw) /* _NEW_BUFFERS */ struct intel_renderbuffer *depth_irb = intel_get_renderbuffer(fb, BUFFER_DEPTH); struct intel_renderbuffer *stencil_irb = intel_get_renderbuffer(fb, BUFFER_STENCIL); - struct intel_mipmap_tree *depth_mt = depth_irb ? depth_irb->mt : NULL; + struct intel_mipmap_tree *depth_mt = intel_renderbuffer_get_mt(depth_irb); struct intel_mipmap_tree *stencil_mt = get_stencil_miptree(stencil_irb); uint32_t tile_x = brw->depthstencil.tile_x; uint32_t tile_y = brw->depthstencil.tile_y; diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 00edce42740..93efbb16f6f 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -1009,7 +1009,8 @@ gen4_update_renderbuffer_surface(struct brw_context *brw, * miptree and render into that. */ intel_renderbuffer_move_to_temp(brw, irb, false); - mt = irb->mt; + assert(irb->align_wa_mt); + mt = irb->align_wa_mt; } } diff --git a/src/mesa/drivers/dri/i965/intel_fbo.c b/src/mesa/drivers/dri/i965/intel_fbo.c index 864ff32a1bb..478e7b88842 100644 --- a/src/mesa/drivers/dri/i965/intel_fbo.c +++ b/src/mesa/drivers/dri/i965/intel_fbo.c @@ -952,11 +952,11 @@ intel_renderbuffer_move_to_temp(struct brw_context *brw, intel_get_image_dims(rb->TexImage, &width, &height, &depth); - new_mt = intel_miptree_create(brw, rb->TexImage->TexObject->Target, + assert(irb->align_wa_mt == NULL); + new_mt = intel_miptree_create(brw, GL_TEXTURE_2D, intel_image->base.Base.TexFormat, - intel_image->base.Base.Level, - intel_image->base.Base.Level, - width, height, depth, + 0, 0, + width, height, 1, irb->mt->num_samples, layout_flags); @@ -964,11 +964,16 @@ intel_renderbuffer_move_to_temp(struct brw_context *brw, intel_miptree_alloc_hiz(brw, new_mt); } - intel_miptree_copy_teximage(brw, intel_image, new_mt, invalidate); + if (!invalidate) + intel_miptree_copy_slice(brw, intel_image->mt, + intel_image->base.Base.Level, irb->mt_layer, + new_mt, 0, 0); - intel_miptree_reference(&irb->mt, intel_image->mt); - intel_renderbuffer_set_draw_offset(irb); + intel_miptree_reference(&irb->align_wa_mt, new_mt); intel_miptree_release(&new_mt); + + irb->draw_x = 0; + irb->draw_y = 0; } void diff --git a/src/mesa/drivers/dri/i965/intel_fbo.h b/src/mesa/drivers/dri/i965/intel_fbo.h index 86811b4225e..56c8e6b3b20 100644 --- a/src/mesa/drivers/dri/i965/intel_fbo.h +++ b/src/mesa/drivers/dri/i965/intel_fbo.h @@ -67,6 +67,16 @@ struct intel_renderbuffer */ struct intel_mipmap_tree *singlesample_mt; + /* Gen < 6 doesn't have layer specifier for render targets or depth. Driver + * needs to manually offset surfaces to correct level/layer. There are, + * however, alignment restrictions to respect as well and in come cases + * the only option is to use temporary single slice surface which driver + * copies after rendering to the full miptree. + * + * See intel_renderbuffer_move_to_temp(). + */ + struct intel_mipmap_tree *align_wa_mt; + /** * \name Miptree view * \{ @@ -136,6 +146,14 @@ intel_renderbuffer(struct gl_renderbuffer *rb) return NULL; } +static inline struct intel_mipmap_tree * +intel_renderbuffer_get_mt(struct intel_renderbuffer *irb) +{ + if (!irb) + return NULL; + + return (irb->align_wa_mt) ? irb->align_wa_mt : irb->mt; +} /** * \brief Return the framebuffer attachment specified by attIndex. @@ -188,6 +206,12 @@ intel_renderbuffer_get_tile_offsets(struct intel_renderbuffer *irb, uint32_t *tile_x, uint32_t *tile_y) { + if (irb->align_wa_mt) { + *tile_x = 0; + *tile_y = 0; + return 0; + } + return intel_miptree_get_tile_offsets(irb->mt, irb->mt_level, irb->mt_layer, tile_x, tile_y); } diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index 3eaf5e58c1e..0320cf88adb 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -1309,7 +1309,7 @@ intel_miptree_copy_slice_sw(struct brw_context *brw, } } -static void +void intel_miptree_copy_slice(struct brw_context *brw, struct intel_mipmap_tree *src_mt, unsigned src_level, unsigned src_layer, diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h index f7b8e678cd8..5e457989c28 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h @@ -814,6 +814,13 @@ void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt, GLuint img, GLuint x, GLuint y); void +intel_miptree_copy_slice(struct brw_context *brw, + struct intel_mipmap_tree *src_mt, + unsigned src_level, unsigned src_layer, + struct intel_mipmap_tree *dst_mt, + unsigned dst_level, unsigned dst_layer); + +void intel_miptree_copy_teximage(struct brw_context *brw, struct intel_texture_image *intelImage, struct intel_mipmap_tree *dst_mt, bool invalidate); |