Re: [Mesa-dev] [PATCH 06/24] mesa: implement SPIR-V loading in glShaderBinary

2017-11-28 Thread Eduardo Lima

On 11/27/2017 11:34 PM, Ian Romanick wrote:

On 11/15/2017 05:22 AM, Eduardo Lima Mitev wrote:

From: Nicolai Hähnle 

v2: Add a gl_shader_spirv_data member to gl_shader, which already
encapsulates a gl_spirv_module where the binary will be saved.
(Eduardo Lima)
---
  src/mesa/main/glspirv.c   | 52 +++
  src/mesa/main/glspirv.h   |  5 +
  src/mesa/main/mtypes.h|  4 
  src/mesa/main/shaderapi.c | 41 ++---
  src/mesa/main/shaderobj.c |  2 ++
  5 files changed, 101 insertions(+), 3 deletions(-)

diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
index d4724ad245c..390fa9e6984 100644
--- a/src/mesa/main/glspirv.c
+++ b/src/mesa/main/glspirv.c
@@ -23,6 +23,8 @@
  
  #include "glspirv.h"
  
+#include "errors.h"

+
  #include "util/u_atomic.h"
  
  void

@@ -61,6 +63,56 @@ _mesa_shader_spirv_data_reference(struct 
gl_shader_spirv_data **dest,
p_atomic_inc(&src->RefCount);
  }
  
+void

+_mesa_spirv_shader_binary(struct gl_context *ctx,
+  GLint n, struct gl_shader **shaders,
+  const void* binary, GLint length)

Since _mesa_ShaderBinary will already check length < 0, make length
size_t.  You can also make n be unsigned or plain int.


True, I will fix that.


+{
+   struct gl_spirv_module *module;
+   struct gl_shader_spirv_data *spirv_data;
+
+   if (!ctx->Extensions.ARB_gl_spirv) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderBinary(SPIR-V)");
+  return;
+   }

I think this error should get moved to _mesa_ShaderBinary with the rest
of the API error checks.


Ok.


+
+   if (n <= 0)
+  return;

_mesa_ShaderBinary already checks n < 0.  Maybe just elide the call to
_mesa_spirv_shader_binary if n == 0?


Ok.


+
+   assert(length >= 0);
+
+   module = malloc(sizeof(*module) + (size_t)length);
+   if (!module) {
+  _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderBinary");
+  return;
+   }
+
+   p_atomic_set(&module->RefCount, 0);
+   module->Length = length;
+   memcpy(&module->Binary[0], binary, length);
+
+   for (int i = 0; i < n; ++i) {
+  struct gl_shader *sh = shaders[i];
+
+  spirv_data = rzalloc(NULL, struct gl_shader_spirv_data);
+  _mesa_shader_spirv_data_reference(&sh->spirv_data, spirv_data);
+  _mesa_spirv_module_reference(&spirv_data->SpirVModule, module);
+
+  sh->SpirVBinary = GL_TRUE;

It didn't occur to me while reviewing the earlier patch, but if
SpirVBinary is never visible to the API, we should use bool, true, and
false instead of the GL types.


I agree with this change, but per Timothy's comments, I have locally 
removed the SpirVBinary flag altogether to use nullness of spriv_data 
instead.

So it doesn't apply anymore.


+  sh->CompileStatus = compile_failure;
+
+  free((void *)sh->Source);
+  sh->Source = NULL;
+  free((void *)sh->FallbackSource);
+  sh->FallbackSource = NULL;
+
+  ralloc_free(sh->ir);
+  sh->ir = NULL;
+  ralloc_free(sh->symbols);
+  sh->symbols = NULL;
+   }
+}
+
  void GLAPIENTRY
  _mesa_SpecializeShaderARB(GLuint shader,
const GLchar *pEntryPoint,
diff --git a/src/mesa/main/glspirv.h b/src/mesa/main/glspirv.h
index b8a0125ea9f..5ffaa230629 100644
--- a/src/mesa/main/glspirv.h
+++ b/src/mesa/main/glspirv.h
@@ -71,6 +71,11 @@ void
  _mesa_shader_spirv_data_reference(struct gl_shader_spirv_data **dest,
struct gl_shader_spirv_data *src);
  
+void

+_mesa_spirv_shader_binary(struct gl_context *ctx,
+  GLint n, struct gl_shader **shaders,
+  const void* binary, GLint length);
+
  /**
   * \name API functions
   */
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index cfc763f043e..f19477eb027 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -88,6 +88,7 @@ struct st_context;
  struct gl_uniform_storage;
  struct prog_instruction;
  struct gl_program_parameter_list;
+struct gl_shader_spirv_data;
  struct set;
  struct set_entry;
  struct vbo_context;
@@ -2637,6 +2638,9 @@ struct gl_shader
 GLuint TransformFeedbackBufferStride[MAX_FEEDBACK_BUFFERS];
  
 struct gl_shader_info info;

+
+   /* ARB_gl_spirv related data */
+   struct gl_shader_spirv_data *spirv_data;
  };
  
  
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c

