[Mesa-dev] [RFC 2/4] glsl IR: only allow optimization of interstage variable

2015-10-13 Thread Gregory Hainaut
GL_ARB_separate_shader_objects allow to match by name variable or block
interface. Input varying can't be removed because it is will impact the
location assignment.

It fixes the bug 79783 and likely any application that uses
GL_ARB_separate_shader_objects extension.

piglit test: arb_separate_shader_object-rendezvous_by_name

Signed-off-by: Gregory Hainaut 
---
 src/glsl/opt_dead_code.cpp | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/src/glsl/opt_dead_code.cpp b/src/glsl/opt_dead_code.cpp
index 071485a..37329f6 100644
--- a/src/glsl/opt_dead_code.cpp
+++ b/src/glsl/opt_dead_code.cpp
@@ -75,6 +75,24 @@ do_dead_code(exec_list *instructions, bool 
uniform_locations_assigned)
  || !entry->declaration)
 continue;
 
+  /* Section 7.4.1 (Shader Interface Matching) of the OpenGL 4.5
+   * (Core Profile) spec says:
+   *
+   *"With separable program objects, interfaces between shader
+   *stages may involve the outputs from one program object and the
+   *inputs from a second program object.  For such interfaces, it is
+   *not possible to detect mismatches at link time, because the
+   *programs are linked separately. When each such program is
+   *linked, all inputs or outputs interfacing with another program
+   *stage are treated as active."
+   */
+  if (entry->var->data.always_active_io &&
+(!entry->var->data.explicit_location ||
+ entry->var->data.location >= VARYING_SLOT_VAR0) &&
+(entry->var->data.mode == ir_var_shader_in ||
+ entry->var->data.mode == ir_var_shader_out))
+ continue;
+
   if (entry->assign) {
 /* Remove a single dead assignment to the variable we found.
  * Don't do so if it's a shader or function output or a shader
-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 0/4] V3: Improve GLSL support of GL_ARB_separate_shader_objects

2015-10-13 Thread Gregory Hainaut
New version that improves previous code quality and fixes several outstanding 
issues.
Piglit wasn't run yet.

v3:
Squash commit 1&2
* Use a better name for the new attribute: always_active_io
* Use ir_variable directly instead of ir_variable_refcount_visitor
* Put related code in linker.cpp

Add 2 new commits to fix wrong interface matching in more complex case.
Commit 3: avoid collision between user and linker slot assignment
Commit 4: avoid unpredictable sorting of varying

Commit 1/2/3 fix the piglit test: arb_separate_shader_object-rendezvous_by_name 
posted on piglit ML
Commit 4 was tested on the PCSX2 application. I need to implement a new test.

Gregory Hainaut (4):
  glsl IR: add always_active_io attribute to ir_variable
  glsl IR: only allow optimization of interstage variable
  glsl: avoid linker and user varying location to overlap
  glsl: don't sort varying in separate shader mode

 src/glsl/ir.cpp|  1 +
 src/glsl/ir.h  |  7 +
 src/glsl/link_varyings.cpp | 76 ++
 src/glsl/linker.cpp| 73 
 src/glsl/opt_dead_code.cpp | 18 +++
 5 files changed, 169 insertions(+), 6 deletions(-)

-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 3/4] glsl: avoid linker and user varying location to overlap

2015-10-13 Thread Gregory Hainaut
Current behavior on the interface matching:

layout (location = 0) out0; // Assigned to VARYING_SLOT_VAR0 by user
out1; // Assigned to VARYING_SLOT_VAR0 by the linker

New behavior on the interface matching:

layout (location = 0) out0; // Assigned to VARYING_SLOT_VAR0 by user
out1; // Assigned to VARYING_SLOT_VAR1 by the linker

piglit: arb_separate_shader_object-rendezvous_by_name
Signed-off-by: Gregory Hainaut 
---
 src/glsl/link_varyings.cpp | 46 +++---
 1 file changed, 43 insertions(+), 3 deletions(-)

diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
index 7e77a67..6d6e9b5 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -766,7 +766,7 @@ public:
gl_shader_stage consumer_stage);
~varying_matches();
void record(ir_variable *producer_var, ir_variable *consumer_var);
-   unsigned assign_locations();
+   unsigned assign_locations(uint64_t reserved_slots);
void store_locations() const;
 
 private:
@@ -986,7 +986,7 @@ varying_matches::record(ir_variable *producer_var, 
ir_variable *consumer_var)
  * passed to varying_matches::record().
  */
 unsigned
-varying_matches::assign_locations()
+varying_matches::assign_locations(uint64_t reserved_slots)
 {
/* Sort varying matches into an order that makes them easy to pack. */
qsort(this->matches, this->num_matches, sizeof(*this->matches),
@@ -1013,6 +1013,10 @@ varying_matches::assign_locations()
   != this->matches[i].packing_class) {
  *location = ALIGN(*location, 4);
   }
+  while ((*location < MAX_VARYING * 4u) &&
+(reserved_slots & (1u << *location / 4u))) {
+ *location = ALIGN(*location + 1, 4);
+  }
 
   this->matches[i].generic_location = *location;
 
@@ -1376,6 +1380,38 @@ canonicalize_shader_io(exec_list *ir, enum 
ir_variable_mode io_mode)
 }
 
 /**
+ * Generate a bitfield map of the already reserved slots for a shader.
+ *
+ * In theory a 32 bits value will be enough but a 64 bits value is future 
proof.
+ */
+uint64_t
+reserved_varying_slot(struct gl_shader *stage, ir_variable_mode io_mode)
+{
+   assert(mode == ir_var_shader_in || mode == ir_var_shader_out);
+   assert(MAX_VARYING <= 64); /* avoid an overflow of the returned value */
+
+   uint64_t slots = 0;
+   int var_slot;
+
+   if (!stage)
+  return slots;
+
+   foreach_in_list(ir_instruction, node, stage->ir) {
+  ir_variable *const var = node->as_variable();
+
+  if (var == NULL || var->data.mode != io_mode || 
!var->data.explicit_location)
+ continue;
+
+  var_slot = var->data.location - VARYING_SLOT_VAR0;
+  if (var_slot >= 0 && var_slot < MAX_VARYING)
+ slots |= 1u << var_slot;
+   }
+
+   return slots;
+}
+
+
+/**
  * Assign locations for all variables that are produced in one pipeline stage
  * (the "producer") and consumed in the next stage (the "consumer").
  *
@@ -1550,7 +1586,11 @@ assign_varying_locations(struct gl_context *ctx,
  matches.record(matched_candidate->toplevel_var, NULL);
}
 
-   const unsigned slots_used = matches.assign_locations();
+   const uint64_t reserved_slots =
+  reserved_varying_slot(producer, ir_var_shader_out) |
+  reserved_varying_slot(consumer, ir_var_shader_in);
+
+   const unsigned slots_used = matches.assign_locations(reserved_slots);
matches.store_locations();
 
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 4/4] glsl: don't sort varying in separate shader mode

2015-10-13 Thread Gregory Hainaut
Current issue is the addition of FLAT qualifier on varying_matches::record()
which break the varying expected order

Future issue is the removal of the interpolation qualifier matching constrain

In my humble opinion, it is the responsability of the GL developer to optimize
their slots assignment in SSO with the help of GL_ARB_enhanced_layouts

Signed-off-by: Gregory Hainaut 
---
 src/glsl/link_varyings.cpp | 36 ++--
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
index 6d6e9b5..31efee7 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -766,7 +766,7 @@ public:
gl_shader_stage consumer_stage);
~varying_matches();
void record(ir_variable *producer_var, ir_variable *consumer_var);
-   unsigned assign_locations(uint64_t reserved_slots);
+   unsigned assign_locations(uint64_t reserved_slots, bool separate_shader);
void store_locations() const;
 
 private:
@@ -986,11 +986,34 @@ varying_matches::record(ir_variable *producer_var, 
ir_variable *consumer_var)
  * passed to varying_matches::record().
  */
 unsigned
-varying_matches::assign_locations(uint64_t reserved_slots)
+varying_matches::assign_locations(uint64_t reserved_slots, bool 
separate_shader)
 {
-   /* Sort varying matches into an order that makes them easy to pack. */
-   qsort(this->matches, this->num_matches, sizeof(*this->matches),
- &varying_matches::match_comparator);
+   /* Disable the varying sorting for separate shader program
+* 1/ All programs must sort the code in the same order to guarantee the
+*interface matching. However varying_matches::record() will change the
+*interpolation qualifier of some stages.
+*
+* 2/ GLSL version 4.50 removes the matching constrain on the interpolation
+*qualifier.
+*
+* Chapter 4.5 of GLSL 4.40:
+*"The type and presence of interpolation qualifiers of variables with
+*the same name declared in all linked shaders for the same cross-stage
+*interface must match, otherwise the link command will fail.
+*
+*When comparing an output from one stage to an input of a subsequent
+*stage, the input and output don't match if their interpolation
+*qualifiers (or lack thereof) are not the same."
+*
+* Chapter 4.5 of GLSL 4.50:
+*"It is a link-time error if, within the same stage, the interpolation
+*qualifiers of variables of the same name do not match."
+*/
+   if (!separate_shader) {
+  /* Sort varying matches into an order that makes them easy to pack. */
+  qsort(this->matches, this->num_matches, sizeof(*this->matches),
+&varying_matches::match_comparator);
+   }
 
unsigned generic_location = 0;
unsigned generic_patch_location = MAX_VARYING*4;
@@ -1590,7 +1613,8 @@ assign_varying_locations(struct gl_context *ctx,
   reserved_varying_slot(producer, ir_var_shader_out) |
   reserved_varying_slot(consumer, ir_var_shader_in);
 
-   const unsigned slots_used = matches.assign_locations(reserved_slots);
+   const unsigned slots_used = matches.assign_locations(reserved_slots,
+prog->SeparateShader);
matches.store_locations();
 
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 1/4] glsl IR: add always_active_io attribute to ir_variable

2015-10-13 Thread Gregory Hainaut
The value will be set in separate-shader program when an input/output
must remains active (i.e. deadcode removal isn't allowed because it will create
interface location/name-matching mismatch)

v3:
* Rename the attribute
* Use ir_variable directly instead of ir_variable_refcount_visitor
* Move the foreach IR code in the linker file

Signed-off-by: Gregory Hainaut 
---
 src/glsl/ir.cpp |  1 +
 src/glsl/ir.h   |  7 +
 src/glsl/linker.cpp | 73 +
 3 files changed, 81 insertions(+)

diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 2c45b9e..f3f7355 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -1650,6 +1650,7 @@ ir_variable::ir_variable(const struct glsl_type *type, 
const char *name,
this->data.pixel_center_integer = false;
this->data.depth_layout = ir_depth_layout_none;
this->data.used = false;
+   this->data.always_active_io = false;
this->data.read_only = false;
this->data.centroid = false;
this->data.sample = false;
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 43a2bf0..a91add9 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -658,6 +658,13 @@ public:
   unsigned assigned:1;
 
   /**
+   * When separate shader programs are enabled, only interstage
+   * variables can be safely removed of the shader interface. Others
+   * input/output must remains active.
+   */
+  unsigned always_active_io:1;
+
+  /**
* Enum indicating how the variable was declared.  See
* ir_var_declaration_type.
*
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index a97b4ef..3a30d0c 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -3599,6 +3599,70 @@ link_assign_subroutine_types(struct gl_shader_program 
*prog)
}
 }
 
+static void
+ir_set_always_active_io(exec_list *ir, ir_variable_mode io_mode)
+{
+   assert(mode == ir_var_shader_in || mode == ir_var_shader_out);
+
+   foreach_in_list(ir_instruction, node, ir) {
+  ir_variable *const var = node->as_variable();
+
+  if (var == NULL || var->data.mode != io_mode)
+ continue;
+
+  var->data.always_active_io = true;
+   }
+}
+
+static void
+set_always_active_io(struct gl_shader_program *prog)
+{
+   unsigned first, last;
+   assert(prog->SeparateShader);
+
+   first = MESA_SHADER_STAGES;
+   last = 0;
+
+   /* Determine first and last stage. Excluding the compute stage */
+   for (unsigned i = 0; i < MESA_SHADER_COMPUTE; i++) {
+  if (!prog->_LinkedShaders[i])
+ continue;
+  if (first == MESA_SHADER_STAGES)
+ first = i;
+  last = i;
+   }
+
+   if (first == MESA_SHADER_STAGES)
+  return;
+
+   for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {
+  gl_shader *sh = prog->_LinkedShaders[stage];
+  if (!sh)
+ continue;
+
+  if (first == last) {
+ /* Single shader program: allowed inactive variable
+  * 1/ input of the VS
+  * 2/ output of the FS
+  */
+ if (stage != MESA_SHADER_VERTEX)
+ir_set_always_active_io(sh->ir, ir_var_shader_in);
+ if (stage != MESA_SHADER_FRAGMENT)
+ir_set_always_active_io(sh->ir, ir_var_shader_out);
+  } else {
+ /* Multiple shaders program: allowed inactive variable
+  * 1/ input of the VS
+  * 2/ output of the FS
+  * 3/ interstage variables
+  */
+ if (stage == first && stage != MESA_SHADER_VERTEX)
+ir_set_always_active_io(sh->ir, ir_var_shader_in);
+ else if (stage == last && stage != MESA_SHADER_FRAGMENT)
+ir_set_always_active_io(sh->ir, ir_var_shader_out);
+  }
+   }
+}
+
 void
 link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
 {
@@ -3858,6 +3922,15 @@ link_shaders(struct gl_context *ctx, struct 
gl_shader_program *prog)
   }
}
 
+
+   /**
+* When separate shader programs are enabled, only interstage
+* variables can be safely removed of the shader interface. Others
+* input/output must remains active.
+*/
+   if (prog->SeparateShader)
+  set_always_active_io(prog);
+
if (!interstage_cross_validate_uniform_blocks(prog))
   goto done;
 
-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 2/4] glsl IR: only allow optimization of interstage variable

2015-10-25 Thread Gregory Hainaut
GL_ARB_separate_shader_objects allow to match by name variable or block
interface. Input varying can't be removed because it is will impact the
location assignment.

It fixes the bug 79783 and likely any application that uses
GL_ARB_separate_shader_objects extension.

piglit test: arb_separate_shader_object-rendezvous_by_name

Signed-off-by: Gregory Hainaut 
---
 src/glsl/opt_dead_code.cpp | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/src/glsl/opt_dead_code.cpp b/src/glsl/opt_dead_code.cpp
index c5be166..fef5e92 100644
--- a/src/glsl/opt_dead_code.cpp
+++ b/src/glsl/opt_dead_code.cpp
@@ -75,6 +75,24 @@ do_dead_code(exec_list *instructions, bool 
uniform_locations_assigned)
  || !entry->declaration)
 continue;
 
+  /* Section 7.4.1 (Shader Interface Matching) of the OpenGL 4.5
+   * (Core Profile) spec says:
+   *
+   *"With separable program objects, interfaces between shader
+   *stages may involve the outputs from one program object and the
+   *inputs from a second program object.  For such interfaces, it is
+   *not possible to detect mismatches at link time, because the
+   *programs are linked separately. When each such program is
+   *linked, all inputs or outputs interfacing with another program
+   *stage are treated as active."
+   */
+  if (entry->var->data.always_active_io &&
+(!entry->var->data.explicit_location ||
+ entry->var->data.location >= VARYING_SLOT_VAR0) &&
+(entry->var->data.mode == ir_var_shader_in ||
+ entry->var->data.mode == ir_var_shader_out))
+ continue;
+
   if (!entry->assign_list.is_empty()) {
 /* Remove all the dead assignments to the variable we found.
  * Don't do so if it's a shader or function output, though.
-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 1/4] glsl IR: add always_active_io attribute to ir_variable

2015-10-25 Thread Gregory Hainaut
The value will be set in separate-shader program when an input/output
must remains active (i.e. deadcode removal isn't allowed because it will create
interface location/name-matching mismatch)

v3:
* Rename the attribute
* Use ir_variable directly instead of ir_variable_refcount_visitor
* Move the foreach IR code in the linker file

v4:
* Fix variable name in assert

Signed-off-by: Gregory Hainaut 
---
 src/glsl/ir.cpp |  1 +
 src/glsl/ir.h   |  7 +
 src/glsl/linker.cpp | 73 +
 3 files changed, 81 insertions(+)

diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 8933b23..0c1430b 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -1666,6 +1666,7 @@ ir_variable::ir_variable(const struct glsl_type *type, 
const char *name,
this->data.pixel_center_integer = false;
this->data.depth_layout = ir_depth_layout_none;
this->data.used = false;
+   this->data.always_active_io = false;
this->data.read_only = false;
this->data.centroid = false;
this->data.sample = false;
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 9c9f22d..0223665 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -658,6 +658,13 @@ public:
   unsigned assigned:1;
 
   /**
+   * When separate shader programs are enabled, only interstage
+   * variables can be safely removed of the shader interface. Others
+   * input/output must remains active.
+   */
+  unsigned always_active_io:1;
+
+  /**
* Enum indicating how the variable was declared.  See
* ir_var_declaration_type.
*
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 424b92a..845 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -3896,6 +3896,70 @@ split_ubos_and_ssbos(void *mem_ctx,
assert(*num_ubos + *num_ssbos == num_blocks);
 }
 
+static void
+ir_set_always_active_io(exec_list *ir, ir_variable_mode io_mode)
+{
+   assert(io_mode == ir_var_shader_in || io_mode == ir_var_shader_out);
+
+   foreach_in_list(ir_instruction, node, ir) {
+  ir_variable *const var = node->as_variable();
+
+  if (var == NULL || var->data.mode != io_mode)
+ continue;
+
+  var->data.always_active_io = true;
+   }
+}
+
+static void
+set_always_active_io(struct gl_shader_program *prog)
+{
+   unsigned first, last;
+   assert(prog->SeparateShader);
+
+   first = MESA_SHADER_STAGES;
+   last = 0;
+
+   /* Determine first and last stage. Excluding the compute stage */
+   for (unsigned i = 0; i < MESA_SHADER_COMPUTE; i++) {
+  if (!prog->_LinkedShaders[i])
+ continue;
+  if (first == MESA_SHADER_STAGES)
+ first = i;
+  last = i;
+   }
+
+   if (first == MESA_SHADER_STAGES)
+  return;
+
+   for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {
+  gl_shader *sh = prog->_LinkedShaders[stage];
+  if (!sh)
+ continue;
+
+  if (first == last) {
+ /* Single shader program: allowed inactive variable
+  * 1/ input of the VS
+  * 2/ output of the FS
+  */
+ if (stage != MESA_SHADER_VERTEX)
+ir_set_always_active_io(sh->ir, ir_var_shader_in);
+ if (stage != MESA_SHADER_FRAGMENT)
+ir_set_always_active_io(sh->ir, ir_var_shader_out);
+  } else {
+ /* Multiple shaders program: allowed inactive variable
+  * 1/ input of the VS
+  * 2/ output of the FS
+  * 3/ interstage variables
+  */
+ if (stage == first && stage != MESA_SHADER_VERTEX)
+ir_set_always_active_io(sh->ir, ir_var_shader_in);
+ else if (stage == last && stage != MESA_SHADER_FRAGMENT)
+ir_set_always_active_io(sh->ir, ir_var_shader_out);
+  }
+   }
+}
+
 void
 link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
 {
@@ -4155,6 +4219,15 @@ link_shaders(struct gl_context *ctx, struct 
gl_shader_program *prog)
   }
}
 
+
+   /**
+* When separate shader programs are enabled, only interstage
+* variables can be safely removed of the shader interface. Others
+* input/output must remains active.
+*/
+   if (prog->SeparateShader)
+  set_always_active_io(prog);
+
if (!interstage_cross_validate_uniform_blocks(prog))
   goto done;
 
-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 0/4] V4: Improve GLSL support of GL_ARB_separate_shader_objects

2015-10-25 Thread Gregory Hainaut
v4:
Rebase against lastest master and fix bad variable name in assert.

A new test was developed to properly check commit 4 behavior.
I ran most of the piglit test without regression.

v3:
Squash old commit 1&2
* Use a better name for the new attribute: always_active_io
* Use ir_variable directly instead of ir_variable_refcount_visitor
* Put related code in linker.cpp

Add 2 new commits to fix wrong interface matching in more complex case.
Commit 3: avoid collision between user and linker slot assignment
Commit 4: avoid unpredictable sorting of varying

Commit 1/2/3 fix the piglit test: arb_separate_shader_object-rendezvous_by_name 
posted on piglit ML
Commit 4 was tested on the PCSX2 application.

Gregory Hainaut (4):
  glsl IR: add always_active_io attribute to ir_variable
  glsl IR: only allow optimization of interstage variable
  glsl: avoid linker and user varying location to overlap
  glsl: don't sort varying in separate shader mode

 src/glsl/ir.cpp|  1 +
 src/glsl/ir.h  |  7 +
 src/glsl/link_varyings.cpp | 76 ++
 src/glsl/linker.cpp| 73 
 src/glsl/opt_dead_code.cpp | 18 +++
 5 files changed, 169 insertions(+), 6 deletions(-)

-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 3/4] glsl: avoid linker and user varying location to overlap

2015-10-25 Thread Gregory Hainaut
Current behavior on the interface matching:

layout (location = 0) out0; // Assigned to VARYING_SLOT_VAR0 by user
out1; // Assigned to VARYING_SLOT_VAR0 by the linker

New behavior on the interface matching:

layout (location = 0) out0; // Assigned to VARYING_SLOT_VAR0 by user
out1; // Assigned to VARYING_SLOT_VAR1 by the linker

piglit: arb_separate_shader_object-rendezvous_by_name

v4:
* Fix variable name in assert

Signed-off-by: Gregory Hainaut 
---
 src/glsl/link_varyings.cpp | 46 +++---
 1 file changed, 43 insertions(+), 3 deletions(-)

diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
index 7e77a67..67d04cb 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -766,7 +766,7 @@ public:
gl_shader_stage consumer_stage);
~varying_matches();
void record(ir_variable *producer_var, ir_variable *consumer_var);
-   unsigned assign_locations();
+   unsigned assign_locations(uint64_t reserved_slots);
void store_locations() const;
 
 private:
@@ -986,7 +986,7 @@ varying_matches::record(ir_variable *producer_var, 
ir_variable *consumer_var)
  * passed to varying_matches::record().
  */
 unsigned
-varying_matches::assign_locations()
+varying_matches::assign_locations(uint64_t reserved_slots)
 {
/* Sort varying matches into an order that makes them easy to pack. */
qsort(this->matches, this->num_matches, sizeof(*this->matches),
@@ -1013,6 +1013,10 @@ varying_matches::assign_locations()
   != this->matches[i].packing_class) {
  *location = ALIGN(*location, 4);
   }
+  while ((*location < MAX_VARYING * 4u) &&
+(reserved_slots & (1u << *location / 4u))) {
+ *location = ALIGN(*location + 1, 4);
+  }
 
   this->matches[i].generic_location = *location;
 
@@ -1376,6 +1380,38 @@ canonicalize_shader_io(exec_list *ir, enum 
ir_variable_mode io_mode)
 }
 
 /**
+ * Generate a bitfield map of the already reserved slots for a shader.
+ *
+ * In theory a 32 bits value will be enough but a 64 bits value is future 
proof.
+ */
+uint64_t
+reserved_varying_slot(struct gl_shader *stage, ir_variable_mode io_mode)
+{
+   assert(io_mode == ir_var_shader_in || io_mode == ir_var_shader_out);
+   assert(MAX_VARYING <= 64); /* avoid an overflow of the returned value */
+
+   uint64_t slots = 0;
+   int var_slot;
+
+   if (!stage)
+  return slots;
+
+   foreach_in_list(ir_instruction, node, stage->ir) {
+  ir_variable *const var = node->as_variable();
+
+  if (var == NULL || var->data.mode != io_mode || 
!var->data.explicit_location)
+ continue;
+
+  var_slot = var->data.location - VARYING_SLOT_VAR0;
+  if (var_slot >= 0 && var_slot < MAX_VARYING)
+ slots |= 1u << var_slot;
+   }
+
+   return slots;
+}
+
+
+/**
  * Assign locations for all variables that are produced in one pipeline stage
  * (the "producer") and consumed in the next stage (the "consumer").
  *
@@ -1550,7 +1586,11 @@ assign_varying_locations(struct gl_context *ctx,
  matches.record(matched_candidate->toplevel_var, NULL);
}
 
-   const unsigned slots_used = matches.assign_locations();
+   const uint64_t reserved_slots =
+  reserved_varying_slot(producer, ir_var_shader_out) |
+  reserved_varying_slot(consumer, ir_var_shader_in);
+
+   const unsigned slots_used = matches.assign_locations(reserved_slots);
matches.store_locations();
 
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 4/4] glsl: don't sort varying in separate shader mode

2015-10-25 Thread Gregory Hainaut
Current issue is the addition of FLAT qualifier on varying_matches::record()
which break the varying expected order

Future issue is the removal of the interpolation qualifier matching constrain

In my humble opinion, it is the responsability of the GL developer to optimize
their slots assignment in SSO with the help of GL_ARB_enhanced_layouts

Signed-off-by: Gregory Hainaut 
---
 src/glsl/link_varyings.cpp | 36 ++--
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
index 67d04cb..f1794c3 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -766,7 +766,7 @@ public:
gl_shader_stage consumer_stage);
~varying_matches();
void record(ir_variable *producer_var, ir_variable *consumer_var);
-   unsigned assign_locations(uint64_t reserved_slots);
+   unsigned assign_locations(uint64_t reserved_slots, bool separate_shader);
void store_locations() const;
 
 private:
@@ -986,11 +986,34 @@ varying_matches::record(ir_variable *producer_var, 
ir_variable *consumer_var)
  * passed to varying_matches::record().
  */
 unsigned
-varying_matches::assign_locations(uint64_t reserved_slots)
+varying_matches::assign_locations(uint64_t reserved_slots, bool 
separate_shader)
 {
-   /* Sort varying matches into an order that makes them easy to pack. */
-   qsort(this->matches, this->num_matches, sizeof(*this->matches),
- &varying_matches::match_comparator);
+   /* Disable the varying sorting for separate shader program
+* 1/ All programs must sort the code in the same order to guarantee the
+*interface matching. However varying_matches::record() will change the
+*interpolation qualifier of some stages.
+*
+* 2/ GLSL version 4.50 removes the matching constrain on the interpolation
+*qualifier.
+*
+* Chapter 4.5 of GLSL 4.40:
+*"The type and presence of interpolation qualifiers of variables with
+*the same name declared in all linked shaders for the same cross-stage
+*interface must match, otherwise the link command will fail.
+*
+*When comparing an output from one stage to an input of a subsequent
+*stage, the input and output don't match if their interpolation
+*qualifiers (or lack thereof) are not the same."
+*
+* Chapter 4.5 of GLSL 4.50:
+*"It is a link-time error if, within the same stage, the interpolation
+*qualifiers of variables of the same name do not match."
+*/
+   if (!separate_shader) {
+  /* Sort varying matches into an order that makes them easy to pack. */
+  qsort(this->matches, this->num_matches, sizeof(*this->matches),
+&varying_matches::match_comparator);
+   }
 
unsigned generic_location = 0;
unsigned generic_patch_location = MAX_VARYING*4;
@@ -1590,7 +1613,8 @@ assign_varying_locations(struct gl_context *ctx,
   reserved_varying_slot(producer, ir_var_shader_out) |
   reserved_varying_slot(consumer, ir_var_shader_in);
 
-   const unsigned slots_used = matches.assign_locations(reserved_slots);
+   const unsigned slots_used = matches.assign_locations(reserved_slots,
+prog->SeparateShader);
matches.store_locations();
 
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] Time to merge threaded GL dispatch? (aka glthread)

2017-02-06 Thread Gregory Hainaut
Hello,

> A note on synchronizations. Borderlands 2 has 170 thread syncs per
> frame. That means the app thread has to stop and wait 170x per frame.
> Despite that, it still has 70% higher performance in some cases. My
> theory is that if you have a lot of draw calls, you can have a lot of
> syncs, because the sheer amount of draw calls will just make those
> syncs irrelevant. 200 syncs per 4k draw calls is like 1 sync per 20
> draw calls.

Here a feedback of my quick test

On PCSX2 (PS2 emulator), I noticed that synchronization badly impacts
the perf. In my case, there are mostly related to texture transfer
(CPU->GPU) and clear buffer functions. Strangely I didn't notice
anything related to BufferSubData* but I guess it is the same.

Those functions trigger a sync because of the pointer parameter.
However texture transfer could use a PBO so it isn't a real pointer.
And clear uses a pointer to a color hence a small payload (worst case
is likely around 16/32B). IMHO, it can surely be inlined/memcpy in the
gl dispatcher (otherwise the old GL2 clear API is sync free).

I hacked the code to remove the sync on texture transfer and I got a
major speed boost. I didn't count the number of draw call neither sync
ratio. But I suspect that perf impact could depends on the sync
repartition. Unlike me, I guess that Borderlands2 uploads/clears
buffers/textures/uniform at the start of the frame. Which mean various
small sync at the start of the frame (which might be optimized as a
spin lock). Therefore the hot rendering loop might be sync free hence
the speed boost.

To conclude, based on my single testcase, current state of the code
isn't yet optimal and it might explain why few apps see any perf
improvement so far. But the potential is here.

Cheers,
Gregory
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] Time to merge threaded GL dispatch? (aka glthread)

2017-02-07 Thread Gregory Hainaut
>
> Hi,
>
> On Mon, 2017-02-06 at 13:43 +0100, Jan Ziak wrote:
> >* Shadow of Mordor benchmark: 30 FPS w/o glthread -> 20 FPS with
> *>* glthread
> *>
> For what it is worth, all the Feral games have a dispatch thread that
> primarily calls GL functions.
>
> James
>
>
Hello James,


Did you have the opportunity to compare Feral's dispatcher threading
implementation versus Nvidia's threading option. If yes, is there any
performance difference? In other word, did you implement it because some
(most) drivers miss this optimization or because it can really bring some
performance improvements (when done carefully).


Thanks you,
Gregory
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] Time to merge threaded GL dispatch? (aka glthread)

2017-02-08 Thread Gregory Hainaut
>
> >* Hello James,
> *> > >* Did you have the opportunity to compare Feral's dispatcher threading
> *>* implementation versus Nvidia's threading option. If yes, is there any
> *>* performance difference? In other word, did you implement it because
> *>* some (most) drivers miss this optimization or because it can really
> *>* bring some performance improvements (when done carefully).
> *
> We can't directly compare to Nvidia's option, as our threaded GL
> implementation is a necessity for us. OpenGL contexts must be bound to
> a specific thread, unlike D3D devices, and we have games written for
> D3D using multiple threads to dispatch graphics work (and sometimes
> using multiple D3D devices from the same thread). We make one dispatch
> thread for each GL context to avoid having to unbind the context from a
> thread. There is some locking so that only one game thread may submit
> to a context's dispatch thread at once, but that locking is very
> lightweight compared to what would happen if we repeatedly attached and
> detached GL contexts on game threads. GL_KHR_context_flush_control was
> supposed to help with that, by allowing opting out of flushing the GL
> context when unbinding it from a thread, but last time we tried that,
> there were some synchronous X requests in SDL2 making it remain slow.
>
> Having said that, we did at one point have a path which used
> GLX_MESA_multithreaded_make_current when it was available. We found the
> GL dispatch threads was quicker on all the games we were working on at
> the time.
>
> James
>
>
Oh I see. I already got similar context threading issue when I ported my
app from Dx to GL. Thanks  for the full explanation (and for all games
ported on Linux ^^).
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] Time to merge threaded GL dispatch? (aka glthread)

2017-02-08 Thread gregory hainaut
> Regresses performance:
> * Shadow of Mordor (with multiple game gfx settings & driver/HW?)
> * PCSX2 emulator

As Marek said the code still miss some optimization opportunities. FWIW, PCSX2 
uses persistant PBO for texture transfer so it can be done without any sync. I 
removed the sync (with a hack), I won +25% on FPS and rendering was limited by 
the GPU (Nouveau).

Gregory
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] Time to merge threaded GL dispatch? (aka glthread)

2017-02-10 Thread gregory hainaut
Hello,

I ran piglit (glthread false vs true) on the Marek branch and Nouveau driver.
Of course we can still debate, if piglit is good enough to detect multi 
threading issue.

I spot a small typo that generate ~400 fails (*mat2x4* uniform got 6 scalar 
instead of 8).

piglit status with the typo patch : warn +2/ fail + 4/ crash +5 

All regressions are on GLX tests but glsl-uniform-out-of-bounds. The
latter reports a wrong error INVALID_VALUE (there is an extra glthread check
because count is too big) instead of INVALID_OPERATION (not an array
uniform must have a count of 1). I'm not sure it worth a fix.


On GLX side, I can explain some crashes (didn't debug all neither fail)
and I suspect there are related to the previous report.

At the context creation a glthread dispatcher is created and the *TLS*
variable u_current_table is set with the new gl marshal function.
If deprecated non-VBO functions are detected
(glBegin/glVertexPointer/... and others horror from the previous
century), the code will disable glthread.

1/ thread will be deleted
2/ u_current_table will be set to the original value

However u_current_table is local to a thread. So a single thread will
get the correct dispatcher table. Remaining threads will keep the
previous marshal thread. If a glthread function is called without the
thread behind, then BOOM. I don't know how to fix it. However, is it
really a necessity to care for such "old" application.

Note: display list update also the table, I'm not sure of the impact. I
don't know if piglit test display list


Unfortunately it is way too late (at least for closed application, open
source can easily be updated), but one could imagine a context flag to
select a gl dispatcher. IMHO, the application is the best judge to
enable it. Automatic detection on the driver is quite complicated. It is way 
cheaper
to add an env value in the .desktop file.


IMHO, it would be better to just drop the "automatic removal" of
glthread. Old application will be slower if an user set wrongly an env
variable which is more reasonable than a crash.


Cheers,
Gregory
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 14/26] mesa: Connect the generated GL command marshalling code to the build.

2017-02-12 Thread gregory hainaut
> >> >  void
> >> >  _mesa_glthread_init(struct gl_context *ctx)
> >> >  {
> >> > struct glthread_state *glthread = calloc(1, sizeof(*glthread));
> >> >
> >> > if (!glthread)
> >> >return;
> >> >
> >> > +   /* The marshalling dispatch table isn't integrated with the
> >> > Begin/End
> >> > +* dispatch table for desktop OpenGL, and the drawing functions
> >> > are
> >> > +* synchronous to support user vertex arrays on everything but
> >> > GL core
> >> > +* (even GLES 2/3) anyway, which means you'll end up with too
> >> > much overhead
> >> > +* from threading.
> >> > +*/
> >> > +   if (ctx->API != API_OPENGL_CORE)
> >> > +  return;
> >>
> >> Leaking glthread ?
> >>
> > This is odd, the version I have locally which I rebased from Marek's
> > git repo frees glthread.
> >
> > Marek, what's happened here?  Are these patches different from the ones
> > in your git repo?
> 
> No, they are the same. Maybe you fixed it locally?
> 
> Marek

The code was removed patch 24.
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] Time to merge threaded GL dispatch? (aka glthread)

2017-02-13 Thread Gregory Hainaut
>
> On 11/02/17 06:36 AM, gregory hainaut wrote:
> > >* On GLX side, I can explain some crashes (didn't debug all neither fail)
> *>* and I suspect there are related to the previous report.
> *> >* At the context creation a glthread dispatcher is created and the *TLS*
> *>* variable u_current_table is set with the new gl marshal function.
> *>* If deprecated non-VBO functions are detected
> *>* (glBegin/glVertexPointer/... and others horror from the previous
> *>* century), the code will disable glthread.
> *> >* 1/ thread will be deleted
> *>* 2/ u_current_table will be set to the original value
> *> >* However u_current_table is local to a thread. So a single thread will
> *>* get the correct dispatcher table. Remaining threads will keep the
> *>* previous marshal thread. If a glthread function is called without the
> *>* thread behind, then BOOM.
> *
> If I understand correctly, this scenario can only happen if the
> application takes advantage of the GLX_MESA_multithread_makecurrent
> extension. I wonder if we shouldn't just stop advertising that extension
> with glthread enabled.
>
> Actually, I wonder how well GLX_MESA_multithread_makecurrent works
> regardless of glthread. I suspect the assumption of a 1:1 correspondence
> between threads and contexts is quite widespread in the Mesa code. Case
> in point, the piglit test glx at glx-multithread-texture 
> <https://lists.freedesktop.org/mailman/listinfo/mesa-dev> has been failing
> forever with radeonsi, though it passes with llvmpipe. Are there any
> real world applications which require GLX_MESA_multithread_makecurrent,
> or at least get a significant benefit from it?
>
>
Hello,


Yes you're right. I just found out yesterday that it was related to
GLX_MESA_multithread_makecurrent.
I did a small patch to not kill glthread when direct GL1 code is used. It
avoid the crash but it is far
from robust. You could imagine situation where 1 thread uses dispatcher
function and another
use std serial call (of course without any sync of glthread). Now if you
use only modern GL
(that will always use glthread), it might work. Note: Piglit is working as
both thread will restore
the standard dispatch function.

Feral said that they tried the extension but a gl dispatcher was faster.
Googling a bit I found
Eric's initial mail. So it seems to be used. Extension isn't published on
Kronos, so usage likely
remain confidential. Potentially glthread will be as fast as GLX_MT on
cairo. But you're right,
I don't see the point to support both at the same time.

> I'm happy now with the implementation of this extension, I've got
> tests for most of the issues mentioned (the one that's really missing
> is the bind-to-new-drawable one, but I don't anticipate issues with
> it), and cairo-gl is getting a ~35% performance improvement from it
> and is passing cairo's threading tests other than the one that fails
> due to non-threading-related issuse.
>
>
Actually glx-multithread-texture is pass with glthread (nouveau)


As a quick summary:
* there are now only 2 minors fail on piglit with my latest patches  (sent
to Marek)
* I have a pending patch to allow asynchronous PBO transfer
* Now that piglit is crash free I will give a try to both glxgear and
glmark. Hopefully they will be both good.

Gregory
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] Time to merge threaded GL dispatch? (aka glthread)

