[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