[Mesa-dev] [PATCH 13/19] i965: Complete stubs for HiZ operation meta-ops
Chad Versace
chad at chad-versace.us
Fri Sep 23 17:37:43 PDT 2011
Complete the following functions:
brw_hiz_resolve_depthbuffer
brw_hiz_resolve_hizbuffer
In addition to these meta-ops, we must manipulate several state batches
(see comments to brw_hiz_meta_save). That work is done in the subsequent
commit "i965: Manipulate state batches for Hiz meta-ops".
Signed-off-by: Chad Versace <chad at chad-versace.us>
---
src/mesa/drivers/dri/i965/brw_hiz.c | 266 ++++++++++++++++++++++++++++++++++-
1 files changed, 262 insertions(+), 4 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_hiz.c b/src/mesa/drivers/dri/i965/brw_hiz.c
index 4e8baa0..8815a26 100644
--- a/src/mesa/drivers/dri/i965/brw_hiz.c
+++ b/src/mesa/drivers/dri/i965/brw_hiz.c
@@ -21,27 +21,285 @@
* IN THE SOFTWARE.
*/
+#include <assert.h>
+
+#include "mesa/drivers/common/meta.h"
+
#include "mesa/main/arrayobj.h"
#include "mesa/main/bufferobj.h"
+#include "mesa/main/depth.h"
+#include "mesa/main/enable.h"
#include "mesa/main/fbobject.h"
+#include "mesa/main/renderbuffer.h"
#include "mesa/main/shaderapi.h"
+#include "mesa/main/varray.h"
+#include "main/arrayobj.h"
+#include "main/bufferobj.h"
+#include "main/fbobject.h"
+#include "main/shaderapi.h"
+#include "intel_fbo.h"
+#include "intel_regions.h"
+#include "intel_tex.h"
+
+#include "brw_context.h"
+#include "brw_defines.h"
#include "brw_hiz.h"
+static const uint32_t brw_hiz_meta_save =
+
+ /* Disable alpha, depth, and stencil test.
+ *
+ * See the following sections of the Sandy Bridge PRM, Volume 1, Part2:
+ * - 7.5.3.1 Depth Buffer Clear
+ * - 7.5.3.2 Depth Buffer Resolve
+ * - 7.5.3.3 Hierarchical Depth Buffer Resolve
+ */
+ MESA_META_ALPHA_TEST |
+ MESA_META_DEPTH_TEST |
+ MESA_META_STENCIL_TEST |
+
+ /* Disable viewport mapping.
+ *
+ * From page 11 of the Sandy Bridge PRM, Volume 2, Part 1, Section 1.3
+ * 3D Primitives Overview:
+ * RECTLIST:
+ * Viewport Mapping must be DISABLED (as is typical with the use of
+ * screen- space coordinates).
+ *
+ * We must also manually disable 3DSTATE_SF.Viewport_Transform_Enable.
+ */
+ MESA_META_VIEWPORT |
+
+ /* Disable clipping.
+ *
+ * From page 11 of the Sandy Bridge PRM, Volume 2, Part 1, Section 1.3
+ * 3D Primitives Overview:
+ * Either the CLIP unit should be DISABLED, or the CLIP unit’s Clip
+ * Mode should be set to a value other than CLIPMODE_NORMAL.
+ *
+ * We must also manually disable 3DSTATE_CLIP.Clip_Enable.
+ */
+ MESA_META_CLIP |
+
+ /* Render a solid rectangle (set 3DSTATE_SF.FrontFace_Fill_Mode).
+ *
+ * From page 249 of the Sandy Bridge PRM, Volume 2, Part 1, Section
+ * 6.4.1.1 3DSTATE_SF, FrontFace_Fill_Mode:
+ * SOLID: Any triangle or rectangle object found to be front-facing
+ * is rendered as a solid object. This setting is required when
+ * (rendering rectangle (RECTLIST) objects.
+ * Also see field BackFace_Fill_Mode.
+ *
+ * Note: MESA_META_RASTERIZAION also disables culling, but that is
+ * irrelevant. See 3DSTATE_SF.Cull_Mode.
+ */
+ MESA_META_RASTERIZATION |
+
+ /* Each HiZ operation uses a vertex shader and VAO. */
+ MESA_META_SHADER |
+ MESA_META_VERTEX |
+
+ /* Disable scissoring.
+ *
+ * Scissoring is disabled for resolves because a resolve operation
+ * should resolve the entire buffer. Scissoring is disabled for depth
+ * clears because, if we are performing a partial depth clear, then we
+ * specify the clear region with the RECTLIST vertices.
+ */
+ MESA_META_SCISSOR;
+
+/**
+ * Initialize static data needed for HiZ operations.
+ */
+static void
+brw_hiz_init(struct brw_context *brw)
+{
+ struct gl_context *ctx = &brw->intel.ctx;
+ struct brw_hiz_state *hiz = &brw->hiz;
+
+ if (hiz->fbo != 0)
+ return;
+
+ /* Create depthbuffer.
+ *
+ * Until glRenderbufferStorage is called, the renderbuffer hash table
+ * maps the renderbuffer name to a dummy renderbuffer. We need the
+ * renderbuffer to be registered in the hash table so that framebuffer
+ * validation succeeds, so we hackishly allocate storage then immediately
+ * discard it.
+ */
+ GLuint depth_rb_name;
+ _mesa_GenRenderbuffersEXT(1, &depth_rb_name);
+ _mesa_BindRenderbufferEXT(GL_RENDERBUFFER, depth_rb_name);
+ _mesa_RenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 32, 32);
+ _mesa_reference_renderbuffer(&hiz->depth_rb,
+ _mesa_lookup_renderbuffer(ctx, depth_rb_name));
+ intel_region_release(&((struct intel_renderbuffer*) hiz->depth_rb)->region);
+
+ /* Setup FBO. */
+ _mesa_GenFramebuffersEXT(1, &hiz->fbo);
+ _mesa_BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, hiz->fbo);
+ _mesa_FramebufferRenderbufferEXT(GL_DRAW_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER,
+ hiz->depth_rb->Name);
+
+ /* Compile vertex shader. */
+ const char *vs_source =
+ "#version 110\n"
+ "attribute vec4 position;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = position;\n"
+ "}\n";
+ GLuint vs = _mesa_CreateShaderObjectARB(GL_VERTEX_SHADER);
+ _mesa_ShaderSourceARB(vs, 1, &vs_source, NULL);
+ _mesa_CompileShaderARB(vs);
+
+ /* Link and use program. */
+ hiz->shader.program = _mesa_CreateProgramObjectARB();
+ _mesa_AttachShader(hiz->shader.program, vs);
+ _mesa_LinkProgramARB(hiz->shader.program);
+ _mesa_UseProgramObjectARB(hiz->shader.program);
+
+ /* Create and bind VAO. */
+ _mesa_GenVertexArrays(1, &hiz->vao);
+ _mesa_BindVertexArray(hiz->vao);
+
+ /* Setup VBO for 'position'. */
+ hiz->shader.position_location =
+ _mesa_GetAttribLocationARB(hiz->shader.program, "position");
+ _mesa_GenBuffersARB(1, &hiz->shader.position_vbo);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, hiz->shader.position_vbo);
+ _mesa_VertexAttribPointerARB(hiz->shader.position_location,
+ 2, /*components*/
+ GL_FLOAT,
+ GL_FALSE, /*normalized?*/
+ 0, /*stride*/
+ NULL);
+ _mesa_EnableVertexAttribArrayARB(hiz->shader.position_location);
+}
+
+static void
+brw_hiz_setup_depth_rb(struct brw_context *brw,
+ struct intel_region *depth_region)
+{
+ struct gl_renderbuffer *rb = brw->hiz.depth_rb;
+ struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+
+ rb->Format = depth_region->hiz.depth_format;
+ rb->_BaseFormat = _mesa_get_format_base_format(rb->Format);
+ rb->DataType = intel_mesa_format_to_rb_datatype(rb->Format);
+ rb->InternalFormat = rb->_BaseFormat;
+ rb->Width = depth_region->width;
+ rb->Height = depth_region->height;
+
+ intel_region_reference(&irb->region, depth_region);
+}
+
+static void
+brw_hiz_teardown_depth_rb(struct gl_renderbuffer *rb)
+{
+ struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+ intel_region_release(&irb->region);
+}
+
+static void
+brw_hiz_op_exec(struct intel_context *intel,
+ struct intel_region *depth_region,
+ enum brw_hiz_op op)
+{
+ struct gl_context *ctx = &intel->ctx;
+ struct brw_context *brw = brw_context(ctx);
+ struct brw_hiz_state *hiz = &brw->hiz;
+
+ /* Prevent recursive HiZ operations. */
+ if (brw->hiz.op != BRW_HIZ_OP_NONE)
+ return;
+
+ /* Save state. */
+ GLuint save_drawbuffer;
+ GLuint save_renderbuffer;
+ _mesa_meta_begin(ctx, brw_hiz_meta_save);
+ _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &save_drawbuffer);
+ _mesa_GetIntegerv(GL_RENDERBUFFER_BINDING, &save_renderbuffer);
+
+ /* Initialize static data for HiZ operations. */
+ brw_hiz_init(brw);
+
+ /* Set depth state. */
+ if (!ctx->Depth.Mask) {
+ /* Set 3DSTATE_WM.Depth_Buffer_Write_Enable. */
+ _mesa_DepthMask(GL_TRUE);
+ }
+ if (op == BRW_HIZ_OP_DEPTH_RESOLVE) {
+ _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
+ _mesa_DepthFunc(GL_NEVER);
+ }
+
+ /* Setup FBO. */
+ brw_hiz_setup_depth_rb(brw, depth_region);
+ _mesa_BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, hiz->fbo);
+
+
+ /* A rectangle primitive (3DPRIM_RECTLIST) consists of only three
+ * vertices. The vertices reside in screen space.
+ *
+ * v2 ------ implied
+ * | |
+ * | |
+ * v0 ----- v1
+ *
+ * TODO: Adjust RECTLIST vertices for partial depth clears.
+ */
+ const int width = hiz->depth_rb->Width;
+ const int height = hiz->depth_rb->Height;
+ const GLfloat positions[] = {
+ 0, height,
+ width, height,
+ 0, 0,
+ };
+
+ /* Setup program and vertex attributes. */
+ _mesa_UseProgramObjectARB(hiz->shader.program);
+ _mesa_BindVertexArray(hiz->vao);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER, hiz->shader.position_vbo);
+ _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(positions), positions,
+ GL_DYNAMIC_DRAW_ARB);
+
+ /* Execute hiz op. */
+ brw->hiz.op = op;
+ _mesa_DrawArrays(GL_TRIANGLES, 0, 3);
+ brw->hiz.op = BRW_HIZ_OP_NONE;
+
+ /* Restore state. */
+ brw_hiz_teardown_depth_rb(hiz->depth_rb);
+ _mesa_BindRenderbufferEXT(GL_RENDERBUFFER, save_renderbuffer);
+ _mesa_BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, save_drawbuffer);
+ _mesa_meta_end(ctx);
+}
+
void
brw_hiz_resolve_depthbuffer(struct intel_context *intel,
struct intel_region *depth_region)
{
- /* stub */
- abort();
+ if (depth_region->hiz.need_resolve != INTEL_HIZ_NEED_DEPTH_RESOLVE)
+ return;
+
+ brw_hiz_op_exec(intel, depth_region, BRW_HIZ_OP_DEPTH_RESOLVE);
+ depth_region->hiz.need_resolve = INTEL_HIZ_NEED_NO_RESOLVE;
}
void
brw_hiz_resolve_hizbuffer(struct intel_context *intel,
struct intel_region *depth_region)
{
- /* stub */
- abort();
+ if (depth_region->hiz.need_resolve != INTEL_HIZ_NEED_HIZ_RESOLVE)
+ return;
+
+ brw_hiz_op_exec(intel, depth_region, BRW_HIZ_OP_HIZ_RESOLVE);
+ depth_region->hiz.need_resolve = INTEL_HIZ_NEED_NO_RESOLVE;
}
void
--
1.7.6.2
More information about the mesa-dev
mailing list