2017-02-13 Thread Gregory Hainaut
Hum, I need to check it. I think I disabled EGL because I didn't have
latest waffle on my Debian (and Nvidia didn't support fully EGL back
then).

However, I forgot to say that a fair number of piglit tests are based
on GL1 direct call. (typically to draw a rectangle without a VBO). All
those tests will disable glthread in the middle. In the current state,
piglit is far from ideal to test glthread. Maybe CTS could help to
increase the coverage. I will give it a shot.

Gregory

On 2/13/17, Marek Olšák  wrote:
> On Mon, Feb 13, 2017 at 11:10 AM, Gregory Hainaut
>  wrote:
>>> On 11/02/17 06:36 AM, gregory hainaut wrote:
>>> >
>>> > On GLX side, I can explain some crashes (didn't debug all neither
>>> > fail)
>>> > and I suspect there are related to the previous report.
>>> >
>>> > At the context creation a glthread dispatcher is created and the *TLS*
>>> > variable u_current_table is set with the new gl marshal function.
>>> > If deprecated non-VBO functions are detected
>>> > (glBegin/glVertexPointer/... and others horror from the previous
>>> > century), the code will disable glthread.
>>> >
>>> > 1/ thread will be deleted
>>> > 2/ u_current_table will be set to the original value
>>> >
>>> > However u_current_table is local to a thread. So a single thread will
>>> > get the correct dispatcher table. Remaining threads will keep the
>>> > previous marshal thread. If a glthread function is called without the
>>> > thread behind, then BOOM.
>>>
>>> If I understand correctly, this scenario can only happen if the
>>> application takes advantage of the GLX_MESA_multithread_makecurrent
>>> extension. I wonder if we shouldn't just stop advertising that extension
>>> with glthread enabled.
>>>
>>> Actually, I wonder how well GLX_MESA_multithread_makecurrent works
>>> regardless of glthread. I suspect the assumption of a 1:1 correspondence
>>> between threads and contexts is quite widespread in the Mesa code. Case
>>> in point, the piglit test glx at glx-multithread-texture has been
>>> failing
>>> forever with radeonsi, though it passes with llvmpipe. Are there any
>>> real world applications which require GLX_MESA_multithread_makecurrent,
>>> or at least get a significant benefit from it?
>>
>>
>> Hello,
>>
>>
>> Yes you're right. I just found out yesterday that it was related to
>> GLX_MESA_multithread_makecurrent.
>> I did a small patch to not kill glthread when direct GL1 code is used. It
>> avoid the crash but it is far
>> from robust. You could imagine situation where 1 thread uses dispatcher
>> function and another
>> use std serial call (of course without any sync of glthread). Now if you
>> use
>> only modern GL
>> (that will always use glthread), it might work. Note: Piglit is working
>> as
>> both thread will restore
>> the standard dispatch function.
>>
>> Feral said that they tried the extension but a gl dispatcher was faster.
>> Googling a bit I found
>> Eric's initial mail. So it seems to be used. Extension isn't published on
>> Kronos, so usage likely
>> remain confidential. Potentially glthread will be as fast as GLX_MT on
>> cairo. But you're right,
>> I don't see the point to support both at the same time.
>>>
>>> I'm happy now with the implementation of this extension, I've got
>>> tests for most of the issues mentioned (the one that's really missing
>>> is the bind-to-new-drawable one, but I don't anticipate issues with
>>> it), and cairo-gl is getting a ~35% performance improvement from it
>>> and is passing cairo's threading tests other than the one that fails
>>> due to non-threading-related issuse.
>>
>>
>> Actually glx-multithread-texture is pass with glthread (nouveau)
>>
>>
>> As a quick summary:
>> * there are now only 2 minors fail on piglit with my latest patches
>> (sent
>> to Marek)
>> * I have a pending patch to allow asynchronous PBO transfer
>> * Now that piglit is crash free I will give a try to both glxgear and
>> glmark. Hopefully they will be both good.
>
> Note that if you run piglit with egl/drm, it might not have glthread
> enabled.
>
> Marek
>
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] Time to merge threaded GL dispatch? (aka glthread)

2017-02-13 Thread Gregory Hainaut
If I remember correctly I got something like 4K-8K fails (total is 40K
tests)  when I broke the GL1 restore dispatch function. So it is
around 10%-20%. Maybe it was only the test below 3.1. I was afraid
that various modern extension could still be tested with some GL1
drawing.

On 2/13/17, Marek Olšák  wrote:
> On Mon, Feb 13, 2017 at 3:56 PM, Gregory Hainaut
>  wrote:
>> Hum, I need to check it. I think I disabled EGL because I didn't have
>> latest waffle on my Debian (and Nvidia didn't support fully EGL back
>> then).
>>
>> However, I forgot to say that a fair number of piglit tests are based
>> on GL1 direct call. (typically to draw a rectangle without a VBO). All
>
> I'd disagree. All GL 3.1 tests and above have to use VBOs. GL core requires
> it.
>
> Marek
>
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] Time to merge threaded GL dispatch? (aka glthread)

2017-02-13 Thread gregory hainaut
On Mon, 13 Feb 2017 17:04:01 +0100
Marek Olšák  wrote:

> On Mon, Feb 13, 2017 at 4:14 PM, Gregory Hainaut
>  wrote:
> > If I remember correctly I got something like 4K-8K fails (total is 40K
> > tests)  when I broke the GL1 restore dispatch function. So it is
> > around 10%-20%. Maybe it was only the test below 3.1. I was afraid
> > that various modern extension could still be tested with some GL1
> > drawing.
> 
> The number of tests run doesn't necessarily correspond to the amount
> of test coverage. 10 tests doing different things can be more useful
> than 1 tests doing the same thing.
> 
> Marek

Fair point.

As a side note, I tested both glxgear and glmark2 which are now crash-free :)
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH] doc: GL_ARB_buffer_storage is supported on llvmpipe/swr

2017-02-24 Thread Gregory Hainaut
At least, the extension is exported (gallium capability
PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT is 1)

Signed-off-by: Gregory Hainaut 
---
 docs/features.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/features.txt b/docs/features.txt
index d9528e9..9d3a460 100644
--- a/docs/features.txt
+++ b/docs/features.txt
@@ -191,7 +191,7 @@ GL 4.3, GLSL 4.30 -- all DONE: i965/gen8+, nvc0, radeonsi
 GL 4.4, GLSL 4.40 -- all DONE: i965/gen8+, nvc0, radeonsi
 
   GL_MAX_VERTEX_ATTRIB_STRIDE   DONE (all drivers)
-  GL_ARB_buffer_storage DONE (i965, nv50, r600)
+  GL_ARB_buffer_storage DONE (i965, nv50, 
r600, llvmpipe, swr)
   GL_ARB_clear_texture  DONE (i965, nv50, 
r600, llvmpipe, softpipe)
   GL_ARB_enhanced_layouts   DONE (i965, nv50, 
llvmpipe, softpipe)
   - compile-time constant expressions   DONE
-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] doc: GL_ARB_buffer_storage is supported on llvmpipe/swr

2017-02-26 Thread Gregory Hainaut
On 2/25/17, Edward O'Callaghan  wrote:
> Acked-by: Edward O'Callaghan 
>
> On 02/25/2017 07:45 AM, Gregory Hainaut wrote:
>> At least, the extension is exported (gallium capability
>> PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT is 1)
>>
>> Signed-off-by: Gregory Hainaut 
>> ---
>>  docs/features.txt | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/docs/features.txt b/docs/features.txt
>> index d9528e9..9d3a460 100644
>> --- a/docs/features.txt
>> +++ b/docs/features.txt
>> @@ -191,7 +191,7 @@ GL 4.3, GLSL 4.30 -- all DONE: i965/gen8+, nvc0,
>> radeonsi
>>  GL 4.4, GLSL 4.40 -- all DONE: i965/gen8+, nvc0, radeonsi
>>
>>GL_MAX_VERTEX_ATTRIB_STRIDE   DONE (all
>> drivers)
>> -  GL_ARB_buffer_storage DONE (i965, nv50,
>> r600)
>> +  GL_ARB_buffer_storage DONE (i965, nv50,
>> r600, llvmpipe, swr)
>>GL_ARB_clear_texture  DONE (i965, nv50,
>> r600, llvmpipe, softpipe)
>>GL_ARB_enhanced_layouts   DONE (i965, nv50,
>> llvmpipe, softpipe)
>>- compile-time constant expressions   DONE
>>
>
>

Hello,

I don't have git access. Could you push it too ?

Thanks you,
Gregory
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 01/12] sso: Create extensions entry points

2013-07-27 Thread gregory hainaut
On Fri, 24 May 2013 16:27:59 -0700
Ian Romanick  wrote:

> I'm finally getting off my lazy behind and reviewing this series.  I'll 
> probably only be able to review one or two patches today, but I should 
> be able to get through the rest shortly.
> 
> So far, it's just little stuff.
> 

Hello. Did you review "the rest" (5-9, 11) ? Or did I miss your reply.

By the way did you get any news on the various "spec bug" that you had opened.

Cheers
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] Status of GL_ARB_separate_shader_objects? I would like to help.

2013-03-22 Thread gregory hainaut
Hello,

I would like to run PCSX2 on mesa drivers but unfortunately it miss a
couple of features, mostly the GL_ARB_separate_shader_objects extension.

I think I can help to implement this extension at least the opengl (ie
not glsl) plumbering part (with some piglit tests). The extension
GL_EXT_separate_shader_object is marked supported by the driver but I
don't know if GLSL fully support separate program or with limitation.

I already begun to implement the extension, enough to write some piglit
tests. However 2 parts on the specs are not clear for me.

* GenProgramPipelines doesn't create object!
... Spec extract:
These names are marked as used, for the purposes of GenBuffers only,
  but they acquire buffer state only when they are first bound with
  BindBuffer (see below), just as if they were unused.
...

Basically any command (like BindBuffer) that access the pipeline will
create the pipeline. It seems like vertex array object. From an
implemention point of view it seems much easier to create the object
during GenProgramPipelines call. However I don't know if
IsProgramPipeline must return FALSE if the object was never really
created (bind) like VAO.

* Mix between Pipeline object and the standard
  UseProgram/ActiveProgram. Here some extract of the spec:

# BindProgramPipeline may also be used
  to bind an existing program pipeline object.
If no current program object has been established by UseProgram, the
  pro- gram objects used for each shader stage and for uniform updates
  are taken from the bound program pipeline object, if any. If there is
  a current program object established by UseProgram, the bound program
  pipeline object has no effect on rendering or uniform updates. When a
  bound program pipeline object is used for rendering, individual
  shader executables are taken from its program objects as de- scribed
  in the discussion of UseProgram in section 7.3).

# glUseProgram
If program is non-zero, this command will make program the current
program object. This will install executable code as part of the
current rendering state for each shader stage present when the program
was last successfully linked. If UsePro- gram is called with program
set to zero, then there is no current program object.

From
http://www.opengl.org/registry/specs/ARB/separate_shader_objects.txt If
both extensions are supported, the rule giving priority to UseProgram
over pipeline objects needs to be updated, given that the single
UseProgram binding point is replaced by a collection of binding points.
We effectively treat this collection of binding points as another
pipeline object, and treat that object as higher priority if it has a
program attached to *any* attachment point.  The priority rules in this
spec are rewritten as follows:

  The executable code for an individual shader stage is taken from
  the current program for that stage.  If there is a current
  program object for any shader stage or for uniform updates
  established by UseProgram, UseShaderProgramEXT, or
  ActiveProgramEXT, the current program for that stage (if any) is
  considered current.  Otherwise, if there is a bound program
  pipeline object ...

Note that with these rules, it's not possible to mix program
objects bound to the context with program objects bound to a
program pipeline object; if any program is bound to the context,
the current pipeline object is ignored.


So how the following case must be handle?

case 1/
RESET STATE
glUseProgram(2)
BindProgramPipeline(5)
# no effect but is the pipeline bound or not?
# My understand is not.

case 2/
RESET STATE
BindProgramPipeline(5)
glUseProgram(2)
# higher priority than the pipeline. Do we
# unbind the pipeline? 
glUseProgram(0)
# What state is expected NULL or pipeline 5? my understanding is NULL

Case 3/
RESET STATE
BindProgramPipeline(5)
glUseProgram(0)  
# Don't use a real program.  What state is
# expected NULL or pipeline 5? My understanding is NULL


Cheers,
Gregory
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] Status of GL_ARB_separate_shader_objects? I would like to help.

2013-03-23 Thread gregory hainaut
On Fri, 22 Mar 2013 15:44:07 -0700
Matt Turner  wrote:

> On Fri, Mar 22, 2013 at 1:00 PM, gregory hainaut
>  wrote:
> > * GenProgramPipelines doesn't create object!
> > ... Spec extract:
> > These names are marked as used, for the purposes of GenBuffers only,
> >   but they acquire buffer state only when they are first bound with
> >   BindBuffer (see below), just as if they were unused.
> > ...
> >
> > Basically any command (like BindBuffer) that access the pipeline
> > will create the pipeline. It seems like vertex array object. From an
> > implemention point of view it seems much easier to create the object
> > during GenProgramPipelines call. However I don't know if
> > IsProgramPipeline must return FALSE if the object was never really
> > created (bind) like VAO.
> 
> This is a weird part of the spec. After glGen* (but before glBind*)
> the associated glIs* function usually returns false. It's something
> that no one but conformance tests seem to care about. See commit
> fd93d55141f11069fb76a9b377ad1af88d0ecdd3 (in Mesa) for how to fix this
> kind of thing.
> 
> I said "usually" above because there is some inconsistency. The
> ARB_sampler_objects spec says that the act of calling glIsSampler()
> actually creates the object.
> 
> It looks like for ARB_separate_shader_objects that glGen* followed by
> glIs* should return false (like VAOs).

Ok. Thanks for the example. I updated my code and create a  piglit
test. By the way, fglrx doesn't follow this behavior, dunno for nvidia.


On the mix UseProgram/BindProgramPipeline subjet. 
I try to search the spec for additional info and found this example:
##
Issue 4:
When a non-zero program is passed to UseProgram, any subsequent
uniform updates will affect that program, ignoring the active
program in any bound pipeline object.  For example:

  glUseProgram(0);
  glBindProgramPipeline(1);
  glActiveProgram(1, 2);
  glUniform1f(0, 3.0);  // affects program 2
  glUseProgram(3);
  glUniform1f(0, 3.0);  // affects program 3
  glUseProgram(0);
  glUniform1f(0, 3.0);  // affects program 2
###

So after glUseProgram(0), the state of the pipeline is restored (or they
forgot to update this part of the spec when they clarify the priority
rule), at least the ActiveProgram. Anyway, I write an extensive piglit
test and check the behavior on fglrx. Here the outcome, glUseProgram(0)
destroy current program state, the pipeline need to be rebound
again for any shader based rendering. However ActiveProgram is restored
as the previous example! Any opinion is welcome, run the test on
nvidia? Mimic AMD behavior?

Cheers
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [Piglit] [RFC] ARB_separate_shader_objects test v2

2013-03-28 Thread gregory hainaut
On Tue, 26 Mar 2013 16:58:17 -0700
Jordan Justen  wrote:

> Tested with NVidia binary:
> fail :: spec/ARB_separate_shader_objects/sso-GetProgramPipelineiv
> fail :: spec/ARB_separate_shader_objects/sso-mix_pipeline_useprogram
> crash :: spec/ARB_separate_shader_objects/sso-IsProgramPipeline
> (results piglit output attached)
> 
> On Tue, Mar 26, 2013 at 12:56 PM, gregory hainaut
>  wrote:
> > Plese find below my (really too big) patch.
> 
> It's not really big at all, but I think the piglit-shader changes need
> to be a separate commit/patch.
> 
> -Jordan

Thanks very much for your test.

V2:
* split the patch properly with git :)
* sso-GetProgramPipelineiv: fix a VS linker error. Print current test
  step.
* sso-mix_pipeline_useprogram: fix a wrong expected. Now the test must
  work on nvidia :)
* sso-IsProgramPipeline: Print more current test step
=> my guess is  nvidia choke on glDeleteProgramPipelines( -1,
   id);
=> Nvidia as AMD doesn't follow the spec (not very serious)

Gregory
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 1/3] piglit util: new functions piglit_program_pipeline_check_status/quiet

2013-03-28 Thread gregory hainaut
Equivalent to piglit_link_check_status/quiet but with program object pipeline
---
 tests/util/piglit-shader.c |   50 
 tests/util/piglit-shader.h |2 ++
 2 files changed, 52 insertions(+)

diff --git a/tests/util/piglit-shader.c b/tests/util/piglit-shader.c
index c67e58a..d7a0266 100644
--- a/tests/util/piglit-shader.c
+++ b/tests/util/piglit-shader.c
@@ -213,6 +213,45 @@ link_check_status(GLint prog, FILE *output)
return ok;
 }
 
+/* Same function as above but for program pipeline */
+static GLboolean
+program_pipeline_check_status(GLuint pipeline, FILE *output)
+{
+   GLchar *info = NULL;
+   GLint size;
+   GLint ok;
+
+   piglit_require_extension("GL_ARB_separate_shader_objects");
+
+   glValidateProgramPipeline(pipeline);
+   glGetProgramPipelineiv(pipeline, GL_VALIDATE_STATUS, &ok);
+
+   /* Some drivers return a size of 1 for an empty log.  This is the size
+* of a log that contains only a terminating NUL character.
+*/
+   glGetProgramPipelineiv(pipeline, GL_INFO_LOG_LENGTH, &size);
+   if (size > 1) {
+   info = malloc(size);
+   glGetProgramPipelineInfoLog(pipeline, size, NULL, info);
+   }
+
+   if (!ok) {
+   fprintf(output, "Failed to validate the pipeline: %s\n",
+   (info != NULL) ? info : "");
+   }
+   else if (0 && info != NULL) {
+   /* Enable this to get extra linking info.
+* Even if there's no link errors, the info log may
+* have some remarks.
+*/
+   printf("Pipeline validataion warning: %s\n", info);
+   }
+
+   free(info);
+
+   return ok;
+}
+
 GLboolean
 piglit_link_check_status(GLint prog)
 {
@@ -234,6 +273,17 @@ piglit_link_check_status_quiet(GLint prog)
return link_check_status(prog, stdout);
 }
 
+GLboolean
+piglit_program_pipeline_check_status(GLuint pipeline)
+{
+   return program_pipeline_check_status(pipeline, stderr);
+}
+
+GLboolean
+piglit_program_pipeline_check_status_quiet(GLuint pipeline)
+{
+   return program_pipeline_check_status(pipeline, stdout);
+}
 
 GLint piglit_link_simple_program(GLint vs, GLint fs)
 {
diff --git a/tests/util/piglit-shader.h b/tests/util/piglit-shader.h
index 12cf731..0bb7792 100644
--- a/tests/util/piglit-shader.h
+++ b/tests/util/piglit-shader.h
@@ -34,6 +34,8 @@ GLuint piglit_compile_shader(GLenum target, const char 
*filename);
 GLuint piglit_compile_shader_text(GLenum target, const char *text);
 GLboolean piglit_link_check_status(GLint prog);
 GLboolean piglit_link_check_status_quiet(GLint prog);
+GLboolean piglit_program_pipeline_check_status(GLuint pipeline);
+GLboolean piglit_program_pipeline_check_status_quiet(GLuint pipeline);
 GLint piglit_link_simple_program(GLint vs, GLint fs);
 
 #if defined(PIGLIT_USE_OPENGL_ES1)
-- 
1.7.10.4
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 2/3] add 3 news tests for arb_separate_shader_objects

2013-03-28 Thread gregory hainaut
iv.c)
+piglit_add_executable (arb_separate_shader_object-mix_pipeline_useprogram 
mix_pipeline_useprogram.c)
diff --git a/tests/spec/arb_separate_shader_objects/CMakeLists.txt 
b/tests/spec/arb_separate_shader_objects/CMakeLists.txt
new file mode 100644
index 000..144a306
--- /dev/null
+++ b/tests/spec/arb_separate_shader_objects/CMakeLists.txt
@@ -0,0 +1 @@
+piglit_include_target_api()
diff --git a/tests/spec/arb_separate_shader_objects/GetProgramPipelineiv.c 
b/tests/spec/arb_separate_shader_objects/GetProgramPipelineiv.c
new file mode 100644
index 000..81f6978
--- /dev/null
+++ b/tests/spec/arb_separate_shader_objects/GetProgramPipelineiv.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright © 2013 Gregory Hainaut 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+   config.supports_gl_compat_version = 10;
+
+   config.window_width = 32;
+   config.window_height = 32;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static GLboolean pass;
+
+enum piglit_result
+piglit_display(void)
+{
+   /* UNREACHED */
+   return PIGLIT_FAIL;
+}
+
+static GLint
+stage2bitfield(GLint stage) {
+   switch(stage) {
+   case GL_VERTEX_SHADER: return GL_VERTEX_SHADER_BIT;
+   case GL_FRAGMENT_SHADER: return GL_FRAGMENT_SHADER_BIT;
+   case GL_GEOMETRY_SHADER: return GL_GEOMETRY_SHADER_BIT;
+   case GL_TESS_CONTROL_SHADER: return GL_TESS_CONTROL_SHADER_BIT;
+   case GL_TESS_EVALUATION_SHADER:return 
GL_TESS_EVALUATION_SHADER_BIT;
+   case GL_COMPUTE_SHADER: return GL_COMPUTE_SHADER_BIT;
+   default:return 0;
+   }
+   return 0;
+}
+
+static void
+check_stage(GLint pipe, GLint expected, GLint stage, GLboolean supported) {
+   GLint param = 0;
+   glGetProgramPipelineiv(pipe, stage, ¶m);
+
+   if (!supported) {
+   pass &= piglit_check_gl_error(GL_INVALID_ENUM);
+   } else if (param != expected) {
+   fprintf(stderr, "Failed to get program of stage %s.\n", 
piglit_get_gl_enum_name(stage));
+   pass = GL_FALSE;
+   }
+}
+
+static void
+use_stage_and_check(GLint pipe, GLint program, GLint stage, GLboolean 
supported) {
+   printf("Attach program (%d) to stage (%s). Expected to be supported: 
%s\n", program,
+   piglit_get_gl_enum_name(stage), supported ? "yes" : 
"no");
+   glUseProgramStages(pipe, stage2bitfield(stage), program);
+   if (!supported) {
+   pass &= piglit_check_gl_error(GL_INVALID_VALUE);
+   } else {
+   pass &= piglit_check_gl_error(GL_NO_ERROR);
+   }
+
+   check_stage(pipe, program, stage, supported);
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+   GLint vs, fs, gs, tcs, tes;
+   GLint ver;
+   GLuint pipe = 0;
+   GLint param = 0;
+   char version[100];
+   const char *shader_source[2];
+
+   const char *vs_source_150 =
+   "out gl_PerVertex {\n"
+   "vec4 gl_Position;\n"
+   "};\n"
+   "\n"
+   "in vec4 position;\n"
+   "\n"
+   "void main()\n"
+   "{\n"
+   "   gl_Position = position;\n"
+   "}\n";
+   const char *vs_source_140 =
+   "void main()\n"
+   "{\n"
+   "   gl_Position = gl_Vertex;\n"
+   "}\n";
+   const char *fs_source =
+   "void main()\n"
+   "{\n"
+   "   gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0);\n"
+   "}\n";
+  

[Mesa-dev] [PATCH 3/3] update EXT_transform_feedback error detection

2013-03-28 Thread gregory hainaut
program pipeline add new INVALID_OPERATION (spec chapter 13.2.2)

Note: FGLRX don't report any of the expected errors...
---
 tests/all.tests|4 +-
 tests/spec/ext_transform_feedback/api-errors.c |   84 +++-
 2 files changed, 85 insertions(+), 3 deletions(-)

diff --git a/tests/all.tests b/tests/all.tests
index 2cbf3c4..cd759b5 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -1906,7 +1906,9 @@ for mode in ['interleaved_ok_base', 
'interleaved_ok_range',
  'bind_range_offset_2', 'bind_range_offset_3',
  'bind_range_offset_5', 'bind_offset_offset_1',
  'bind_offset_offset_2', 'bind_offset_offset_3',
- 'bind_offset_offset_5', 'not_a_program']:
+ 'bind_offset_offset_5', 'not_a_program',
+ 'useprogstage_noactive', 'useprogstage_active',
+ 'bind_pipeline']:
 test_name = 'api-errors {0}'.format(mode)
 ext_transform_feedback[test_name] = concurrent_test(
 'ext_transform_feedback-{0}'.format(test_name))
diff --git a/tests/spec/ext_transform_feedback/api-errors.c 
b/tests/spec/ext_transform_feedback/api-errors.c
index 04470b2..ba4fff8 100644
--- a/tests/spec/ext_transform_feedback/api-errors.c
+++ b/tests/spec/ext_transform_feedback/api-errors.c
@@ -78,6 +78,9 @@ enum test_mode {
BIND_BAD_SIZE,
BIND_BAD_OFFSET,
NOT_A_PROGRAM,
+   USEPROGSTAGE_ACTIVE,
+   USEPROGSTAGE_NOACTIVE,
+   BIND_PIPELINE
 };
 
 enum bind_mode {
@@ -97,6 +100,32 @@ static const char *vstext =
"  gl_Position = vec4(1.0);\n"
"}\n";
 
+static const char *vstext_sep_150 =
+   "#extension GL_ARB_separate_shader_objects : enable\n"
+   "out gl_PerVertex {\n"
+   "vec4 gl_Position;\n"
+   "};\n"
+   "varying vec4 foo;\n"
+   "varying vec4 bar;\n"
+   "\n"
+   "void main()\n"
+   "{\n"
+   "  foo = vec4(1.0);\n"
+   "  bar = vec4(1.0);\n"
+   "  gl_Position = vec4(1.0);\n"
+   "}\n";
+static const char *vstext_sep_140 =
+   "#extension GL_ARB_separate_shader_objects : enable\n"
+   "varying vec4 foo;\n"
+   "varying vec4 bar;\n"
+   "\n"
+   "void main()\n"
+   "{\n"
+   "  foo = vec4(1.0);\n"
+   "  bar = vec4(1.0);\n"
+   "  gl_Position = vec4(1.0);\n"
+   "}\n";
+
 static const char *varyings[] = { "foo", "bar" };
 
 static struct test_desc
@@ -151,6 +180,10 @@ static struct test_desc
{ "bind_offset_offset_3",BIND_BAD_OFFSET,  3, OFFSET, 
GL_INTERLEAVED_ATTRIBS, 1 },
{ "bind_offset_offset_5",BIND_BAD_OFFSET,  5, OFFSET, 
GL_INTERLEAVED_ATTRIBS, 1 },
{ "not_a_program",   NOT_A_PROGRAM,0, BASE,   
GL_INTERLEAVED_ATTRIBS, 1 },
+   { "useprogstage_noactive",   USEPROGSTAGE_NOACTIVE,0, BASE,   
GL_INTERLEAVED_ATTRIBS, 1 },
+   { "useprogstage_active", USEPROGSTAGE_ACTIVE,  0, BASE,   
GL_INTERLEAVED_ATTRIBS, 1 },
+   { "bind_pipeline",   BIND_PIPELINE,0, BASE,   
GL_INTERLEAVED_ATTRIBS, 1 },
+
 };
 
 static void
@@ -186,6 +219,7 @@ do_test(const struct test_desc *test)
 {
GLuint vs;
GLuint progs[2];
+   GLuint pipes[2];
GLuint bufs[NUM_BUFFERS];
float initial_xfb_buffer_contents[XFB_BUFFER_SIZE];
GLboolean pass = GL_TRUE;
@@ -193,6 +227,10 @@ do_test(const struct test_desc *test)
int num_varyings = test->mode == NO_VARYINGS ? 0 : test->num_buffers;
GLint max_separate_attribs;
 
+   if (test->mode == USEPROGSTAGE_ACTIVE || test->mode == 
USEPROGSTAGE_NOACTIVE || test->mode == BIND_PIPELINE) {
+   piglit_require_extension("GL_ARB_separate_shader_objects");
+   }
+
glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
  &max_separate_attribs);
printf("MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTIBS=%i\n",
@@ -200,7 +238,19 @@ do_test(const struct test_desc *test)
 
printf("Compile vertex shader\n");
vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext);
-   if (test->mode == NOT_A_PROGRAM) {
+   if (test->mode == USEPROGSTAGE_ACTIVE || test->mode == 
USEPROGSTAGE_NOACTIVE || test->mode == BIND_PIPELINE) {
+   /* Note, we can't use glCreateShaderProgramv because the setup 
of transform feedback
+* must be done before linking
+*/
+   if (piglit_get_gl_version() >= 32)
+   vs = piglit_compile_shader_text(GL_VERTEX_SHADER, 
vstext_sep_150);
+   else
+   vs = piglit_compile_shader_text(GL_VERTEX_SHADER, 
vstext_sep_140);
+   progs[0] = glCreateProgram();
+   glProgramParameteri(progs[0], GL_PROGRAM_SEPARABLE, GL_TRUE);
+   glAttachShader(progs[0], vs);
+
+   } else if (test->mode == NOT_A_PROGRAM) {
printf("Create a program and then delete it\n");
   

Re: [Mesa-dev] [PATCH 00/12] RFC: add support of ARB_separate_shader_object extensions

2013-04-06 Thread gregory hainaut
On Fri, 05 Apr 2013 14:44:54 -0700
Ian Romanick  wrote:

> On 04/05/2013 02:25 PM, gregory wrote:
> > Hello,
> >
> > Please find an implementation of the ARB_separate_shader_objects 
> > extensions. I concentrate mostly on the state part of
> > the extensions aka the pipeline object. I think GLSL already compiled 
> > program separately anyway.
> >
> > I test my implementation on the test that I send yesterday ago on piglit. 
> > All tests are ok but I miss a test for new uniform function.
> > Besides there are still some parts unimplemented:
> > 1/ GLX Protocol: not sure it will be useful, as understand GLX is kinda 
> > drepecated
> 
> We don't have any other GLX support for GLSL, so I wouldn't worry about it.
> 
> > 2/ Display list: need to be done or maybe enable the extensions on CORE 
> > profile
> 
> I haven't had any requests for the functionality with compatibility 
> profiles.  As far as I can tell, all of the ISVs that want this feature 
> are already shifting to core profiles.
> 
> Maybe Aras can give us one humble ISVs opinion. :)

We can also enable the extension on compatibility profile but without the 
display list part. Not ideal but better than nothings.
FYI, only glUseProgramStages can be compiled within a display list. All others 
entry points are executed immediately.

> 
> > Stuff that bug me:
> > 1/ I don't get how to use ralloc_strdup. So I set the ralloc's context to 
> > NULL, not sure it is fully correct
> 
> The ralloc memory context is (usually) some other thing allocated by 
> ralloc.  When the context is freed, all of the things allocated using 
> that context will also be freed.  So,
> 
>  a = ralloc_size(NULL, 32);
>  b = ralloc_size(a, 32);
>  ...
>  ralloc_free(a);
> 
> Will free both a and b.
> 
> You can also use ralloc_steal to reparent an allocation.  So,
> 
>  a = ralloc_size(NULL, 32);
>  b = ralloc_size(a, 32);
>  c = ralloc_size(NULL, 32);
> 
>  ralloc_steal(c, b);
> 
>  ralloc_free(a);
> 
> will only cause a to be freed.  b is now in the context of c.
> 
> We use this in the GLSL compiler to, basically, implement a 
> mark-and-sweep garbage collector.  As various parts of the compiler 
> allocate new objects and orphan others, we'll do a ralloc_steal pass to 
> reparent all of the objects that are still connected.  A ralloc_free of 
> the old context will destroy all the objects that are no longer connected.

Thanks very much for the input. I definitely had a memory leak which is now 
fixed on my tree :)

> 
> > 2/ I implement the feature as a pure mesa state. I don't know if they're 
> > any rule to create driver functions. Maybe it
> > would be better to add 
> > CreatePipelineObject/DeletePipelineObject/BindPipeline/UseProgramStages. 
> > Opinion is welcome
> >
> > Note: I didn't yet rebase my work on latest mesa. Not sure if it is 
> > critical for a preliminary review.
> > Note2: I create the xml manually, don't know if there is any automatic flow.
> >
> > Thanks
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 05/12] sso: replace Shader binding point with _Shader

2013-04-11 Thread gregory hainaut
On Sat, 06 Apr 2013 08:52:35 -0600
Brian Paul  wrote:

> One more comment for now below.  I may not get to review the rest for 
> a few days.
> 
> -Brian

Thanks very much for the review. I redid properly my patch and rebase
my work on a more recent mesa version. I want to do a piglit non regression test
first and double check any typo. Then I will probabaly post the V2 friday
except if you prefer to finish the first review first.

FYI, I choose to keep the shorter "Current" so we got the basic 
"Pipeline.Current"

Cheers,
Gregory