index 9090bee9fb0..240d9fe6cbc 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -42,6 +42,7 @@
  #include "main/context.h"
  #include "main/dispatch.h"
  #include "main/enums.h"
+#include "main/glspirv.h"
  #include "main/hash.h"
  #include "main/mtypes.h"
  #include "main/pipelineobj.h"
@@ -1054,6 +1055,17 @@ set_shader_source(struct gl_shader *sh, const GLchar 
*source)
  {
 assert(sh);
  
+   /* The GL_ARB_gl_spirv spec adds the following to the end of the description

+* of ShaderSource:
+*
+*   "If  was previo

Re: [Mesa-dev] [PATCH 06/24] mesa: implement SPIR-V loading in glShaderBinary

2017-11-27 Thread Ian Romanick
On 11/15/2017 05:22 AM, Eduardo Lima Mitev wrote:
> From: Nicolai Hähnle 
> 
> v2: Add a gl_shader_spirv_data member to gl_shader, which already
>encapsulates a gl_spirv_module where the binary will be saved.
>(Eduardo Lima)
> ---
>  src/mesa/main/glspirv.c   | 52 
> +++
>  src/mesa/main/glspirv.h   |  5 +
>  src/mesa/main/mtypes.h|  4 
>  src/mesa/main/shaderapi.c | 41 ++---
>  src/mesa/main/shaderobj.c |  2 ++
>  5 files changed, 101 insertions(+), 3 deletions(-)
> 
> diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
> index d4724ad245c..390fa9e6984 100644
> --- a/src/mesa/main/glspirv.c
> +++ b/src/mesa/main/glspirv.c
> @@ -23,6 +23,8 @@
>  
>  #include "glspirv.h"
>  
> +#include "errors.h"
> +
>  #include "util/u_atomic.h"
>  
>  void
> @@ -61,6 +63,56 @@ _mesa_shader_spirv_data_reference(struct 
> gl_shader_spirv_data **dest,
>p_atomic_inc(&src->RefCount);
>  }
>  
> +void
> +_mesa_spirv_shader_binary(struct gl_context *ctx,
> +  GLint n, struct gl_shader **shaders,
> +  const void* binary, GLint length)

Since _mesa_ShaderBinary will already check length < 0, make length
size_t.  You can also make n be unsigned or plain int.

> +{
> +   struct gl_spirv_module *module;
> +   struct gl_shader_spirv_data *spirv_data;
> +
> +   if (!ctx->Extensions.ARB_gl_spirv) {
> +  _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderBinary(SPIR-V)");
> +  return;
> +   }

I think this error should get moved to _mesa_ShaderBinary with the rest
of the API error checks.

> +
> +   if (n <= 0)
> +  return;

_mesa_ShaderBinary already checks n < 0.  Maybe just elide the call to
_mesa_spirv_shader_binary if n == 0?

> +
> +   assert(length >= 0);
> +
> +   module = malloc(sizeof(*module) + (size_t)length);
> +   if (!module) {
> +  _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderBinary");
> +  return;
> +   }
> +
> +   p_atomic_set(&module->RefCount, 0);
> +   module->Length = length;
> +   memcpy(&module->Binary[0], binary, length);
> +
> +   for (int i = 0; i < n; ++i) {
> +  struct gl_shader *sh = shaders[i];
> +
> +  spirv_data = rzalloc(NULL, struct gl_shader_spirv_data);
> +  _mesa_shader_spirv_data_reference(&sh->spirv_data, spirv_data);
> +  _mesa_spirv_module_reference(&spirv_data->SpirVModule, module);
> +
> +  sh->SpirVBinary = GL_TRUE;

It didn't occur to me while reviewing the earlier patch, but if
SpirVBinary is never visible to the API, we should use bool, true, and
false instead of the GL types.

> +  sh->CompileStatus = compile_failure;
> +
> +  free((void *)sh->Source);
> +  sh->Source = NULL;
> +  free((void *)sh->FallbackSource);
> +  sh->FallbackSource = NULL;
> +
> +  ralloc_free(sh->ir);
> +  sh->ir = NULL;
> +  ralloc_free(sh->symbols);
> +  sh->symbols = NULL;
> +   }
> +}
> +
>  void GLAPIENTRY
>  _mesa_SpecializeShaderARB(GLuint shader,
>const GLchar *pEntryPoint,
> diff --git a/src/mesa/main/glspirv.h b/src/mesa/main/glspirv.h
> index b8a0125ea9f..5ffaa230629 100644
> --- a/src/mesa/main/glspirv.h
> +++ b/src/mesa/main/glspirv.h
> @@ -71,6 +71,11 @@ void
>  _mesa_shader_spirv_data_reference(struct gl_shader_spirv_data **dest,
>struct gl_shader_spirv_data *src);
>  
> +void
> +_mesa_spirv_shader_binary(struct gl_context *ctx,
> +  GLint n, struct gl_shader **shaders,
> +  const void* binary, GLint length);
> +
>  /**
>   * \name API functions
>   */
> diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
> index cfc763f043e..f19477eb027 100644
> --- a/src/mesa/main/mtypes.h
> +++ b/src/mesa/main/mtypes.h
> @@ -88,6 +88,7 @@ struct st_context;
>  struct gl_uniform_storage;
>  struct prog_instruction;
>  struct gl_program_parameter_list;
> +struct gl_shader_spirv_data;
>  struct set;
>  struct set_entry;
>  struct vbo_context;
> @@ -2637,6 +2638,9 @@ struct gl_shader
> GLuint TransformFeedbackBufferStride[MAX_FEEDBACK_BUFFERS];
>  
> struct gl_shader_info info;
> +
> +   /* ARB_gl_spirv related data */
> +   struct gl_shader_spirv_data *spirv_data;
>  };
>  
>  
> diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
> index 9090bee9fb0..240d9fe6cbc 100644
> --- a/src/mesa/main/shaderapi.c
> +++ b/src/mesa/main/shaderapi.c
> @@ -42,6 +42,7 @@
>  #include "main/context.h"
>  #include "main/dispatch.h"
>  #include "main/enums.h"
> +#include "main/glspirv.h"
>  #include "main/hash.h"
>  #include "main/mtypes.h"
>  #include "main/pipelineobj.h"
> @@ -1054,6 +1055,17 @@ set_shader_source(struct gl_shader *sh, const GLchar 
> *source)
>  {
> assert(sh);
>  
> +   /* The GL_ARB_gl_spirv spec adds the following to the end of the 
> description
> +* of ShaderSource:
> +*
> +*   "If  was previously associated with a SPIR-V mo

[Mesa-dev] [PATCH 06/24] mesa: implement SPIR-V loading in glShaderBinary

2017-11-15 Thread Eduardo Lima Mitev
From: Nicolai Hähnle 

v2: Add a gl_shader_spirv_data member to gl_shader, which already
   encapsulates a gl_spirv_module where the binary will be saved.
   (Eduardo Lima)
---
 src/mesa/main/glspirv.c   | 52 +++
 src/mesa/main/glspirv.h   |  5 +
 src/mesa/main/mtypes.h|  4 
 src/mesa/main/shaderapi.c | 41 ++---
 src/mesa/main/shaderobj.c |  2 ++
 5 files changed, 101 insertions(+), 3 deletions(-)

diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
index d4724ad245c..390fa9e6984 100644
--- a/src/mesa/main/glspirv.c
+++ b/src/mesa/main/glspirv.c
@@ -23,6 +23,8 @@
 
 #include "glspirv.h"
 
+#include "errors.h"
+
 #include "util/u_atomic.h"
 
 void
@@ -61,6 +63,56 @@ _mesa_shader_spirv_data_reference(struct 
gl_shader_spirv_data **dest,
   p_atomic_inc(&src->RefCount);
 }
 
+void
+_mesa_spirv_shader_binary(struct gl_context *ctx,
+  GLint n, struct gl_shader **shaders,
+  const void* binary, GLint length)
+{
+   struct gl_spirv_module *module;
+   struct gl_shader_spirv_data *spirv_data;
+
+   if (!ctx->Extensions.ARB_gl_spirv) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderBinary(SPIR-V)");
+  return;
+   }
+
+   if (n <= 0)
+  return;
+
+   assert(length >= 0);
+
+   module = malloc(sizeof(*module) + (size_t)length);
+   if (!module) {
+  _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderBinary");
+  return;
+   }
+
+   p_atomic_set(&module->RefCount, 0);
+   module->Length = length;
+   memcpy(&module->Binary[0], binary, length);
+
+   for (int i = 0; i < n; ++i) {
+  struct gl_shader *sh = shaders[i];
+
+  spirv_data = rzalloc(NULL, struct gl_shader_spirv_data);
+  _mesa_shader_spirv_data_reference(&sh->spirv_data, spirv_data);
+  _mesa_spirv_module_reference(&spirv_data->SpirVModule, module);
+
+  sh->SpirVBinary = GL_TRUE;
+  sh->CompileStatus = compile_failure;
+
+  free((void *)sh->Source);
+  sh->Source = NULL;
+  free((void *)sh->FallbackSource);
+  sh->FallbackSource = NULL;
+
+  ralloc_free(sh->ir);
+  sh->ir = NULL;
+  ralloc_free(sh->symbols);
+  sh->symbols = NULL;
+   }
+}
+
 void GLAPIENTRY
 _mesa_SpecializeShaderARB(GLuint shader,
   const GLchar *pEntryPoint,
diff --git a/src/mesa/main/glspirv.h b/src/mesa/main/glspirv.h
index b8a0125ea9f..5ffaa230629 100644
--- a/src/mesa/main/glspirv.h
+++ b/src/mesa/main/glspirv.h
@@ -71,6 +71,11 @@ void
 _mesa_shader_spirv_data_reference(struct gl_shader_spirv_data **dest,
   struct gl_shader_spirv_data *src);
 
+void
+_mesa_spirv_shader_binary(struct gl_context *ctx,
+  GLint n, struct gl_shader **shaders,
+  const void* binary, GLint length);
+
 /**
  * \name API functions
  */
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index cfc763f043e..f19477eb027 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -88,6 +88,7 @@ struct st_context;
 struct gl_uniform_storage;
 struct prog_instruction;
 struct gl_program_parameter_list;
+struct gl_shader_spirv_data;
 struct set;
 struct set_entry;
 struct vbo_context;
@@ -2637,6 +2638,9 @@ struct gl_shader
GLuint TransformFeedbackBufferStride[MAX_FEEDBACK_BUFFERS];
 
struct gl_shader_info info;
+
+   /* ARB_gl_spirv related data */
+   struct gl_shader_spirv_data *spirv_data;
 };
 
 
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 9090bee9fb0..240d9fe6cbc 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -42,6 +42,7 @@
 #include "main/context.h"
 #include "main/dispatch.h"
 #include "main/enums.h"
