Re: [Mesa-dev] [PATCH] i965: Implement bounds checking for transform feedback output.

2011-12-19 Thread Paul Berry
On 15 December 2011 15:20, Kenneth Graunke kenn...@whitecape.org wrote:

 Signed-off-by: Kenneth Graunke kenn...@whitecape.org
 ---
  src/mesa/drivers/dri/i965/brw_context.c |1 +
  src/mesa/drivers/dri/i965/brw_context.h |3 ++
  src/mesa/drivers/dri/i965/brw_gs_emit.c |   10 
  src/mesa/drivers/dri/i965/gen6_sol.c|   38
 +++
  4 files changed, 52 insertions(+), 0 deletions(-)

 diff --git a/src/mesa/drivers/dri/i965/brw_context.c
 b/src/mesa/drivers/dri/i965/brw_context.c
 index 7d360b0..fd60853 100644
 --- a/src/mesa/drivers/dri/i965/brw_context.c
 +++ b/src/mesa/drivers/dri/i965/brw_context.c
 @@ -117,6 +117,7 @@ static void brwInitDriverFunctions( struct
 dd_function_table *functions )
brw_init_queryobj_functions(functions);

functions-PrepareExecBegin = brwPrepareExecBegin;
 +   functions-BeginTransformFeedback = brw_begin_transform_feedback;
functions-EndTransformFeedback = brw_end_transform_feedback;
  }

 diff --git a/src/mesa/drivers/dri/i965/brw_context.h
 b/src/mesa/drivers/dri/i965/brw_context.h
 index 8e52488..20623d4 100644
 --- a/src/mesa/drivers/dri/i965/brw_context.h
 +++ b/src/mesa/drivers/dri/i965/brw_context.h
 @@ -1073,6 +1073,9 @@ brw_fprog_uses_noperspective(const struct
 gl_fragment_program *fprog);

  /* gen6_sol.c */
  void
 +brw_begin_transform_feedback(struct gl_context *ctx,
 +struct gl_transform_feedback_object *obj);