> 
> On 04/05/2013 03:27 PM, gregory wrote:
> > To avoid NULL pointer check a default pipeline object is installed in 
> > _Shader when no
> > program is current
> >
> > The spec say that UseProgram/UseShaderProgramEXT/ActiveProgramEXT got an 
> > higher
> > priority over the pipeline object. When default program is uninstall, the 
> > pipeline is
> > used if any was bound.
> >
> > Note: A careful rename need to be done now...
> > ---
> >   src/mesa/main/mtypes.h  |4 ++
> >   src/mesa/main/pipelineobj.c |8 
> >   src/mesa/main/shaderapi.c   |   91 
> > +--
> >   3 files changed, 100 insertions(+), 3 deletions(-)
> >
> > diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
> > index 2445574..dc54f3d 100644
> > --- a/src/mesa/main/mtypes.h
> > +++ b/src/mesa/main/mtypes.h
> > @@ -2433,6 +2433,9 @@ struct gl_pipeline_shader_state
> >  /** Currently bound pipeline object. See _mesa_BindProgramPipeline() */
> >  struct gl_shader_state *PipelineObj;
> >
> > +   /* Default Object to ensure that _Shader is never NULL */
> > +   struct gl_shader_state *Default;
> > +
> >  /** Pipeline objects */
> >  struct _mesa_HashTable *Objects;
> >   };
> > @@ -3541,6 +3544,7 @@ struct gl_context
> >
> >  struct gl_pipeline_shader_state Pipeline; /**<  GLSL pipeline shader 
> > object state */
> >  struct gl_shader_state Shader; /**<  GLSL shader object state */
> > +   struct gl_shader_state *_Shader; /**<  Points to ::Shader or 
> > ::Pipeline.PipelineObj or ::Pipeline.Default */
> 
> If gl_shader_state gets renamed to gl_pipeline_object then this field 
> would probably be better name CurrentPipeline, or similar.
> 
> 
> 
> >  struct gl_shader_compiler_options 
> > ShaderCompilerOptions[MESA_SHADER_TYPES];
> >
> >  struct gl_query_state Query;  /**<  occlusion, timer queries */
> > diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
> > index 7a56c67..c805cdf 100644
> > --- a/src/mesa/main/pipelineobj.c
> > +++ b/src/mesa/main/pipelineobj.c
> > @@ -97,6 +97,10 @@ _mesa_init_pipeline(struct gl_context *ctx)
> >  ctx->Pipeline.Objects = _mesa_NewHashTable();
> >
> >  ctx->Pipeline.PipelineObj = NULL;
> > +
> > +   /* Install a default Pipeline */
> > +   ctx->Pipeline.Default = _mesa_new_pipeline_object(ctx, 0);
> > +   _mesa_reference_pipeline_object(ctx,&ctx->_Shader, 
> > ctx->Pipeline.Default);
> >   }
> >
> >
> > @@ -120,6 +124,10 @@ _mesa_free_pipeline_data(struct gl_context *ctx)
> >   {
> >  _mesa_HashDeleteAll(ctx->Pipeline.Objects, delete_pipelineobj_cb, ctx);
> >  _mesa_DeleteHashTable(ctx->Pipeline.Objects);
> > +
> > +   _mesa_reference_pipeline_object(ctx,&ctx->_Shader, NULL);
> > +   _mesa_delete_pipeline_object(ctx, ctx->Pipeline.Default);
> > +
> >   }
> >
> >   /**
> > diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
> > index a86a429..1092287 100644
> > --- a/src/mesa/main/shaderapi.c
> > +++ b/src/mesa/main/shaderapi.c
> > @@ -43,6 +43,7 @@
> >   #include "main/hash.h"
> >   #include "main/mfeatures.h"
> >   #include "main/mtypes.h"
> > +#include "main/pipelineobj.h"
> >   #include "main/shaderapi.h"
> >   #include "main/shaderobj.h"
> >   #include "main/transformfeedback.h"
> > @@ -138,6 +139,8 @@ _mesa_free_shader_state(struct gl_context *ctx)
> >  _mesa_reference_shader_program(ctx,&ctx->Shader.ActiveProgram, NULL);
> >
> >  /* Extended for ARB_separate_shader_objects */
> > +   _mesa_reference_pipeline_object(ctx,&ctx->_Shader, NULL);
> > +
> >  assert(ctx->Shader.RefCount == 1);
> >  _glthread_DESTROY_MUTEX(ctx->Shader.Mutex);
> >   }
> > @@ -1453,7 +1456,29 @@ _mesa_UseProgram(GLhandleARB program)
> > shProg = NULL;
> >  }
> >
> > -   _mesa_use_program(ctx, shProg);
> > +   /*
> > +* The executable code for an individual shader stage is taken from the
> > +* current program for that stage.  If there is a current program object
> > +* for any shader stage or for uniform updates established by 
> > UseProgram,
> > +* UseShaderProgramEXT, or ActiveProgramEXT, the current program for 
> > that
> > +* stage (if any) is considered current.  Otherwise, if there is a bound
> > +* program pipeline object ...
> > +*/
> > +   if (program) {
> > +  /* Attach shader state to the binding point */
> > +  _mesa_reference_pipeline_object(ctx,&ctx->_Shader,&ctx->Shader);
> > + 

Re: [Mesa-dev] [PATCH 00/12] RFC: add support of ARB_separate_shader_object extensions V2

2013-04-12 Thread gregory hainaut
On Fri, 12 Apr 2013 09:39:15 -0700 (PDT)
Jose Fonseca  wrote:

> - Original Message -
> > From: "gregory" 
> > To: "gregory hainaut" 
> 
> FWIW, your emails BCC'ing the list are a bit of a pain. They manage elude 
> most of my mail filtering rules, and replying-to-all doesn't include the 
> list...
> 
> Jose
> 
> > Sent: Friday, April 12, 2013 5:22:02 PM
> > Subject: [Mesa-dev] [PATCH 00/12] RFC: add support of 
> > ARB_separate_shader_object extensions V2
> [...]


Thanks for the info I will look. 

Actually I'm not sure it is a bcc. I setup git to send the email to my draft 
box, then I used the redirect (to avoid wrapping issue)
 feature of claws-mail and I manually set "to: mesa" and myself in "cc". The 
"to :myself" was done by git header but I'm not sure it is used. Maybe it
will work better if I send directly git email to my upload queue with the good 
cc!

Sorry for the disturbance
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 00/12] RFC: add support of ARB_separate_shader_object extensions V2

2013-04-12 Thread gregory hainaut
On Fri, 12 Apr 2013 19:02:47 +0200
gregory hainaut  wrote:

> On Fri, 12 Apr 2013 09:39:15 -0700 (PDT)
> Jose Fonseca  wrote:
> 
> > - Original Message -
> > > From: "gregory" 
> > > To: "gregory hainaut" 
> > 
> > FWIW, your emails BCC'ing the list are a bit of a pain. They manage elude 
> > most of my mail filtering rules, and replying-to-all doesn't include the 
> > list...
> > 
> > Jose
> > 
> > > Sent: Friday, April 12, 2013 5:22:02 PM
> > > Subject: [Mesa-dev] [PATCH 00/12] RFC: add support of 
> > > ARB_separate_shader_object extensions V2
> > [...]
> 
> 
> Thanks for the info I will look. 
> 
> Actually I'm not sure it is a bcc. I setup git to send the email to my draft 
> box, then I used the redirect (to avoid wrapping issue)
>  feature of claws-mail and I manually set "to: mesa" and myself in "cc". The 
> "to :myself" was done by git header but I'm not sure it is used. Maybe it
> will work better if I send directly git email to my upload queue with the 
> good cc!
> 
> Sorry for the disturbance

FYI, I changed my flow to bypass the redirect feature. Future patch will be 
better :)

By the way I upload a github tree:
https://github.com/gregory38/mesa-sso/tree/sso2

Branch: sso2

Gregory
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 01/12] sso: Create extensions entry points

2013-04-12 Thread gregory hainaut
On Fri, 12 Apr 2013 12:38:19 -0700
Eric Anholt  wrote:

> Please, patches for Mesa have to actually be addressed to Mesa.

What do you mean? The github tree (was requested by Jordan)? Or because the 
mail header doesn't contains mesa address (mail client setup issue that it is 
now fixed) ? 

> I'm really excited to see progress on SSO, so hopefully we can get some
> of this landed soon.

> 
> gregory  writes:
> 
> > V2: formatting improvement
> 
> patch versioning generally comes at the end of the commit message.
> 
> Also, could you fix up your git author info to include your full name?
> 
> > diff --git a/src/mapi/glapi/gen/ARB_separate_shader_objects.xml 
> > b/src/mapi/glapi/gen/ARB_separate_shader_objects.xml
> > new file mode 100644
> > index 000..29a37f5
> > --- /dev/null
> > +++ b/src/mapi/glapi/gen/ARB_separate_shader_objects.xml
> 
> > +  
> > + 
> > + 
> > +  
> > +  
> > + 
> > + 
> > +  
> 
> Missing ProgramParameteri here.
Unfortunately it complains about duplication. The function is already defined 
in ARB_get_program_binary.xml. I could put a dummy name with an alias.
I don't see any specific syntax on the python.

> 
> > +  
> > + 
> > + 
> > + 
> > +  
> 
> > +  

Re: [Mesa-dev] [PATCH 01/12] sso: Create extensions entry points

2013-05-02 Thread gregory hainaut
On Fri, 12 Apr 2013 13:52:46 -0700
Eric Anholt  wrote:

> gregory hainaut  writes:
> 
> > On Fri, 12 Apr 2013 12:38:19 -0700
> > Eric Anholt  wrote:
> >
> >> Please, patches for Mesa have to actually be addressed to Mesa.
> >
> > What do you mean? The github tree (was requested by Jordan)? Or
> > because the mail header doesn't contains mesa address (mail client
> > setup issue that it is now fixed) ?
> 
> The mail header.
> 

Any feedback on the others patches ? Would you prefer a resending of the patch
 with the proper mail header ?


signature.asc
Description: PGP signature
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 00/12] RFC: add support of ARB_separate_shader_object extensions V3

2013-05-03 Thread Gregory Hainaut
Please find an implementation of the ARB_separate_shader_objects extensions. I 
concentrate
mostly on the state part of the extensions aka the pipeline object. I think GLSL
already compiled program separately anyway.

I test my implementation on the test that I send on piglit mailing list. All 
tests 
are ok but I miss a test for new uniform function. Besides there are still some 
parts unimplemented:
1/ GLX Protocol: dropped
2/ Display list: would be done later if someone is interested otherwise dropped

Stuff that bug me:
1/ I implement the feature as a pure mesa state. I don't know if they're any 
rule to create driver functions. Maybe it 
   would be better to add 
CreatePipelineObject/DeletePipelineObject/BindPipeline/UseProgramStages. 
Opinion is welcome

A github branch can be found here (based on v2 but v3 add only comment):
* https://github.com/gregory38/mesa-sso/tree/sso2

V2: 
* fix ralloc memory leak
* follow mesa formating rule
* rename Pipeline.PipelineObj to Pipeline.Current
* rename gl_shader_state to gl_pipeline_object
* rebase on current mesa

V3:
* resend properly the patches on the mesa mailing list
* Add minor comment


Note: Rebase done on ac1118d53c0b22db8dcd6fcdcd2d1a245037dbc1

Gregory Hainaut (12):
  sso: Create extensions entry points
  sso: Add pipeline container/state
  sso: add support of GL_PROGRAM_SEPARABLE and CreateShaderProgramv
  sso: implement ActiveShaderProgram & GetProgramPipelineiv
  sso: replace Shader binding point with _Shader
  sso: rename Shader to the pointer _Shader
  sso: update meta state
  sso: Implement _mesa_UseProgramStages
  sso: implement BindProgramPipeline
  sso: update glGet: GL_PROGRAM_PIPELINE_BINDING
  sso: implement ValidateProgramPipeline and GetProgramPipelineInfoLog
  sso: Finally enable the extension on Gallium

 src/mapi/glapi/gen/ARB_separate_shader_objects.xml |  401 ++
 src/mapi/glapi/gen/Makefile.am |1 +
 src/mapi/glapi/gen/gl_API.xml  |6 +-
 src/mapi/glapi/gen/gl_genexec.py   |1 +
 src/mesa/drivers/common/meta.c |   38 +-
 src/mesa/drivers/dri/i965/brw_gs.c |2 +-
 src/mesa/drivers/dri/i965/brw_shader.cpp   |4 +-
 src/mesa/drivers/dri/i965/brw_vs.c |4 +-
 src/mesa/drivers/dri/i965/brw_vs_surface_state.c   |2 +-
 src/mesa/drivers/dri/i965/brw_wm.c |2 +-
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c   |2 +-
 src/mesa/drivers/dri/i965/gen6_sol.c   |6 +-
 src/mesa/drivers/dri/i965/gen6_vs_state.c  |2 +-
 src/mesa/drivers/dri/i965/gen6_wm_state.c  |2 +-
 src/mesa/drivers/dri/i965/gen7_sol_state.c |4 +-
 src/mesa/drivers/dri/i965/gen7_vs_state.c  |2 +-
 src/mesa/drivers/dri/i965/gen7_wm_state.c  |2 +-
 src/mesa/main/api_validate.c   |2 +-
 src/mesa/main/context.c|   44 +-
 src/mesa/main/extensions.c |1 +
 src/mesa/main/ff_fragment_shader.cpp   |8 +-
 src/mesa/main/get.c|   19 +
 src/mesa/main/get_hash_params.py   |3 +
 src/mesa/main/mtypes.h |   43 +-
 src/mesa/main/pipelineobj.c|  834 
 src/mesa/main/pipelineobj.h|  102 +++
 src/mesa/main/shaderapi.c  |  252 --
 src/mesa/main/shaderapi.h  |   10 +-
 src/mesa/main/state.c  |   14 +-
 src/mesa/main/texstate.c   |   12 +-
 src/mesa/main/transformfeedback.c  |4 +-
 src/mesa/main/uniform_query.cpp|   75 +-
 src/mesa/main/uniforms.c   |  466 ++-
 src/mesa/main/uniforms.h   |   86 ++
 src/mesa/program/ir_to_mesa.cpp|   12 +-
 src/mesa/sources.mak   |1 +
 src/mesa/state_tracker/st_atom_clip.c  |2 +-
 src/mesa/state_tracker/st_atom_constbuf.c  |4 +-
 src/mesa/state_tracker/st_cb_drawpixels.c  |2 +-
 src/mesa/state_tracker/st_draw.c   |6 +-
 src/mesa/state_tracker/st_extensions.c |1 +
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp |2 +-
 src/mesa/state_tracker/st_program.c|6 +-
 src/mesa/swrast/s_fragprog.c   |2 +-
 44 files changed, 2319 insertions(+), 175 deletions(-)
 create mode 100644 src/mapi/glapi/gen/ARB_separate_shader_objects.xml
 create mode 100644 src/mesa/main/pipelineobj.c
 create mode 100644 src/mesa/main/pipelineobj.h

-- 
1.7.10.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 02/12] sso: Add pipeline container/state

2013-05-03 Thread Gregory Hainaut
V1:
* Extend gl_shader_state as pipeline object state
* Add a new container gl_pipeline_shader_state that contains
  binding point of the previous object
* Update mesa init/free shader state due to the extension of
  the attibute
* Add an init/free pipeline function for the context
* Implement GenProgramPipeline/DeleteProgramPipeline/IsProgramPipeline.
 I based my work on the VAO code.

V2:
* Rename gl_shader_state to gl_pipeline_object
* Rename Pipeline.PipelineObj to Pipeline.Current
* Rename ValidationStatus to Validated
* Formatting improvement
---
 src/mesa/main/context.c |3 +
 src/mesa/main/mtypes.h  |   30 +-
 src/mesa/main/pipelineobj.c |  234 ++-
 src/mesa/main/pipelineobj.h |   25 +
 src/mesa/main/shaderapi.c   |   14 ++-
 src/mesa/main/shaderapi.h   |3 +
 6 files changed, 303 insertions(+), 6 deletions(-)

diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 0539934..d089827 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -106,6 +106,7 @@
 #include "macros.h"
 #include "matrix.h"
 #include "multisample.h"
+#include "pipelineobj.h"
 #include "pixel.h"
 #include "pixelstore.h"
 #include "points.h"
@@ -762,6 +763,7 @@ init_attrib_groups(struct gl_context *ctx)
_mesa_init_lighting( ctx );
_mesa_init_matrix( ctx );
_mesa_init_multisample( ctx );
+   _mesa_init_pipeline( ctx );
_mesa_init_pixel( ctx );
_mesa_init_pixelstore( ctx );
_mesa_init_point( ctx );
@@ -1167,6 +1169,7 @@ _mesa_free_context_data( struct gl_context *ctx )
_mesa_free_texture_data( ctx );
_mesa_free_matrix_data( ctx );
_mesa_free_viewport_data( ctx );
+   _mesa_free_pipeline_data(ctx);
_mesa_free_program_data(ctx);
_mesa_free_shader_state(ctx);
_mesa_free_queryobj_data(ctx);
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 05d8518..4487068 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2381,9 +2381,19 @@ struct gl_shader_program
 
 /**
  * Context state for GLSL vertex/fragment shaders.
+ * Extended to support pipeline object
  */
-struct gl_shader_state
+struct gl_pipeline_object
 {
+   /** Name of the pipeline object as received from glGenProgramPipelines.
+* It would be 0 for shaders without separate shader objects.
+*/
+   GLuint Name;
+
+   GLint RefCount;
+
+   _glthread_Mutex Mutex;
+
/**
 * Programs used for rendering
 *
@@ -2405,8 +2415,23 @@ struct gl_shader_state
struct gl_shader_program *ActiveProgram;
 
GLbitfield Flags;/**< Mask of GLSL_x flags */
+
+   GLboolean Validated; /**< Pipeline Validation status */
+
+   GLboolean EverBound; /**< Has the pipeline object been 
created */
 };
 
+/**
+ * Context state for GLSL pipeline shaders.
+ */
+struct gl_pipeline_shader_state
+{
+   /** Currently bound pipeline object. See _mesa_BindProgramPipeline() */
+   struct gl_pipeline_object *Current;
+
+   /** Pipeline objects */
+   struct _mesa_HashTable *Objects;
+};
 
 /**
  * Compiler options for a single GLSL shaders type
@@ -3514,7 +3539,8 @@ struct gl_context
struct gl_geometry_program_state GeometryProgram;
struct gl_ati_fragment_shader_state ATIFragmentShader;
 
-   struct gl_shader_state Shader; /**< GLSL shader object state */
+   struct gl_pipeline_shader_state Pipeline; /**< GLSL pipeline shader object 
state */
+   struct gl_pipeline_object Shader; /**< GLSL shader object state */
struct gl_shader_compiler_options ShaderCompilerOptions[MESA_SHADER_TYPES];
 
struct gl_query_state Query;  /**< occlusion, timer queries */
diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
index e7e628b..d81bd0e 100644
--- a/src/mesa/main/pipelineobj.c
+++ b/src/mesa/main/pipelineobj.c
@@ -30,6 +30,9 @@
  * Implementation of pipeline object related API functions. Based on
  * GL_ARB_separate_shader_objects extension.
  *
+ * XXX things to do:
+ * 1/ Do we need to create 2 new drivers functions: CreatePipelineObject
+ * DeletePipelineObject
  */
 
 #include "main/glheader.h"
@@ -51,6 +54,168 @@
 #include "../glsl/glsl_parser_extras.h"
 #include "../glsl/ir_uniform.h"
 
+/**
+ * Delete a pipeline object.
+ */
+void
+_mesa_delete_pipeline_object(struct gl_context *ctx, struct gl_pipeline_object 
*obj)
+{
+   _mesa_reference_shader_program(ctx, &obj->_CurrentFragmentProgram, NULL);
+   _mesa_reference_shader_program(ctx, &obj->CurrentFragmentProgram, NULL);
+   _mesa_reference_shader_program(ctx, &obj->CurrentVertexProgram, NULL);
+   _mesa_reference_shader_program(ctx, &obj->CurrentGeometryProgram, NULL);
+   _mesa_reference_shader_program(ctx, &obj->ActiveProgram, NULL);
+   _glthread_DESTROY_MUTEX(obj->Mutex);
+   ralloc_free(obj);
+}
+
+/**
+ * Allocate and initialize a new pipeline object.
+ */
+static struct gl_pipeline_object *
+_mesa_new_pipeline_object(struct gl_context *ctx, GLuint name)
+{
+   struct gl_pipeline_object *obj = rz

[Mesa-dev] [PATCH 03/12] sso: add support of GL_PROGRAM_SEPARABLE and CreateShaderProgramv

2013-05-03 Thread Gregory Hainaut
V1:
CreateShaderProgramv is similar as CreateShaderProgramEXT. The 2 differences are
1/ it an array of strings
2/ it support the GL_PROGRAM_SEPARABLE (aka SeparateShader) flag

V2: Formatting improvement
---
 src/mesa/main/mtypes.h|5 +++
 src/mesa/main/shaderapi.c |   94 +++--
 src/mesa/main/shaderapi.h |3 +-
 3 files changed, 72 insertions(+), 30 deletions(-)

diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 4487068..f979cd0 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2255,6 +2255,11 @@ struct gl_shader_program
 * glClear()).
 */
GLboolean InternalSeparateShader;
+   /* ARB_separate_shader_objects
+* indicates whether program can be bound for individual pipeline stages 
using
+* UseProgramStages after it is next linked.
+*/
+   GLboolean SeparateShader;
 
GLuint NumShaders;  /**< number of attached shaders */
struct gl_shader **Shaders; /**< List of attached the shaders */
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 774163d..46072ba 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -622,6 +622,11 @@ get_programiv(struct gl_context *ctx, GLuint program, 
GLenum pname, GLint *param
case GL_PROGRAM_BINARY_LENGTH:
   *params = 0;
   return;
+   case GL_PROGRAM_SEPARABLE:
+  if (!ctx->Extensions.ARB_separate_shader_objects)
+ break;
+  *params = shProg->SeparateShader;
+  return;
default:
   break;
}
@@ -1702,6 +1707,25 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, 
GLint value)
*/
   shProg->BinaryRetreivableHint = value;
   return;
+
+   case GL_PROGRAM_SEPARABLE:
+  if (!ctx->Extensions.ARB_separate_shader_objects)
+ break;
+
+  /* Spec imply that the behavior is the same as ARB_get_program_binary
+   * Chapter 7.3 Program Objects
+   */
+  if (value != GL_TRUE && value != GL_FALSE) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glProgramParameteri(pname=%s, value=%d): "
+ "value must be 0 or 1.",
+ _mesa_lookup_enum_by_nr(pname),
+ value);
+ return;
+  }
+  shProg->SeparateShader = value;
+  return;
+
default:
   break;
}
@@ -1773,59 +1797,71 @@ _mesa_ActiveProgramEXT(GLuint program)
return;
 }
 
-
-/**
- * For GL_EXT_separate_shader_objects
- */
-GLuint GLAPIENTRY
-_mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
+static GLuint
+_mesa_create_shader_program(struct gl_context* ctx, GLboolean separate,
+GLenum type, GLsizei count, const GLchar* const 
*strings)
 {
-   GET_CURRENT_CONTEXT(ctx);
const GLuint shader = create_shader(ctx, type);
GLuint program = 0;
 
if (shader) {
-  shader_source(ctx, shader, _mesa_strdup(string));
+  _mesa_ShaderSource(shader, count, strings, NULL);
+
   compile_shader(ctx, shader);
 
   program = create_shader_program(ctx);
   if (program) {
-struct gl_shader_program *shProg;
-struct gl_shader *sh;
-GLint compiled = GL_FALSE;
+ struct gl_shader_program *shProg;
+ struct gl_shader *sh;
+ GLint compiled = GL_FALSE;
 
-shProg = _mesa_lookup_shader_program(ctx, program);
-sh = _mesa_lookup_shader(ctx, shader);
+ shProg = _mesa_lookup_shader_program(ctx, program);
+ sh = _mesa_lookup_shader(ctx, shader);
 
-get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
-if (compiled) {
-   attach_shader(ctx, program, shader);
-   link_program(ctx, program);
-   detach_shader(ctx, program, shader);
+ shProg->SeparateShader = separate;
 
+ get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
+ if (compiled) {
+attach_shader(ctx, program, shader);
+link_program(ctx, program);
+detach_shader(ctx, program, shader);
 #if 0
-   /* Possibly... */
-   if (active-user-defined-varyings-in-linked-program) {
-  append-error-to-info-log;
-  shProg->LinkStatus = GL_FALSE;
-   }
+/* Possibly... */
+if (active-user-defined-varyings-in-linked-program) {
+   append-error-to-info-log;
+   shProg->LinkStatus = GL_FALSE;
+}
 #endif
-}
+ }
 
-ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
+ ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
   }
-
   delete_shader(ctx, shader);
}
-
return program;
 }
 
 /**
+ * For GL_EXT_separate_shader_objects
+ */
+GLuint GLAPIENTRY
+_mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   return _mesa_create_shader_program(ctx, GL_FALSE, type, 1, &string);
+}
+
+/**
  * ARB_separate_shader_objects: Compile & Link Program
+ * Bas

[Mesa-dev] [PATCH 04/12] sso: implement ActiveShaderProgram & GetProgramPipelineiv

2013-05-03 Thread Gregory Hainaut
V2:
* Rename object
* Formatting improvement
---
 src/mesa/main/pipelineobj.c |   77 +++
 1 file changed, 77 insertions(+)

diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
index d81bd0e..ffbeeae 100644
--- a/src/mesa/main/pipelineobj.c
+++ b/src/mesa/main/pipelineobj.c
@@ -231,6 +231,30 @@ _mesa_UseProgramStages(GLuint pipeline, GLbitfield stages, 
GLuint program)
 void GLAPIENTRY
 _mesa_ActiveShaderProgram(GLuint pipeline, GLuint program)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg = (program != 0)
+  ? _mesa_lookup_shader_program_err(ctx, program, 
"glActiveShaderProgram(program)")
+  : NULL;
+
+   struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+
+   if (!pipe) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, 
"glActiveShaderProgram(pipeline)");
+  return;
+   }
+
+   /* Object is created by any Pipeline call but glGenProgramPipelines,
+* glIsProgramPipeline and GetProgramPipelineInfoLog
+*/
+   pipe->EverBound = GL_TRUE;
+
+   if ((shProg != NULL) && !shProg->LinkStatus) {
+  _mesa_error(ctx, GL_INVALID_OPERATION,
+"glActiveShaderProgram(program %u not linked)", shProg->Name);
+  return;
+   }
+
+   _mesa_reference_shader_program(ctx, &pipe->ActiveProgram, shProg);
 }
 
 /**
@@ -348,6 +372,59 @@ _mesa_IsProgramPipeline(GLuint pipeline)
 void GLAPIENTRY
 _mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+
+   /* Are geometry shaders available in this context?
+*/
+   const bool has_gs = _mesa_is_desktop_gl(ctx) && 
ctx->Extensions.ARB_geometry_shader4;
+
+   if (!pipe) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, 
"glGetProgramPipelineiv(pipeline)");
+  return;
+   }
+
+   /* Object is created by any Pipeline call but glGenProgramPipelines,
+* glIsProgramPipeline and GetProgramPipelineInfoLog
+*/
+   pipe->EverBound = GL_TRUE;
+
+   switch (pname) {
+   case GL_ACTIVE_PROGRAM:
+  *params = pipe->ActiveProgram ? pipe->ActiveProgram->Name : 0;
+  return;
+   case GL_INFO_LOG_LENGTH:
+  // TODO
+  *params = 0;
+  return;
+   case GL_VALIDATE_STATUS:
+  *params = pipe->ValidationStatus;
+  return;
+   case GL_VERTEX_SHADER:
+  *params = pipe->CurrentVertexProgram ? pipe->CurrentVertexProgram->Name 
: 0;
+  return;
+   case GL_TESS_EVALUATION_SHADER:
+  /* NOT YET SUPPORTED */
+  break;
+   case GL_TESS_CONTROL_SHADER:
+  /* NOT YET SUPPORTED */
+  break;
+   case GL_GEOMETRY_SHADER:
+  if (!has_gs) break;
+  *params = pipe->CurrentGeometryProgram ? 
pipe->CurrentGeometryProgram->Name : 0;;
+  return;
+   case GL_FRAGMENT_SHADER:
+  *params = pipe->CurrentFragmentProgram ? 
pipe->CurrentFragmentProgram->Name : 0;;
+  return;
+   case GL_COMPUTE_SHADER:
+  /* NOT YET SUPPORTED */
+  break;
+   default:
+  break;
+   }
+
+   _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramPipelineiv(pname=%s)",
+ _mesa_lookup_enum_by_nr(pname));
 }
 
 /**
-- 
1.7.10.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 06/12] sso: rename Shader to the pointer _Shader

2013-05-03 Thread Gregory Hainaut
Basically a sed but shaderapi.c and get.c.
get.c => GL_CURRENT_PROGAM always refer to the "old" UseProgram behavior
shaderapi.c => the old api stil update the Shader object directly

V2: formatting improvement
---
 src/mesa/drivers/common/meta.c   |   10 ++--
 src/mesa/drivers/dri/i965/brw_gs.c   |2 +-
 src/mesa/drivers/dri/i965/brw_shader.cpp |4 +-
 src/mesa/drivers/dri/i965/brw_vs.c   |4 +-
 src/mesa/drivers/dri/i965/brw_vs_surface_state.c |2 +-
 src/mesa/drivers/dri/i965/brw_wm.c   |2 +-
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c |2 +-
 src/mesa/drivers/dri/i965/gen6_sol.c |6 +-
 src/mesa/drivers/dri/i965/gen6_vs_state.c|2 +-
 src/mesa/drivers/dri/i965/gen6_wm_state.c|2 +-
 src/mesa/drivers/dri/i965/gen7_sol_state.c   |4 +-
 src/mesa/drivers/dri/i965/gen7_vs_state.c|2 +-
 src/mesa/drivers/dri/i965/gen7_wm_state.c|2 +-
 src/mesa/main/api_validate.c |2 +-
 src/mesa/main/context.c  |   32 +--
 src/mesa/main/ff_fragment_shader.cpp |8 +--
 src/mesa/main/get.c  |   10 
 src/mesa/main/shaderapi.c|   26 -
 src/mesa/main/state.c|   14 ++---
 src/mesa/main/texstate.c |   12 ++--
 src/mesa/main/transformfeedback.c|4 +-
 src/mesa/main/uniform_query.cpp  |4 +-
 src/mesa/main/uniforms.c |   66 +++---
 src/mesa/program/ir_to_mesa.cpp  |   12 ++--
 src/mesa/state_tracker/st_atom_clip.c|2 +-
 src/mesa/state_tracker/st_atom_constbuf.c|4 +-
 src/mesa/state_tracker/st_cb_drawpixels.c|2 +-
 src/mesa/state_tracker/st_draw.c |6 +-
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp   |2 +-
 src/mesa/state_tracker/st_program.c  |6 +-
 src/mesa/swrast/s_fragprog.c |2 +-
 31 files changed, 134 insertions(+), 124 deletions(-)

diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index e3ab82b..927573d 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -617,13 +617,13 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
 
   if (ctx->Extensions.ARB_shader_objects) {
 _mesa_reference_shader_program(ctx, &save->VertexShader,
-   ctx->Shader.CurrentVertexProgram);
+   ctx->_Shader->CurrentVertexProgram);
 _mesa_reference_shader_program(ctx, &save->GeometryShader,
-   ctx->Shader.CurrentGeometryProgram);
+   ctx->_Shader->CurrentGeometryProgram);
 _mesa_reference_shader_program(ctx, &save->FragmentShader,
-   ctx->Shader.CurrentFragmentProgram);
+   ctx->_Shader->CurrentFragmentProgram);
 _mesa_reference_shader_program(ctx, &save->ActiveShader,
-   ctx->Shader.ActiveProgram);
+   ctx->_Shader->ActiveProgram);
 
  _mesa_UseProgram(0);
   }
@@ -965,7 +965,7 @@ _mesa_meta_end(struct gl_context *ctx)
 _mesa_use_shader_program(ctx, GL_FRAGMENT_SHADER,
  save->FragmentShader);
 
-  _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram,
+  _mesa_reference_shader_program(ctx, &ctx->_Shader->ActiveProgram,
 save->ActiveShader);
 
   _mesa_reference_shader_program(ctx, &save->VertexShader, NULL);
diff --git a/src/mesa/drivers/dri/i965/brw_gs.c 
b/src/mesa/drivers/dri/i965/brw_gs.c
index caa3b3e..31b01df 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.c
+++ b/src/mesa/drivers/dri/i965/brw_gs.c
@@ -189,7 +189,7 @@ static void populate_key( struct brw_context *brw,
   /* _NEW_TRANSFORM_FEEDBACK */
   if (_mesa_is_xfb_active_and_unpaused(ctx)) {
  const struct gl_shader_program *shaderprog =
-ctx->Shader.CurrentVertexProgram;
+ctx->_Shader->CurrentVertexProgram;
  const struct gl_transform_feedback_info *linked_xfb_info =
 &shaderprog->LinkedTransformFeedback;
  int i;
diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp 
b/src/mesa/drivers/dri/i965/brw_shader.cpp
index b3bd1b9..7259fde 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -257,7 +257,7 @@ brw_link_shader(struct gl_context *ctx, struct 
gl_shader_program *shProg)
 
   _mesa_reference_program(ctx, &prog, NULL);
 
-  if (ctx->Shader.Flags & GLSL_DUMP) {
+  if (ctx->_Shader->Flags & GLSL_DUMP) {
  printf("\n");
  pri

[Mesa-dev] [PATCH 07/12] sso: update meta state

2013-05-03 Thread Gregory Hainaut
save and restore _Shader/Pipeline binding point. Rational we don't want any 
conflict
when the program will be unattached.

V2: formatting improvement
---
 src/mesa/drivers/common/meta.c |   28 +---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index 927573d..01a63bd 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -51,6 +51,7 @@
 #include "main/macros.h"
 #include "main/matrix.h"
 #include "main/mipmap.h"
+#include "main/pipelineobj.h"
 #include "main/pixel.h"
 #include "main/pbo.h"
 #include "main/polygon.h"
@@ -142,6 +143,8 @@ struct save_state
struct gl_shader_program *GeometryShader;
struct gl_shader_program *FragmentShader;
struct gl_shader_program *ActiveShader;
+   struct gl_pipeline_object   *_Shader;
+   struct gl_pipeline_object   *Pipeline;
 
/** MESA_META_STENCIL_TEST */
struct gl_stencil_attrib Stencil;
@@ -615,6 +618,14 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
  _mesa_set_enable(ctx, GL_FRAGMENT_SHADER_ATI, GL_FALSE);
   }
 
+  if (ctx->Extensions.ARB_separate_shader_objects) {
+ /* Warning it must be done before _mesa_UseProgram call */
+ _mesa_reference_pipeline_object(ctx, &save->_Shader, ctx->_Shader);
+ _mesa_reference_pipeline_object(ctx, &save->Pipeline,
+ ctx->Pipeline.Current);
+ _mesa_BindProgramPipeline(0);
+  }
+
   if (ctx->Extensions.ARB_shader_objects) {
 _mesa_reference_shader_program(ctx, &save->VertexShader,
ctx->_Shader->CurrentVertexProgram);
@@ -954,16 +965,26 @@ _mesa_meta_end(struct gl_context *ctx)
   save->ATIFragmentShaderEnabled);
   }
 
+  /* Warning it must be done before _mesa_use_shader_program call */
+  if (ctx->Extensions.ARB_separate_shader_objects) {
+ _mesa_reference_pipeline_object(ctx, &ctx->_Shader, save->_Shader);
+ _mesa_reference_pipeline_object(ctx, &ctx->Pipeline.Current,
+ save->Pipeline);
+ _mesa_reference_pipeline_object(ctx, &save->Pipeline, NULL);
+  }
+
   if (ctx->Extensions.ARB_vertex_shader)
-_mesa_use_shader_program(ctx, GL_VERTEX_SHADER, save->VertexShader);
+_mesa_use_shader_program(ctx, GL_VERTEX_SHADER, save->VertexShader,
+  ctx->_Shader);
 
   if (ctx->Extensions.ARB_geometry_shader4)
 _mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB,
- save->GeometryShader);
+ save->GeometryShader, ctx->_Shader);
 
   if (ctx->Extensions.ARB_fragment_shader)
 _mesa_use_shader_program(ctx, GL_FRAGMENT_SHADER,
- save->FragmentShader);
+ save->FragmentShader, ctx->_Shader);
+
 
   _mesa_reference_shader_program(ctx, &ctx->_Shader->ActiveProgram,
 save->ActiveShader);
@@ -972,6 +993,7 @@ _mesa_meta_end(struct gl_context *ctx)
   _mesa_reference_shader_program(ctx, &save->GeometryShader, NULL);
   _mesa_reference_shader_program(ctx, &save->FragmentShader, NULL);
   _mesa_reference_shader_program(ctx, &save->ActiveShader, NULL);
+  _mesa_reference_pipeline_object(ctx, &save->_Shader, NULL);
}
 
if (state & MESA_META_STENCIL_TEST) {
-- 
1.7.10.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 05/12] sso: replace Shader binding point with _Shader

2013-05-03 Thread Gregory Hainaut
To avoid NULL pointer check a default pipeline object is installed in _Shader 
when no
program is current

The spec say that UseProgram/UseShaderProgramEXT/ActiveProgramEXT got an higher
priority over the pipeline object. When default program is uninstall, the 
pipeline is
used if any was bound.

Note: A careful rename need to be done now...

V2: formating improvement
---
 src/mesa/main/mtypes.h  |5 +++
 src/mesa/main/pipelineobj.c |8 
 src/mesa/main/shaderapi.c   |   87 +--
 3 files changed, 97 insertions(+), 3 deletions(-)

diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index f979cd0..adf518b 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2434,6 +2434,9 @@ struct gl_pipeline_shader_state
/** Currently bound pipeline object. See _mesa_BindProgramPipeline() */
struct gl_pipeline_object *Current;
 
+   /* Default Object to ensure that _Shader is never NULL */
+   struct gl_pipeline_object *Default;
+
/** Pipeline objects */
struct _mesa_HashTable *Objects;
 };
@@ -3546,6 +3549,8 @@ struct gl_context
 
struct gl_pipeline_shader_state Pipeline; /**< GLSL pipeline shader object 
state */
struct gl_pipeline_object Shader; /**< GLSL shader object state */
+   struct gl_pipeline_object *_Shader; /**< Points to ::Shader or 
::Pipeline.Current
+ or ::Pipeline.Default */
struct gl_shader_compiler_options ShaderCompilerOptions[MESA_SHADER_TYPES];
 
struct gl_query_state Query;  /**< occlusion, timer queries */
diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
index ffbeeae..5add307 100644
--- a/src/mesa/main/pipelineobj.c
+++ b/src/mesa/main/pipelineobj.c
@@ -95,6 +95,10 @@ _mesa_init_pipeline(struct gl_context *ctx)
ctx->Pipeline.Objects = _mesa_NewHashTable();
 
ctx->Pipeline.Current = NULL;
+
+   /* Install a default Pipeline */
+   ctx->Pipeline.Default = _mesa_new_pipeline_object(ctx, 0);
+   _mesa_reference_pipeline_object(ctx, &ctx->_Shader, ctx->Pipeline.Default);
 }
 
 
@@ -118,6 +122,10 @@ _mesa_free_pipeline_data(struct gl_context *ctx)
 {
_mesa_HashDeleteAll(ctx->Pipeline.Objects, delete_pipelineobj_cb, ctx);
_mesa_DeleteHashTable(ctx->Pipeline.Objects);
+
+   _mesa_reference_pipeline_object(ctx, &ctx->_Shader, NULL);
+   _mesa_delete_pipeline_object(ctx, ctx->Pipeline.Default);
+
 }
 
 /**
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 46072ba..c25f49f 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -43,6 +43,7 @@
 #include "main/hash.h"
 #include "main/mfeatures.h"
 #include "main/mtypes.h"
+#include "main/pipelineobj.h"
 #include "main/shaderapi.h"
 #include "main/shaderobj.h"
 #include "main/transformfeedback.h"
@@ -138,6 +139,8 @@ _mesa_free_shader_state(struct gl_context *ctx)
_mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
 
/* Extended for ARB_separate_shader_objects */
+   _mesa_reference_pipeline_object(ctx, &ctx->_Shader, NULL);
+
assert(ctx->Shader.RefCount == 1);
_glthread_DESTROY_MUTEX(ctx->Shader.Mutex);
 }
