[Mesa-dev] [PATCH 06/14] i965/blorp: Add support for loading vertices for glsl-based blits

Topi Pohjolainen topi.pohjolainen at intel.com
Thu Apr 23 11:18:20 PDT 2015


Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 src/mesa/drivers/dri/i965/brw_blorp.h    |  5 ++
 src/mesa/drivers/dri/i965/gen6_blorp.cpp | 94 ++++++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_blorp.h b/src/mesa/drivers/dri/i965/brw_blorp.h
index 253d6e6..92db991 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.h
+++ b/src/mesa/drivers/dri/i965/brw_blorp.h
@@ -415,6 +415,9 @@ public:
    virtual void gen7_emit_ps_config(struct brw_context *brw) const;
 
 protected:
+   static void gen6_emit_vertex_elems(struct brw_context *brw,
+                                      bool with_tex_coords);
+
    const unsigned dst_num_samples;
    const struct gl_fragment_program * const fp;
    const struct brw_wm_prog_data * const wm_prog_data;
@@ -449,6 +452,8 @@ public:
                         GLenum filter, GLenum target,
                         bool mirror_x, bool mirror_y);
 
+   virtual void gen6_emit_vertices(struct brw_context *brw) const;
+
 private:
    const float src_x0, src_y0, src_x1, src_y1;
    const struct gl_framebuffer * const read_fb;
diff --git a/src/mesa/drivers/dri/i965/gen6_blorp.cpp b/src/mesa/drivers/dri/i965/gen6_blorp.cpp
index 7ba414e..5a4c301 100644
--- a/src/mesa/drivers/dri/i965/gen6_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/gen6_blorp.cpp
@@ -1177,6 +1177,100 @@ brw_meta_fs_params::gen6_emit_multisample_state(struct brw_context *brw) const
    gen6_emit_3dstate_sample_mask(brw, sample_mask);
 }
 
+void
+brw_meta_fs_params::gen6_emit_vertex_elems(struct brw_context *brw,
+                                           bool with_tex_coords)
+{
+   /* 3DSTATE_VERTEX_ELEMENTS
+    *
+    * These are instructions for VF (vertex fetcher) how the URB is to be
+    * filled with vertex data.
+    *
+    * First element is the vertex header. Second component designates the
+    * layer and gets assigned to the primitive instance identifier. All 
+    * other three components are zero and we can tell the VF to fill them
+    * with constants instead of supplying data from the buffer.
+    * Second element contains the vertex coordinates (x,y,w,z). We tell the
+    * VF to load X and Y from the vertex buffer and to use constant values
+    * of zero and one for the Z and W coordinates respectively.
+    * Finally the third element contains the texture coordinates. Similarly
+    * to the vertex coordinates, X and Y are supplied in the vertex buffer
+    * while Z and W are constants.
+    */
+   const int num_elements = with_tex_coords ? 3 : 2;
+   const int batch_length = 1 + 2 * num_elements;
+
+   BEGIN_BATCH(batch_length);
+   OUT_BATCH((_3DSTATE_VERTEX_ELEMENTS << 16) | (batch_length - 2));
+   /* Element 0 */
+   OUT_BATCH(GEN6_VE0_VALID |
+             BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_VE0_FORMAT_SHIFT |
+             0 << BRW_VE0_SRC_OFFSET_SHIFT);
+   OUT_BATCH(BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_0_SHIFT |
+             BRW_VE1_COMPONENT_STORE_IID << BRW_VE1_COMPONENT_1_SHIFT |
+             BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT |
+             BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT);
+   /* Element 1 */
+   OUT_BATCH(GEN6_VE0_VALID |
+             BRW_SURFACEFORMAT_R32G32_FLOAT << BRW_VE0_FORMAT_SHIFT |
+             0 << BRW_VE0_SRC_OFFSET_SHIFT);
+   OUT_BATCH(BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT |
+             BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_1_SHIFT |
+             BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT |
+             BRW_VE1_COMPONENT_STORE_1_FLT << BRW_VE1_COMPONENT_3_SHIFT);
+   /* Element 2 */
+   if (with_tex_coords) {
+      OUT_BATCH(GEN6_VE0_VALID |
+                BRW_SURFACEFORMAT_R32G32B32_FLOAT << BRW_VE0_FORMAT_SHIFT |
+                8 << BRW_VE0_SRC_OFFSET_SHIFT);
+      OUT_BATCH(BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT |
+                BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_1_SHIFT |
+                BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_2_SHIFT |
+                BRW_VE1_COMPONENT_STORE_1_FLT << BRW_VE1_COMPONENT_3_SHIFT);
+   }
+   ADVANCE_BATCH();
+}
+
+void
+brw_meta_blit_params::gen6_emit_vertices(struct brw_context *brw) const
+{
+   uint32_t vertex_offset;
+   const bool use_unorm_tex_coords = target == GL_TEXTURE_RECTANGLE;
+   const float s0 = src_x0 / (use_unorm_tex_coords ? 1 : src.width);
+   const float s1 = src_x1 / (use_unorm_tex_coords ? 1 : src.width);
+   const float t0 = src_y0 / (use_unorm_tex_coords ? 1 : src.height);
+   const float t1 = src_y1 / (use_unorm_tex_coords ? 1 : src.height);
+
+   /* Minimum layer setting works for all the textures types but texture_3d
+    * for which the setting has no effect. Use the z-coordinate instead.
+    * Note also that in texture_3d case hardware wants the depth coordinate
+    * as normalized.
+    */
+   const float z_normalizer = MAX2(((float)src.mt->logical_depth0) - 1, 1);
+   const float z = target == GL_TEXTURE_3D ?
+                      ((float)src.layer) / z_normalizer : 0;
+
+   /* See gen6_blorp_emit_vertices() */
+   const float vertices[] = {
+      /* v0 */ (float)x0, (float)y1, s0, t1, z,
+      /* v1 */ (float)x1, (float)y1, s1, t1, z,
+      /* v2 */ (float)x0, (float)y0, s0, t0, z
+   };
+
+   float *vertex_data = (float *)brw_state_batch(
+                                    brw, AUB_TRACE_VERTEX_BUFFER,
+                                    sizeof(vertices), 32,
+                                    &vertex_offset);
+   memcpy(vertex_data, vertices, sizeof(vertices));
+
+   const unsigned num_verts = 3;
+   const unsigned num_elems = sizeof(vertices) / (num_verts  * sizeof(float));
+   gen6_blorp_emit_vertex_buffer_state(brw, num_elems, sizeof(vertices),
+                                       vertex_offset);
+
+   gen6_emit_vertex_elems(brw, true);
+}
+
 /**
  * \brief Execute a blit or render pass operation.
  *
-- 
1.9.3



More information about the mesa-dev mailing list