Argh, I fail at code review.  I found another problem: this function is
missing the argument GLenum mode, which should come after gl_context
ctx, causing the function pointer assignment in brw_context.c to generate
a warning.  It's a benign warning, because the function only uses the ctx
argument, and the calling conventions work out so that it gets passed in
the same way regardless of whether mode is present.  But for portability we
should make the function signatures match.


 +void
  brw_end_transform_feedback(struct gl_context *ctx,
struct gl_transform_feedback_object *obj);

 diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c
 b/src/mesa/drivers/dri/i965/brw_gs_emit.c
 index 72d4eca..5dd3734 100644
 --- a/src/mesa/drivers/dri/i965/brw_gs_emit.c
 +++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c
 @@ -352,6 +352,15 @@ gen6_sol_program(struct brw_gs_compile *c, struct
 brw_gs_prog_key *key,
*/
   brw_MOV(p, get_element_ud(c-reg.header, 5),
   get_element_ud(c-reg.SVBI, 0));
 +
 +  /* Make sure that the buffers have enough room for all the
 vertices. */
 +  brw_ADD(p, get_element_ud(c-reg.temp, 0),
 +get_element_ud(c-reg.SVBI, 0), brw_imm_ud(num_verts));
 +  brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L,
 +get_element_ud(c-reg.temp, 0),
 +get_element_ud(c-reg.SVBI, 4));
 +  brw_IF(p, BRW_EXECUTE_1);
 +
   /* For each vertex, generate code to output each varying using the
* appropriate binding table entry.
*/
 @@ -392,6 +401,7 @@ gen6_sol_program(struct brw_gs_compile *c, struct
 brw_gs_prog_key *key,
 get_element_ud(c-reg.header, 5), brw_imm_ud(1));
  }
   }
 +  brw_ENDIF(p);

   /* Now, reinitialize the header register from R0 to restore the
 parts of
* the register that we overwrote while streaming out transform
 feedback
 diff --git a/src/mesa/drivers/dri/i965/gen6_sol.c
 b/src/mesa/drivers/dri/i965/gen6_sol.c
 index b11bce2..56d4a6a 100644
 --- a/src/mesa/drivers/dri/i965/gen6_sol.c
 +++ b/src/mesa/drivers/dri/i965/gen6_sol.c
 @@ -26,6 +26,7 @@
  * Code to initialize the binding table entries used by transform feedback.
  */

 +#include main/macros.h
  #include brw_context.h
  #include intel_buffer_objects.h
  #include intel_batchbuffer.h
 @@ -101,6 +102,43 @@ const struct brw_tracked_state gen6_sol_surface = {
  };

  void
 +brw_begin_transform_feedback(struct gl_context *ctx,
 +struct gl_transform_feedback_object *obj)
 +{
 +   struct intel_context *intel = intel_context(ctx);
 +   const struct gl_shader_program *vs_prog =
 +  ctx-Shader.CurrentVertexProgram;
 +   const struct gl_transform_feedback_info *linked_xfb_info =
 +  vs_prog-LinkedTransformFeedback;
 +   struct gl_transform_feedback_object *xfb_obj =
 +  ctx-TransformFeedback.CurrentObject;
 +
 +   unsigned max_index = 0x;
 +
 +   /* Compute the maximum number of vertices that we can write without
 +* overflowing any of the buffers currently being used for feedback.
 +*/
 +   for (int i = 0; i  MAX_FEEDBACK_ATTRIBS; ++i) {
 +  unsigned stride = linked_xfb_info-BufferStride[i];
 +
 +  /* Skip any inactive buffers, which have a stride of 0. */
 +  if (stride == 0)
 +continue;
 +
 +  unsigned max_for_this_buffer = xfb_obj-Size[i] / (4 * stride);
 +  max_index = MIN2(max_index, max_for_this_buffer);
 +   }
 +
 +   /* Initialize the SVBI 0 register 

Re: [Mesa-dev] [PATCH] i965: Implement bounds checking for transform feedback output.

2011-12-16 Thread Paul Berry
On 15 December 2011 15:20, Kenneth Graunke kenn...@whitecape.org wrote:

 Signed-off-by: Kenneth Graunke kenn...@whitecape.org
 ---
  src/mesa/drivers/dri/i965/brw_context.c |1 +
  src/mesa/drivers/dri/i965/brw_context.h |3 ++
  src/mesa/drivers/dri/i965/brw_gs_emit.c |   10 
  src/mesa/drivers/dri/i965/gen6_sol.c|   38
 +++
  4 files changed, 52 insertions(+), 0 deletions(-)

 diff --git a/src/mesa/drivers/dri/i965/brw_context.c
 b/src/mesa/drivers/dri/i965/brw_context.c
 index 7d360b0..fd60853 100644
 --- a/src/mesa/drivers/dri/i965/brw_context.c
 +++ b/src/mesa/drivers/dri/i965/brw_context.c
 @@ -117,6 +117,7 @@ static void brwInitDriverFunctions( struct
 dd_function_table *functions )
brw_init_queryobj_functions(functions);

functions-PrepareExecBegin = brwPrepareExecBegin;
 +   functions-BeginTransformFeedback = brw_begin_transform_feedback;
functions-EndTransformFeedback = brw_end_transform_feedback;
  }

 diff --git a/src/mesa/drivers/dri/i965/brw_context.h
 b/src/mesa/drivers/dri/i965/brw_context.h
 index 8e52488..20623d4 100644
 --- a/src/mesa/drivers/dri/i965/brw_context.h
 +++ b/src/mesa/drivers/dri/i965/brw_context.h
 @@ -1073,6 +1073,9 @@ brw_fprog_uses_noperspective(const struct
 gl_fragment_program *fprog);

  /* gen6_sol.c */
  void
 +brw_begin_transform_feedback(struct gl_context *ctx,
 +struct gl_transform_feedback_object *obj);
 +void
  brw_end_transform_feedback(struct gl_context *ctx,
struct gl_transform_feedback_object *obj);

 diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c
 b/src/mesa/drivers/dri/i965/brw_gs_emit.c
 index 72d4eca..5dd3734 100644
 --- a/src/mesa/drivers/dri/i965/brw_gs_emit.c
 +++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c
 @@ -352,6 +352,15 @@ gen6_sol_program(struct brw_gs_compile *c, struct
 brw_gs_prog_key *key,
*/
   brw_MOV(p, get_element_ud(c-reg.header, 5),
   get_element_ud(c-reg.SVBI, 0));
 +
 +  /* Make sure that the buffers have enough room for all the
 vertices. */
 +  brw_ADD(p, get_element_ud(c-reg.temp, 0),
 +get_element_ud(c-reg.SVBI, 0), brw_imm_ud(num_verts));
 +  brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L,
 +get_element_ud(c-reg.temp, 0),
 +get_element_ud(c-reg.SVBI, 4));
 +  brw_IF(p, BRW_EXECUTE_1);
 +
   /* For each vertex, generate code to output each varying using the
* appropriate binding table entry.
*/
 @@ -392,6 +401,7 @@ gen6_sol_program(struct brw_gs_compile *c, struct
 brw_gs_prog_key *key,
 get_element_ud(c-reg.header, 5), brw_imm_ud(1));
  }
   }
 +  brw_ENDIF(p);

   /* Now, reinitialize the header register from R0 to restore the
 parts of
* the register that we overwrote while streaming out transform
 feedback
 diff --git a/src/mesa/drivers/dri/i965/gen6_sol.c
 b/src/mesa/drivers/dri/i965/gen6_sol.c
 index b11bce2..56d4a6a 100644
 --- a/src/mesa/drivers/dri/i965/gen6_sol.c
 +++ b/src/mesa/drivers/dri/i965/gen6_sol.c
 @@ -26,6 +26,7 @@
  * Code to initialize the binding table entries used by transform feedback.
  */

 +#include main/macros.h
  #include brw_context.h
  #include intel_buffer_objects.h
  #include intel_batchbuffer.h
 @@ -101,6 +102,43 @@ const struct brw_tracked_state gen6_sol_surface = {
  };

  void
 +brw_begin_transform_feedback(struct gl_context *ctx,
 +struct gl_transform_feedback_object *obj)
 +{
 +   struct intel_context *intel = intel_context(ctx);
 +   const struct gl_shader_program *vs_prog =
 +  ctx-Shader.CurrentVertexProgram;
 +   const struct gl_transform_feedback_info *linked_xfb_info =
 +  vs_prog-LinkedTransformFeedback;
 +   struct gl_transform_feedback_object *xfb_obj =
 +  ctx-TransformFeedback.CurrentObject;
 +
 +   unsigned max_index = 0x;
 +
 +   /* Compute the maximum number of vertices that we can write without
 +* overflowing any of the buffers currently being used for feedback.
 +*/
 +   for (int i = 0; i  MAX_FEEDBACK_ATTRIBS; ++i) {


Minor nit: MAX_FEEDBACK_ATTRIBS (32) is the correct bound for generic Mesa
code, but in i965, we only support 4 buffers, so this loop bound should
probably be BRW_MAX_SOL_BUFFERS.


 +  unsigned stride = linked_xfb_info-BufferStride[i];
 +
 +  /* Skip any inactive buffers, which have a stride of 0. */
 +  if (stride == 0)
 +continue;
 +
 +  unsigned max_for_this_buffer = xfb_obj-Size[i] / (4 * stride);
 +  max_index = MIN2(max_index, max_for_this_buffer);
 +   }
 +
 +   /* Initialize the SVBI 0 register to zero and set the maximum index. */
 +   BEGIN_BATCH(4);
 +   OUT_BATCH(_3DSTATE_GS_SVB_INDEX  16 | (4 - 2));
 +   OUT_BATCH(0); /* SVBI 0 */
 +   OUT_BATCH(0);
 +   OUT_BATCH(max_index);
 +   ADVANCE_BATCH();
 +}
 +
 +void
  brw_end_transform_feedback(struct gl_context *ctx,
  

Re: [Mesa-dev] [PATCH] i965: Implement bounds checking for transform feedback output.

2011-12-16 Thread Ian Romanick

On 12/16/2011 10:44 AM, Paul Berry wrote:

On 16 December 2011 10:04, Paul Berry stereotype...@gmail.com
mailto:stereotype...@gmail.com wrote:

On 15 December 2011 15:20, Kenneth Graunke kenn...@whitecape.org
mailto:kenn...@whitecape.org wrote:

Signed-off-by: Kenneth Graunke kenn...@whitecape.org
mailto:kenn...@whitecape.org
---
  src/mesa/drivers/dri/i965/brw_context.c |1 +
  src/mesa/drivers/dri/i965/brw_context.h |3 ++
  src/mesa/drivers/dri/i965/brw_gs_emit.c |   10 
  src/mesa/drivers/dri/i965/gen6_sol.c|   38
+++
  4 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.c
b/src/mesa/drivers/dri/i965/brw_context.c
index 7d360b0..fd60853 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -117,6 +117,7 @@ static void brwInitDriverFunctions( struct
dd_function_table *functions )
brw_init_queryobj_functions(functions);

functions-PrepareExecBegin = brwPrepareExecBegin;
+   functions-BeginTransformFeedback =
brw_begin_transform_feedback;
functions-EndTransformFeedback = brw_end_transform_feedback;
  }