@@ -1455,7 +1458,29 @@ _mesa_UseProgram(GLhandleARB program)
   shProg = NULL;
}
 
-   _mesa_use_program(ctx, shProg);
+   /*
+* The executable code for an individual shader stage is taken from the
+* current program for that stage.  If there is a current program object
+* for any shader stage or for uniform updates established by UseProgram,
+* UseShaderProgramEXT, or ActiveProgramEXT, the current program for that
+* stage (if any) is considered current.  Otherwise, if there is a bound
+* program pipeline object ...
+*/
+   if (program) {
+  /* Attach shader state to the binding point */
+  _mesa_reference_pipeline_object(ctx, &ctx->_Shader, &ctx->Shader);
+  /* Update the program */
+  _mesa_use_program(ctx, shProg);
+   } else {
+  /* Must be done first: detach the progam */
+  _mesa_use_program(ctx, shProg);
+  /* Unattach shader_state binding point */
+  _mesa_reference_pipeline_object(ctx, &ctx->_Shader, 
ctx->Pipeline.Default);
+  /* If a pipeline was bound, rebind it */
+  if (ctx->Pipeline.Current) {
+ _mesa_BindProgramPipeline(ctx->Pipeline.Current->Name);
+  }
+   }
 }
 
 
@@ -1778,7 +1803,35 @@ _mesa_UseShaderProgramEXT(GLenum type, GLuint program)
   }
}
 
-   _mesa_use_shader_program(ctx, type, shProg);
+   /*
+* The executable code for an individual shader stage is taken from the
+* current program for that stage.  If there is a current program object
+* for any shader stage or for uniform updates established by UseProgram,
+* UseShaderProgramEXT, or ActiveProgramEXT, the current program for that
+* stage (if any) is considered current.  Otherwise, if there is a bound
+* program pipeline object ...
+*/
+   if (program) {
+  /* Attach shader state to the binding

[Mesa-dev] [PATCH 08/12] sso: Implement _mesa_UseProgramStages

2013-05-03 Thread Gregory Hainaut
Implement _mesa_UseProgramStages => 
arb_separate_shader_object-GetProgramPipelineiv is now pass :)

Extend use_shader_program to support a different target. Allow to reuse the 
function to update
the pipeline state. Note I bypass the flush when target isn't current. Maybe it 
would be better to
create a new UseProgramStages driver function

V2: formatting & rename
---
 src/mesa/main/pipelineobj.c |  111 +++
 src/mesa/main/shaderapi.c   |   32 +++--
 src/mesa/main/shaderapi.h   |3 +-
 3 files changed, 131 insertions(+), 15 deletions(-)

diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
index 5add307..3cdca63 100644
--- a/src/mesa/main/pipelineobj.c
+++ b/src/mesa/main/pipelineobj.c
@@ -33,6 +33,8 @@
  * XXX things to do:
  * 1/ Do we need to create 2 new drivers functions: CreatePipelineObject
  * DeletePipelineObject
+ * 2/ We probably need a UseProgramStages driver function. It would avoir to
+ * dirty all stages
  */
 
 #include "main/glheader.h"
@@ -231,6 +233,115 @@ _mesa_reference_pipeline_object_(struct gl_context *ctx,
 void GLAPIENTRY
 _mesa_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
 {
+   GET_CURRENT_CONTEXT(ctx);
+
+   struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+   struct gl_shader_program *shProg = NULL;
+
+   if (!pipe) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, "glUseProgramStages(pipeline)");
+  return;
+   }
+
+   /* Object is created by any Pipeline call but glGenProgramPipelines,
+* glIsProgramPipeline and GetProgramPipelineInfoLog
+*/
+   pipe->EverBound = GL_TRUE;
+
+   /* NOT YET SUPPORTED:
+* GL_TESS_CONTROL_SHADER_BIT
+* GL_TESS_EVALUATION_SHADER_BIT
+* GL_COMPUTE_SHADER_BIT
+*/
+   GLbitfield any_valid_stages = GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT;
+   if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4)
+  any_valid_stages |= GL_GEOMETRY_SHADER_BIT;
+
+   if (stages != GL_ALL_SHADER_BITS && (stages  & ~any_valid_stages) != 0) {
+  _mesa_error(ctx, GL_INVALID_VALUE, "glUseProgramStages(Stages)");
+  return;
+   }
+
+   /*
+*  An INVALID_OPERATION error is generated :
+*  by UseProgramStages if the program pipeline object it refers to is 
current
+*  and the current transform feedback object is active and not paused;
+*/
+   /*
+* 6a. Should the fragment shader program object be allowed to changed
+* within transform feedback mode?
+* RESOLVED:  No, this should generate an GL_INVALID_OPERATION error.
+*/
+   if (ctx->_Shader == pipe) {
+  if (_mesa_is_xfb_active_and_unpaused(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+   "glUseProgramStages(transform feedback active)");
+ return;
+  }
+   }
+
+   if (program) {
+  /* An INVALID_OPERATION error is generated if program is the name of a
+   * shader object
+   */
+  struct gl_shader *sh = _mesa_lookup_shader(ctx, program);
+  if (sh != NULL) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+   "glUseProgramStages(progam is a shader object)");
+ return;
+  }
+
+  /* An INVALID_VALUE error is generated if program is not the name of ei-
+   * ther a program or shader object
+   */
+  shProg = _mesa_lookup_shader_program(ctx, program);
+  if (shProg == NULL) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+   "glUseProgramStages(progam is not a program object)");
+ return;
+  }
+
+  /* An INVALID_OPERATION error is generated if the program object named
+   * by program was linked without the PROGRAM_SEPARABLE parameter set, has
+   * not been linked, or was last linked unsuccessfully. The corresponding 
shader
+   * stages in pipeline are not modified.
+   */
+  if (!shProg->LinkStatus) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+   "glUseProgramStages(program not linked)");
+ return;
+  }
+  if (!shProg->SeparateShader) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+   "glUseProgramStages(program wasn't linked with the 
PROGRAM_SEPARABLE flag)");
+ return;
+  }
+   }
+
+   /*
+*  7.  What happens if you have a program object current for a shader 
stage,
+*but the program object doesn't contain an executable for that stage?
+
+*RESOLVED:  This is not an error; instead it is as though there were no
+*program bound to that stage.  We have two different notions for
+*programs bound to shader stages.  A program is "current" for a stage
+*if it bound to that stage in the active program pipeline object.  A
+*program is "active" for a stage if it is current and it has an
+*executable for this stage.  In this case, the program would be current
+*but not active.
+
+*When no program is active for a stage, the stage will be replaced

[Mesa-dev] [PATCH 09/12] sso: implement BindProgramPipeline

2013-05-03 Thread Gregory Hainaut
Test become green in piglit:
The updated ext_transform_feedback-api-errors:useprogstage_noactive 
useprogstage_active bind_pipeline
arb_separate_shader_object-GetProgramPipelineiv
arb_separate_shader_object-IsProgramPipeline

For the moment I reuse Driver.UseProgram but I guess it will be better to create
a UseProgramStages functions. Opinion is welcome

V2: formatting & rename
---
 src/mesa/main/pipelineobj.c |   60 +++
 1 file changed, 60 insertions(+)

diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
index 3cdca63..2d18192 100644
--- a/src/mesa/main/pipelineobj.c
+++ b/src/mesa/main/pipelineobj.c
@@ -35,6 +35,10 @@
  * DeletePipelineObject
  * 2/ We probably need a UseProgramStages driver function. It would avoir to
  * dirty all stages
+ * 3/ Maybe create a bind pipeline driver function to notify that all
+ * program was updated. Currently I call UseProgram with NULL because there 
isn't
+ * a single program
+ * 4/ When vertices need to be flushed (FLUSH_VERTICES)
  */
 
 #include "main/glheader.h"
@@ -382,6 +386,62 @@ _mesa_ActiveShaderProgram(GLuint pipeline, GLuint program)
 void GLAPIENTRY
 _mesa_BindProgramPipeline(GLuint pipeline)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_pipeline_object *newObj = NULL;
+
+   if (ctx->_Shader->Name == pipeline)
+  return;   /* rebinding the same pipeline object- no change */
+
+   /*
+*  An INVALID_OPERATION error is generated :
+*  by BindProgramPipeline if the current transform feedback object is 
active
+*  and not paused;
+*/
+   if (_mesa_is_xfb_active_and_unpaused(ctx)) {
+  _mesa_error(ctx, GL_INVALID_OPERATION,
+"glBindProgramPipeline(transform feedback active)");
+  return;
+   }
+
+   /*
+* Get pointer to new pipeline object (newObj)
+*/
+   if (pipeline) {
+  /* non-default pipeline object */
+  newObj = lookup_pipeline_object(ctx, pipeline);
+  if (!newObj) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBindProgramPipeline(non-gen 
name)");
+ return;
+  }
+
+  /* Object is created by any Pipeline call but glGenProgramPipelines,
+   * glIsProgramPipeline and GetProgramPipelineInfoLog
+   */
+  newObj->EverBound = GL_TRUE;
+   }
+
+   /* First bind the Pipeline to pipeline binding point */
+   _mesa_reference_pipeline_object(ctx, &ctx->Pipeline.Current, newObj);
+
+   /* Spec say:
+* if any program is bound to the context, the current pipeline object is
+* ignored.
+*/
+   if (&ctx->Shader != ctx->_Shader) {
+  if (pipeline) {
+ /* Bound the pipeline to the current program and
+  * restore the pipeline state
+  */
+ _mesa_reference_pipeline_object(ctx, &ctx->_Shader, newObj);
+  } else {
+ /* Unbind the pipeline */
+ _mesa_reference_pipeline_object(ctx, &ctx->_Shader, 
ctx->Pipeline.Default);
+  }
+  FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+  /* FIXME */
+  if (ctx->Driver.UseProgram)
+ ctx->Driver.UseProgram(ctx, NULL);
+   }
 }
 
 /**
-- 
1.7.10.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 10/12] sso: update glGet: GL_PROGRAM_PIPELINE_BINDING

2013-05-03 Thread Gregory Hainaut
---
 src/mesa/main/get.c  |9 +
 src/mesa/main/get_hash_params.py |3 +++
 2 files changed, 12 insertions(+)

diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 54159c0..6cbb7db 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -369,6 +369,7 @@ EXTRA_EXT(ARB_map_buffer_alignment);
 EXTRA_EXT(ARB_texture_cube_map_array);
 EXTRA_EXT(ARB_texture_buffer_range);
 EXTRA_EXT(ARB_texture_multisample);
+EXTRA_EXT(ARB_separate_shader_objects);
 
 static const int
 extra_ARB_color_buffer_float_or_glcore[] = {
@@ -889,6 +890,14 @@ find_custom_value(struct gl_context *ctx, const struct 
value_desc *d, union valu
  _mesa_problem(ctx, "driver doesn't implement GetTimestamp");
   }
   break;
+   /* GL_ARB_separate_shader_objects */
+   case GL_PROGRAM_PIPELINE_BINDING:
+  if (ctx->Pipeline.Current) {
+ v->value_int = ctx->Pipeline.Current->Name;
+  } else {
+ v->value_int = 0;
+  }
+  break;
}
 }
 
diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py
index 2b97da6..43a11cf 100644
--- a/src/mesa/main/get_hash_params.py
+++ b/src/mesa/main/get_hash_params.py
@@ -709,6 +709,9 @@ descriptor=[
 
 # GL_ARB_texture_cube_map_array
   [ "TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB", "LOC_CUSTOM, TYPE_INT, 
TEXTURE_CUBE_ARRAY_INDEX, extra_ARB_texture_cube_map_array" ],
+
+# GL_ARB_separate_shader_objects
+  [ "PROGRAM_PIPELINE_BINDING", "LOC_CUSTOM, TYPE_INT, 
GL_PROGRAM_PIPELINE_BINDING, extra_ARB_separate_shader_objects" ],
 ]},
 
 # Enums restricted to OpenGL Core profile
-- 
1.7.10.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 11/12] sso: implement ValidateProgramPipeline and GetProgramPipelineInfoLog

2013-05-03 Thread Gregory Hainaut
Implementation note:
I don't use context for ralloc (don't know how).

The check on PROGRAM_SEPARABLE flags is also done when the pipeline isn't bound.
It doesn't make any sense in a DSA style API.

Maybe we could replace _mesa_validate_program_pipeline by  
_mesa_validate_program_pipeline.
For example we could recreate a dummy pipeline object. However the new function 
checks
also the TEXTURE_IMAGE_UNIT number not sure of the impact.

V2:
Fix memory leak with ralloc_strdup
Formatting improvement
---
 src/mesa/main/context.c |9 ++
 src/mesa/main/mtypes.h  |2 +
 src/mesa/main/pipelineobj.c |  221 ++-
 src/mesa/main/pipelineobj.h |3 +
 src/mesa/main/uniform_query.cpp |   71 +
 src/mesa/main/uniforms.h|3 +
 6 files changed, 305 insertions(+), 4 deletions(-)

diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 6a0619a..559e21f 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -1767,6 +1767,7 @@ _mesa_check_blend_func_error(struct gl_context *ctx)
  * Prior to drawing anything with glBegin, glDrawArrays, etc. this function
  * is called to see if it's valid to render.  This involves checking that
  * the current shader is valid and the framebuffer is complete.
+ * It also check the current pipeline object is valid if any.
  * If an error is detected it'll be recorded here.
  * \return GL_TRUE if OK to render, GL_FALSE if not
  */
@@ -1876,6 +1877,14 @@ _mesa_valid_to_render(struct gl_context *ctx, const char 
*where)
   }
}
 
+   /* A pipeline object is bound */
+   if (ctx->_Shader->Name && !ctx->_Shader->Validated) {
+  /* Error message will be printed inside _mesa_validate_program_pipeline 
*/
+  if (!_mesa_validate_program_pipeline(ctx, ctx->_Shader, GL_TRUE)) {
+ return GL_FALSE;
+  }
+   }
+
if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
   _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
   "%s(incomplete framebuffer)", where);
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index adf518b..ce88860 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2424,6 +2424,8 @@ struct gl_pipeline_object
GLboolean Validated; /**< Pipeline Validation status */
 
GLboolean EverBound; /**< Has the pipeline object been 
created */
+
+   GLchar *InfoLog;
 };
 
 /**
diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
index 2d18192..d7948ff 100644
--- a/src/mesa/main/pipelineobj.c
+++ b/src/mesa/main/pipelineobj.c
@@ -87,6 +87,7 @@ _mesa_new_pipeline_object(struct gl_context *ctx, GLuint name)
   _glthread_INIT_MUTEX(obj->Mutex);
   obj->RefCount = 1;
   obj->Flags = _mesa_get_shader_flags();
+  obj->InfoLog = ralloc_strdup(obj, "");
}
 
return obj;
@@ -339,13 +340,15 @@ _mesa_UseProgramStages(GLuint pipeline, GLbitfield 
stages, GLuint program)
 *disabled (tessellation control and evaluation, geometry), or have
 *undefined results (core profile vertex and fragment).
 */
-
if (stages & GL_VERTEX_SHADER_BIT)
   _mesa_use_shader_program(ctx, GL_VERTEX_SHADER, shProg, pipe);
if (stages & GL_FRAGMENT_SHADER_BIT)
   _mesa_use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg, pipe);
if (stages & GL_GEOMETRY_SHADER_BIT)
   _mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, shProg, pipe);
+
+   /* Validation would need to be redone */
+   pipe->Validated = GL_FALSE;
 }
 
 /**
@@ -573,11 +576,10 @@ _mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, 
GLint *params)
   *params = pipe->ActiveProgram ? pipe->ActiveProgram->Name : 0;
   return;
case GL_INFO_LOG_LENGTH:
-  // TODO
-  *params = 0;
+  *params = pipe->Validated;
   return;
case GL_VALIDATE_STATUS:
-  *params = pipe->ValidationStatus;
+  *params = pipe->Validated;
   return;
case GL_VERTEX_SHADER:
   *params = pipe->CurrentVertexProgram ? pipe->CurrentVertexProgram->Name 
: 0;
@@ -606,16 +608,227 @@ _mesa_GetProgramPipelineiv(GLuint pipeline, GLenum 
pname, GLint *params)
  _mesa_lookup_enum_by_nr(pname));
 }
 
+static GLboolean
+ProgramEnabledEverywhere(struct gl_pipeline_object *pipe,
+ struct gl_shader_program *prog,
+ char *errMsg, size_t errMsgLength)
+{
+   if (!prog) return GL_TRUE;
+
+   GLboolean status = GL_TRUE;
+
+   if (prog->_LinkedShaders[MESA_SHADER_VERTEX]) {
+  if (pipe->CurrentVertexProgram) {
+ if (prog->Name != pipe->CurrentVertexProgram->Name) {
+status = GL_FALSE;
+ }
+  } else {
+ status = GL_FALSE;
+  }
+   }
+
+   if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT]) {
+  if (pipe->CurrentFragmentProgram) {
+ if (prog->Name != pipe->CurrentFragmentProgram->Name) {
+status = GL_FALSE;
+ }
+  } else {
+  

[Mesa-dev] [PATCH 12/12] sso: Finally enable the extension on Gallium

2013-05-03 Thread Gregory Hainaut
Note: it probably work on others drivers.
---
 src/mesa/state_tracker/st_extensions.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/src/mesa/state_tracker/st_extensions.c 
b/src/mesa/state_tracker/st_extensions.c
index f986480..4ce74f2 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -519,6 +519,7 @@ void st_init_extensions(struct st_context *st)
ctx->Extensions.ARB_half_float_vertex = GL_TRUE;
ctx->Extensions.ARB_internalformat_query = GL_TRUE;
ctx->Extensions.ARB_map_buffer_range = GL_TRUE;
+   ctx->Extensions.ARB_separate_shader_objects = GL_TRUE;
ctx->Extensions.ARB_shader_objects = GL_TRUE;
ctx->Extensions.ARB_shading_language_100 = GL_TRUE;
ctx->Extensions.ARB_texture_border_clamp = GL_TRUE; /* XXX temp */
-- 
1.7.10.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 10/12] sso: update glGet: GL_PROGRAM_PIPELINE_BINDING

2013-05-04 Thread gregory hainaut
On Fri, 3 May 2013 12:04:48 -0700
Matt Turner  wrote:

> On Fri, May 3, 2013 at 10:44 AM, Gregory Hainaut
>  wrote:
> > ---
> >  src/mesa/main/get.c  |9 +
> >  src/mesa/main/get_hash_params.py |3 +++
> >  2 files changed, 12 insertions(+)
> >
> > diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
> > index 54159c0..6cbb7db 100644
> > --- a/src/mesa/main/get.c
> > +++ b/src/mesa/main/get.c
> > @@ -369,6 +369,7 @@ EXTRA_EXT(ARB_map_buffer_alignment);
> >  EXTRA_EXT(ARB_texture_cube_map_array);
> >  EXTRA_EXT(ARB_texture_buffer_range);
> >  EXTRA_EXT(ARB_texture_multisample);
> > +EXTRA_EXT(ARB_separate_shader_objects);
> >
> >  static const int
> >  extra_ARB_color_buffer_float_or_glcore[] = {
> > @@ -889,6 +890,14 @@ find_custom_value(struct gl_context *ctx, const struct 
> > value_desc *d, union valu
> >   _mesa_problem(ctx, "driver doesn't implement GetTimestamp");
> >}
> >break;
> > +   /* GL_ARB_separate_shader_objects */
> > +   case GL_PROGRAM_PIPELINE_BINDING:
> > +  if (ctx->Pipeline.Current) {
> > + v->value_int = ctx->Pipeline.Current->Name;
> > +  } else {
> > + v->value_int = 0;
> > +  }
> > +  break;
> > }
> >  }
> 
> This looks believable, but I can't find a description in the extension
> spec or GL 4.1+ specs that say precisely what this query is supposed
> to do. Looks like it's just mentioned in the extension spec, and not
> at all in GL 4.1+ specs.


Yes you're right that strange. There is also a couple of line in glGet man page.

GL_PROGRAM_PIPELINE_BINDING
  
params a single value, the name of the currently bound 
program pipeline
object, or zero if no program pipeline object is bound.
See glBindProgramPipeline.

Both Nvidia and AMD support this query. I did a quick update on my piglit test, 
on the AMD side:
* UseProgram(2)
* BindPipeline(5) (the pipeline isn't really bound because UseProgram got an 
higher priority)
* Get GL_PROGRAM_PIPELINE_BINDING => 5

I will try to check the behavior on Nvidia implementation.

> > diff --git a/src/mesa/main/get_hash_params.py 
> > b/src/mesa/main/get_hash_params.py
> > index 2b97da6..43a11cf 100644
> > --- a/src/mesa/main/get_hash_params.py
> > +++ b/src/mesa/main/get_hash_params.py
> > @@ -709,6 +709,9 @@ descriptor=[
> >
> >  # GL_ARB_texture_cube_map_array
> >[ "TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB", "LOC_CUSTOM, TYPE_INT, 
> > TEXTURE_CUBE_ARRAY_INDEX, extra_ARB_texture_cube_map_array" ],
> > +
> > +# GL_ARB_separate_shader_objects
> > +  [ "PROGRAM_PIPELINE_BINDING", "LOC_CUSTOM, TYPE_INT, 
> > GL_PROGRAM_PIPELINE_BINDING, extra_ARB_separate_shader_objects" ],
> >  ]},
> >
> >  # Enums restricted to OpenGL Core profile
> > --
> > 1.7.10.4
> >
> > ___
> > mesa-dev mailing list
> > mesa-dev@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/mesa-dev
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 04/12] sso: implement ActiveShaderProgram & GetProgramPipelineiv

2013-05-04 Thread gregory hainaut
On Fri, 3 May 2013 11:56:39 -0700
Matt Turner  wrote:

> On Fri, May 3, 2013 at 10:44 AM, Gregory Hainaut
>  wrote:
> > V2:
> > * Rename object
> > * Formatting improvement
> > ---
> >  src/mesa/main/pipelineobj.c |   77 
> > +++
> >  1 file changed, 77 insertions(+)
> >
> > diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
> > index d81bd0e..ffbeeae 100644
> > --- a/src/mesa/main/pipelineobj.c
> > +++ b/src/mesa/main/pipelineobj.c
> > @@ -231,6 +231,30 @@ _mesa_UseProgramStages(GLuint pipeline, GLbitfield 
> > stages, GLuint program)
> >  void GLAPIENTRY
> >  _mesa_ActiveShaderProgram(GLuint pipeline, GLuint program)
> >  {
> > +   GET_CURRENT_CONTEXT(ctx);
> > +   struct gl_shader_program *shProg = (program != 0)
> > +  ? _mesa_lookup_shader_program_err(ctx, program, 
> > "glActiveShaderProgram(program)")
> > +  : NULL;
> > +
> > +   struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
> > +
> > +   if (!pipe) {
> > +  _mesa_error(ctx, GL_INVALID_OPERATION, 
> > "glActiveShaderProgram(pipeline)");
> > +  return;
> > +   }
> > +
> > +   /* Object is created by any Pipeline call but glGenProgramPipelines,
> > +* glIsProgramPipeline and GetProgramPipelineInfoLog
> > +*/
> > +   pipe->EverBound = GL_TRUE;
> > +
> > +   if ((shProg != NULL) && !shProg->LinkStatus) {
> > +  _mesa_error(ctx, GL_INVALID_OPERATION,
> > +"glActiveShaderProgram(program %u not linked)", shProg->Name);
> > +  return;
> > +   }
> > +
> > +   _mesa_reference_shader_program(ctx, &pipe->ActiveProgram, shProg);
> >  }
> >
> >  /**
> > @@ -348,6 +372,59 @@ _mesa_IsProgramPipeline(GLuint pipeline)
> >  void GLAPIENTRY
> >  _mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
> >  {
> > +   GET_CURRENT_CONTEXT(ctx);
> > +   struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
> > +
> > +   /* Are geometry shaders available in this context?
> > +*/
> > +   const bool has_gs = _mesa_is_desktop_gl(ctx) && 
> > ctx->Extensions.ARB_geometry_shader4;
> 
> The geometry shaders in GL 3.2 aren't exactly the same as in
> ARB_geometry_shader4, so it's conceivable that we could support 3.2
> without ARB_geometry_shader4. Probably should be changed to
> 
> const bool has_gs = _mesa_is_desktop_gl(ctx) && (ctx->Version >= 32 ||
> ctx->Extensions.ARB_geometry_shader4);
> 
> > +
> > +   if (!pipe) {
> > +  _mesa_error(ctx, GL_INVALID_OPERATION, 
> > "glGetProgramPipelineiv(pipeline)");
> > +  return;
> > +   }
> > +
> > +   /* Object is created by any Pipeline call but glGenProgramPipelines,
> > +* glIsProgramPipeline and GetProgramPipelineInfoLog
> > +*/
> > +   pipe->EverBound = GL_TRUE;
> > +
> > +   switch (pname) {
> > +   case GL_ACTIVE_PROGRAM:
> > +  *params = pipe->ActiveProgram ? pipe->ActiveProgram->Name : 0;
> > +  return;
> > +   case GL_INFO_LOG_LENGTH:
> > +  // TODO
> > +  *params = 0;
> > +  return;
> > +   case GL_VALIDATE_STATUS:
> > +  *params = pipe->ValidationStatus;
> > +  return;
> > +   case GL_VERTEX_SHADER:
> > +  *params = pipe->CurrentVertexProgram ? 
> > pipe->CurrentVertexProgram->Name : 0;
> > +  return;
> > +   case GL_TESS_EVALUATION_SHADER:
> > +  /* NOT YET SUPPORTED */
> > +  break;
> > +   case GL_TESS_CONTROL_SHADER:
> > +  /* NOT YET SUPPORTED */
> > +  break;
> > +   case GL_GEOMETRY_SHADER:
> > +  if (!has_gs) break;
> > +  *params = pipe->CurrentGeometryProgram ? 
> > pipe->CurrentGeometryProgram->Name : 0;;
> > +  return;
> > +   case GL_FRAGMENT_SHADER:
> > +  *params = pipe->CurrentFragmentProgram ? 
> > pipe->CurrentFragmentProgram->Name : 0;;
> 
> Double ; at the ends of these two lines.
> 
> > +  return;
> > +   case GL_COMPUTE_SHADER:
> > +  /* NOT YET SUPPORTED */
> > +  break;
> 
> GL_COMPUTE_SHADER isn't valid, even in GL 4.3 where compute shaders
> are part of core.
>
Feel like they forget to update the spec when they add this new stage. I will 
remove it. Thanks.
 
> > +   default:
> > +  break;
> > +   }
> 
> The spec

Re: [Mesa-dev] [PATCH 04/12] sso: implement ActiveShaderProgram & GetProgramPipelineiv

2013-05-04 Thread gregory hainaut
On Sat, 04 May 2013 12:37:05 -0700
Kenneth Graunke  wrote:

> On 05/03/2013 10:44 AM, Gregory Hainaut wrote:
> > V2:
> > * Rename object
> > * Formatting improvement
> > ---
> >   src/mesa/main/pipelineobj.c |   77 
> > +++
> >   1 file changed, 77 insertions(+)
> >
> > diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
> > index d81bd0e..ffbeeae 100644
> > --- a/src/mesa/main/pipelineobj.c
> > +++ b/src/mesa/main/pipelineobj.c
> > @@ -231,6 +231,30 @@ _mesa_UseProgramStages(GLuint pipeline, GLbitfield 
> > stages, GLuint program)
> >   void GLAPIENTRY
> >   _mesa_ActiveShaderProgram(GLuint pipeline, GLuint program)
> >   {
> > +   GET_CURRENT_CONTEXT(ctx);
> > +   struct gl_shader_program *shProg = (program != 0)
> > +  ? _mesa_lookup_shader_program_err(ctx, program, 
> > "glActiveShaderProgram(program)")
> > +  : NULL;
> > +
> > +   struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
> > +
> > +   if (!pipe) {
> > +  _mesa_error(ctx, GL_INVALID_OPERATION, 
> > "glActiveShaderProgram(pipeline)");
> > +  return;
> > +   }
> > +
> > +   /* Object is created by any Pipeline call but glGenProgramPipelines,
> > +* glIsProgramPipeline and GetProgramPipelineInfoLog
> > +*/
> > +   pipe->EverBound = GL_TRUE;
> 
> This doesn't seem right to me.  I found this section of the spec:
> 
> """
>  A program pipeline object is created by binding a name returned by
>  GenProgramPipelines with the command
> 
>  void BindProgramPipeline(uint pipeline);
> 
>   is the program pipeline object name. The resulting program
>  pipeline object is a new state vector, comprising ACTIVE_PROGRAM,
>  VERTEX_SHADER, GEOMETRY_SHADER, FRAGMENT_SHADER, TESS_CONTROL_SHADER,
>  and TESS_EVALUATION_SHADER.
> """
> 
> It sure sounds to me like BindProgramPipeline is the only thing that 
> should set EverBound.  Is there another part of the spec that I missed 
> which suggests otherwise?
>

You mean http://www.opengl.org/registry/specs/ARB/separate_shader_objects.txt ? 
Or an older glspec?

Don't know which one is the reference but here an extract (duplicated 4 times)
of glspec43.core.20130214.pdf:
Page 104-105 (void UseProgramStages)
Page 105-106 (void ActiveShaderProgram)
Page 144 (void GetProgramPipelineiv)
Page 339 (void ValidateProgramPipeline)
"""
If pipeline is a name that has been generated (without subsequent deletion) by
GenProgramPipelines, but refers to a program pipeline object that has not been
previously bound, the GL first creates a new state vector in the same manner as
when BindProgramPipeline creates a new program pipeline object.
"""

> > +
> > +   if ((shProg != NULL) && !shProg->LinkStatus) {
> > +  _mesa_error(ctx, GL_INVALID_OPERATION,
> > +"glActiveShaderProgram(program %u not linked)", shProg->Name);
> > +  return;
> > +   }
> > +
> > +   _mesa_reference_shader_program(ctx, &pipe->ActiveProgram, shProg);
> >   }
> >
> >   /**
> > @@ -348,6 +372,59 @@ _mesa_IsProgramPipeline(GLuint pipeline)
> >   void GLAPIENTRY
> >   _mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
> >   {
> > +   GET_CURRENT_CONTEXT(ctx);
> > +   struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
> > +
> > +   /* Are geometry shaders available in this context?
> > +*/
> > +   const bool has_gs = _mesa_is_desktop_gl(ctx) && 
> > ctx->Extensions.ARB_geometry_shader4;
> > +
> > +   if (!pipe) {
> > +  _mesa_error(ctx, GL_INVALID_OPERATION, 
> > "glGetProgramPipelineiv(pipeline)");
> > +  return;
> > +   }
> > +
> > +   /* Object is created by any Pipeline call but glGenProgramPipelines,
> > +* glIsProgramPipeline and GetProgramPipelineInfoLog
> > +*/
> > +   pipe->EverBound = GL_TRUE;
> > +
> > +   switch (pname) {
> > +   case GL_ACTIVE_PROGRAM:
> > +  *params = pipe->ActiveProgram ? pipe->ActiveProgram->Name : 0;
> > +  return;
> > +   case GL_INFO_LOG_LENGTH:
> > +  // TODO
> > +  *params = 0;
> > +  return;
> > +   case GL_VALIDATE_STATUS:
> > +  *params = pipe->ValidationStatus;
> > +  return;
> > +   case GL_VERTEX_SHADER:
> > +  *params = pipe->CurrentVertexProgram ? 
> > pipe->

Re: [Mesa-dev] [PATCH 10/12] sso: update glGet: GL_PROGRAM_PIPELINE_BINDING

2013-05-24 Thread gregory hainaut
On Sat, 4 May 2013 11:35:22 +0200
gregory hainaut  wrote:

> On Fri, 3 May 2013 12:04:48 -0700
> Matt Turner  wrote:
> 
> > On Fri, May 3, 2013 at 10:44 AM, Gregory Hainaut
> >  wrote:
> > > ---
> > >  src/mesa/main/get.c  |9 +
> > >  src/mesa/main/get_hash_params.py |3 +++
> > >  2 files changed, 12 insertions(+)
> > >
> > > diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
> > > index 54159c0..6cbb7db 100644
> > > --- a/src/mesa/main/get.c
> > > +++ b/src/mesa/main/get.c
> > > @@ -369,6 +369,7 @@ EXTRA_EXT(ARB_map_buffer_alignment);
> > >  EXTRA_EXT(ARB_texture_cube_map_array);
> > >  EXTRA_EXT(ARB_texture_buffer_range);
> > >  EXTRA_EXT(ARB_texture_multisample);
> > > +EXTRA_EXT(ARB_separate_shader_objects);
> > >
> > >  static const int
> > >  extra_ARB_color_buffer_float_or_glcore[] = {
> > > @@ -889,6 +890,14 @@ find_custom_value(struct gl_context *ctx, const 
> > > struct value_desc *d, union valu
> > >   _mesa_problem(ctx, "driver doesn't implement GetTimestamp");
> > >}
> > >break;
> > > +   /* GL_ARB_separate_shader_objects */
> > > +   case GL_PROGRAM_PIPELINE_BINDING:
> > > +  if (ctx->Pipeline.Current) {
> > > + v->value_int = ctx->Pipeline.Current->Name;
> > > +  } else {
> > > + v->value_int = 0;
> > > +  }
> > > +  break;
> > > }
> > >  }
> > 
> > This looks believable, but I can't find a description in the extension
> > spec or GL 4.1+ specs that say precisely what this query is supposed
> > to do. Looks like it's just mentioned in the extension spec, and not
> > at all in GL 4.1+ specs.
> 
> 
> Yes you're right that strange. There is also a couple of line in glGet man 
> page.
> 
> GL_PROGRAM_PIPELINE_BINDING
>   
> params a single value, the name of the currently 
> bound program pipeline
> object, or zero if no program pipeline object is 
> bound.
> See glBindProgramPipeline.
> 
> Both Nvidia and AMD support this query. I did a quick update on my piglit 
> test, on the AMD side:
> * UseProgram(2)
> * BindPipeline(5) (the pipeline isn't really bound because UseProgram got an 
> higher priority)
> * Get GL_PROGRAM_PIPELINE_BINDING => 5
> 
> I will try to check the behavior on Nvidia implementation.

Nvidia implementation "is" this one:
  if (ctx->_Shader) {
 v->value_int = ctx->_Shader->Name;
  } else {
 v->value_int = 0;
  }

So on my previous example
* UseProgram(2)
* BindPipeline(5)
* Get GL_PROGRAM_PIPELINE_BINDING => 0

There is no spec but the SSO spec was written by Nvidia so I would say that 
Nvidia is correct.

> > > diff --git a/src/mesa/main/get_hash_params.py 
> > > b/src/mesa/main/get_hash_params.py
> > > index 2b97da6..43a11cf 100644
> > > --- a/src/mesa/main/get_hash_params.py
> > > +++ b/src/mesa/main/get_hash_params.py
> > > @@ -709,6 +709,9 @@ descriptor=[
> > >
> > >  # GL_ARB_texture_cube_map_array
> > >[ "TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB", "LOC_CUSTOM, TYPE_INT, 
> > > TEXTURE_CUBE_ARRAY_INDEX, extra_ARB_texture_cube_map_array" ],
> > > +
> > > +# GL_ARB_separate_shader_objects
> > > +  [ "PROGRAM_PIPELINE_BINDING", "LOC_CUSTOM, TYPE_INT, 
> > > GL_PROGRAM_PIPELINE_BINDING, extra_ARB_separate_shader_objects" ],
> > >  ]},
> > >
> > >  # Enums restricted to OpenGL Core profile
> > > --
> > > 1.7.10.4
> > >
> > > ___
> > > mesa-dev mailing list
> > > mesa-dev@lists.freedesktop.org
> > > http://lists.freedesktop.org/mailman/listinfo/mesa-dev
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 02/12] sso: Add pipeline container/state

2013-05-28 Thread gregory hainaut
On Tue, 28 May 2013 12:30:56 -0700
Ian Romanick  wrote:

