From 82711611cf1dce82a667e531c2befad5a494f1cf Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Thu, 6 Feb 2014 17:02:37 -0800 Subject: [PATCH] i965: Refactor Gen8 depth packet emission. The existing code followed the vtable function signature, which is not a great fit: many of the parameters are unused, and the function still inspects global state, making it less reusable. This patch refactors the depth buffer packet emission code into a new function which takes exactly the parameters it needs, and which uses no global state. It then makes the existing vtable function call the new one. Ideally, we would remove the vtable function, and clean up that interface. But that can happen once HiZ is working. Signed-off-by: Kenneth Graunke Reviewed-by: Eric Anholt --- src/mesa/drivers/dri/i965/gen8_depth_state.c | 171 +++++++++++-------- 1 file changed, 99 insertions(+), 72 deletions(-) diff --git a/src/mesa/drivers/dri/i965/gen8_depth_state.c b/src/mesa/drivers/dri/i965/gen8_depth_state.c index 2c64e5951ce..f30ff289c72 100644 --- a/src/mesa/drivers/dri/i965/gen8_depth_state.c +++ b/src/mesa/drivers/dri/i965/gen8_depth_state.c @@ -25,90 +25,44 @@ #include "intel_mipmap_tree.h" #include "intel_regions.h" #include "intel_fbo.h" +#include "intel_resolve_map.h" #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" -void -gen8_emit_depth_stencil_hiz(struct brw_context *brw, - struct intel_mipmap_tree *depth_mt, - uint32_t depth_offset, - uint32_t depthbuffer_format, - uint32_t depth_surface_type, - struct intel_mipmap_tree *stencil_mt, - bool hiz, bool separate_stencil, - uint32_t width, uint32_t height, - uint32_t tile_x, uint32_t tile_y) +/** + * Helper function to emit depth related command packets. + */ +static void +emit_depth_packets(struct brw_context *brw, + struct intel_mipmap_tree *depth_mt, + uint32_t depthbuffer_format, + uint32_t depth_surface_type, + bool depth_writable, + struct intel_mipmap_tree *stencil_mt, + bool stencil_writable, + uint32_t stencil_offset, + bool hiz, + uint32_t width, + uint32_t height, + uint32_t depth, + uint32_t lod, + uint32_t min_array_element) { - struct gl_context *ctx = &brw->ctx; - struct gl_framebuffer *fb = ctx->DrawBuffer; - uint32_t surftype; - unsigned int depth = 1; - unsigned int min_array_element; - GLenum gl_target = GL_TEXTURE_2D; - unsigned int lod; - const struct intel_mipmap_tree *mt = depth_mt ? depth_mt : stencil_mt; - const struct intel_renderbuffer *irb = NULL; - const struct gl_renderbuffer *rb = NULL; - intel_emit_depth_stall_flushes(brw); - irb = intel_get_renderbuffer(fb, BUFFER_DEPTH); - if (!irb) - irb = intel_get_renderbuffer(fb, BUFFER_STENCIL); - rb = (struct gl_renderbuffer *) irb; - - if (rb) { - depth = MAX2(rb->Depth, 1); - if (rb->TexImage) - gl_target = rb->TexImage->TexObject->Target; - } - - switch (gl_target) { - case GL_TEXTURE_CUBE_MAP_ARRAY: - case GL_TEXTURE_CUBE_MAP: - /* The PRM claims that we should use BRW_SURFACE_CUBE for this - * situation, but experiments show that gl_Layer doesn't work when we do - * this. So we use BRW_SURFACE_2D, since for rendering purposes this is - * equivalent. - */ - surftype = BRW_SURFACE_2D; - depth *= 6; - break; - default: - surftype = translate_tex_target(gl_target); - break; - } - - if (fb->MaxNumLayers > 0 || !irb) { - min_array_element = 0; - } else if (irb->mt->num_samples > 1) { - /* Convert physical to logical layer. */ - min_array_element = irb->mt_layer / irb->mt->num_samples; - } else { - min_array_element = irb->mt_layer; - } - - lod = irb ? irb->mt_level - irb->mt->first_level : 0; - - if (mt) { - width = mt->logical_width0; - height = mt->logical_height0; - } - /* _NEW_BUFFERS, _NEW_DEPTH, _NEW_STENCIL */ BEGIN_BATCH(8); OUT_BATCH(GEN7_3DSTATE_DEPTH_BUFFER << 16 | (8 - 2)); - OUT_BATCH((surftype << 29) | - ((ctx->Depth.Mask != 0) << 28) | - ((stencil_mt != NULL && ctx->Stencil._WriteEnabled) << 27) | - ((hiz ? 1 : 0) << 22) | - (depthbuffer_format << 18) | + OUT_BATCH(depth_surface_type << 29 | + (depth_writable ? (1 << 28) : 0) | + (stencil_mt != NULL && stencil_writable) << 27 | + (hiz ? 1 : 0) << 22 | + depthbuffer_format << 18 | (depth_mt ? depth_mt->region->pitch - 1 : 0)); if (depth_mt) { OUT_RELOC64(depth_mt->region->bo, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, - 0); + I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); } else { OUT_BATCH(0); OUT_BATCH(0); @@ -165,7 +119,7 @@ gen8_emit_depth_stencil_hiz(struct brw_context *brw, OUT_BATCH(HSW_STENCIL_ENABLED | (2 * stencil_mt->region->pitch - 1)); OUT_RELOC64(stencil_mt->region->bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, - brw->depthstencil.stencil_offset); + stencil_offset); OUT_BATCH(stencil_mt ? stencil_mt->qpitch >> 2 : 0); ADVANCE_BATCH(); } @@ -176,3 +130,76 @@ gen8_emit_depth_stencil_hiz(struct brw_context *brw, OUT_BATCH(1); ADVANCE_BATCH(); } + +/* Awful vtable-compatible function; should be cleaned up in the future. */ +void +gen8_emit_depth_stencil_hiz(struct brw_context *brw, + struct intel_mipmap_tree *depth_mt, + uint32_t depth_offset, + uint32_t depthbuffer_format, + uint32_t depth_surface_type, + struct intel_mipmap_tree *stencil_mt, + bool hiz, bool separate_stencil, + uint32_t width, uint32_t height, + uint32_t tile_x, uint32_t tile_y) +{ + struct gl_context *ctx = &brw->ctx; + struct gl_framebuffer *fb = ctx->DrawBuffer; + uint32_t surftype; + unsigned int depth = 1; + unsigned int min_array_element; + GLenum gl_target = GL_TEXTURE_2D; + unsigned int lod; + const struct intel_mipmap_tree *mt = depth_mt ? depth_mt : stencil_mt; + const struct intel_renderbuffer *irb = NULL; + const struct gl_renderbuffer *rb = NULL; + + irb = intel_get_renderbuffer(fb, BUFFER_DEPTH); + if (!irb) + irb = intel_get_renderbuffer(fb, BUFFER_STENCIL); + rb = (struct gl_renderbuffer *) irb; + + if (rb) { + depth = MAX2(rb->Depth, 1); + if (rb->TexImage) + gl_target = rb->TexImage->TexObject->Target; + } + + switch (gl_target) { + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_TEXTURE_CUBE_MAP: + /* The PRM claims that we should use BRW_SURFACE_CUBE for this + * situation, but experiments show that gl_Layer doesn't work when we do + * this. So we use BRW_SURFACE_2D, since for rendering purposes this is + * equivalent. + */ + surftype = BRW_SURFACE_2D; + depth *= 6; + break; + default: + surftype = translate_tex_target(gl_target); + break; + } + + if (fb->MaxNumLayers > 0 || !irb) { + min_array_element = 0; + } else if (irb->mt->num_samples > 1) { + /* Convert physical to logical layer. */ + min_array_element = irb->mt_layer / irb->mt->num_samples; + } else { + min_array_element = irb->mt_layer; + } + + lod = irb ? irb->mt_level - irb->mt->first_level : 0; + + if (mt) { + width = mt->logical_width0; + height = mt->logical_height0; + } + + emit_depth_packets(brw, depth_mt, brw_depthbuffer_format(brw), surftype, + ctx->Depth.Mask != 0, + stencil_mt, ctx->Stencil._WriteEnabled, + brw->depthstencil.stencil_offset, + hiz, width, height, depth, lod, min_array_element); +} -- 2.30.2