diff --git a/src/mesa/drivers/dri/i965/brw_context.h
b/src/mesa/drivers/dri/i965/brw_context.h
index 8e52488..20623d4 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -1073,6 +1073,9 @@ brw_fprog_uses_noperspective(const struct
gl_fragment_program *fprog);

  /* gen6_sol.c */
  void
+brw_begin_transform_feedback(struct gl_context *ctx,
+struct gl_transform_feedback_object
*obj);
+void
  brw_end_transform_feedback(struct gl_context *ctx,
struct gl_transform_feedback_object
*obj);

diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c
b/src/mesa/drivers/dri/i965/brw_gs_emit.c
index 72d4eca..5dd3734 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c
@@ -352,6 +352,15 @@ gen6_sol_program(struct brw_gs_compile *c,
struct brw_gs_prog_key *key,
*/
   brw_MOV(p, get_element_ud(c-reg.header, 5),
   get_element_ud(c-reg.SVBI, 0));
+
+  /* Make sure that the buffers have enough room for all
the vertices. */
+  brw_ADD(p, get_element_ud(c-reg.temp, 0),
+get_element_ud(c-reg.SVBI, 0),
brw_imm_ud(num_verts));
+  brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L,
+get_element_ud(c-reg.temp, 0),
+get_element_ud(c-reg.SVBI, 4));
+  brw_IF(p, BRW_EXECUTE_1);
+