> On 05/03/2013 10:44 AM, Gregory Hainaut wrote:
> > V1:
> > * Extend gl_shader_state as pipeline object state
> > * Add a new container gl_pipeline_shader_state that contains
> >binding point of the previous object
> > * Update mesa init/free shader state due to the extension of
> >the attibute
> > * Add an init/free pipeline function for the context
> > * Implement GenProgramPipeline/DeleteProgramPipeline/IsProgramPipeline.
> >   I based my work on the VAO code.
> >
> > V2:
> > * Rename gl_shader_state to gl_pipeline_object
> > * Rename Pipeline.PipelineObj to Pipeline.Current
> > * Rename ValidationStatus to Validated
> > * Formatting improvement
> > ---
> >   src/mesa/main/context.c |3 +
> >   src/mesa/main/mtypes.h  |   30 +-
> >   src/mesa/main/pipelineobj.c |  234 
> > ++-
> >   src/mesa/main/pipelineobj.h |   25 +
> >   src/mesa/main/shaderapi.c   |   14 ++-
> >   src/mesa/main/shaderapi.h   |3 +
> >   6 files changed, 303 insertions(+), 6 deletions(-)
> >
> > diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
> > index 0539934..d089827 100644
> > --- a/src/mesa/main/context.c
> > +++ b/src/mesa/main/context.c
> > @@ -106,6 +106,7 @@
> >   #include "macros.h"
> >   #include "matrix.h"
> >   #include "multisample.h"
> > +#include "pipelineobj.h"
> >   #include "pixel.h"
> >   #include "pixelstore.h"
> >   #include "points.h"
> > @@ -762,6 +763,7 @@ init_attrib_groups(struct gl_context *ctx)
> >  _mesa_init_lighting( ctx );
> >  _mesa_init_matrix( ctx );
> >  _mesa_init_multisample( ctx );
> > +   _mesa_init_pipeline( ctx );
> >  _mesa_init_pixel( ctx );
> >  _mesa_init_pixelstore( ctx );
> >  _mesa_init_point( ctx );
> > @@ -1167,6 +1169,7 @@ _mesa_free_context_data( struct gl_context *ctx )
> >  _mesa_free_texture_data( ctx );
> >  _mesa_free_matrix_data( ctx );
> >  _mesa_free_viewport_data( ctx );
> > +   _mesa_free_pipeline_data(ctx);
> >  _mesa_free_program_data(ctx);
> >  _mesa_free_shader_state(ctx);
> >  _mesa_free_queryobj_data(ctx);
> > diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
> > index 05d8518..4487068 100644
> > --- a/src/mesa/main/mtypes.h
> > +++ b/src/mesa/main/mtypes.h
> > @@ -2381,9 +2381,19 @@ struct gl_shader_program
> >
> >   /**
> >* Context state for GLSL vertex/fragment shaders.
> > + * Extended to support pipeline object
> >*/
> > -struct gl_shader_state
> > +struct gl_pipeline_object
> >   {
> > +   /** Name of the pipeline object as received from glGenProgramPipelines.
> > +* It would be 0 for shaders without separate shader objects.
> > +*/
> > +   GLuint Name;
> > +
> > +   GLint RefCount;
> > +
> > +   _glthread_Mutex Mutex;
> > +
> >  /**
> >   * Programs used for rendering
> >   *
> 
> I think this comment needs to be updated.  The rest of it says
> 
>  *
>  * There is a separate program set for each shader stage.  If
>  * GL_EXT_separate_shader_objects is not supported, each of these 
> must point
>  * to \c NULL or to the same program.
>  */
> 
> However, I think the shader stages can only point to different programs 
> for the default pipeline object (gl_pipeline_object::Name == 0).  Right?
Hum no it is more complicated.

When gl_pipeline_object::Name != 0, you can put any program on shader stage.

When gl_pipeline_object::Name == 0, there is the 2 possibilities
0/ GL_EXT_separate_shader_objects is not supported. All program must be the 
same.
1/ GL_EXT_separate_shader_objects is supported. You can set different program.
 
> > @@ -2405,8 +2415,23 @@ struct gl_shader_state
> >  struct gl_shader_program *ActiveProgram;
> >
> >  GLbitfield Flags;/**< Mask of GLSL_x flags */
> > +
> > +   GLboolean Validated; /**< Pipeline Validation status */
> > +
> > +   GLboolean EverBound; /**< Has the pipeline object been 
> > created */
> >   };
> >
> > +/**
> > + * Context state for GLSL pipeline shaders.
> > + */
> > +struct gl_pipeline_shader_state
> > +{
> > +   /** Currently bound pipeline object. See _mesa_BindProgramPipeline() */
> > +   struct gl_pipeline_object *Current;
>

[Mesa-dev] [PATCH] gallium egl: mark KHR_create_context as supported

2013-06-08 Thread Gregory Hainaut
Don't know why it was not already activated! Code seem to be common between
dri2 and gallium.

Piglit tested on r600 gallium.
---
 src/gallium/state_trackers/egl/common/egl_g3d.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c 
b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 7cc4e8f..12b767a 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -579,6 +579,7 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy)
dpy->Extensions.KHR_reusable_sync = EGL_TRUE;
dpy->Extensions.KHR_fence_sync = EGL_TRUE;
 
+   dpy->Extensions.KHR_create_context = EGL_TRUE;
dpy->Extensions.KHR_surfaceless_context = EGL_TRUE;
 
if (dpy->Platform == _EGL_PLATFORM_DRM) {
-- 
1.7.10.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 3/3] glsl/opt: disable optimization of varying input

2015-09-20 Thread Gregory Hainaut
GL_ARB_separate_shader_objects allow to match by name variable or block
interface. Input varying can't be removed as it is will impact the location
assignment.

The patch only disable deadcode optimization for inputs that don't have
an explicit location. It allows to remove various builtin variables.

In theory, I think we must keep them as it could impact the location
assignment. However I'm not sure anyone use a mix of match by names/by
locations.

Interface example:
layout (location = 0) vec4 zero;
vec4 one;  // assignment might be 0 if zero isn't used.

It fixes the bug 79783 and likely any application that uses
GL_ARB_separate_shader_objects extension.

Signed-off-by: Gregory Hainaut 
---
 src/glsl/opt_dead_code.cpp | 16 
 1 file changed, 16 insertions(+)

diff --git a/src/glsl/opt_dead_code.cpp b/src/glsl/opt_dead_code.cpp
index e4bf874..9852747 100644
--- a/src/glsl/opt_dead_code.cpp
+++ b/src/glsl/opt_dead_code.cpp
@@ -131,6 +131,22 @@ do_dead_code(exec_list *instructions, bool 
uniform_locations_assigned)
continue;
  }
 
+ /* Section 7.4.1 (Shader Interface Matching) of the OpenGL 4.5
+  * (Core Profile) spec says:
+  *
+  *"With separable program objects, interfaces between shader
+  *stages may involve the outputs from one program object and the
+  *inputs from a second program object.  For such interfaces, it is
+  *not possible to detect mismatches at link time, because the
+  *programs are linked separately. When each such program is
+  *linked, all inputs or outputs interfacing with another program
+  *stage are treated as active."
+  */
+if (entry->var->data.mode == ir_var_shader_in &&
+   !entry->var->data.attribute_input &&
+   !entry->var->data.explicit_location)
+   continue;
+
 entry->var->remove();
 progress = true;
 
-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 1/3] glsl/link: don't consider unused variable as read variable.

2015-09-20 Thread Gregory Hainaut
Current checks rely on the optimization phase to remove deadcode
varying. Therefore remaining varying are used.

Deadcode Optimizations won't be possible anymore with the support of
GL_ARB_separate_shader_objects. So it requires to check the used flag of
the varying.

Signed-off-by: Gregory Hainaut 
---
 src/glsl/link_varyings.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
