summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.c51
-rw-r--r--src/mesa/drivers/dri/i965/brw_misc_state.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c3
-rw-r--r--src/mesa/drivers/dri/i965/intel_fbo.c19
-rw-r--r--src/mesa/drivers/dri/i965/intel_fbo.h24
-rw-r--r--src/mesa/drivers/dri/i965/intel_mipmap_tree.c2
-rw-r--r--src/mesa/drivers/dri/i965/intel_mipmap_tree.h7
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);