+#include "main/glspirv.h"
 #include "main/hash.h"
 #include "main/mtypes.h"
 #include "main/pipelineobj.h"
@@ -1054,6 +1055,17 @@ set_shader_source(struct gl_shader *sh, const GLchar 
*source)
 {
assert(sh);
 
+   /* The GL_ARB_gl_spirv spec adds the following to the end of the description
+* of ShaderSource:
+*
+*   "If  was previously associated with a SPIR-V module (via the
+*ShaderBinary command), that association is broken. Upon successful
+*completion of this command the SPIR_V_BINARY_ARB state of 
+*is set to FALSE."
+*/
+   _mesa_shader_spirv_data_reference(&sh->spirv_data, NULL);
+   sh->SpirVBinary = GL_FALSE;
+
if (sh->CompileStatus == compile_skipped && !sh->FallbackSource) {
   /* If shader was previously compiled back-up the source in case of cache
* fallback.
@@ -2147,9 +2159,7 @@ _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum 
binaryformat,
const void* binary, GLint length)
 {
GET_CURRENT_CONTEXT(ctx);
-   (void) shaders;
-   (void) binaryformat;
-   (void) binary;
+   struct gl_shader **sh;
 
/* Page 68, section 7.2 'Shader Binaries" of the of the OpenGL ES 3.1, and
 * page 88 of the OpenG