index f7a7b8c..72d6632 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -1579,7 +1579,7 @@ assign_varying_locations(struct gl_context *ctx,
 
  if (var && var->data.mode == ir_var_shader_in &&
  var->data.is_unmatched_generic_inout) {
-if (prog->IsES) {
+if (var->data.used && prog->IsES) {
/*
 * On Page 91 (Page 97 of the PDF) of the GLSL ES 1.0 spec:
 *
@@ -1594,7 +1594,7 @@ assign_varying_locations(struct gl_context *ctx,
   _mesa_shader_stage_to_string(consumer->Stage),
   var->name,
   _mesa_shader_stage_to_string(producer->Stage));
-} else if (prog->Version <= 120) {
+} else if (var->data.used && prog->Version <= 120) {
/* On page 25 (page 31 of the PDF) of the GLSL 1.20 spec:
 *
 * Only those varying variables used (i.e. read) in
-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 2/3] glsl/ast2hir: add a new flag attribute_input for VS input

2015-09-20 Thread Gregory Hainaut
GL_ARB_separate_shader_objects requires that all inputs varying remains active.

This flag allow to distinguish input attribute from the input varying.

Flag will be used on next commit.

Signed-off-by: Gregory Hainaut 
---
 src/glsl/ast_to_hir.cpp | 4 
 src/glsl/ir.h   | 9 +
 2 files changed, 13 insertions(+)

diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 72c6459..16bf849 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -2590,6 +2590,10 @@ apply_type_qualifier_to_variable(const struct 
ast_type_qualifier *qual,
_mesa_shader_stage_to_string(state->stage));
}
 
+   if (state->stage == MESA_SHADER_VERTEX &&
+ (qual->flags.q.attribute || qual->flags.q.in))
+  var->data.attribute_input = 1;
+
/* Disallow layout qualifiers which may only appear on layout declarations. 
*/
if (qual->flags.q.prim_type) {
   _mesa_glsl_error(loc, state,
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index f9ddf74..a1f5fa0 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -627,6 +627,15 @@ public:
   unsigned precise:1;
 
   /**
+   * Is the variable an input from the Vertex Shader?
+   *
+   * GL_ARB_separate_shader_objects doesn't allow the optimization of
+   * unused varying variable. However unused-attribute must still be
+   * optimized.
+   */
+  unsigned attribute_input:1;
+
+  /**
* Has this variable been used for reading or writing?
*
* Several GLSL semantic checks require knowledge of whether or not a
-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH 0/3][RFC] Improve GLSL support of GL_ARB_separate_shader_objects

2015-09-20 Thread Gregory Hainaut
Current GLSL badly optimizes the code making it incompatible with the
GL_ARB_separate_shader_objects extension.

Typical example of the current behavior:

VS:
out SHADER
{
vec4 var_zero; // location will always be 0
vec2 var_one; // location will always be 1
} VSout;

FS:
in SHADER
{
vec4 var_zero;
vec2 var_one; // ERROR: location would be wrongly set to 0 if var_zero is 
inactive
} PSin;

In short, SSO allow to match by name but you can't make any hypothesis on the
previous/next stage. Therefore you must consider all inputs as actives.

Commit decription:
patch 1/ Tighten up some linker error checks to avoid dependency with the
 deadcode optimization phase. Phase that will be partially removed in
 patch 3.

patch 2/ Add a new variable flags in the AST to distinguish attribute from
 varying. It is still legal to removed unused attribute.

patch 3/ Disable the optimization of varying inputs that don't have an explicit
 location. The idea was to keep the optimization for all builtins
 varyings. Besides it won't trigger the bug if explicit location are
 used for all variables. I'm not sure what it is the best solutions.


Piglit test done on older Mesa/Nouveau (8276ba260) due to libdrm newer 
requirement.

[30454/30454] crash: 29, fail: 221, pass: 20749, skip: 9451, warn: 4 -

The fix was validated on the PCSX2 application. I will try to create a
piglit tests of the above situation.


Gregory Hainaut (3):
  glsl/link: don't consider unused variable as read variable.
  glsl/ast2hir: add a new flag attribute_input for VS input
  glsl/opt: disable optimization of varying input

 src/glsl/ast_to_hir.cpp|  4 
 src/glsl/ir.h  |  9 +
 src/glsl/link_varyings.cpp |  4 ++--
 src/glsl/opt_dead_code.cpp | 16 
 4 files changed, 31 insertions(+), 2 deletions(-)

-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 0/3][RFC] Improve GLSL support of GL_ARB_separate_shader_objects

2015-09-30 Thread gregory hainaut
On Fri, 25 Sep 2015 16:40:31 -0700
Ian Romanick  wrote:

> On 09/20/2015 01:15 PM, Gregory Hainaut wrote:
> > Current GLSL badly optimizes the code making it incompatible with the
> > GL_ARB_separate_shader_objects extension.
> > 
> > Typical example of the current behavior:
> > 
> > VS:
> > out SHADER
> > {
> > vec4 var_zero; // location will always be 0
> > vec2 var_one; // location will always be 1
> > } VSout;
> > 
> > FS:
> > in SHADER
> > {
> > vec4 var_zero;
> > vec2 var_one; // ERROR: location would be wrongly set to 0 if var_zero 
> > is inactive
> > } PSin;
> > 
> > In short, SSO allow to match by name but you can't make any hypothesis on 
> > the
> > previous/next stage. Therefore you must consider all inputs as actives.
> 
> Welcome back. :)

Oh, thanks you :)
 
> I think I understand what is happening, but I think the approach is not
> quite right.  My understanding, with the aid of the spec quote in patch
> 3, is that any interstage I/O (i.e., not vertex inputs and not fragment
> outputs) that are explicitly declared in a stage, even if unused in that
> stage, cannot be eliminated.  This is roughly like layout(shared) on UBOs.

Yes
 
> This set of changes only prevents unused interstage inputs from being
> eliminated.  It does nothing for vertex, geometry, or tessellation
> outputs.  It also prevents the elimination of user-declared inputs that
> could previously be eliminated.  It seems that if the VS and FS
> mentioned above were linked together, var_zero would (incorrectly) not
> be eliminated.  Right?

Yes, you're right. I extended my current piglit test to check 
both input and output wrong that are wrongly eliminated. I also made a small
test to check interstage optimization.

> I think patches 1 and 2 should just be dropped.  A new patch 1 should
> add a method that determines whether or not a ir_var_shader_in or
> ir_var_shader_out is interstage.  I thought such a function existed, but
> I could not find it.  The replacement for patch 3 would change the logic
> to "if it's interstage I/O, and there isn't an explicit location, and
> this stage isn't linked with a following stage, do not eliminate the
> variable."
> 
> The "this stage isn't linked with a following stage" part is important
> because we still want to eliminate vertex shader outputs in separable
> shaders if the vertex shader is linked directly with (only) a geometry
> shader, for example.
> 
So far, I manage to annotate the ir with an interstage flag. However some issues
are remaining with explicit location.

Here the bad FS program:

layout(location = 0) in vec4 blue;
in vec4 green;
in vec4 red;

void main()
{
out_color = vec4(green.xyz, 1);
}

// IR for the FS
(declare (location=26 shader_in ) vec4 green)
(declare (location=27 shader_in ) vec4 red)
(declare (location=4 shader_out ) vec4 out_color)

// IR for the VS (same interface but declared as out)
(declare (location=0 shader_out ) vec4 gl_Position)
(declare (temporary ) vec4 gl_Position)
(declare (location=26 shader_out ) vec4 blue)
(declare (temporary ) vec4 blue)
(declare (location=26 shader_out flat) vec4 green)
(declare (temporary ) vec4 green)
(declare (location=27 shader_out flat) vec4 red)
(declare (temporary ) vec4 red)
(declare (location=17 shader_in ) vec4 piglit_vertex)

As you can see there are 2 problems.
1/ location in the VS overlap, 26 appears 2 times.
I'm not sure that Mesa support it actually (or if it isn't allowed).

2/ FS doesn't reserve slot 26 (VARYING_SLOT_VAR0) for blue and start directly 
to the slot 26
Technically I could just disable the optimization of those variables too. But 
sadly
I hit issue number 1 for FS too.

Any idea of where it could be wrong?

Thanks.

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 0/3][RFC] Improve GLSL support of GL_ARB_separate_shader_objects

2015-09-30 Thread gregory hainaut
On Wed, 30 Sep 2015 21:18:43 +0200
gregory hainaut  wrote:

> On Fri, 25 Sep 2015 16:40:31 -0700
> Ian Romanick  wrote:
> 
> > On 09/20/2015 01:15 PM, Gregory Hainaut wrote:
> > > Current GLSL badly optimizes the code making it incompatible with the
> > > GL_ARB_separate_shader_objects extension.
> > > 
> > > Typical example of the current behavior:
> > > 
> > > VS:
> > > out SHADER
> > > {
> > > vec4 var_zero; // location will always be 0
> > > vec2 var_one; // location will always be 1
> > > } VSout;
> > > 
> > > FS:
> > > in SHADER
> > > {
> > > vec4 var_zero;
> > > vec2 var_one; // ERROR: location would be wrongly set to 0 if 
> > > var_zero is inactive
> > > } PSin;
> > > 
> > > In short, SSO allow to match by name but you can't make any hypothesis on 
> > > the
> > > previous/next stage. Therefore you must consider all inputs as actives.
> > 
> > Welcome back. :)
> 
> Oh, thanks you :)
>  
> > I think I understand what is happening, but I think the approach is not
> > quite right.  My understanding, with the aid of the spec quote in patch
> > 3, is that any interstage I/O (i.e., not vertex inputs and not fragment
> > outputs) that are explicitly declared in a stage, even if unused in that
> > stage, cannot be eliminated.  This is roughly like layout(shared) on UBOs.
> 
> Yes
>  
> > This set of changes only prevents unused interstage inputs from being
> > eliminated.  It does nothing for vertex, geometry, or tessellation
> > outputs.  It also prevents the elimination of user-declared inputs that
> > could previously be eliminated.  It seems that if the VS and FS
> > mentioned above were linked together, var_zero would (incorrectly) not
> > be eliminated.  Right?
> 
> Yes, you're right. I extended my current piglit test to check 
> both input and output wrong that are wrongly eliminated. I also made a small
> test to check interstage optimization.
> 
> > I think patches 1 and 2 should just be dropped.  A new patch 1 should
> > add a method that determines whether or not a ir_var_shader_in or
> > ir_var_shader_out is interstage.  I thought such a function existed, but
> > I could not find it.  The replacement for patch 3 would change the logic
> > to "if it's interstage I/O, and there isn't an explicit location, and
> > this stage isn't linked with a following stage, do not eliminate the
> > variable."
> > 
> > The "this stage isn't linked with a following stage" part is important
> > because we still want to eliminate vertex shader outputs in separable
> > shaders if the vertex shader is linked directly with (only) a geometry
> > shader, for example.
> > 
> So far, I manage to annotate the ir with an interstage flag. However some 
> issues
> are remaining with explicit location.
> 
> Here the bad FS program:
> 
> layout(location = 0) in vec4 blue;
> in vec4 green;
> in vec4 red;
> 
> void main()
> {
> out_color = vec4(green.xyz, 1);
> }
> 
> // IR for the FS
> (declare (location=26 shader_in ) vec4 green)
> (declare (location=27 shader_in ) vec4 red)
> (declare (location=4 shader_out ) vec4 out_color)
> 
> // IR for the VS (same interface but declared as out)
> (declare (location=0 shader_out ) vec4 gl_Position)
> (declare (temporary ) vec4 gl_Position)
> (declare (location=26 shader_out ) vec4 blue)
> (declare (temporary ) vec4 blue)
> (declare (location=26 shader_out flat) vec4 green)
> (declare (temporary ) vec4 green)
> (declare (location=27 shader_out flat) vec4 red)
> (declare (temporary ) vec4 red)
> (declare (location=17 shader_in ) vec4 piglit_vertex)
> 
> As you can see there are 2 problems.
> 1/ location in the VS overlap, 26 appears 2 times.
> I'm not sure that Mesa support it actually (or if it isn't allowed).
> 
> 2/ FS doesn't reserve slot 26 (VARYING_SLOT_VAR0) for blue and start directly 
> to the slot 26
> Technically I could just disable the optimization of those variables too. But 
> sadly
> I hit issue number 1 for FS too.
> 
> Any idea of where it could be wrong?
> 
> Thanks.
> 
Hum, just further reading of the code, I found a comment in
link_invalidate_variable_locations that code must be updated for
GL_ARB_separate_shader_objects. In the above test, the explicit variable
has is_unmatched_generic_layout = 0 so varying_matches::record doesn't
record it. Not sure if the comment is still valid.

Otherwise, it seems that varying_matches::assign_locations doesn't take into 
account 
already reserved locations.
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 1/3] glsl IR: add not_interstage attribute to ir_variable

2015-10-03 Thread Gregory Hainaut
The negative form was used to keep interstage as the default value

Note: I put the ir_set_not_interstage_io function in opt_dead_code
because it will be used to disable deadcode optimization. Feel free
to point me a better place if it exists.

Signed-off-by: Gregory Hainaut 
---
 src/glsl/ir.h  |  6 ++
 src/glsl/ir_optimization.h |  2 ++
 src/glsl/opt_dead_code.cpp | 19 +++
 3 files changed, 27 insertions(+)

diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index f9ddf74..b4c4ace 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -649,6 +649,12 @@ public:
   unsigned assigned:1;
 
   /**
+   * When separate shader programs are enabled, only interstage
+   * variables can be safely removed of the shader interface.
+   */
+  unsigned not_interstage:1;
+
+  /**
* Enum indicating how the variable was declared.  See
* ir_var_declaration_type.
*
diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
index 265b223..bdd6ccc 100644
--- a/src/glsl/ir_optimization.h
+++ b/src/glsl/ir_optimization.h
@@ -72,6 +72,8 @@ enum lower_packing_builtins_op {
LOWER_PACK_USE_BFE   = 0x2000,
 };
 
+void ir_set_not_interstage_io(exec_list *instructions, ir_variable_mode mode);
+
 bool do_common_optimization(exec_list *ir, bool linked,
bool uniform_locations_assigned,
 const struct gl_shader_compiler_options *options,
diff --git a/src/glsl/opt_dead_code.cpp b/src/glsl/opt_dead_code.cpp
index e4bf874..d70c855 100644
--- a/src/glsl/opt_dead_code.cpp
+++ b/src/glsl/opt_dead_code.cpp
@@ -35,6 +35,25 @@
 
 static bool debug = false;
 
+void
+ir_set_not_interstage_io(exec_list *instructions, ir_variable_mode mode)
+{
+   ir_variable_refcount_visitor v;
+
+   assert(mode == ir_var_shader_in || mode == ir_var_shader_out);
+
+   v.run(instructions);
+
+   struct hash_entry *e;
+   hash_table_foreach(v.ht, e) {
+  ir_variable_refcount_entry *entry = (ir_variable_refcount_entry 
*)e->data;
+
+  if (entry->var->data.mode == mode)
+ entry->var->data.not_interstage = 1;
+   }
+}
+
+
 /**
  * Do a dead code pass over instructions and everything that instructions
  * references.
-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 2/3] glsl link: annotate not_interstage attribute of the ir_var after link phase

2015-10-03 Thread Gregory Hainaut
Signed-off-by: Gregory Hainaut 
---
 src/glsl/linker.cpp | 47 +++
 1 file changed, 47 insertions(+)

diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index fd69dbc..a4a8ab4 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -3378,6 +3378,51 @@ link_assign_subroutine_types(struct gl_shader_program 
*prog)
}
 }
 
+static void
+set_interstage_io(struct gl_shader_program *prog)
+{
+   unsigned first, last;
+
+   /* In monolithic build, IO can be freely optimized */
+   if (!prog->SeparateShader)
+  return;
+
+   first = MESA_SHADER_STAGES;
+   last = 0;
+
+   /* Determine first and last stage. Excluding the compute stage */
+   for (unsigned i = 0; i < MESA_SHADER_COMPUTE; i++) {
+  if (!prog->_LinkedShaders[i])
+ continue;
+  if (first == MESA_SHADER_STAGES)
+ first = i;
+  last = i;
+   }
+
+   if (first == MESA_SHADER_STAGES)
+  return;
+
+   for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {
+  gl_shader *sh = prog->_LinkedShaders[stage];
+  if (!sh)
+ continue;
+
+  if (first == last) {
+ /* Single shader program */
+ if (first != MESA_SHADER_VERTEX)
+ir_set_not_interstage_io(sh->ir, ir_var_shader_in);
+ if (first != MESA_SHADER_FRAGMENT)
+ir_set_not_interstage_io(sh->ir, ir_var_shader_out);
+  } else {
+ /* Multiple shaders program */
+ if (stage == first && stage != MESA_SHADER_VERTEX)
+ir_set_not_interstage_io(sh->ir, ir_var_shader_in);
+ else if (stage == last && stage != MESA_SHADER_FRAGMENT)
+ir_set_not_interstage_io(sh->ir, ir_var_shader_out);
+  }
+   }
+}
+
 void
 link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
 {
@@ -3637,6 +3682,8 @@ link_shaders(struct gl_context *ctx, struct 
gl_shader_program *prog)
   }
}
 
+   set_interstage_io(prog);
+
if (!interstage_cross_validate_uniform_blocks(prog))
   goto done;
 
-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 3/3] glsl IR: only allow optimization of interstage variable

2015-10-03 Thread Gregory Hainaut
GL_ARB_separate_shader_objects allow to match by name variable or block
interface. Input varying can't be removed as it is will impact the location
assignment.

It fixes the bug 79783 and likely any application that uses
GL_ARB_separate_shader_objects extension.

Signed-off-by: Gregory Hainaut 
---
 src/glsl/opt_dead_code.cpp | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/src/glsl/opt_dead_code.cpp b/src/glsl/opt_dead_code.cpp
index d70c855..9ddee4d 100644
--- a/src/glsl/opt_dead_code.cpp
+++ b/src/glsl/opt_dead_code.cpp
@@ -94,6 +94,24 @@ do_dead_code(exec_list *instructions, bool 
uniform_locations_assigned)
  || !entry->declaration)
 continue;
 
+  /* Section 7.4.1 (Shader Interface Matching) of the OpenGL 4.5
+   * (Core Profile) spec says:
+   *
+   *"With separable program objects, interfaces between shader
+   *stages may involve the outputs from one program object and the
+   *inputs from a second program object.  For such interfaces, it is
+   *not possible to detect mismatches at link time, because the
+   *programs are linked separately. When each such program is
+   *linked, all inputs or outputs interfacing with another program
+   *stage are treated as active."
+   */
+  if (entry->var->data.not_interstage &&
+(!entry->var->data.explicit_location ||
+ entry->var->data.location >= VARYING_SLOT_VAR0) &&
+(entry->var->data.mode == ir_var_shader_in ||
+ entry->var->data.mode == ir_var_shader_out))
+ continue;
+
   if (entry->assign) {
 /* Remove a single dead assignment to the variable we found.
  * Don't do so if it's a shader or function output or a shader
-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 0/3] V2: Improve GLSL support of GL_ARB_separate_shader_objects

2015-10-03 Thread Gregory Hainaut
> In short, SSO allow to match by name but you can't make any hypothesis on the
> previous/next stage. Therefore you must consider all inputs and output as 
> actives.

New version based on Ian's feedbacks.
* Real interstage variables of the program are still optimized
* Both output and input of the program remains active
* An old bug still remains if name and explicit location rendezvous are mixed

Commits decription:
1/ add a not_interstage parameter that will be 1 when variable is either an
   input of output of the program. I didn't know where to put the 
ir_set_not_interstage_io
   function. Maybe it can be moved in linker.cpp.
2/ Set the interstage parameter based on the shader position in the pipeline 
   program. Potentially can be squased with the previous one.
3/ Don't do deadcode removal of not_interstage variable with the exception
   of the built-in varyings because they don't impact location of others 
variables

Gregory Hainaut (4):
  glsl IR: add not_interstage attribute to ir_variable
  glsl link: annotate not_interstage attribute of the ir_var after link
phase
  glsl IR: only allow optimization of interstage variable
  allow compilation on my system

 configure.ac   |  6 --
 src/glsl/ir.h  |  6 ++
 src/glsl/ir_optimization.h |  2 ++
 src/glsl/linker.cpp| 47 ++
 src/glsl/opt_dead_code.cpp | 37 
 5 files changed, 96 insertions(+), 2 deletions(-)

-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [RFC 0/3] V2: Improve GLSL support of GL_ARB_separate_shader_objects

2015-10-03 Thread gregory hainaut
On Sat, 03 Oct 2015 09:35:49 +
Mike Lothian  wrote:

> Would it be better to have is_interstage=0 rather than a double negative?
> 
Yes. I think it just need to set 1 in the constructor (forget to 
update it by the way...) as default value. Otherwise it can be 
renamed to is_unlinked_io (or something similar).

> 
> > > In short, SSO allow to match by name but you can't make any hypothesis
> > on the
> > > previous/next stage. Therefore you must consider all inputs and output as
> > > actives.
> >
> > New version based on Ian's feedbacks.
> > * Real interstage variables of the program are still optimized
> > * Both output and input of the program remains active
> > * An old bug still remains if name and explicit location rendezvous are
> > mixed
> >
> > Commits decription:
> > 1/ add a not_interstage parameter that will be 1 when variable is either an
> >input of output of the program. I didn't know where to put the
> > ir_set_not_interstage_io
> >function. Maybe it can be moved in linker.cpp.
> > 2/ Set the interstage parameter based on the shader position in the
> > pipeline
> >program. Potentially can be squased with the previous one.
> > 3/ Don't do deadcode removal of not_interstage variable with the exception
> >of the built-in varyings because they don't impact location of others
> > variables
> >
> > Gregory Hainaut (4):
> >   glsl IR: add not_interstage attribute to ir_variable
> >   glsl link: annotate not_interstage attribute of the ir_var after link
> > phase
> >   glsl IR: only allow optimization of interstage variable
> >   allow compilation on my system
> >
> >  configure.ac   |  6 --
> >  src/glsl/ir.h  |  6 ++
> >  src/glsl/ir_optimization.h |  2 ++
> >  src/glsl/linker.cpp| 47
> > ++
> >  src/glsl/opt_dead_code.cpp | 37 
> >  5 files changed, 96 insertions(+), 2 deletions(-)
> >
> > --
> > 2.1.4
> >
> > ___
> > mesa-dev mailing list
> > mesa-dev@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> >
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [RFC 0/3] V2: Improve GLSL support of GL_ARB_separate_shader_objects

2015-10-05 Thread gregory hainaut
On Sat, 3 Oct 2015 11:59:49 +0200
gregory hainaut  wrote:

> On Sat, 03 Oct 2015 09:35:49 +
> Mike Lothian  wrote:
> 
> > Would it be better to have is_interstage=0 rather than a double negative?
> > 
> Yes. I think it just need to set 1 in the constructor (forget to 
> update it by the way...) as default value. Otherwise it can be 
> renamed to is_unlinked_io (or something similar).
> 
> > 
> > > > In short, SSO allow to match by name but you can't make any hypothesis
> > > on the
> > > > previous/next stage. Therefore you must consider all inputs and output 
> > > > as
> > > > actives.
> > >
> > > New version based on Ian's feedbacks.
> > > * Real interstage variables of the program are still optimized
> > > * Both output and input of the program remains active
> > > * An old bug still remains if name and explicit location rendezvous are
> > > mixed
> > >
> > > Commits decription:
> > > 1/ add a not_interstage parameter that will be 1 when variable is either 
> > > an
> > >input of output of the program. I didn't know where to put the
> > > ir_set_not_interstage_io
> > >function. Maybe it can be moved in linker.cpp.
> > > 2/ Set the interstage parameter based on the shader position in the
> > > pipeline
> > >    program. Potentially can be squased with the previous one.
> > > 3/ Don't do deadcode removal of not_interstage variable with the exception
> > >of the built-in varyings because they don't impact location of others
> > > variables
> > >
> > > Gregory Hainaut (4):
> > >   glsl IR: add not_interstage attribute to ir_variable
> > >   glsl link: annotate not_interstage attribute of the ir_var after link
> > > phase
> > >   glsl IR: only allow optimization of interstage variable
> > >   allow compilation on my system
> > >
> > >  configure.ac   |  6 --
> > >  src/glsl/ir.h  |  6 ++
> > >  src/glsl/ir_optimization.h |  2 ++
> > >  src/glsl/linker.cpp| 47
> > > ++
> > >  src/glsl/opt_dead_code.cpp | 37 
> > >  5 files changed, 96 insertions(+), 2 deletions(-)
> > >
> > > --
> > > 2.1.4
> > >
> > > ___
> > > mesa-dev mailing list
> > > mesa-dev@lists.freedesktop.org
> > > http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> > >

I found another issue with my application (lucky me).

out SHADER
{
vec4 t;
vec4 c;
flat vec4 fc;
} VSout;

in SHADER
{
vec4 t;
vec4 c;
flat vec4 fc;
} PSin;


will be transformed into the following interface in SSO (in 
varying_matches::record) to

out SHADER
{
flat vec4 t;
flat vec4 c;
flat vec4 fc;
} VSout;

in SHADER
{
vec4 t;
vec4 c;
flat vec4 fc;
} PSin;

It doesn't change the interpolation/rendering as it will use the one
from the FS. However it will affect the
match_comparator function. So the sorting in
varying_matches::assign_locations will 
behave differently for some parameters. I don't know how to handle
this. Either we could adapt the sort function
to mask the flat value. Or we mustn't add the flat qualifier. Any opinions or
other solutions?
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH] mesa: faster validation of sampler unit mapping for SSO

2016-06-24 Thread Gregory Hainaut
Code was inspired from _mesa_update_shader_textures_used

However unlike _mesa_update_shader_textures_used that only check for a single
stage, it will check all stages.

It avoids to loop on all uniforms, only active samplers are checked.

Signed-off-by: Gregory Hainaut 
---
 src/mesa/main/uniform_query.cpp | 69 ++---
 1 file changed, 31 insertions(+), 38 deletions(-)

diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index 127f097..4fa4e6e 100644
--- a/src/mesa/main/uniform_query.cpp
+++ b/src/mesa/main/uniform_query.cpp
@@ -1068,58 +1068,51 @@ _mesa_sampler_uniforms_pipeline_are_valid(struct 
gl_pipeline_object *pipeline)
 * - The number of active samplers in the program exceeds the
 *   maximum number of texture image units allowed."
 */
+
+   GLbitfield mask;
+   GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
+   struct gl_shader *shader;
unsigned active_samplers = 0;
const struct gl_shader_program **shProg =
   (const struct gl_shader_program **) pipeline->CurrentProgram;
 
-   const glsl_type *unit_types[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
-   memset(unit_types, 0, sizeof(unit_types));
+
+   memset(TexturesUsed, 0, sizeof(TexturesUsed));
 
for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
   if (!shProg[idx])
  continue;
 
-  for (unsigned i = 0; i < shProg[idx]->NumUniformStorage; i++) {
- const struct gl_uniform_storage *const storage =
-&shProg[idx]->UniformStorage[i];
+  shader = shProg[idx]->_LinkedShaders[idx];
+  if (!shader || !shader->Program)
+ continue;
 
- if (!storage->type->is_sampler())
+  mask = shader->Program->SamplersUsed;
+  while (mask) {
+ const int s = u_bit_scan(&mask);
+ GLuint unit = shader->SamplerUnits[s];
+ GLuint tgt = shader->SamplerTargets[s];
+
+ /* FIXME: Samplers are initialized to 0 and Mesa doesn't do a
+  * great job of eliminating unused uniforms currently so for now
+  * don't throw an error if two sampler types both point to 0.
+  */
+ if (unit == 0)
 continue;
 
- active_samplers++;
-
- const unsigned count = MAX2(1, storage->array_elements);
- for (unsigned j = 0; j < count; j++) {
-const unsigned unit = storage->storage[j].i;
-
-/* FIXME: Samplers are initialized to 0 and Mesa doesn't do a
- * great job of eliminating unused uniforms currently so for now
- * don't throw an error if two sampler types both point to 0.
- */
-if (unit == 0)
-   continue;
-
-/* The types of the samplers associated with a particular texture
- * unit must be an exact match.  Page 74 (page 89 of the PDF) of
- * the OpenGL 3.3 core spec says:
- *
- * "It is not allowed to have variables of different sampler
- * types pointing to the same texture image unit within a
- * program object."
- */
-if (unit_types[unit] == NULL) {
-   unit_types[unit] = storage->type;
-} else if (unit_types[unit] != storage->type) {
-   pipeline->InfoLog =
-  ralloc_asprintf(pipeline,
-  "Texture unit %d is accessed both as %s "
-  "and %s",
-  unit, unit_types[unit]->name,
-  storage->type->name);
-   return false;
-}
+ if (TexturesUsed[unit] & ~(1 << tgt)) {
+pipeline->InfoLog =
+   ralloc_asprintf(pipeline,
+ "Program %d: "
+ "Texture unit %d is accessed with 2 different types",
+ shProg[idx]->Name, unit);
+return false;
  }
+
+ TexturesUsed[unit] |= (1 << tgt);
   }
+
+  active_samplers += shader->num_samplers;
}
 
if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) {
-- 
2.1.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] mesa: faster validation of sampler unit mapping for SSO

2016-06-25 Thread Gregory Hainaut
Hello Timothy,

On my use case: high FS frequency switches. Few sampler.
Perf event (relative to nouveau_dri.so) goes from 5.01% to 1.68% for
the _mesa_sampler_uniforms_pipeline_are_valid function.

Unfortunately it didn't translate into measurable speed change. I have
too much FPS variation (cache? temperature, GPU turbo?).

Honestly I was reluctant to send the patch, but the code isn't more
complex. I let's you judge.

Gregory

On 6/25/16, Timothy Arceri  wrote:
> On Fri, 2016-06-24 at 10:07 +0200, Gregory Hainaut wrote:
>> Code was inspired from _mesa_update_shader_textures_used
>>
>> However unlike _mesa_update_shader_textures_used that only check for
>> a single
>> stage, it will check all stages.
>>
>> It avoids to loop on all uniforms, only active samplers are checked.
>
> Hi Gregory,
>
> Is there any measurable change as a result of this? Normally
> performance changes should come with some results in the commit
> message.
>
> Tim
>
>>
>> Signed-off-by: Gregory Hainaut 
>> ---
>>  src/mesa/main/uniform_query.cpp | 69 ++-
>> --
>>  1 file changed, 31 insertions(+), 38 deletions(-)
>>
>> diff --git a/src/mesa/main/uniform_query.cpp
>> b/src/mesa/main/uniform_query.cpp
>> index 127f097..4fa4e6e 100644
>> --- a/src/mesa/main/uniform_query.cpp
>> +++ b/src/mesa/main/uniform_query.cpp
>> @@ -1068,58 +1068,51 @@
>> _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object
>> *pipeline)
>>  * - The number of active samplers in the program exceeds
>> the
>>  *   maximum number of texture image units allowed."
>>  */
>> +
>> +   GLbitfield mask;
>> +   GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
>> +   struct gl_shader *shader;
>> unsigned active_samplers = 0;
>> const struct gl_shader_program **shProg =
>>    (const struct gl_shader_program **) pipeline->CurrentProgram;
>>
>> -   const glsl_type *unit_types[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
>> -   memset(unit_types, 0, sizeof(unit_types));
>> +
>> +   memset(TexturesUsed, 0, sizeof(TexturesUsed));
>>
>> for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline-
>> >CurrentProgram); idx++) {
>>    if (!shProg[idx])
>>   continue;
>>
>> -  for (unsigned i = 0; i < shProg[idx]->NumUniformStorage; i++)
>> {
>> - const struct gl_uniform_storage *const storage =
>> -&shProg[idx]->UniformStorage[i];
>> +  shader = shProg[idx]->_LinkedShaders[idx];
>> +  if (!shader || !shader->Program)
>> + continue;
>>
>> - if (!storage->type->is_sampler())
>> +  mask = shader->Program->SamplersUsed;
>> +  while (mask) {
>> + const int s = u_bit_scan(&mask);
>> + GLuint unit = shader->SamplerUnits[s];
>> + GLuint tgt = shader->SamplerTargets[s];
>> +
>> + /* FIXME: Samplers are initialized to 0 and Mesa doesn't do
>> a
>> +  * great job of eliminating unused uniforms currently so
>> for now
>> +  * don't throw an error if two sampler types both point to
>> 0.
>> +  */
>> + if (unit == 0)
>>  continue;
>>
>> - active_samplers++;
>> -
>> - const unsigned count = MAX2(1, storage->array_elements);
>> - for (unsigned j = 0; j < count; j++) {
>> -const unsigned unit = storage->storage[j].i;
>> -
>> -/* FIXME: Samplers are initialized to 0 and Mesa doesn't
>> do a
>> - * great job of eliminating unused uniforms currently so
>> for now
>> - * don't throw an error if two sampler types both point
>> to 0.
>> - */
>> -if (unit == 0)
>> -   continue;
>> -
>> -/* The types of the samplers associated with a
>> particular texture
>> - * unit must be an exact match.  Page 74 (page 89 of the
>> PDF) of
>> - * the OpenGL 3.3 core spec says:
>> - *
>> - * "It is not allowed to have variables of different
>> sampler
>> - * types pointing to the same texture image unit
>> within a
>> - * program object."
>> - */
>> -if (unit_types[unit] == NULL) {
>> -   unit_types[unit] = storage->type;
>> -  

Re: [Mesa-dev] [PATCH 3/7] glsl: optimise inputs/outputs with explicit locations

2015-11-21 Thread gregory hainaut
Hello Timoty,

The patch introduces a regression on deqp test. (I'm nearly sure there are 
hidden piglit tests that trigger the same error)

DEQP test: deqp-gles31 
--deqp-case=dEQP-GLES31.functional.separate_shader.interface.same_location

Be awware that you need to patch Mesa (temporary hack) to start the test. See 
below

The relevant log:
// vertex interface
layout(location=0) out highp float vtxVar0;
// fragment interface
layout(location=0) out highp float frgVar0;
// mesa warning
warning: fragment shader varying frgVar0 not written by vertex shader

Cheers,
Gregory

diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
index 90dff13..6e333c5 100644
--- a/src/mesa/main/pipelineobj.c
+++ b/src/mesa/main/pipelineobj.c
@@ -646,7 +646,8 @@ _mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, 
GLint *params)
   return;
case GL_VALIDATE_STATUS:
   /* If pipeline is not bound, return initial value 0. */
-  *params = (ctx->_Shader->Name != pipe->Name) ? 0 : pipe->Validated;
+  //*params = (ctx->_Shader->Name != pipe->Name) ? 0 : pipe->Validated;
+  *params = pipe->Validated;
   return;
case GL_VERTEX_SHADER:
   *params = pipe->CurrentProgram[MESA_SHADER_VERTEX]



On Sat, 21 Nov 2015 19:02:02 +1100
Timothy Arceri  wrote:

> From: Timothy Arceri 
> 
> This change allows used defined inputs/outputs with explicit locations
> to be removed if they are detected to not be used between shaders
> at link time.
> 
> To enable this we change the is_unmatched_generic_inout field to be
> flagged when we have a user defined varying. Previously
> explicit_location was assumed to be set only in builtins however SSO
> allows the user to set an explicit location.
> 
> We then add a function to match explicit locations between shaders.
> 
> Cc: Gregory Hainaut 
> ---
>  src/glsl/link_varyings.cpp |  6 ++--
>  src/glsl/linker.cpp| 82 
> +++---
>  2 files changed, 74 insertions(+), 14 deletions(-)
> 
> diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
> index c0b4b3e..ac2755f 100644
> --- a/src/glsl/link_varyings.cpp
> +++ b/src/glsl/link_varyings.cpp
> @@ -896,8 +896,10 @@ varying_matches::record(ir_variable *producer_var, 
> ir_variable *consumer_var)
>  {
> assert(producer_var != NULL || consumer_var != NULL);
>  
> -   if ((producer_var && !producer_var->data.is_unmatched_generic_inout)
> -   || (consumer_var && !consumer_var->data.is_unmatched_generic_inout)) {
> +   if ((producer_var && (!producer_var->data.is_unmatched_generic_inout ||
> +   producer_var->data.explicit_location)) ||
> +   (consumer_var && (!consumer_var->data.is_unmatched_generic_inout ||
> +   consumer_var->data.explicit_location))) {
>/* Either a location already exists for this variable (since it is part
> * of fixed functionality), or it has already been recorded as part of 
> a
> * previous match.
> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
> index 5ff433c..1db7b7a 100644
> --- a/src/glsl/linker.cpp
> +++ b/src/glsl/linker.cpp
> @@ -631,20 +631,12 @@ link_invalidate_variable_locations(exec_list *ir)
>  
>/* ir_variable::is_unmatched_generic_inout is used by the linker while
> * connecting outputs from one stage to inputs of the next stage.
> -   *
> -   * There are two implicit assumptions here.  First, we assume that any
> -   * built-in variable (i.e., non-generic in or out) will have
> -   * explicit_location set.  Second, we assume that any generic in or out
> -   * will not have explicit_location set.
> -   *
> -   * This second assumption will only be valid until
> -   * GL_ARB_separate_shader_objects is supported.  When that extension is
> -   * implemented, this function will need some modifications.
> */
> -  if (!var->data.explicit_location) {
> - var->data.is_unmatched_generic_inout = 1;
> -  } else {
> +  if (var->data.explicit_location &&
> +  var->data.location < VARYING_SLOT_VAR0) {
>   var->data.is_unmatched_generic_inout = 0;
> +  } else {
> + var->data.is_unmatched_generic_inout = 1;
>}
> }
>  }
> @@ -2421,6 +2413,7 @@ assign_attribute_or_color_locations(gl_shader_program 
> *prog,
>continue;
>  
>if (var->data.explicit_location) {
> + var->data.is_unmatched_generic_inout = 0;
>if ((var->data.location >= (int)(max_index + generic_base))
>|| (var->data.location < 0)) {
>   linker_error(prog,
> @@ -2690,6 +2683,61 @@ ass

Re: [Mesa-dev] [PATCH 3/3] mesa: return initial value for VALIDATE_STATUS if pipe not bound

2015-11-22 Thread gregory hainaut
On Sun, 22 Nov 2015 14:25:31 +1100
Timothy Arceri  wrote:

> On Tue, 2015-09-01 at 13:53 +0300, Tapani Pälli wrote:
> > From OpenGL 4.5 Core spec (7.13):
> > 
> > "If pipeline is a name that has been generated (without
> > subsequent
> > deletion) by GenProgramPipelines, but refers to a program
> > pipeline
> > object that has not been previously bound, the GL first creates
> > a new state vector in the same manner as when BindProgramPipeline
> > creates a new program pipeline object."
> > 
> > I interpret this as "If GetProgramPipelineiv gets called without a
> > bound (but valid) pipeline object, the state should reflect initial
> > state of a new pipeline object." This is also expected behaviour by
> > ES31-CTS.sepshaderobjs.PipelineApi conformance test.
> > 
> > Signed-off-by: Tapani Pälli 
> > ---
> >  src/mesa/main/pipelineobj.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/src/mesa/main/pipelineobj.c
> > b/src/mesa/main/pipelineobj.c
> > index 07acbf1..c2e1d29 100644
> > --- a/src/mesa/main/pipelineobj.c
> > +++ b/src/mesa/main/pipelineobj.c
> > @@ -614,7 +614,8 @@ _mesa_GetProgramPipelineiv(GLuint pipeline,
> > GLenum pname, GLint *params)
> >*params = pipe->InfoLog ? strlen(pipe->InfoLog) + 1 : 0;
> >return;
> > case GL_VALIDATE_STATUS:
> > -  *params = pipe->Validated;
> > +  /* If pipeline is not bound, return initial value 0. */
> > +  *params = (ctx->_Shader->Name != pipe->Name)
> > ? 0 : pipe->Validated;
> 
> Hi Tapani,
> 
> As Gregory has pointed out this change causes a large number of the
> SSO deqp tests to fail.
> 
> I'm not sure what the solution is yet but one thing I have noticed is
> that with this change we will always return a value of 0 as nothing
> ever sets the value of ctx->_Shader->Name.
> 
> I did try setting it when the bind is done but the deqp tests still
> fail as the bind is done after the validate in those tests. Are you
> sure that this must return 0 if the pipe is not bound?
> 
> Tim
> 
> >return;
> > case GL_VERTEX_SHADER:
> >*params = pipe->CurrentProgram[MESA_SHADER_VERTEX]

Hello,

Here my understanding of the specification (with my point of view of GL
users).

On various objects, gen* cmds reserve a key in a hash table but objects
aren't created. Generally the object are created when they're bound (often call 
bind to
create). However SSO API is (closer of the/a) direct state access API. It is 
really 
awkward to bind the object to modify it. Besides there is now full DSA. 

So for me, the following pipeline command must created the object if it
wasn't created (read if it wasn't bound)

1/ BindProgramPipeline
2/ UseProgramStages
3/ CreateProgramPipelines (???: not sure, but likely)
4/ ActiveShaderProgram
5/ GetProgramPipelineiv
6/ ValidateProgramPipeline

Note: can be read as all pipeline commands, so it is nearly equivalent to
create the object in GenProgramPipelines. The only exception is 
IsProgramPipeline.


So GetProgramPipelineiv (and others gl cmd) must start with:
if (! pipe->IsCreated ) {
pipe->Init();
pipe->IsCreated = true;
}


For example:
GenProgramPipelines(1, &pipe);
GetProgramPipelineiv(pipe, X, X); // Must create the object and therefore will 
return the initial value (0)

GenProgramPipelines(1, &pipe2);
ValidateProgramPipeline(pipe2); // Will create the object
GetProgramPipelineiv(pipe2, X, X); // object was created by 
ValidateProgramPipeline, we can return the property

As a side note, if Mesa is updated. Piglit test will need some updates too.

Best regards,
Gregory
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] glsl: implement recent spec update to SSO validation

2015-11-23 Thread Gregory Hainaut
Thanks. Yes I think it must be this way. I said the same to Tapani 1
hour ago (but stupid gmail didn't reply all...).

On 11/23/15, Timothy Arceri  wrote:
> On Mon, 2015-11-23 at 23:24 +1100, Timothy Arceri wrote:
>> From: Timothy Arceri 
>>
>> Enables 200+ dEQP SSO tests to proceed passed validation,
>> while not regressing ES31-CTS.sepshaderobjs.PipelineApi.
>>
>> Cc: Tapani Pälli 
>> Cc: Gregory Hainaut 
>> ---
>>  src/mesa/main/pipelineobj.c | 25 -
>>  1 file changed, 24 insertions(+), 1 deletion(-)
>>
>> diff --git a/src/mesa/main/pipelineobj.c
>> b/src/mesa/main/pipelineobj.c
>> index 90dff13..99e1491 100644
>> --- a/src/mesa/main/pipelineobj.c
>> +++ b/src/mesa/main/pipelineobj.c
>> @@ -646,7 +646,7 @@ _mesa_GetProgramPipelineiv(GLuint pipeline,
>> GLenum pname, GLint *params)
>>return;
>> case GL_VALIDATE_STATUS:
>>/* If pipeline is not bound, return initial value 0. */
>
> Whoops, I've removed this comment locally also.
>
>> -  *params = (ctx->_Shader->Name != pipe->Name) ? 0 : pipe
>> ->Validated;
>> +  *params = pipe->Validated;
>>return;
>> case GL_VERTEX_SHADER:
>>*params = pipe->CurrentProgram[MESA_SHADER_VERTEX]
>> @@ -858,6 +858,29 @@ _mesa_validate_program_pipeline(struct
>> gl_context* ctx,
>>}
>> }
>>
>> +   /* Section 11.1.3.11 (Validation) of the OpenGL 4.5 spec says:
>> +*
>> +*"An INVALID_OPERATION error is generated by any command
>> that trans-
>> +*fers vertices to the GL or launches compute work if the
>> current set
>> +*of active program objects cannot be executed, for reasons
>> including:
>> +*
>> +*   ...
>> +*
>> +*   - There is no current program object specified by
>> UseProgram,
>> +* there is a current program pipeline object, and that
>> object is
>> +* empty (no executable code is installed for any stage).
>> +*/
>> +   bool program_empty = true;
>> +   for (i = 0; i < MESA_SHADER_STAGES; i++) {
>> +  if (pipe->CurrentProgram[i]) {
>> + program_empty = false;
>> + break;
>> +  }
>> +   }
>> +   if(program_empty) {
>> +  goto err;
>> +   }
>> +
>> /* Section 2.11.11 (Shader Execution), subheading "Validation,"
>> of the
>>  * OpenGL 4.1 spec says:
>>  *
>
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] glsl: implement recent spec update to SSO validation

2015-11-23 Thread Gregory Hainaut
It is a different issue and it seems I already did it (or someone else
patched it).

You can see those lines in the code.
   /* Object is created by any Pipeline call but glGenProgramPipelines,
* glIsProgramPipeline and GetProgramPipelineInfoLog
*/
   pipe->EverBound = GL_TRUE;

The trick is that object is created by GenProgramPipelines (unlike the
spec said). Only a flag is updated to mark the object as created. And
normally validated must be 0 after the init (rzalloc?).





On 11/23/15, Tapani Pälli  wrote:
> Hi;
>
> On 11/23/2015 02:24 PM, Timothy Arceri wrote:
>> From: Timothy Arceri 
>>
>> Enables 200+ dEQP SSO tests to proceed passed validation,
>> while not regressing ES31-CTS.sepshaderobjs.PipelineApi.
>>
>> Cc: Tapani Pälli 
>> Cc: Gregory Hainaut 
>> ---
>>   src/mesa/main/pipelineobj.c | 25 -
>>   1 file changed, 24 insertions(+), 1 deletion(-)
>>
>> diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
>> index 90dff13..99e1491 100644
>> --- a/src/mesa/main/pipelineobj.c
>> +++ b/src/mesa/main/pipelineobj.c
>> @@ -646,7 +646,7 @@ _mesa_GetProgramPipelineiv(GLuint pipeline, GLenum
>> pname, GLint *params)
>> return;
>>  case GL_VALIDATE_STATUS:
>> /* If pipeline is not bound, return initial value 0. */
>> -  *params = (ctx->_Shader->Name != pipe->Name) ? 0 :
>> pipe->Validated;
>> +  *params = pipe->Validated;
>
> I agree with the added check below but I feel worried with this change
> as the test is testing explicitly if pipeline was bound before the call,
> here it just happens to be empty as well.
>
> I guess my main worry is that we don't seem to be implementing following:
>
> "If pipeline is a name that has been generated (without subsequent
> deletion) by GenProgramPipelines, but refers to a program pipeline
> object that has not been previously bound, the GL first creates a new
> state vector in the same manner as when BindProgramPipeline creates a
> new program pipeline object."
>
> So we don't realy create 'new state vector' for a new program pipeline
> object but try to return same values as one would have?
>
>
>> return;
>>  case GL_VERTEX_SHADER:
>> *params = pipe->CurrentProgram[MESA_SHADER_VERTEX]
>> @@ -858,6 +858,29 @@ _mesa_validate_program_pipeline(struct gl_context*
>> ctx,
>> }
>>  }
>>
>> +   /* Section 11.1.3.11 (Validation) of the OpenGL 4.5 spec says:
>> +*
>> +*"An INVALID_OPERATION error is generated by any command that
>> trans-
>> +*fers vertices to the GL or launches compute work if the current
>> set
>> +*of active program objects cannot be executed, for reasons
>> including:
>> +*
>> +*   ...
>> +*
>> +*   - There is no current program object specified by
>> UseProgram,
>> +* there is a current program pipeline object, and that object
>> is
>> +* empty (no executable code is installed for any stage).
>> +*/
>> +   bool program_empty = true;
>> +   for (i = 0; i < MESA_SHADER_STAGES; i++) {
>> +  if (pipe->CurrentProgram[i]) {
>> + program_empty = false;
>> + break;
>> +  }
>> +   }
>> +   if(program_empty) {
>> +  goto err;
>> +   }
>> +
>>  /* Section 2.11.11 (Shader Execution), subheading "Validation," of
>> the
>>   * OpenGL 4.1 spec says:
>>   *
>>
>
> // Tapani
>
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH v6 1/3] mesa/glthread: track buffer creation/destruction

2017-05-21 Thread Gregory Hainaut
It would be used in next commit to allow asynchronous PBO transfer.

The tracking saves the buffer name into a hash. Saving pointer
will be more complex as the buffer is created in BindBuffer due to IsBuffer
insanity.

Perf wise DeleteBuffers is now synchronous for robustness.

v5: properly delete hash element with the help of _mesa_HashDeleteAll

v6: rebase
Signed-off-by: Gregory Hainaut 
---
 src/mapi/glapi/gen/ARB_direct_state_access.xml |   2 +-
 src/mapi/glapi/gen/gl_API.xml  |   4 +-
 src/mesa/main/glthread.h   |  10 +++
 src/mesa/main/marshal.c| 113 +
 src/mesa/main/marshal.h|  24 ++
 src/mesa/main/mtypes.h |   5 ++
 src/mesa/main/shared.c |  14 +++
 7 files changed, 169 insertions(+), 3 deletions(-)

diff --git a/src/mapi/glapi/gen/ARB_direct_state_access.xml 
b/src/mapi/glapi/gen/ARB_direct_state_access.xml
index b8780f75b3..8761920c91 100644
--- a/src/mapi/glapi/gen/ARB_direct_state_access.xml
+++ b/src/mapi/glapi/gen/ARB_direct_state_access.xml
@@ -42,21 +42,21 @@
 

   
   
   
   

 

 
-   
+   
   
   

 

   
   
   
   

diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index 762fb5a676..829f99b0f0 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -5053,27 +5053,27 @@
 
 
 
 
 
 
 
 
 
-
+
 
 
 
 
 
-
+
 
 
 
 
 
 
 
 
 
 
diff --git a/src/mesa/main/glthread.h b/src/mesa/main/glthread.h
index 50c1db2548..494e94270a 100644
--- a/src/mesa/main/glthread.h
+++ b/src/mesa/main/glthread.h
@@ -85,20 +85,30 @@ struct glthread_state
 * Tracks on the main thread side whether the current vertex array binding
 * is in a VBO.
 */
bool vertex_array_is_vbo;
 
/**
 * Tracks on the main thread side whether the current element array (index
 * buffer) binding is in a VBO.
 */
bool element_array_is_vbo;
+
+   /**
+* Tracks on the main thread side the bound unpack pixel buffer
+*/
+   GLint pixel_unpack_buffer_bound;
+
+   /**
+* Tracks on the main thread side the bound pack pixel buffer
+*/
+   GLint pixel_pack_buffer_bound;
 };
 
 /**
  * A single batch of commands queued up for later execution by a thread pool
  * task.
  */
 struct glthread_batch
 {
/**
 * Next batch of commands to execute after this batch, or NULL if this is
diff --git a/src/mesa/main/marshal.c b/src/mesa/main/marshal.c
index ae4efb5ecb..4037b793ee 100644
--- a/src/mesa/main/marshal.c
+++ b/src/mesa/main/marshal.c
@@ -25,20 +25,21 @@
  *
  * Custom functions for marshalling GL calls from the main thread to a worker
  * thread when automatic code generation isn't appropriate.
  */
 
 #include "main/enums.h"
 #include "main/macros.h"
 #include "marshal.h"
 #include "dispatch.h"
 #include "marshal_generated.h"
+#include "hash.h"
 
 #ifdef HAVE_PTHREAD
 
 struct marshal_cmd_Flush
 {
struct marshal_cmd_base cmd_base;
 };
 
 
 void
@@ -189,20 +190,132 @@ _mesa_marshal_ShaderSource(GLuint shader, GLsizei count,
   }
   _mesa_post_marshal_hook(ctx);
} else {
   _mesa_glthread_finish(ctx);
   CALL_ShaderSource(ctx->CurrentServerDispatch,
 (shader, count, string, length_tmp));
}
free(length_tmp);
 }
 
+/**
+ * Used as a placeholder for track_buffers_creation/track_buffers_destruction
+ * so we know if buffer really exists in track_buffers_binding.
+ */
+static struct gl_buffer_object DummyBufferObject;
+
+static void track_buffers_creation(GLsizei n, GLuint * buffers)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLsizei i;
+
+   if (n < 0 || !buffers)
+  return;
+
+   _mesa_HashLockMutex(ctx->Shared->ShadowBufferObjects);
+
+   for (i = 0; i < n ; i++) {
+  _mesa_HashInsertLocked(ctx->Shared->ShadowBufferObjects, buffers[i],
+&DummyBufferObject);
+   }
+
+   _mesa_HashUnlockMutex(ctx->Shared->ShadowBufferObjects);
+}
+
+static void track_buffers_destruction(GLsizei n, const GLuint * buffers)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLsizei i;
+   struct glthread_state *glthread = ctx->GLThread;
+
+   if (n < 0 || !buffers)
+  return;
+
+   _mesa_HashLockMutex(ctx->Shared->ShadowBufferObjects);
+
+   for (i = 0; i < n ; i++) {
+  if (buffers[i] == glthread->pixel_pack_buffer_bound)
+ glthread->pixel_pack_buffer_bound = 0;
+
+  if (buffers[i] == glthread->pixel_unpack_buffer_bound)
+ glthread->pixel_unpack_buffer_bound = 0;
+
+  /* Technically the buffer can still exist if it is bound to another
+   * context. It isn't important as nex

[Mesa-dev] [PATCH v6 3/3] mapi/glthread: generate asynchronous code for PBO transfer

2017-05-21 Thread Gregory Hainaut
Improve speed on PCSX2

v2:
Add ppbo/ubpo status in XML file
Disable variable parameter (as the pointer would be a fixed offset)

v3:
split buffer tracking into separate patches.
use 'goto fallback_to_sync' when asynchronous transfer isn't supported

v4:
add Nicolai comment to explain why ppbo isn't impacted by the variable_params
issue

Signed-off-by: Gregory Hainaut 
---
 src/mapi/glapi/gen/ARB_direct_state_access.xml | 16 +++
 src/mapi/glapi/gen/ARB_robustness.xml  |  2 +-
 src/mapi/glapi/gen/gl_API.dtd  | 10 +
 src/mapi/glapi/gen/gl_API.xml  | 28 +-
 src/mapi/glapi/gen/gl_marshal.py   | 23 -
 src/mapi/glapi/gen/marshal_XML.py  | 21 ++-
 6 files changed, 67 insertions(+), 33 deletions(-)

diff --git a/src/mapi/glapi/gen/ARB_direct_state_access.xml 
b/src/mapi/glapi/gen/ARB_direct_state_access.xml
index 8761920c91..6ae1a6c249 100644
--- a/src/mapi/glapi/gen/ARB_direct_state_access.xml
+++ b/src/mapi/glapi/gen/ARB_direct_state_access.xml
@@ -367,79 +367,79 @@

   
   
   
   
   
   
   

 
-   
+   
   
   
   
   
   
   
   

 
-   
+   
   
   
   
   
   
   
   
   
   

 
-   
+   
   
   
   
   
   
   
   
   
   
   
   

 
-   
+   
   
   
   
   
   
   
   

 
-   
+   
   
   
   
   
   
   
   
   
   

 
-   
+   
   
   
   
   
   
   
   
   
   
   
@@ -516,30 +516,30 @@
 

   

 

   
   

 
-   
+   
   
   
   
   
   
   

 
-   
+   
   
   
   
   

 

   
   
   
diff --git a/src/mapi/glapi/gen/ARB_robustness.xml 
b/src/mapi/glapi/gen/ARB_robustness.xml
index 9b2f2f0a74..6e1ac09ce0 100644
--- a/src/mapi/glapi/gen/ARB_robustness.xml
+++ b/src/mapi/glapi/gen/ARB_robustness.xml
@@ -75,21 +75,21 @@
 
 
 
 
 
 
 
 
 
 
-
+
 
 
 
 
 
 
 
 
 
 
diff --git a/src/mapi/glapi/gen/gl_API.dtd b/src/mapi/glapi/gen/gl_API.dtd
index b464250777..447b03a41d 100644
--- a/src/mapi/glapi/gen/gl_API.dtd
+++ b/src/mapi/glapi/gen/gl_API.dtd
@@ -115,28 +115,30 @@ param:
  img_send_null - boolean flag to determine if blank pixel data should
 be sent when a NULL pointer is passed.  This is only used by
 TexImage1D and TexImage2D.
  img_null_flag - boolean flag to determine if an extra flag is used to
 determine if a NULL pixel pointer was passed.  This is used by
 TexSubImage1D, TexSubImage2D, TexImage3D and others.
  img_pad_dimensions - boolean flag to determine if dimension data and
 offset data should be padded to the next even number of dimensions.
 For example, this will insert an empty "height" field after the
 "width" field in the protocol for TexImage1D.
- marshal - One of "sync", "async", "draw", or "custom", defaulting to
-async unless one of the arguments is something we know we can't
-codegen for.  If "sync", we finish any queued glthread work and call
+ marshal - One of "sync", "async", "draw", "ppbo", "upbo" or "custom",
+defaulting to async unless one of the arguments is something we know we
+can't codegen for.  If "sync", we finish any queued glthread work and 
call
 the Mesa implementation directly.  If "async", we queue the function
 call to be performed by glthread.  If "custom", the prototype will be
 generated but a custom implementation will be present in marshal.c.
 If "draw", it will follow the "async" rules except that "indices" are
-ignored (since they may come from a VBO).
+ignored (since they may come from a VBO). If "ppbo"/"upbo", it will
+follow the "async" rules when a pack/unpack pixel buffer is bound
+otherwise it will follow the "sync" rules.
  marshal_fail - an expression that, if it evaluates true, causes glthread
 to switch back to the Mesa implementation and call it directly.  Used
 to disable glthread for GL compatibility interactions that we don't
 want to track state for.
 
 glx:
  rop - Opcode value for "render" commands
  sop - Opcode value for "single" commands
  vendorpriv - 

[Mesa-dev] [PATCH v4 3/4] egl: implement __DRIbackgroundCallableExtension.isThreadSafe

2017-05-21 Thread Gregory Hainaut
v2:
bump version

v3:
Add code comment
s/IsGlThread/IsThread/ (and variation)
Include X11/Xlibint.h protected by ifdef

Signed-off-by: Gregory Hainaut 
---
 src/egl/drivers/dri2/egl_dri2.c | 28 +++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 0be7132ac5..3295d472f4 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -48,20 +48,24 @@
 #include 
 #include "GL/mesa_glinterop.h"
 #include 
 #include 
 
 #ifdef HAVE_WAYLAND_PLATFORM
 #include "wayland-drm.h"
 #include "wayland-drm-client-protocol.h"
 #endif
 
+#ifdef HAVE_X11_PLATFORM
+#include "X11/Xlibint.h"
+#endif
+
 #include "egl_dri2.h"
 #include "loader/loader.h"
 #include "util/u_atomic.h"
 
 /* The kernel header drm_fourcc.h defines the DRM formats below.  We duplicate
  * some of the definitions here so that building Mesa won't bleeding-edge
  * kernel headers.
  */
 #ifndef DRM_FORMAT_R8
 #define DRM_FORMAT_R8fourcc_code('R', '8', ' ', ' ') /* [7:0] R */
@@ -85,24 +89,46 @@
 
 static void
 dri_set_background_context(void *loaderPrivate)
 {
_EGLContext *ctx = _eglGetCurrentContext();
_EGLThreadInfo *t = _eglGetCurrentThread();
 
_eglBindContextToThread(ctx, t);
 }
 
+static GLboolean
+dri_is_thread_safe(void *loaderPrivate)
+{
+#ifdef HAVE_X11_PLATFORM
+   struct dri2_egl_surface *dri2_surf = loaderPrivate;
+   _EGLDisplay *display =  dri2_surf->base.Resource.Display;
+   Display *xdpy = (Display*)display->PlatformDisplay;
+
+   /* Check Xlib is running in thread safe mode when running on EGL/X11-xlib
+* platform
+*
+* 'lock_fns' is the XLockDisplay function pointer of the X11 display 'dpy'.
+* It wll be NULL if XInitThreads wasn't called.
+*/
+   if (display->Platform == _EGL_PLATFORM_X11 && xdpy && !xdpy->lock_fns)
+  return false;
+#endif
+
+   return true;
+}
+
 const __DRIbackgroundCallableExtension background_callable_extension = {
-   .base = { __DRI_BACKGROUND_CALLABLE, 1 },
+   .base = { __DRI_BACKGROUND_CALLABLE, 2 },
 
.setBackgroundContext = dri_set_background_context,
+   .isThreadSafe = dri_is_thread_safe,
 };
 
 const __DRIuseInvalidateExtension use_invalidate = {
.base = { __DRI_USE_INVALIDATE, 1 }
 };
 
 static const EGLint dri2_to_egl_attribute_map[__DRI_ATTRIB_MAX] = {
[__DRI_ATTRIB_BUFFER_SIZE ]  = EGL_BUFFER_SIZE,
[__DRI_ATTRIB_LEVEL] = EGL_LEVEL,
[__DRI_ATTRIB_RED_SIZE]  = EGL_RED_SIZE,
-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH v4 0/4] Disable glthread if libX11 isn't thread-safe

2017-05-21 Thread Gregory Hainaut
Hello Mesa developers,

Following the discussion from
https://lists.freedesktop.org/archives/mesa-dev/2017-April/153137.html

A check was added to ensure that X11 display can be locked. It should be enough
to ensure thread safety between X11 and glthread.

I also did the check on DRI3 as I'm not 100% sure that it is really thread safe.



v2: based on Nicolai/Matt reviews
Add a check on DRI extension version
Use C comments :)

v3: based on Emil reviews
Split the initial first patch into 3 sub patches dri extension / glx / egl
Improve error message
Improve code readability
Just include libX11 on EGL protected by ifdef

v4: based on Eric feedback, I marked DRI3 as always thread safe

Thanks you for all the review comments.

Best regards,

Gregory Hainaut (4):
  dri: Extend __DRIbackgroundCallableExtensionRec to include a callback
that checks for thread safety
  glx: implement __DRIbackgroundCallableExtension.isThreadSafe
  egl: implement __DRIbackgroundCallableExtension.isThreadSafe
  glthread/gallium: require safe_glthread to start glthread

 include/GL/internal/dri_interface.h  | 11 +++
 src/egl/drivers/dri2/egl_dri2.c  | 28 +++-
 src/gallium/state_trackers/dri/dri_context.c | 21 +
 src/glx/dri2_glx.c   | 15 ++-
 src/glx/dri3_glx.c   | 12 +++-
 5 files changed, 80 insertions(+), 7 deletions(-)

-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH v6 0/3] asynchronous pbo transfer with glthread

2017-05-21 Thread Gregory Hainaut
Hello Mesa developers,

Please find a new version to handle invalid buffer handles.

Allow to handle this kind of case:
   genBuffer(&pbo);
   BindBuffer(pbo)
   DeleteBuffer(pbo);
   BindBuffer(rand_pbo)
   TexSubImage2D(user_memory_pointer); // Data transfer will be synchronous

There are various subtely to handle multi threaded shared context. In order to
keep the code sane, I've considered a buffer invalid when it is deleted by a
context even it is still bound to others contexts. It will force a synchronous
transfer which is always safe.

An example could be
   Ctx A: glGenBuffers(1, &pbo);
   Ctx A: glBindBuffer(PIXEL_UNPACK_BUFFER, pbo);
   Ctx B: glDeleteBuffers(1, &pbo);
   Ctx A: glTexSubImage2D(...); // will be synchronous, even though it
   _could_ be asynchronous (because the PBO that was generated first is
   still bound!)

V3: I mixed up the number so I jumped right away to v4...
V4: improve commments based on Nicolai feedback
V5: Properly delete element of the new hash (first patch)
v6: Rebase on latest master
Note: crash related to unsafe X call will be handled by
"Disable glthread if libX11 isn't thread-safe" series

Best regards,

Gregory Hainaut (3):
  mesa/glthread: track buffer creation/destruction
  mesa/glthread: add tracking of PBO binding
  mapi/glthread: generate asynchronous code for PBO transfer

 src/mapi/glapi/gen/ARB_direct_state_access.xml |  18 +--
 src/mapi/glapi/gen/ARB_robustness.xml  |   2 +-
 src/mapi/glapi/gen/gl_API.dtd  |  10 +-
 src/mapi/glapi/gen/gl_API.xml  |  32 +++---
 src/mapi/glapi/gen/gl_marshal.py   |  23 +++-
 src/mapi/glapi/gen/marshal_XML.py  |  21 +++-
 src/mesa/main/glthread.h   |  10 ++
 src/mesa/main/marshal.c| 149 -
 src/mesa/main/marshal.h|  24 
 src/mesa/main/mtypes.h |   5 +
 src/mesa/main/shared.c |  14 +++
 11 files changed, 269 insertions(+), 39 deletions(-)

-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH v6 2/3] mesa/glthread: add tracking of PBO binding

2017-05-21 Thread Gregory Hainaut
In gl core, buffer must be reserved first by CreateBuffers/GenBuffers
to be valid.

v4: update comments based on Nicolai review
Signed-off-by: Gregory Hainaut 
---
 src/mesa/main/marshal.c | 36 +---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/src/mesa/main/marshal.c b/src/mesa/main/marshal.c
index 4037b793ee..1167271607 100644
--- a/src/mesa/main/marshal.c
+++ b/src/mesa/main/marshal.c
@@ -312,21 +312,34 @@ _mesa_unmarshal_DeleteBuffers(struct gl_context *ctx,
 
 /* BindBufferBase: marshalled asynchronously */
 struct marshal_cmd_BindBufferBase
 {
struct marshal_cmd_base cmd_base;
GLenum target;
GLuint index;
GLuint buffer;
 };
 
-/** Tracks the current bindings for the vertex array and index array buffers.
+/**
+ * Check that buffer is a valid buffer handle
+ * Always return false for ID 0.
+ */
+static bool
+is_bufferobj(struct gl_context *ctx, GLuint buffer)
+{
+   if (buffer == 0)
+  return false;
+   else
+  return _mesa_HashLookup(ctx->Shared->ShadowBufferObjects, buffer) != 
NULL;
+}
+
+/** Tracks the current bindings of GL buffer targets
  *
  * This is part of what we need to enable glthread on compat-GL contexts that
  * happen to use VBOs, without also supporting the full tracking of VBO vs
  * user vertex array bindings per attribute on each vertex array for
  * determining what to upload at draw call time.
  *
  * Note that GL core makes it so that a buffer binding with an invalid handle
  * in the "buffer" parameter will throw an error, and then a
  * glVertexAttribPointer() that followsmight not end up pointing at a VBO.
  * However, in GL core the draw call would throw an error as well, so we don't
@@ -334,37 +347,54 @@ struct marshal_cmd_BindBufferBase
  * marshal user data for draw calls, and the unmarshal will just generate an
  * error or not as appropriate.
  *
  * For compatibility GL, we do need to accurately know whether the draw call
  * on the unmarshal side will dereference a user pointer or load data from a
  * VBO per vertex.  That would make it seem like we need to track whether a
  * "buffer" is valid, so that we can know when an error will be generated
  * instead of updating the binding.  However, compat GL has the ridiculous
  * feature that if you pass a bad name, it just gens a buffer object for you,
  * so we escape without having to know if things are valid or not.
+ *
+ * Pixel buffers are tracked to decide whether pixel transfer goes to a user
+ * pointer (must be synchronous) or a GL buffer (can be asynchronous). Unlike
+ * for VBOs, we do need accurate tracking, since user pointers can be used in
+ * GL core contexts.
  */
 static void
-track_vbo_binding(struct gl_context *ctx, GLenum target, GLuint buffer)
+track_buffers_binding(struct gl_context *ctx, GLenum target, GLuint buffer)
 {
struct glthread_state *glthread = ctx->GLThread;
 
switch (target) {
case GL_ARRAY_BUFFER:
   glthread->vertex_array_is_vbo = (buffer != 0);
   break;
case GL_ELEMENT_ARRAY_BUFFER:
   /* The current element array buffer binding is actually tracked in the
* vertex array object instead of the context, so this would need to
* change on vertex array object updates.
*/
   glthread->element_array_is_vbo = (buffer != 0);
   break;
+   case GL_PIXEL_UNPACK_BUFFER:
+  if (ctx->API == API_OPENGL_COMPAT || is_bufferobj(ctx, buffer))
+ glthread->pixel_unpack_buffer_bound = buffer;
+  else
+ glthread->pixel_unpack_buffer_bound = 0;
+  break;
+   case GL_PIXEL_PACK_BUFFER:
+  if (ctx->API == API_OPENGL_COMPAT || is_bufferobj(ctx, buffer))
+ glthread->pixel_pack_buffer_bound = buffer;
+  else
+ glthread->pixel_pack_buffer_bound = 0;
+  break;
}
 }
 
 
 struct marshal_cmd_BindBuffer
 {
struct marshal_cmd_base cmd_base;
GLenum target;
GLuint buffer;
 };
@@ -382,21 +412,21 @@ _mesa_unmarshal_BindBuffer(struct gl_context *ctx,
CALL_BindBuffer(ctx->CurrentServerDispatch, (target, buffer));
 }
 void GLAPIENTRY
 _mesa_marshal_BindBuffer(GLenum target, GLuint buffer)
 {
GET_CURRENT_CONTEXT(ctx);
size_t cmd_size = sizeof(struct marshal_cmd_BindBuffer);
struct marshal_cmd_BindBuffer *cmd;
debug_print_marshal("BindBuffer");
 
-   track_vbo_binding(ctx, target, buffer);
+   track_buffers_binding(ctx, target, buffer);
 
if (cmd_size <= MARSHAL_MAX_CMD_SIZE) {
   cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_BindBuffer,
 cmd_size);
   cmd->target = target;
   cmd->buffer = buffer;
   _mesa_post_marshal_hook(ctx);
} else {
   _mesa_glthread_finish(ctx);
   CALL_BindBuffer(ctx->CurrentServerDispatch, (target, buffer));
-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH v4 4/4] glthread/gallium: require safe_glthread to start glthread

2017-05-21 Thread Gregory Hainaut
Print an error message for the user if the requirement isn't met, or
we're not thread safe.

v2: based on Nicolai feedbacks
Check the DRI extension version
v3: based on Emil feedbacks
improve commit and error messages.
use backgroundCallable variable to improve readability

Signed-off-by: Gregory Hainaut 
---
 src/gallium/state_trackers/dri/dri_context.c | 21 +
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/src/gallium/state_trackers/dri/dri_context.c 
b/src/gallium/state_trackers/dri/dri_context.c
index 92d79849c4..8cbab5359f 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/dri_context.c
@@ -51,20 +51,22 @@ dri_create_context(gl_api api, const struct gl_config * 
visual,
 {
__DRIscreen *sPriv = cPriv->driScreenPriv;
struct dri_screen *screen = dri_screen(sPriv);
struct st_api *stapi = screen->st_api;
struct dri_context *ctx = NULL;
struct st_context_iface *st_share = NULL;
struct st_context_attribs attribs;
enum st_context_error ctx_err = 0;
unsigned allowed_flags = __DRI_CTX_FLAG_DEBUG |
 __DRI_CTX_FLAG_FORWARD_COMPATIBLE;
+   const __DRIbackgroundCallableExtension *backgroundCallable =
+  screen->sPriv->dri2.backgroundCallable;
 
if (screen->has_reset_status_query)
   allowed_flags |= __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS;
 
if (flags & ~allowed_flags) {
   *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
   goto fail;
}
 
if (!screen->has_reset_status_query && notify_reset) {
@@ -151,24 +153,35 @@ dri_create_context(gl_api api, const struct gl_config * 
visual,
ctx->st->st_manager_private = (void *) ctx;
ctx->stapi = stapi;
 
if (ctx->st->cso_context) {
   ctx->pp = pp_init(ctx->st->pipe, screen->pp_enabled, 
ctx->st->cso_context);
   ctx->hud = hud_create(ctx->st->pipe, ctx->st->cso_context);
}
 
/* Do this last. */
if (ctx->st->start_thread &&
-   /* the driver loader must implement this */
-   screen->sPriv->dri2.backgroundCallable &&
-   driQueryOptionb(&screen->optionCache, "mesa_glthread"))
-  ctx->st->start_thread(ctx->st);
+ driQueryOptionb(&screen->optionCache, "mesa_glthread")) {
+
+  if (backgroundCallable && backgroundCallable->base.version >= 2 &&
+driQueryOptionb(&screen->optionCache, "mesa_glthread")) {
+
+ if (backgroundCallable->isThreadSafe(cPriv->loaderPrivate))
+ctx->st->start_thread(ctx->st);
+ else
+fprintf(stderr, "dri_create_context: glthread isn't thread safe "
+  "- missing call XInitThreads\n");
+  } else {
+ fprintf(stderr, "dri_create_context: requested glthread but driver "
+   "is missing backgroundCallable V2 extension\n");
+  }
+   }
 
*error = __DRI_CTX_ERROR_SUCCESS;
return GL_TRUE;
 
  fail:
if (ctx && ctx->st)
   ctx->st->destroy(ctx->st);
 
free(ctx);
return GL_FALSE;
-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH v4 2/4] glx: implement __DRIbackgroundCallableExtension.isThreadSafe

2017-05-21 Thread Gregory Hainaut
v2:
bump version

v3:
Add code comment
s/IsGlThread/IsThread/ (and variation)

v4:
DRI3 doesn't hit X through GL call so it is always safe

Signed-off-by: Gregory Hainaut 
---
 src/glx/dri2_glx.c | 15 ++-
 src/glx/dri3_glx.c | 12 +++-
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 145f44d6e8..4f163688f2 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -946,20 +946,32 @@ dri2GetSwapInterval(__GLXDRIdrawable *pdraw)
   return priv->swap_interval;
 }
 
 static void
 driSetBackgroundContext(void *loaderPrivate)
 {
struct dri2_context *pcp = (struct dri2_context *) loaderPrivate;
__glXSetCurrentContext(&pcp->base);
 }
 
+static GLboolean
+driIsThreadSafe(void *loaderPrivate)
+{
+   struct dri2_context *pcp = (struct dri2_context *) loaderPrivate;
+   /* Check Xlib is running in thread safe mode
+*
+* 'lock_fns' is the XLockDisplay function pointer of the X11 display 'dpy'.
+* It wll be NULL if XInitThreads wasn't called.
+*/
+   return pcp->base.psc->dpy->lock_fns != NULL;
+}
+
 static const __DRIdri2LoaderExtension dri2LoaderExtension = {
.base = { __DRI_DRI2_LOADER, 3 },
 
.getBuffers  = dri2GetBuffers,
.flushFrontBuffer= dri2FlushFrontBuffer,
.getBuffersWithFormat= dri2GetBuffersWithFormat,
 };
 
 static const __DRIdri2LoaderExtension dri2LoaderExtension_old = {
.base = { __DRI_DRI2_LOADER, 3 },
@@ -967,23 +979,24 @@ static const __DRIdri2LoaderExtension 
dri2LoaderExtension_old = {
.getBuffers  = dri2GetBuffers,
.flushFrontBuffer= dri2FlushFrontBuffer,
.getBuffersWithFormat= NULL,
 };
 
 static const __DRIuseInvalidateExtension dri2UseInvalidate = {
.base = { __DRI_USE_INVALIDATE, 1 }
 };
 
 static const __DRIbackgroundCallableExtension driBackgroundCallable = {
-   .base = { __DRI_BACKGROUND_CALLABLE, 1 },
+   .base = { __DRI_BACKGROUND_CALLABLE, 2 },
 
.setBackgroundContext= driSetBackgroundContext,
+   .isThreadSafe= driIsThreadSafe,
 };
 
 _X_HIDDEN void
 dri2InvalidateBuffers(Display *dpy, XID drawable)
 {
__GLXDRIdrawable *pdraw =
   dri2GetGlxDrawableFromXDrawableId(dpy, drawable);
struct dri2_screen *psc;
struct dri2_drawable *pdp = (struct dri2_drawable *) pdraw;
 
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index e1dc5aa4a8..d07968e3c5 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -496,37 +496,47 @@ dri3_flush_front_buffer(__DRIdrawable *driDrawable, void 
*loaderPrivate)
loader_dri3_wait_gl(draw);
 }
 
 static void
 dri_set_background_context(void *loaderPrivate)
 {
struct dri3_context *pcp = (struct dri3_context *)loaderPrivate;
__glXSetCurrentContext(&pcp->base);
 }
 
+static GLboolean
+dri_is_thread_safe(void *loaderPrivate)
+{
+   /* Unlike DRI2, DRI3 doesn't call GetBuffers/GetBuffersWithFormat
+* during draw so we're safe here.
+*/
+   return true;
+}
+
 /* The image loader extension record for DRI3
  */
 static const __DRIimageLoaderExtension imageLoaderExtension = {
.base = { __DRI_IMAGE_LOADER, 1 },
 
.getBuffers  = loader_dri3_get_buffers,
.flushFrontBuffer= dri3_flush_front_buffer,
 };
 
 const __DRIuseInvalidateExtension dri3UseInvalidate = {
.base = { __DRI_USE_INVALIDATE, 1 }
 };
 
 static const __DRIbackgroundCallableExtension driBackgroundCallable = {
-   .base = { __DRI_BACKGROUND_CALLABLE, 1 },
+   .base = { __DRI_BACKGROUND_CALLABLE, 2 },
 
.setBackgroundContext = dri_set_background_context,
+   .isThreadSafe = dri_is_thread_safe,
 };
 
 static const __DRIextension *loader_extensions[] = {
&imageLoaderExtension.base,
&dri3UseInvalidate.base,
&driBackgroundCallable.base,
NULL
 };
 
 /** dri3_swap_buffers
-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH v4 1/4] dri: Extend __DRIbackgroundCallableExtensionRec to include a callback that checks for thread safety

2017-05-21 Thread Gregory Hainaut
DRI-drivers could call Xlib functions, for example to allocate a new back
buffer.

When glthread is enabled, the driver runs mostly on a separate thread.
Therefore we need to guarantee the thread safety between libX11 calls
from the applications (not aware of the extra thread) and the ones from
the driver.

See discussion thread:
   https://lists.freedesktop.org/archives/mesa-dev/2017-April/152547.html

Fortunately, Xlib allows to lock display to ensure thread safety but
XInitThreads must be called first by the application to initialize the lock
function pointer. This patch will allow to check XInitThreads was called
to allow glthread on GLX or EGL platform.

Note: a tentative was done to port libX11 code to XCB but it didn't solve fully
thread safety.
See discussion thread:
   https://lists.freedesktop.org/archives/mesa-dev/2017-April/153137.html

Note: Nvidia forces the driver to call XInitThreads. Quoting their manpage:
"The NVIDIA OpenGL driver will automatically attempt to enable Xlib
thread-safe mode if needed. However, it might not be possible in some
situations, such as when the NVIDIA OpenGL driver library is dynamically
loaded after Xlib has been loaded and initialized. If that is the case,
threaded optimizations will stay disabled unless the application is
modified to call XInitThreads() before initializing Xlib or to link
directly against the NVIDIA OpenGL driver library. Alternatively, using
the LD_PRELOAD environment variable to include the NVIDIA OpenGL driver
library should also achieve the desired result."

v2: based on Nicolai and Matt feedback
Use C style comment
v3: based on Emil feedback
split the patch in 3
s/isGlThreadSafe/isThreadSafe/

Signed-off-by: Gregory Hainaut 
---
 include/GL/internal/dri_interface.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/GL/internal/dri_interface.h 
b/include/GL/internal/dri_interface.h
index c83056aa70..8381f704e4 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1714,13 +1714,24 @@ struct __DRIbackgroundCallableExtensionRec {
 * non-background thread (i.e. a thread that has already been bound to a
 * context using __DRIcoreExtensionRec::bindContext()); when this happens,
 * the \c loaderPrivate pointer must be equal to the pointer that was
 * passed to the driver when the currently bound context was created.
 *
 * This call should execute quickly enough that the driver can call it with
 * impunity whenever a background thread starts performing drawing
 * operations (e.g. it should just set a thread-local variable).
 */
void (*setBackgroundContext)(void *loaderPrivate);
+
+   /**
+* Indicate that it is multithread safe to use glthread.  For GLX/EGL
+* platforms using Xlib, that involves calling XInitThreads, before
+* opening an X display.
+*
+* \param loaderPrivate is the value that was passed to to the driver when
+* the context was created.  This can be used by the loader to identify
+* which context any callbacks are associated with.
+*/
+   GLboolean (*isThreadSafe)(void *loaderPrivate);
 };
 
 #endif
-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH v5 1/4] dri: Extend __DRIbackgroundCallableExtensionRec to include a callback that checks for thread safety

2017-05-29 Thread Gregory Hainaut
DRI-drivers could call Xlib functions, for example to allocate a new back
buffer.

When glthread is enabled, the driver runs mostly on a separate thread.
Therefore we need to guarantee the thread safety between libX11 calls
from the applications (not aware of the extra thread) and the ones from
the driver.

See discussion thread:
   https://lists.freedesktop.org/archives/mesa-dev/2017-April/152547.html

Fortunately, Xlib allows to lock display to ensure thread safety but
XInitThreads must be called first by the application to initialize the lock
function pointer. This patch will allow to check XInitThreads was called
to allow glthread on GLX or EGL platform.

Note: a tentative was done to port libX11 code to XCB but it didn't solve fully
thread safety.
See discussion thread:
   https://lists.freedesktop.org/archives/mesa-dev/2017-April/153137.html

Note: Nvidia forces the driver to call XInitThreads. Quoting their manpage:
"The NVIDIA OpenGL driver will automatically attempt to enable Xlib
thread-safe mode if needed. However, it might not be possible in some
situations, such as when the NVIDIA OpenGL driver library is dynamically
loaded after Xlib has been loaded and initialized. If that is the case,
threaded optimizations will stay disabled unless the application is
modified to call XInitThreads() before initializing Xlib or to link
directly against the NVIDIA OpenGL driver library. Alternatively, using
the LD_PRELOAD environment variable to include the NVIDIA OpenGL driver
library should also achieve the desired result."

v2: based on Nicolai and Matt feedback
Use C style comment

v3: based on Emil feedback
split the patch in 3
s/isGlThreadSafe/isThreadSafe/

v5: based on Marek comment
Add a comment that isThreadSafe is supported by extension v2

Signed-off-by: Gregory Hainaut 
---
 include/GL/internal/dri_interface.h | 13 +
 1 file changed, 13 insertions(+)

diff --git a/include/GL/internal/dri_interface.h 
b/include/GL/internal/dri_interface.h
index c83056aa70..ffe99499fc 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1714,13 +1714,26 @@ struct __DRIbackgroundCallableExtensionRec {
 * non-background thread (i.e. a thread that has already been bound to a
 * context using __DRIcoreExtensionRec::bindContext()); when this happens,
 * the \c loaderPrivate pointer must be equal to the pointer that was
 * passed to the driver when the currently bound context was created.
 *
 * This call should execute quickly enough that the driver can call it with
 * impunity whenever a background thread starts performing drawing
 * operations (e.g. it should just set a thread-local variable).
 */
void (*setBackgroundContext)(void *loaderPrivate);
+
+   /**
+* Indicate that it is multithread safe to use glthread.  For GLX/EGL
+* platforms using Xlib, that involves calling XInitThreads, before
+* opening an X display.
+*
+* Note: only supported if extension version is at least 2.
+*
+* \param loaderPrivate is the value that was passed to to the driver when
+* the context was created.  This can be used by the loader to identify
+* which context any callbacks are associated with.
+*/
+   GLboolean (*isThreadSafe)(void *loaderPrivate);
 };
 
 #endif
-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH v5 2/4] glx: implement __DRIbackgroundCallableExtension.isThreadSafe

2017-05-29 Thread Gregory Hainaut
v2:
bump version

v3:
Add code comment
s/IsGlThread/IsThread/ (and variation)

v4:
DRI3 doesn't hit X through GL call so it is always safe

Signed-off-by: Gregory Hainaut 
---
 src/glx/dri2_glx.c | 15 ++-
 src/glx/dri3_glx.c | 12 +++-
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 145f44d6e8..4f163688f2 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -946,20 +946,32 @@ dri2GetSwapInterval(__GLXDRIdrawable *pdraw)
   return priv->swap_interval;
 }
 
 static void
 driSetBackgroundContext(void *loaderPrivate)
 {
struct dri2_context *pcp = (struct dri2_context *) loaderPrivate;
__glXSetCurrentContext(&pcp->base);
 }
 
+static GLboolean
+driIsThreadSafe(void *loaderPrivate)
+{
+   struct dri2_context *pcp = (struct dri2_context *) loaderPrivate;
+   /* Check Xlib is running in thread safe mode
+*
+* 'lock_fns' is the XLockDisplay function pointer of the X11 display 'dpy'.
+* It wll be NULL if XInitThreads wasn't called.
+*/
+   return pcp->base.psc->dpy->lock_fns != NULL;
+}
+
 static const __DRIdri2LoaderExtension dri2LoaderExtension = {
.base = { __DRI_DRI2_LOADER, 3 },
 
.getBuffers  = dri2GetBuffers,
.flushFrontBuffer= dri2FlushFrontBuffer,
.getBuffersWithFormat= dri2GetBuffersWithFormat,
 };
 
 static const __DRIdri2LoaderExtension dri2LoaderExtension_old = {
.base = { __DRI_DRI2_LOADER, 3 },
@@ -967,23 +979,24 @@ static const __DRIdri2LoaderExtension 
dri2LoaderExtension_old = {
.getBuffers  = dri2GetBuffers,
.flushFrontBuffer= dri2FlushFrontBuffer,
.getBuffersWithFormat= NULL,
 };
 
 static const __DRIuseInvalidateExtension dri2UseInvalidate = {
.base = { __DRI_USE_INVALIDATE, 1 }
 };
 
 static const __DRIbackgroundCallableExtension driBackgroundCallable = {
-   .base = { __DRI_BACKGROUND_CALLABLE, 1 },
+   .base = { __DRI_BACKGROUND_CALLABLE, 2 },
 
.setBackgroundContext= driSetBackgroundContext,
+   .isThreadSafe= driIsThreadSafe,
 };
 
 _X_HIDDEN void
 dri2InvalidateBuffers(Display *dpy, XID drawable)
 {
__GLXDRIdrawable *pdraw =
   dri2GetGlxDrawableFromXDrawableId(dpy, drawable);
struct dri2_screen *psc;
struct dri2_drawable *pdp = (struct dri2_drawable *) pdraw;
 
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index e1dc5aa4a8..d07968e3c5 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -496,37 +496,47 @@ dri3_flush_front_buffer(__DRIdrawable *driDrawable, void 
*loaderPrivate)
loader_dri3_wait_gl(draw);
 }
 
 static void
 dri_set_background_context(void *loaderPrivate)
 {
struct dri3_context *pcp = (struct dri3_context *)loaderPrivate;
__glXSetCurrentContext(&pcp->base);
 }
 
+static GLboolean
+dri_is_thread_safe(void *loaderPrivate)
+{
+   /* Unlike DRI2, DRI3 doesn't call GetBuffers/GetBuffersWithFormat
+* during draw so we're safe here.
+*/
+   return true;
+}
+
 /* The image loader extension record for DRI3
  */
 static const __DRIimageLoaderExtension imageLoaderExtension = {
.base = { __DRI_IMAGE_LOADER, 1 },
 
.getBuffers  = loader_dri3_get_buffers,
.flushFrontBuffer= dri3_flush_front_buffer,
 };
 
 const __DRIuseInvalidateExtension dri3UseInvalidate = {
.base = { __DRI_USE_INVALIDATE, 1 }
 };
 
 static const __DRIbackgroundCallableExtension driBackgroundCallable = {
-   .base = { __DRI_BACKGROUND_CALLABLE, 1 },
+   .base = { __DRI_BACKGROUND_CALLABLE, 2 },
 
.setBackgroundContext = dri_set_background_context,
+   .isThreadSafe = dri_is_thread_safe,
 };
 
 static const __DRIextension *loader_extensions[] = {
&imageLoaderExtension.base,
&dri3UseInvalidate.base,
&driBackgroundCallable.base,
NULL
 };
 
 /** dri3_swap_buffers
-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH v5 4/4] glthread/gallium: require safe_glthread to start glthread

2017-05-29 Thread Gregory Hainaut
Print an error message for the user if the requirement isn't met, or
we're not thread safe.

v2: based on Nicolai feedbacks
Check the DRI extension version

v3: based on Emil feedbacks
improve commit and error messages.
use backgroundCallable variable to improve readability

v5: based on Emil feedbacks
Properly check the function pointer

Signed-off-by: Gregory Hainaut 
---
 src/gallium/state_trackers/dri/dri_context.c | 21 +
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/src/gallium/state_trackers/dri/dri_context.c 
b/src/gallium/state_trackers/dri/dri_context.c
index 92d79849c4..ec555e44d7 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/dri_context.c
@@ -51,20 +51,22 @@ dri_create_context(gl_api api, const struct gl_config * 
visual,
 {
__DRIscreen *sPriv = cPriv->driScreenPriv;
struct dri_screen *screen = dri_screen(sPriv);
struct st_api *stapi = screen->st_api;
struct dri_context *ctx = NULL;
struct st_context_iface *st_share = NULL;
struct st_context_attribs attribs;
enum st_context_error ctx_err = 0;
unsigned allowed_flags = __DRI_CTX_FLAG_DEBUG |
 __DRI_CTX_FLAG_FORWARD_COMPATIBLE;
+   const __DRIbackgroundCallableExtension *backgroundCallable =
+  screen->sPriv->dri2.backgroundCallable;
 
if (screen->has_reset_status_query)
   allowed_flags |= __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS;
 
if (flags & ~allowed_flags) {
   *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
   goto fail;
}
 
if (!screen->has_reset_status_query && notify_reset) {
@@ -151,24 +153,35 @@ dri_create_context(gl_api api, const struct gl_config * 
visual,
ctx->st->st_manager_private = (void *) ctx;
ctx->stapi = stapi;
 
if (ctx->st->cso_context) {
   ctx->pp = pp_init(ctx->st->pipe, screen->pp_enabled, 
ctx->st->cso_context);
   ctx->hud = hud_create(ctx->st->pipe, ctx->st->cso_context);
}
 
/* Do this last. */
if (ctx->st->start_thread &&
-   /* the driver loader must implement this */
-   screen->sPriv->dri2.backgroundCallable &&
-   driQueryOptionb(&screen->optionCache, "mesa_glthread"))
-  ctx->st->start_thread(ctx->st);
+ driQueryOptionb(&screen->optionCache, "mesa_glthread")) {
+
+  if (backgroundCallable && backgroundCallable->base.version >= 2 &&
+backgroundCallable->isThreadSafe) {
+
+ if (backgroundCallable->isThreadSafe(cPriv->loaderPrivate))
+ctx->st->start_thread(ctx->st);
+ else
+fprintf(stderr, "dri_create_context: glthread isn't thread safe "
+  "- missing call XInitThreads\n");
+  } else {
+ fprintf(stderr, "dri_create_context: requested glthread but driver "
+   "is missing backgroundCallable V2 extension\n");
+  }
+   }
 
*error = __DRI_CTX_ERROR_SUCCESS;
return GL_TRUE;
 
  fail:
if (ctx && ctx->st)
   ctx->st->destroy(ctx->st);
 
free(ctx);
return GL_FALSE;
-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH v5 3/4] egl: implement __DRIbackgroundCallableExtension.isThreadSafe