Whoops, one other correction.  There's an off-by-one error--this should
be BRW_CONDITIONAL_LE.

For example, let's say we're outputting triangles, the transform
feedback buffer is large enough to hold 6 vertices, and we've output 3
vertices already.  In that case num_verts is 3, SVBI.0 is 3, and SVBI.4
is 6.  The above logic compares SVBI.0 + num_verts  SVBI.4 (6  6), so
it concludes that there isn't room for the second triangle.  It should
be computing SVBI.0 + num_verts = SVBI.4 (6 = 6), because there is
just barely room for the second triangle.


Do we have piglit test cases for these edge conditions?  If we don't, we 
need them. :)



   /* For each vertex, generate code to output each varying
using the
* appropriate binding table entry.
*/
@@ -392,6 +401,7 @@ gen6_sol_program(struct brw_gs_compile *c,
struct brw_gs_prog_key *key,
 get_element_ud(c-reg.header, 5),
brw_imm_ud(1));
  }
   }
+  brw_ENDIF(p);

   /* Now, reinitialize the header register from R0 to
restore the parts of
* the register that we overwrote while streaming out
transform feedback
diff --git a/src/mesa/drivers/dri/i965/gen6_sol.c
b/src/mesa/drivers/dri/i965/gen6_sol.c
index b11bce2..56d4a6a 100644
--- a/src/mesa/drivers/dri/i965/gen6_sol.c
+++ b/src/mesa/drivers/dri/i965/gen6_sol.c
@@ -26,6 +26,7 @@
  * Code to initialize the binding table entries used by
transform feedback.
  */

+#include main/macros.h
  #include brw_context.h
  #include intel_buffer_objects.h
  #include intel_batchbuffer.h
@@ -101,6 +102,43 @@ const struct brw_tracked_state
gen6_sol_surface = {
  };

  void

Re: [Mesa-dev] [PATCH] i965: Implement bounds checking for transform feedback output.