2017-05-29 Thread Gregory Hainaut
v2:
bump version

v3:
Add code comment
s/IsGlThread/IsThread/ (and variation)
Include X11/Xlibint.h protected by ifdef

v5: based on Daniel feedback
Move non X11 code outside of X11 define
Always return true for Wayland

Signed-off-by: Gregory Hainaut 
---
 src/egl/drivers/dri2/egl_dri2.c | 34 +-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 0be7132ac5..8891771e3f 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -48,20 +48,24 @@
 #include 
 #include "GL/mesa_glinterop.h"
 #include 
 #include 
 
 #ifdef HAVE_WAYLAND_PLATFORM
 #include "wayland-drm.h"
 #include "wayland-drm-client-protocol.h"
 #endif
 
+#ifdef HAVE_X11_PLATFORM
+#include "X11/Xlibint.h"
+#endif
+
 #include "egl_dri2.h"
 #include "loader/loader.h"
 #include "util/u_atomic.h"
 
 /* The kernel header drm_fourcc.h defines the DRM formats below.  We duplicate
  * some of the definitions here so that building Mesa won't bleeding-edge
  * kernel headers.
  */
 #ifndef DRM_FORMAT_R8
 #define DRM_FORMAT_R8fourcc_code('R', '8', ' ', ' ') /* [7:0] R */
@@ -85,24 +89,52 @@
 
 static void
 dri_set_background_context(void *loaderPrivate)
 {
_EGLContext *ctx = _eglGetCurrentContext();
_EGLThreadInfo *t = _eglGetCurrentThread();
 
_eglBindContextToThread(ctx, t);
 }
 
+static GLboolean
+dri_is_thread_safe(void *loaderPrivate)
+{
+   struct dri2_egl_surface *dri2_surf = loaderPrivate;
+   _EGLDisplay *display =  dri2_surf->base.Resource.Display;
+
+#ifdef HAVE_X11_PLATFORM
+   Display *xdpy = (Display*)display->PlatformDisplay;
+
+   /* Check Xlib is running in thread safe mode when running on EGL/X11-xlib
+* platform
+*
+* 'lock_fns' is the XLockDisplay function pointer of the X11 display 'dpy'.
+* It wll be NULL if XInitThreads wasn't called.
+*/
+   if (display->Platform == _EGL_PLATFORM_X11 && xdpy && !xdpy->lock_fns)
+  return false;
+#endif
+
+#ifdef HAVE_WAYLAND_PLATFORM
+   if (display->Platform == _EGL_PLATFORM_WAYLAND)
+  return true;
+#endif
+
+   return true;
+}
+
 const __DRIbackgroundCallableExtension background_callable_extension = {
-   .base = { __DRI_BACKGROUND_CALLABLE, 1 },
+   .base = { __DRI_BACKGROUND_CALLABLE, 2 },
 
.setBackgroundContext = dri_set_background_context,
+   .isThreadSafe = dri_is_thread_safe,
 };
 
 const __DRIuseInvalidateExtension use_invalidate = {
.base = { __DRI_USE_INVALIDATE, 1 }
 };
 
 static const EGLint dri2_to_egl_attribute_map[__DRI_ATTRIB_MAX] = {
[__DRI_ATTRIB_BUFFER_SIZE ]  = EGL_BUFFER_SIZE,
[__DRI_ATTRIB_LEVEL] = EGL_LEVEL,
[__DRI_ATTRIB_RED_SIZE]  = EGL_RED_SIZE,
-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH v5 0/4] Disable glthread if libX11 isn't thread-safe

2017-05-29 Thread Gregory Hainaut
Hello Mesa developers,

Following the discussion from
https://lists.freedesktop.org/archives/mesa-dev/2017-April/153137.html

A check was added to ensure that X11 display can be locked. It should be enough
to ensure thread safety between X11 and glthread.

I also did the check on DRI3 as I'm not 100% sure that it is really thread safe.



v2: based on Nicolai/Matt reviews
Add a check on DRI extension version
Use C comments :)

v3: based on Emil reviews
Split the initial first patch into 3 sub patches dri extension / glx / egl
Improve error message
Improve code readability
Just include libX11 on EGL protected by ifdef

v4: based on Eric feedback, I marked DRI3 as always thread safe

v5: Fix the null pointer check on patch 4. I added Daniel comment on
patch 3 but I'm not sure I got it right.

Thanks you for all the review comments.

Best regards,


Gregory Hainaut (4):
  dri: Extend __DRIbackgroundCallableExtensionRec to include a callback
that checks for thread safety
  glx: implement __DRIbackgroundCallableExtension.isThreadSafe
  egl: implement __DRIbackgroundCallableExtension.isThreadSafe
  glthread/gallium: require safe_glthread to start glthread

 include/GL/internal/dri_interface.h  | 13 +++
 src/egl/drivers/dri2/egl_dri2.c  | 34 +++-
 src/gallium/state_trackers/dri/dri_context.c | 21 +
 src/glx/dri2_glx.c   | 15 +++-
 src/glx/dri3_glx.c   | 12 +-
 5 files changed, 88 insertions(+), 7 deletions(-)

-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH v5 0/4] Disable glthread if libX11 isn't thread-safe

2017-05-30 Thread gregory hainaut
On Mon, 29 May 2017 17:12:05 +0100
Emil Velikov  wrote:

> On 29 May 2017 at 15:45, Dieter Nützel  wrote:
> > Hi Gregory,
> >
> > there isn't currently a copy of this on Mesa-Patchwork.
> > Can you please send one over there?
> >
> > And maybe an updated version of:
> > [PATCH v5 0/3] asynchronous pbo transfer with glthread
> >
> > Would be awesome.
> >

Isn't Mesa-Patchwork a bot that parse the mail from the mailing list ? Reading 
Mesa doc,
there is only a note that "patches must be marked superseeded manually"
  
> The series is in master now, so it should be a bit easier ;-)
> 
> Gregory, thanks again for the work. Please keep an eye open for
> reports. it's highly unlikely but still.
> 
> -Emil

Thanks you for the review and the push :)
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH v8 0/3] asynchronous pbo transfer with glthread

2017-07-25 Thread Gregory Hainaut
Hello Mesa developers,

> Please find a new version to handle invalid buffer handles.
>
> Allow to handle this kind of case:
>genBuffer(&pbo);
>BindBuffer(pbo)
>DeleteBuffer(pbo);
>BindBuffer(rand_pbo)
>TexSubImage2D(user_memory_pointer); // Data transfer will be synchronous
>
> There are various subtely to handle multi threaded shared context. In order to
> keep the code sane, I've considered a buffer invalid when it is deleted by a
> context even it is still bound to others contexts. It will force a synchronous
> transfer which is always safe.
>
> An example could be
>Ctx A: glGenBuffers(1, &pbo);
>Ctx A: glBindBuffer(PIXEL_UNPACK_BUFFER, pbo);
>Ctx B: glDeleteBuffers(1, &pbo);
>Ctx A: glTexSubImage2D(...); // will be synchronous, even though it
>_could_ be asynchronous (because the PBO that was generated first is
>still bound!)

V3: I mixed up the number so I jumped right away to v4...
V4: improve commments based on Nicolai feedback
V5: Properly delete element of the new hash (first patch)
v6: Rebase on latest master
v7: Fredrik's suggestion (remove shadow hash table
and rename pixel_*pack_buffer_bound variables)
I rebased the code on latest master, it got extra conflict (gl_marshal.py) since
the resent from Timothy
v8: rebase on latest master

Best regards,

Gregory Hainaut (3):
  mesa/glthread: track buffer destruction
  mesa/glthread: add tracking of PBO binding
  mapi/glthread: generate asynchronous code for PBO transfer

 src/mapi/glapi/gen/ARB_direct_state_access.xml | 16 +++---
 src/mapi/glapi/gen/ARB_robustness.xml  |  2 +-
 src/mapi/glapi/gen/gl_API.dtd  | 10 ++--
 src/mapi/glapi/gen/gl_API.xml  | 30 +-
 src/mapi/glapi/gen/gl_marshal.py   | 24 +++-
 src/mapi/glapi/gen/marshal_XML.py  | 21 +--
 src/mesa/main/glthread.h   | 10 
 src/mesa/main/marshal.c| 76 +-
 src/mesa/main/marshal.h|  8 +++
 9 files changed, 159 insertions(+), 38 deletions(-)

-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH v8 1/3] mesa/glthread: track buffer destruction

2017-07-25 Thread Gregory Hainaut
It would be used in following commits to allow asynchronous PBO transfer.

The tracking saves the buffer name into a hash. Saving pointer
will be more complex as the buffer is created in BindBuffer due to IsBuffer
insanity.

Perf wise DeleteBuffers is now synchronous for robustness.

v5: properly delete hash element with the help of _mesa_HashDeleteAll

v6: rebase

v7: rebase
s/GLint pixel_pack_buffer_bound/GLuint bound_pixel_pack_buffer/
Drop the ShadowBufferObjects hash. Synchronous creation/destruction
gives us enough guarantee to lookup the BufferObjects hash directly.
Drop custom code for GenBuffers/CreateBuffers

v8: rebase
Signed-off-by: Gregory Hainaut 
---
 src/mapi/glapi/gen/gl_API.xml |  2 +-
 src/mesa/main/glthread.h  | 10 ++
 src/mesa/main/marshal.c   | 40 
 src/mesa/main/marshal.h   |  8 
 4 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index 18839ec70c..4b01ca552f 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -5055,21 +5055,21 @@
 
 
 
 
 
 
 
 
 
-
+
 
 
 
 
 
 
 
 
 
 
diff --git a/src/mesa/main/glthread.h b/src/mesa/main/glthread.h
index 306246ca1c..e5c8b79a97 100644
--- a/src/mesa/main/glthread.h
+++ b/src/mesa/main/glthread.h
@@ -88,20 +88,30 @@ struct glthread_state
 * Tracks on the main thread side whether the current vertex array binding
 * is in a VBO.
 */
bool vertex_array_is_vbo;
 
/**
 * Tracks on the main thread side whether the current element array (index
 * buffer) binding is in a VBO.
 */
bool element_array_is_vbo;
+
+   /**
+* Tracks on the main thread side the bound unpack pixel buffer
+*/
+   GLuint bound_pixel_unpack_buffer;
+
+   /**
+* Tracks on the main thread side the bound pack pixel buffer
+*/
+   GLuint bound_pixel_pack_buffer;
 };
 
 void _mesa_glthread_init(struct gl_context *ctx);
 void _mesa_glthread_destroy(struct gl_context *ctx);
 
 void _mesa_glthread_restore_dispatch(struct gl_context *ctx);
 void _mesa_glthread_flush_batch(struct gl_context *ctx);
 void _mesa_glthread_finish(struct gl_context *ctx);
 
 #endif /* _GLTHREAD_H*/
diff --git a/src/mesa/main/marshal.c b/src/mesa/main/marshal.c
index 8f8e8c78ed..1914b5 100644
--- a/src/mesa/main/marshal.c
+++ b/src/mesa/main/marshal.c
@@ -25,20 +25,21 @@
  *
  * Custom functions for marshalling GL calls from the main thread to a worker
  * thread when automatic code generation isn't appropriate.
  */
 
 #include "main/enums.h"
 #include "main/macros.h"
 #include "marshal.h"
 #include "dispatch.h"
 #include "marshal_generated.h"
+#include "hash.h"
 
 struct marshal_cmd_Flush
 {
struct marshal_cmd_base cmd_base;
 };
 
 
 void
 _mesa_unmarshal_Flush(struct gl_context *ctx,
   const struct marshal_cmd_Flush *cmd)
@@ -188,20 +189,59 @@ _mesa_marshal_ShaderSource(GLuint shader, GLsizei count,
   _mesa_post_marshal_hook(ctx);
} else {
   _mesa_glthread_finish(ctx);
   CALL_ShaderSource(ctx->CurrentServerDispatch,
 (shader, count, string, length_tmp));
}
free(length_tmp);
 }
 
 
+static void track_buffers_destruction(struct gl_context *ctx,
+  GLsizei n, const GLuint * buffers)
+{
+   GLsizei i;
+   struct glthread_state *glthread = ctx->GLThread;
+
+   if (n < 0 || !buffers)
+  return;
+
+   for (i = 0; i < n ; i++) {
+  if (buffers[i] == glthread->bound_pixel_pack_buffer)
+ glthread->bound_pixel_pack_buffer = 0;
+
+  if (buffers[i] == glthread->bound_pixel_unpack_buffer)
+ glthread->bound_pixel_unpack_buffer = 0;
+   }
+}
+
+/* DeleteBuffers: custom marshal to track buffers destruction */
+void GLAPIENTRY
+_mesa_marshal_DeleteBuffers(GLsizei n, const GLuint * buffer)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_glthread_finish(ctx);
+   debug_print_sync("DeleteBuffers");
+
+   // It is done before CALL_DeleteBuffers to avoid any ABA multithread issue.
+   track_buffers_destruction(ctx, n, buffer);
+
+   CALL_DeleteBuffers(ctx->CurrentServerDispatch, (n, buffer));
+}
+
+void
+_mesa_unmarshal_DeleteBuffers(struct gl_context *ctx,
+   const struct marshal_cmd_DeleteBuffers *cmd)
+{
+   assert(0);
+}
+
 /* BindBufferBase: marshalled asynchronously */
 struct marshal_cmd_BindBufferBase
 {
struct marshal_cmd_base cmd_base;
GLenum target;
GLuint index;
GLuint buffer;
 };
 
 /** Tracks the current bindings for the vertex array and index array buffers.
diff --git a/src/mesa/main/marshal.h b/src/mesa/main/marshal.h
index 63e0295576..e7f681213c 100644
--- a/src/mesa/main/marshal.h
+++ b/src/mesa/main/marshal.h
@@ -180,20 +180,2

[Mesa-dev] [PATCH v8 3/3] mapi/glthread: generate asynchronous code for PBO transfer

2017-07-25 Thread Gregory Hainaut
Improve speed on PCSX2

v2:
Add ppbo/ubpo status in XML file
Disable variable parameter (as the pointer would be a fixed offset)

v3:
split buffer tracking into separate patches.
use 'goto fallback_to_sync' when asynchronous transfer isn't supported

v4:
add Nicolai comment to explain why ppbo isn't impacted by the variable_params
issue

v7:
rebase (update const handling)
s/GLint pixel_pack_buffer_bound/GLuint bound_pixel_pack_buffer/

Signed-off-by: Gregory Hainaut 
---
 src/mapi/glapi/gen/ARB_direct_state_access.xml | 16 +++
 src/mapi/glapi/gen/ARB_robustness.xml  |  2 +-
 src/mapi/glapi/gen/gl_API.dtd  | 10 +
 src/mapi/glapi/gen/gl_API.xml  | 28 +-
 src/mapi/glapi/gen/gl_marshal.py   | 24 --
 src/mapi/glapi/gen/marshal_XML.py  | 21 ++-
 6 files changed, 67 insertions(+), 34 deletions(-)

diff --git a/src/mapi/glapi/gen/ARB_direct_state_access.xml 
b/src/mapi/glapi/gen/ARB_direct_state_access.xml
index 0c34b63854..c555727682 100644
--- a/src/mapi/glapi/gen/ARB_direct_state_access.xml
+++ b/src/mapi/glapi/gen/ARB_direct_state_access.xml
@@ -367,79 +367,79 @@

   
   
   
   
   
   
   

 
-   
+   
   
   
   
   
   
   
   

 
-   
+   
   
   
   
   
   
   
   
   
   

 
-   
+   
   
   
   
   
   
   
   
   
   
   
   

 
-   
+   
   
   
   
   
   
   
   

 
-   
+   
   
   
   
   
   
   
   
   
   

 
-   
+   
   
   
   
   
   
   
   
   
   
   
@@ -516,30 +516,30 @@
 

   

 

   
   

 
-   
+   
   
   
   
   
   
   

 
-   
+   
   
   
   
   

 

   
   
   
diff --git a/src/mapi/glapi/gen/ARB_robustness.xml 
b/src/mapi/glapi/gen/ARB_robustness.xml
index 9b2f2f0a74..6e1ac09ce0 100644
--- a/src/mapi/glapi/gen/ARB_robustness.xml
+++ b/src/mapi/glapi/gen/ARB_robustness.xml
@@ -75,21 +75,21 @@
 
 
 
 
 
 
 
 
 
 
-
+
 
 
 
 
 
 
 
 
 
 
diff --git a/src/mapi/glapi/gen/gl_API.dtd b/src/mapi/glapi/gen/gl_API.dtd
index b464250777..447b03a41d 100644
--- a/src/mapi/glapi/gen/gl_API.dtd
+++ b/src/mapi/glapi/gen/gl_API.dtd
@@ -115,28 +115,30 @@ param:
  img_send_null - boolean flag to determine if blank pixel data should
 be sent when a NULL pointer is passed.  This is only used by
 TexImage1D and TexImage2D.
  img_null_flag - boolean flag to determine if an extra flag is used to
 determine if a NULL pixel pointer was passed.  This is used by
 TexSubImage1D, TexSubImage2D, TexImage3D and others.
  img_pad_dimensions - boolean flag to determine if dimension data and
 offset data should be padded to the next even number of dimensions.
 For example, this will insert an empty "height" field after the
 "width" field in the protocol for TexImage1D.
- marshal - One of "sync", "async", "draw", or "custom", defaulting to
-async unless one of the arguments is something we know we can't
-codegen for.  If "sync", we finish any queued glthread work and call
+ marshal - One of "sync", "async", "draw", "ppbo", "upbo" or "custom",
+defaulting to async unless one of the arguments is something we know we
+can't codegen for.  If "sync", we finish any queued glthread work and 
call
 the Mesa implementation directly.  If "async", we queue the function
 call to be performed by glthread.  If "custom", the prototype will be
 generated but a custom implementation will be present in marshal.c.
 If "draw", it will follow the "async" rules except that "indices" are
-ignored (since they may come from a VBO).
+ignored (since they may come from a VBO). If "ppbo"/"upbo", it will
+follow the "async" rules when a pack/unpack pixel buffer is bound
+otherwise it will follow the "sync" rules.
  marshal_fail - an expression that, if it evaluates true, causes glthread
 to switch back to the Mesa implementation and call it directly.  Used
 to disable glthread for GL compatibility interactions that we don't
 want to track state for.
 
 glx:
  rop - Opcode value for "render" commands
  sop - Opcode value for "single&qu

[Mesa-dev] [PATCH v8 2/3] mesa/glthread: add tracking of PBO binding

2017-07-25 Thread Gregory Hainaut
In gl core, buffer must be reserved first by CreateBuffers/GenBuffers
to be valid.

v4: update comments based on Nicolai review

v7:
s/GLint pixel_pack_buffer_bound/GLuint bound_pixel_pack_buffer/
Drop the ShadowBufferObjects hash. Synchronous creation/destruction
gives us enough guarantee to lookup the BufferObjects hash directly.

Signed-off-by: Gregory Hainaut 
---
 src/mesa/main/marshal.c | 36 +---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/src/mesa/main/marshal.c b/src/mesa/main/marshal.c
index 1914b5..285a46457d 100644
--- a/src/mesa/main/marshal.c
+++ b/src/mesa/main/marshal.c
@@ -237,21 +237,34 @@ _mesa_unmarshal_DeleteBuffers(struct gl_context *ctx,
 
 /* BindBufferBase: marshalled asynchronously */
 struct marshal_cmd_BindBufferBase
 {
struct marshal_cmd_base cmd_base;
GLenum target;
GLuint index;
GLuint buffer;
 };
 
-/** Tracks the current bindings for the vertex array and index array buffers.
+/**
+ * Check that buffer is a valid buffer handle
+ * Always return false for ID 0.
+ */
+static bool
+is_bufferobj(struct gl_context *ctx, GLuint buffer)
+{
+   if (buffer == 0)
+  return false;
+   else
+  return _mesa_HashLookup(ctx->Shared->BufferObjects, buffer) != NULL;
+}
+
+/** Tracks the current bindings of GL buffer targets
  *
  * This is part of what we need to enable glthread on compat-GL contexts that
  * happen to use VBOs, without also supporting the full tracking of VBO vs
  * user vertex array bindings per attribute on each vertex array for
  * determining what to upload at draw call time.
  *
  * Note that GL core makes it so that a buffer binding with an invalid handle
  * in the "buffer" parameter will throw an error, and then a
  * glVertexAttribPointer() that followsmight not end up pointing at a VBO.
  * However, in GL core the draw call would throw an error as well, so we don't
@@ -259,37 +272,54 @@ struct marshal_cmd_BindBufferBase
  * marshal user data for draw calls, and the unmarshal will just generate an
  * error or not as appropriate.
  *
  * For compatibility GL, we do need to accurately know whether the draw call
  * on the unmarshal side will dereference a user pointer or load data from a
  * VBO per vertex.  That would make it seem like we need to track whether a
  * "buffer" is valid, so that we can know when an error will be generated
  * instead of updating the binding.  However, compat GL has the ridiculous
  * feature that if you pass a bad name, it just gens a buffer object for you,
  * so we escape without having to know if things are valid or not.
+ *
+ * Pixel buffers are tracked to decide whether pixel transfer goes to a user
+ * pointer (must be synchronous) or a GL buffer (can be asynchronous). Unlike
+ * for VBOs, we do need accurate tracking, since user pointers can be used in
+ * GL core contexts.
  */
 static void
-track_vbo_binding(struct gl_context *ctx, GLenum target, GLuint buffer)
+track_buffers_binding(struct gl_context *ctx, GLenum target, GLuint buffer)
 {
struct glthread_state *glthread = ctx->GLThread;
 
switch (target) {
case GL_ARRAY_BUFFER:
   glthread->vertex_array_is_vbo = (buffer != 0);
   break;
case GL_ELEMENT_ARRAY_BUFFER:
   /* The current element array buffer binding is actually tracked in the
* vertex array object instead of the context, so this would need to
* change on vertex array object updates.
*/
   glthread->element_array_is_vbo = (buffer != 0);
   break;
+   case GL_PIXEL_UNPACK_BUFFER:
+  if (ctx->API == API_OPENGL_COMPAT || is_bufferobj(ctx, buffer))
+ glthread->bound_pixel_unpack_buffer = buffer;
+  else
+ glthread->bound_pixel_unpack_buffer = 0;
+  break;
+   case GL_PIXEL_PACK_BUFFER:
+  if (ctx->API == API_OPENGL_COMPAT || is_bufferobj(ctx, buffer))
+ glthread->bound_pixel_pack_buffer = buffer;
+  else
+ glthread->bound_pixel_pack_buffer = 0;
+  break;
}
 }
 
 
 struct marshal_cmd_BindBuffer
 {
struct marshal_cmd_base cmd_base;
GLenum target;
GLuint buffer;
 };
@@ -307,21 +337,21 @@ _mesa_unmarshal_BindBuffer(struct gl_context *ctx,
CALL_BindBuffer(ctx->CurrentServerDispatch, (target, buffer));
 }
 void GLAPIENTRY
 _mesa_marshal_BindBuffer(GLenum target, GLuint buffer)
 {
GET_CURRENT_CONTEXT(ctx);
size_t cmd_size = sizeof(struct marshal_cmd_BindBuffer);
struct marshal_cmd_BindBuffer *cmd;
debug_print_marshal("BindBuffer");
 
-   track_vbo_binding(ctx, target, buffer);
+   track_buffers_binding(ctx, target, buffer);
 
if (cmd_size <= MARSHAL_MAX_CMD_SIZE) {
   cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_BindBuffer,
 cmd_size);
   cmd->target = target;
   cmd->buffer = buffer;
   _mesa_post_marshal_hook(ctx);
} else {
   _mesa_

Re: [Mesa-dev] [PATCH v5 0/3] asynchronous pbo transfer with glthread

2017-04-25 Thread Gregory Hainaut
Hello,

I did more tests on my side. DRI3 + recent stack is fine. Older
(Debian Jessie, ~2y old) XCB hangs/deadlock. So all DRI3 drivers
should be fine (typically AMD). And all applications that called
XInitThread soon enough. So yeah I think we can merge it. Note: I
don't have commit access.

Nouveau doesn't use DRI3 by default. So I'm looking to use XCB for
dri2GetBuffer* operations. I copied the code from EGL/X11. So far it
isn't a success. The dri2_drawable pdraw object is correctly populated
with good value but I have tons of piglit failure. Debug is on-going
but I'm afraid that it might not be possible to use XCB.

Best Regads,
Gregory


On 4/25/17, Dieter Nützel  wrote:
> Am 21.04.2017 12:11, schrieb Marek Olšák:
>> FWIW, I think this series can land, because glthread is not enabled by
>> default, and the libX11 issue is unrelated.
>>
>> Marek
>
>
> Gregory?
>
> For the series:
>
> Tested-by: Dieter Nützel 
>
> On Turks XT (6670).
>
> Dieter
>
>> On Apr 21, 2017 4:22 AM, "Michel Dänzer"  wrote:
>>
>>> On 21/04/17 09:01 AM, Marek Olšák wrote:
>>>> On Thu, Apr 20, 2017 at 9:44 PM, gregory hainaut
>>>>  wrote:
>>>>> On Thu, 20 Apr 2017 20:01:00 +0200
>>>>> Marek Olšák  wrote:
>>>>>
>>>>>> On Thu, Apr 20, 2017 at 6:53 PM, gregory hainaut
>>>>>>  wrote:
>>>>>>> On Thu, 20 Apr 2017 11:57:08 +0200
>>>>>>> Marek Olšák  wrote:
>>>>>>>
>>>>>>>> On Thu, Apr 20, 2017 at 10:28 AM, gregory hainaut
>>>>>>>>  wrote:
>>>>>>>>> On Thu, 20 Apr 2017 12:29:11 +0900
>>>>>>>>> Michel Dänzer  wrote:
>>>>>>>>>
>>>>>>>>>> On 20/04/17 01:54 AM, Gregory Hainaut wrote:
>>>>>>>>>>> Hello,
>>>>>>>>>>>
>>>>>>>>>>> Please find the latest version that include a small fix for
>>> hash deletion. I
>>>>>>>>>>> think the series is good now. Please review/ack it.
>>>>>>>>>>
>>>>>>>>>> I'm afraid I have to NACK it. As discussed in the v4 cover
>>> letter
>>>>>>>>>> thread, Mesa's glthread cannot make any libX11 API calls.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Hello Michel,
>>>>>>>>>
>>>>>>>>> Just to be sure we are on the same line, let's me do a
>>> summary.
>>>>>>>>>
>>>>>>>>> PCSX2 does the following bad pattern
>>>>>>>>> 1/ no call to XInitThread
>>>>>>>>> 2/ XGetGeometry to get the size of the surface
>>>>>>>>> 3/ glDrawArray into the default framebuffer 0 (the window,
>>> I'm not sure how to call it)
>>>>>>>>> => which seem to call DRI2GetBuffersWithFormat under the
>>> hood. I guess to get the
>>>>>>>>> associated buffer of the window.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> So far it was (kind of) working fine because PCSX2 does tons
>>> of PBO transfer. So glthread
>>>>>>>>> was mostly synchronous.
>>>>>>>>>
>>>>>>>>> This series removes the (useless) PBO transfer
>>> synchronization. So now glthread is really
>>>>>>>>> asynchronous and the above bad pattern crash as expected.
>>>>>>>>>
>>>>>>>>> I didn't add any libX11 API call on the patches. And I don't
>>> think we can remvove the DRI stuff.
>>>>>>>>>
>>>>>>>>> Hum, I don't know what will be the impact on the perf but
>>> potentially we can force a synchronization
>>>>>>>>> when there is a draw to framebuffer 0.
>>>>>>>>
>>>>>>>> Can you send us the backtrace when DRI2GetBuffersWithFormat is
>>> called
>>>>>>>> by glDrawArrays?
>>>>>>>>
>>>>>>>> Marek
>>>>>>>
>>>>>>> Hello Marek, Michel,
>>>>>>>
>>>>>>> Here the full backtra

[Mesa-dev] [RFC 0/1] Port dri2GetBuffersWithFormat/dri2GetBuffers to XCB

2017-04-26 Thread Gregory Hainaut
Following the discussion in "[PATCH v4 0/3] asynchronous pbo transfer with 
glthread"

It will help apps that are ported to XCB. But Xlib (without XInitThread) apps
will still crash when glthread is enabled on DRI2.

I only tested the patch on Nouveau

There are 3 remaining possibilities
* Won't fix. DRI3/XCB is the future
* Enable thread safe Xlib by default (which would make sense in multicore CPU 
era)
* Track gl call that will use X11 API to force a sync

Note: I don't know if xcb_dri2_get_buffers_buffers can return a NULL
so I added a check in doubt.

Best Regards,

Gregory Hainaut (1):
  glx: port dri2GetBuffers/dri2GetBuffersWithFormat to XCB

 src/glx/dri2.c | 118 -
 src/glx/dri2.h |  25 
 src/glx/dri2_glx.c |  64 +
 3 files changed, 47 insertions(+), 160 deletions(-)

-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 1/1] glx: port dri2GetBuffers/dri2GetBuffersWithFormat to XCB

2017-04-26 Thread Gregory Hainaut
By default Xlib isn't thread safe so we better avoid it when gl thread
is enabled.

It will help applications that use XCB. But it will still crash if
applications are still relying on Xlib (without XInitThread).

Note: those dri2* functions are typically called by gallium/mesa state
tracker to handle new backbuffer allocation. When the old backbuffer was
previously invalidated due to vsync.

Signed-off-by: Gregory Hainaut 
---
 src/glx/dri2.c | 118 -
 src/glx/dri2.h |  25 
 src/glx/dri2_glx.c |  64 +
 3 files changed, 47 insertions(+), 160 deletions(-)

diff --git a/src/glx/dri2.c b/src/glx/dri2.c
index f00b96525a..eed899e237 100644
--- a/src/glx/dri2.c
+++ b/src/glx/dri2.c
@@ -391,138 +391,20 @@ DRI2DestroyDrawable(Display * dpy, XID drawable)
 
LockDisplay(dpy);
GetReq(DRI2DestroyDrawable, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2DestroyDrawable;
req->drawable = drawable;
UnlockDisplay(dpy);
SyncHandle();
 }
 
-DRI2Buffer *
-DRI2GetBuffers(Display * dpy, XID drawable,
-   int *width, int *height,
-   unsigned int *attachments, int count, int *outCount)
-{
-   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
-   xDRI2GetBuffersReply rep;
-   xDRI2GetBuffersReq *req;
-   DRI2Buffer *buffers;
-   xDRI2Buffer repBuffer;
-   CARD32 *p;
-   int i;
-
-   XextCheckExtension(dpy, info, dri2ExtensionName, False);
-
-   LockDisplay(dpy);
-   GetReqExtra(DRI2GetBuffers, count * 4, req);
-   req->reqType = info->codes->major_opcode;
-   req->dri2ReqType = X_DRI2GetBuffers;
-   req->drawable = drawable;
-   req->count = count;
-   p = (CARD32 *) & req[1];
-   for (i = 0; i < count; i++)
-  p[i] = attachments[i];
-
-   if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
-  UnlockDisplay(dpy);
-  SyncHandle();
-  return NULL;
-   }
-
-   *width = rep.width;
-   *height = rep.height;
-   *outCount = rep.count;
-
-   buffers = malloc(rep.count * sizeof buffers[0]);
-   if (buffers == NULL) {
-  _XEatData(dpy, rep.count * sizeof repBuffer);
-  UnlockDisplay(dpy);
-  SyncHandle();
-  return NULL;
-   }
-
-   for (i = 0; i < rep.count; i++) {
-  _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
-  buffers[i].attachment = repBuffer.attachment;
-  buffers[i].name = repBuffer.name;
-  buffers[i].pitch = repBuffer.pitch;
-  buffers[i].cpp = repBuffer.cpp;
-  buffers[i].flags = repBuffer.flags;
-   }
-
-   UnlockDisplay(dpy);
-   SyncHandle();
-
-   return buffers;
-}
-
-
-DRI2Buffer *
-DRI2GetBuffersWithFormat(Display * dpy, XID drawable,
- int *width, int *height,
- unsigned int *attachments, int count, int *outCount)
-{
-   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
-   xDRI2GetBuffersReply rep;
-   xDRI2GetBuffersReq *req;
-   DRI2Buffer *buffers;
-   xDRI2Buffer repBuffer;
-   CARD32 *p;
-   int i;
-
-   XextCheckExtension(dpy, info, dri2ExtensionName, False);
-
-   LockDisplay(dpy);
-   GetReqExtra(DRI2GetBuffers, count * (4 * 2), req);
-   req->reqType = info->codes->major_opcode;
-   req->dri2ReqType = X_DRI2GetBuffersWithFormat;
-   req->drawable = drawable;
-   req->count = count;
-   p = (CARD32 *) & req[1];
-   for (i = 0; i < (count * 2); i++)
-  p[i] = attachments[i];
-
-   if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
-  UnlockDisplay(dpy);
-  SyncHandle();
-  return NULL;
-   }
-
-   *width = rep.width;
-   *height = rep.height;
-   *outCount = rep.count;
-
-   buffers = malloc(rep.count * sizeof buffers[0]);
-   if (buffers == NULL) {
-  _XEatData(dpy, rep.count * sizeof repBuffer);
-  UnlockDisplay(dpy);
-  SyncHandle();
-  return NULL;
-   }
-
-   for (i = 0; i < rep.count; i++) {
-  _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
-  buffers[i].attachment = repBuffer.attachment;
-  buffers[i].name = repBuffer.name;
-  buffers[i].pitch = repBuffer.pitch;
-  buffers[i].cpp = repBuffer.cpp;
-  buffers[i].flags = repBuffer.flags;
-   }
-
-   UnlockDisplay(dpy);
-   SyncHandle();
-
-   return buffers;
-}
-
-
 void
 DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region,
CARD32 dest, CARD32 src)
 {
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2CopyRegionReq *req;
xDRI2CopyRegionReply rep;
 
XextSimpleCheckExtension(dpy, info, dri2ExtensionName);
 
diff --git a/src/glx/dri2.h b/src/glx/dri2.h
index 4be5bf8eb8..c383e27123 100644
--- a/src/glx/dri2.h
+++ b/src/glx/dri2.h
@@ -30,29 +30,20 @@
  *   Kristian Høgsberg (k...@redhat.com)
  */
 
 #ifndef _DRI2_H_
 #define _DRI2_H_
 
 #include 
 #include 
 #include 
 
-typedef struct
-{
-   unsigned int attachment;
-   unsigned int name;
-   unsigned int pitch;
-   unsigned int cpp;
-  

Re: [Mesa-dev] [PATCH v5 0/3] asynchronous pbo transfer with glthread

2017-04-26 Thread gregory hainaut
On Wed, 26 Apr 2017 11:03:11 +0900
Michel Dänzer  wrote:

> On 25/04/17 06:14 PM, Gregory Hainaut wrote:
> > Hello,
> > 
> > I did more tests on my side. DRI3 + recent stack is fine. Older
> > (Debian Jessie, ~2y old) XCB hangs/deadlock. So all DRI3 drivers
> > should be fine (typically AMD). And all applications that called
> > XInitThread soon enough. So yeah I think we can merge it. Note: I
> > don't have commit access.  
> 
> Okay, I'm not blocking somebody else from pushing the series.
> 
> 
> > Nouveau doesn't use DRI3 by default. So I'm looking to use XCB for
> > dri2GetBuffer* operations. I copied the code from EGL/X11. So far it
> > isn't a success. The dri2_drawable pdraw object is correctly populated
> > with good value but I have tons of piglit failure. Debug is on-going
> > but I'm afraid that it might not be possible to use XCB.  
> 
> Can you share the patch you're testing?
> 
> 

Hello Michel,

I found my issue, I forgot to set the *width, *height pointer. Piglit status is 
good.

You can found the patch here 
https://lists.freedesktop.org/archives/mesa-dev/2017-April/153137.html

Cheers,
Gregory
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [RFC 0/1] Port dri2GetBuffersWithFormat/dri2GetBuffers to XCB

2017-04-26 Thread Gregory Hainaut
On 4/26/17, Michel Dänzer  wrote:
> On 26/04/17 05:07 PM, Gregory Hainaut wrote:
>> Following the discussion in "[PATCH v4 0/3] asynchronous pbo transfer with
>> glthread"
>>
>> It will help apps that are ported to XCB.
>
> How so?

I didn't test it (yet). But I think it is safe to call XCB from
various threads. However if one thread use XLIB, you're screwed (to
access the same display).

>
>> But Xlib (without XInitThread) apps will still crash when glthread is
>> enabled on DRI2.
>
> Do the crashes provide information about where glthread is still calling
> libX11 APIs?
I far from an expert so maybe I misunderstand some stuffs. So, as far
as I understand XLIB and XCB are mixed together. They likely share the
same queues.

Let's say you have an app that does Xlib operations on display (for
example XGetGeometry). As XInitThread wasn't called, you're in YOLO
mode.

glthread (gallium->DRI2) will do operation (GetBuffer) on the same
display through an XCB connection but it is still the same display.
XCB might lock it properly but Xlib call is lock-free.

What happen in my case is that XCB reply was corrupted (count was huge
which lead to memory bad access). My guess was that Xlib calls from
app were the culprit. I will test my XCB version of my app + this
patch. Hopefully, it would be crash free.

>> I only tested the patch on Nouveau
>>
>> There are 3 remaining possibilities
>> * Won't fix. DRI3/XCB is the future
>> * Enable thread safe Xlib by default (which would make sense in multicore
>> CPU era)
>> * Track gl call that will use X11 API to force a sync
>
> Until either of the latter two happens, glthread should only be enabled
> with DRI3.
On one hand, I don't like crash neither but in other hand, it would be
nice to keep glthread for application that call XInitThread properly.
At least, glthread isn't enabled by default.

>
> --
> Earthling Michel Dänzer   |   http://www.amd.com
> Libre software enthusiast | Mesa and X developer
>
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [RFC 1/1] glx: port dri2GetBuffers/dri2GetBuffersWithFormat to XCB

2017-04-26 Thread Gregory Hainaut
On 4/26/17, Michel Dänzer  wrote:
> On 26/04/17 05:07 PM, Gregory Hainaut wrote:
>>
>> Note: those dri2* functions are typically called by gallium/mesa state
>> tracker to handle new backbuffer allocation. When the old backbuffer was
>> previously invalidated due to vsync.
>
> FWIW, DRI2 buffer invalidation isn't directly related to vsync.
Ok.

What happen is that I received DRI2_InvalidateBuffers event instead of
DRI2_BufferSwapComplete when I enabled vsync on my application.

Cheers,
Gregory
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [RFC 0/1] Port dri2GetBuffersWithFormat/dri2GetBuffers to XCB

2017-04-28 Thread gregory hainaut
On Thu, 27 Apr 2017 17:11:30 +0900
Michel Dänzer  wrote:

> On 26/04/17 07:06 PM, Gregory Hainaut wrote:
> > On 4/26/17, Michel Dänzer  wrote:  
>  [...]  
>  [...]  
>  [...]  
> > 
> > I didn't test it (yet). But I think it is safe to call XCB from
> > various threads. However if one thread use XLIB, you're screwed (to
> > access the same display).
> >   
>  [...]  
>  [...]  
>  [...]  
> > I far from an expert so maybe I misunderstand some stuffs. So, as far
> > as I understand XLIB and XCB are mixed together. They likely share the
> > same queues.
> > 
> > Let's say you have an app that does Xlib operations on display (for
> > example XGetGeometry). As XInitThread wasn't called, you're in YOLO
> > mode.
> > 
> > glthread (gallium->DRI2) will do operation (GetBuffer) on the same
> > display through an XCB connection but it is still the same display.
> > XCB might lock it properly but Xlib call is lock-free.  
> 
> I was hoping the lower XCB layer could be used in a thread-safe way even
> if the higher libX11 layer isn't. But maybe that's just wishful thinking.

Hello Michel,

Yeah me too. Besides libX11 relies on (the thread-safe) XCB too.
 
> > What happen in my case is that XCB reply was corrupted (count was huge
> > which lead to memory bad access). My guess was that Xlib calls from
> > app were the culprit.  
> 
> It would be nice to get some certainty, e.g. via the valgrind
> helgrind/drd tools.
So I tried drd. Unfortunately I'm afraid that my testcase (PCSX2) is way 
too complex for this kind of tool.

However, I always got a huge value on the reply->count in GetBuffer. I
investigated it further. Reply->count was 94373760 which can be read
as 1440,1920 so my surface resolution. I think it is enough to prove that
xcb_dri2_get_buffers_with_format_reply is stealing the reply of XGetGeometry.

Note my 2nd kind of crash is XIOError due to a null reply on XGetGeometry.
which make sense based on the above behavior.

FWIW, the crash seem to be gone with this patch + my PCSX2-XCB patches.

However, I need to check DRI3 behavior when I resize the window. As you said
it could trigger buffer invalidation too.
 
> 
>  [...]  
>  [...]  
> > On one hand, I don't like crash neither but in other hand, it would be
> > nice to keep glthread for application that call XInitThread properly.  
> 
> We could check dpy->lock_fns and only enable glthread with DRI2 if it's
> non-NULL. If it's NULL and the environment variable mesa_glthread=true
> is set, we could print a warning to stderr explaining that glthread
> can't be enabled because the application didn't call XInitThreads.
> 
It is good idea. I will check, if I can manage to implement such a check.

Cheers,
Gregory
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 0/2] Disable glthread is libX11 isn't thread-safe

2017-04-28 Thread Gregory Hainaut
Hello,

Following the discussion from
https://lists.freedesktop.org/archives/mesa-dev/2017-April/153137.html

A check was added to ensure that X11 display can be locked. It should be enough
to ensure thread safety between X11 and glthread.

I also did the check on DRI3 as I'm not 100% sure that it is really thread safe.

EGL case is more tricky so the pair (X11/libX11) is marked as unsafe.
I think it is fine because modern EGL application should rely on XCB (on the X11
platform).

Best regards,
Gregory Hainaut (2):
  glx|egl: allow to test if glthread is safe enough on X11 platform
  glthread/gallium: require safe_glthread to start glthread

 include/GL/internal/dri_interface.h  |  9 +
 src/egl/drivers/dri2/egl_dri2.c  | 30 
 src/gallium/state_trackers/dri/dri_context.c | 10 --
 src/glx/dri2_glx.c   |  9 +
 src/glx/dri3_glx.c   |  8 
 5 files changed, 64 insertions(+), 2 deletions(-)

-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 1/2] glx|egl: allow to test if glthread is safe enough on X11 platform

2017-04-28 Thread Gregory Hainaut
I extended the struct __DRIbackgroundCallableExtensionRec because
the other function pointer is already related for glthread.

DRI2/DRI3 glx code path check that display can be locked (basically
XInitThread was called)

EGL code path is more tricky as we don't want to pull X11 header. Instead
the code will assume that it is safe if X11 isn't used or there is no display
(i.e. 100% XCB)

The new function will be used in the next commit

Signed-off-by: Gregory Hainaut 
---
 include/GL/internal/dri_interface.h |  9 +
 src/egl/drivers/dri2/egl_dri2.c | 30 ++
 src/glx/dri2_glx.c  |  9 +
 src/glx/dri3_glx.c  |  8 
 4 files changed, 56 insertions(+)

diff --git a/include/GL/internal/dri_interface.h 
b/include/GL/internal/dri_interface.h
index 86efd1bdc9..28a52ccdb9 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1713,13 +1713,22 @@ struct __DRIbackgroundCallableExtensionRec {
 * non-background thread (i.e. a thread that has already been bound to a
 * context using __DRIcoreExtensionRec::bindContext()); when this happens,
 * the \c loaderPrivate pointer must be equal to the pointer that was
 * passed to the driver when the currently bound context was created.
 *
 * This call should execute quickly enough that the driver can call it with
 * impunity whenever a background thread starts performing drawing
 * operations (e.g. it should just set a thread-local variable).
 */
void (*setBackgroundContext)(void *loaderPrivate);
+   /**
+* Indicate that it is multithread safe to use glthread. Typically
+* XInitThread was called in GLX setup.
+*
+* \param loaderPrivate is the value that was passed to to the driver when
+* the context was created.  This can be used by the loader to identify
+* which context any callbacks are associated with.
+*/
+   GLboolean (*isGlThreadSafe)(void *loaderPrivate);
 };
 
 #endif
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 2cab7d00c1..df2db97bcf 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -85,24 +85,54 @@
 
 static void
 dri_set_background_context(void *loaderPrivate)
 {
_EGLContext *ctx = _eglGetCurrentContext();
_EGLThreadInfo *t = _eglGetCurrentThread();
 
_eglBindContextToThread(ctx, t);
 }
 
+static GLboolean
+dri_is_glthread_safe(void *loaderPrivate)
+{
+#ifdef HAVE_X11_PLATFORM
+   struct dri2_egl_surface *dri2_surf = loaderPrivate;
+   _EGLDisplay *display =  dri2_surf->base.Resource.Display;
+   Display *dpy;
+
+   // Only the libX11 isn't safe
+   if (display->Platform != _EGL_PLATFORM_X11)
+  return true;
+
+   // Will use pure XCB so no libX11 here either
+   if (display->PlatformDisplay == NULL)
+  return true;
+
+   // In an ideal world we would check the X11 lock pointer
+   // (display->PlatformDisplay->lock_fns). Unfortunately it
+   // requires to know the full type. And we don't want to bring X11
+   // headers here.
+   //
+   // So let's assume an unsafe behavior. Modern EGL code shouldn't use
+   // libX11 anyway.
+   return false;
+#else
+   return true;
+#endif
+}
+
 const __DRIbackgroundCallableExtension background_callable_extension = {
.base = { __DRI_BACKGROUND_CALLABLE, 1 },
 
.setBackgroundContext = dri_set_background_context,
+   .isGlThreadSafe   = dri_is_glthread_safe,
 };
 
 const __DRIuseInvalidateExtension use_invalidate = {
.base = { __DRI_USE_INVALIDATE, 1 }
 };
 
 EGLint dri2_to_egl_attribute_map[] = {
0,
EGL_BUFFER_SIZE,/* __DRI_ATTRIB_BUFFER_SIZE */
EGL_LEVEL,/* __DRI_ATTRIB_LEVEL */
diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 145f44d6e8..8f4d2f027f 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -946,20 +946,28 @@ dri2GetSwapInterval(__GLXDRIdrawable *pdraw)
   return priv->swap_interval;
 }
 
 static void
 driSetBackgroundContext(void *loaderPrivate)
 {
struct dri2_context *pcp = (struct dri2_context *) loaderPrivate;
__glXSetCurrentContext(&pcp->base);
 }
 
+static GLboolean
+driIsGlThreadSafe(void *loaderPrivate)
+{
+   struct dri2_context *pcp = (struct dri2_context *) loaderPrivate;
+   return pcp->base.psc->dpy->lock_fns != NULL;
+}
+
+
 static const __DRIdri2LoaderExtension dri2LoaderExtension = {
.base = { __DRI_DRI2_LOADER, 3 },
 
.getBuffers  = dri2GetBuffers,
.flushFrontBuffer= dri2FlushFrontBuffer,
.getBuffersWithFormat= dri2GetBuffersWithFormat,
 };
 
 static const __DRIdri2LoaderExtension dri2LoaderExtension_old = {
.base = { __DRI_DRI2_LOADER, 3 },
@@ -970,20 +978,21 @@ static const __DRIdri2LoaderExtension 
dri2LoaderExtension_old = {
 };
 
 static const __DRIuseInvalidateExtension dri2UseInvalidate

[Mesa-dev] [RFC 2/2] glthread/gallium: require safe_glthread to start glthread

2017-04-28 Thread Gregory Hainaut
Otherwise print a warning

Signed-off-by: Gregory Hainaut 
---
 src/gallium/state_trackers/dri/dri_context.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/gallium/state_trackers/dri/dri_context.c 
b/src/gallium/state_trackers/dri/dri_context.c
index 92d79849c4..35b0c454be 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/dri_context.c
@@ -153,22 +153,28 @@ dri_create_context(gl_api api, const struct gl_config * 
visual,
 
if (ctx->st->cso_context) {
   ctx->pp = pp_init(ctx->st->pipe, screen->pp_enabled, 
ctx->st->cso_context);
   ctx->hud = hud_create(ctx->st->pipe, ctx->st->cso_context);
}
 
/* Do this last. */
if (ctx->st->start_thread &&
/* the driver loader must implement this */
screen->sPriv->dri2.backgroundCallable &&
-   driQueryOptionb(&screen->optionCache, "mesa_glthread"))
-  ctx->st->start_thread(ctx->st);
+   driQueryOptionb(&screen->optionCache, "mesa_glthread")) {
+
+  if 
(ctx->sPriv->dri2.backgroundCallable->isGlThreadSafe(cPriv->loaderPrivate))
+ ctx->st->start_thread(ctx->st);
+  else
+ fprintf(stderr, "MESA warning: glthread can't be enabled because "
+   "the application didn't call XInitThreads\n");
+   }
 
*error = __DRI_CTX_ERROR_SUCCESS;
return GL_TRUE;
 
  fail:
if (ctx && ctx->st)
   ctx->st->destroy(ctx->st);
 
free(ctx);
return GL_FALSE;
-- 
2.11.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


  1   2   >