2011-12-16 Thread Paul Berry
On 16 December 2011 11:09, Ian Romanick i...@freedesktop.org wrote:

 On 12/16/2011 10:44 AM, Paul Berry wrote:

 On 16 December 2011 10:04, Paul Berry stereotype...@gmail.com
 mailto:stereotype441@gmail.**com stereotype...@gmail.com wrote:

On 15 December 2011 15:20, Kenneth Graunke kenn...@whitecape.org
mailto:kenn...@whitecape.org** wrote:

Signed-off-by: Kenneth Graunke kenn...@whitecape.org
mailto:kenn...@whitecape.org**

---
  src/mesa/drivers/dri/i965/brw_**context.c |1 +
  src/mesa/drivers/dri/i965/brw_**context.h |3 ++
  src/mesa/drivers/dri/i965/brw_**gs_emit.c |   10 
  src/mesa/drivers/dri/i965/**gen6_sol.c|   38
++**+
  4 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/**brw_context.c
b/src/mesa/drivers/dri/i965/**brw_context.c
index 7d360b0..fd60853 100644
--- a/src/mesa/drivers/dri/i965/**brw_context.c
+++ b/src/mesa/drivers/dri/i965/**brw_context.c
@@ -117,6 +117,7 @@ static void brwInitDriverFunctions( struct
dd_function_table *functions )
brw_init_queryobj_functions(**functions);

functions-PrepareExecBegin = brwPrepareExecBegin;
+   functions-**BeginTransformFeedback =
brw_begin_transform_feedback;
functions-**EndTransformFeedback =
 brw_end_transform_feedback;
  }

diff --git a/src/mesa/drivers/dri/i965/**brw_context.h
b/src/mesa/drivers/dri/i965/**brw_context.h
index 8e52488..20623d4 100644
--- a/src/mesa/drivers/dri/i965/**brw_context.h
+++ b/src/mesa/drivers/dri/i965/**brw_context.h
@@ -1073,6 +1073,9 @@ brw_fprog_uses_noperspective(**const struct
gl_fragment_program *fprog);

  /* gen6_sol.c */
  void
+brw_begin_transform_feedback(**struct gl_context *ctx,
+struct gl_transform_feedback_object
*obj);
+void
  brw_end_transform_feedback(**struct gl_context *ctx,
struct gl_transform_feedback_object
*obj);

diff --git a/src/mesa/drivers/dri/i965/**brw_gs_emit.c
b/src/mesa/drivers/dri/i965/**brw_gs_emit.c
index 72d4eca..5dd3734 100644
--- a/src/mesa/drivers/dri/i965/**brw_gs_emit.c
+++ b/src/mesa/drivers/dri/i965/**brw_gs_emit.c
@@ -352,6 +352,15 @@ gen6_sol_program(struct brw_gs_compile *c,
struct brw_gs_prog_key *key,
*/
   brw_MOV(p, get_element_ud(c-reg.header, 5),
   get_element_ud(c-reg.SVBI, 0));
+
+  /* Make sure that the buffers have enough room for all
the vertices. */
+  brw_ADD(p, get_element_ud(c-reg.temp, 0),
+get_element_ud(c-reg.SVBI, 0),
brw_imm_ud(num_verts));
+  brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L,
+get_element_ud(c-reg.temp, 0),
+get_element_ud(c-reg.SVBI, 4));
+  brw_IF(p, BRW_EXECUTE_1);
+


 Whoops, one other correction.  There's an off-by-one error--this should
 be BRW_CONDITIONAL_LE.

 For example, let's say we're outputting triangles, the transform
 feedback buffer is large enough to hold 6 vertices, and we've output 3
 vertices already.  In that case num_verts is 3, SVBI.0 is 3, and SVBI.4
 is 6.  The above logic compares SVBI.0 + num_verts  SVBI.4 (6  6), so
 it concludes that there isn't room for the second triangle.  It should
 be computing SVBI.0 + num_verts = SVBI.4 (6 = 6), because there is
 just barely room for the second triangle.


 Do we have piglit test cases for these edge conditions?  If we don't, we
 need them. :)


This one was caught by piglit tests that I'm hoping to send to the list
today.
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev