Re: [Mesa-dev] [PATCH] util/anon_file: Fix build errors due to missing includes

2019-08-09 Thread Eduardo Lima Mitev
It was fixed already with c73988300f943e185a50aaba015f2f114ffcb262.

Eduardo

On 8/8/19 9:31 AM, Eduardo Lima Mitev wrote:
> Including stdlib.h and stdio.h is required in some configurations:
> 
> ../src/util/anon_file.c: In function ‘create_tmpfile_cloexec’:
> ../src/util/anon_file.c:75:9: error: implicit declaration of function 
> ‘mkostemp’ [-Werror=implicit-function-declaration]
> fd = mkostemp(tmpname, O_CLOEXEC);
>  ^~~~
> ../src/util/anon_file.c: In function ‘os_create_anonymous_file’:
> ../src/util/anon_file.c:126:11: error: implicit declaration of function 
> ‘getenv’ [-Werror=implicit-function-declaration]
> path = getenv("XDG_RUNTIME_DIR");
>^~
> ../src/util/anon_file.c:126:9: warning: assignment makes pointer from integer 
> without a cast [-Wint-conversion]
> path = getenv("XDG_RUNTIME_DIR");
>  ^
> ../src/util/anon_file.c:133:7: error: implicit declaration of function 
> ‘asprintf’ [-Werror=implicit-function-declaration]
>asprintf(, "%s/mesa-shared-%s-XX", path, debug_name);
>^~~~
> ../src/util/anon_file.c:141:4: error: implicit declaration of function ‘free’ 
> [-Werror=implicit-function-declaration]
> free(name);
> ^~~~
> ../src/util/anon_file.c:141:4: warning: incompatible implicit declaration of 
> built-in function ‘free’
> ../src/util/anon_file.c:141:4: note: include ‘’ or provide a 
> declaration of ‘free’
> cc1: some warnings being treated as errors
> ---
>  src/util/anon_file.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/src/util/anon_file.c b/src/util/anon_file.c
> index 184b8445bad..3334e793f5c 100644
> --- a/src/util/anon_file.c
> +++ b/src/util/anon_file.c
> @@ -33,6 +33,8 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
>  
>  #ifdef __FreeBSD__
>  #include 
> 
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

[Mesa-dev] [PATCH] util/anon_file: Fix build errors due to missing includes

2019-08-08 Thread Eduardo Lima Mitev
Including stdlib.h and stdio.h is required in some configurations:

../src/util/anon_file.c: In function ‘create_tmpfile_cloexec’:
../src/util/anon_file.c:75:9: error: implicit declaration of function 
‘mkostemp’ [-Werror=implicit-function-declaration]
fd = mkostemp(tmpname, O_CLOEXEC);
 ^~~~
../src/util/anon_file.c: In function ‘os_create_anonymous_file’:
../src/util/anon_file.c:126:11: error: implicit declaration of function 
‘getenv’ [-Werror=implicit-function-declaration]
path = getenv("XDG_RUNTIME_DIR");
   ^~
../src/util/anon_file.c:126:9: warning: assignment makes pointer from integer 
without a cast [-Wint-conversion]
path = getenv("XDG_RUNTIME_DIR");
 ^
../src/util/anon_file.c:133:7: error: implicit declaration of function 
‘asprintf’ [-Werror=implicit-function-declaration]
   asprintf(, "%s/mesa-shared-%s-XX", path, debug_name);
   ^~~~
../src/util/anon_file.c:141:4: error: implicit declaration of function ‘free’ 
[-Werror=implicit-function-declaration]
free(name);
^~~~
../src/util/anon_file.c:141:4: warning: incompatible implicit declaration of 
built-in function ‘free’
../src/util/anon_file.c:141:4: note: include ‘’ or provide a 
declaration of ‘free’
cc1: some warnings being treated as errors
---
 src/util/anon_file.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/util/anon_file.c b/src/util/anon_file.c
index 184b8445bad..3334e793f5c 100644
--- a/src/util/anon_file.c
+++ b/src/util/anon_file.c
@@ -33,6 +33,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #ifdef __FreeBSD__
 #include 
-- 
2.20.1

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

Re: [Mesa-dev] [PATCH 1/2] panfrost: ci: Switch to kernel 5.2-rc1

2019-06-07 Thread Eduardo Lima Mitev
On 5/20/19 11:33 AM, Tomeu Vizoso wrote:
> Signed-off-by: Tomeu Vizoso 
> ---
>  src/gallium/drivers/panfrost/ci/Dockerfile | 7 +++
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/src/gallium/drivers/panfrost/ci/Dockerfile 
> b/src/gallium/drivers/panfrost/ci/Dockerfile
> index 268edf224a20..8c4a4e0444ec 100644
> --- a/src/gallium/drivers/panfrost/ci/Dockerfile
> +++ b/src/gallium/drivers/panfrost/ci/Dockerfile
> @@ -112,12 +112,11 @@ ARG KERNEL_ARCH
>  ARG DEFCONFIG
>  ARG DEVICE_TREES
>  ARG KERNEL_IMAGE_NAME
> -# TODO: Switch to 5.2-rc* when the time comes
> +ENV 
> KERNEL_URL="https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux/+archive/refs/tags/v5.2-rc1.tar.gz;

What's wrong with
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/snapshot/linux-5.2-rc1.tar.gz
?

Eduardo

> +
>  COPY ${KERNEL_ARCH}.config /panfrost-ci/
>  RUN mkdir -p /kernel 
>   && \
> -  wget 
> https://github.com/freedesktop/drm-misc/archive/drm-misc-next-2019-04-18.tar.gz
>  && \
> -  tar xfz drm-misc-next-2019-04-18.tar.gz -C /kernel --strip-components=1
>   && \
> -  rm drm-misc-next-2019-04-18.tar.gz 
>   && \
> +  wget -qO- ${KERNEL_URL} | tar -xvz -C /kernel  
>   && \
>cd /kernel 
>   && \
>ARCH=${KERNEL_ARCH} CROSS_COMPILE="${GCC_ARCH}-" 
> ./scripts/kconfig/merge_config.sh ${DEFCONFIG} 
> /panfrost-ci/${KERNEL_ARCH}.config && \
>ARCH=${KERNEL_ARCH} CROSS_COMPILE="${GCC_ARCH}-" make -j12 
> ${KERNEL_IMAGE_NAME} dtbs && \
> 
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Re: [Mesa-dev] [PATCH 5/9] ir3/nir: Add a new pass 'ir3_nir_lower_io_offsets'

2019-02-26 Thread Eduardo Lima Mitev
On 2/25/19 6:54 PM, Rob Clark wrote:
> On Wed, Feb 13, 2019 at 4:30 PM Eduardo Lima Mitev  wrote:
>>
>> This pass moves to NIR some offset computations that are currently
>> implemented on the IR3 backend compiler, to allow NIR to possibly
>> optimize them.
>>
>> For now, it only supports lowering byte-offset computation for image
>> store and atomics.
>> ---
>>  src/freedreno/Makefile.sources   |   1 +
>>  src/freedreno/ir3/ir3_nir.h  |   1 +
>>  src/freedreno/ir3/ir3_nir_lower_io_offsets.c | 334 +++
>>  3 files changed, 336 insertions(+)
>>  create mode 100644 src/freedreno/ir3/ir3_nir_lower_io_offsets.c
>>
>> diff --git a/src/freedreno/Makefile.sources b/src/freedreno/Makefile.sources
>> index 7fea9de39ef..235fec1c4f2 100644
>> --- a/src/freedreno/Makefile.sources
>> +++ b/src/freedreno/Makefile.sources
>> @@ -31,6 +31,7 @@ ir3_SOURCES := \
>> ir3/ir3_legalize.c \
>> ir3/ir3_nir.c \
>> ir3/ir3_nir.h \
>> +   ir3/ir3_nir_lower_io_offsets.c \
>> ir3/ir3_nir_lower_tg4_to_tex.c \
>> ir3/ir3_print.c \
>> ir3/ir3_ra.c \
>> diff --git a/src/freedreno/ir3/ir3_nir.h b/src/freedreno/ir3/ir3_nir.h
>> index 74201d34160..7983b74af2c 100644
>> --- a/src/freedreno/ir3/ir3_nir.h
>> +++ b/src/freedreno/ir3/ir3_nir.h
>> @@ -36,6 +36,7 @@ void ir3_nir_scan_driver_consts(nir_shader *shader, struct 
>> ir3_driver_const_layo
>>
>>  bool ir3_nir_apply_trig_workarounds(nir_shader *shader);
>>  bool ir3_nir_lower_tg4_to_tex(nir_shader *shader);
>> +bool ir3_nir_lower_io_offsets(nir_shader *shader);
>>
>>  const nir_shader_compiler_options * ir3_get_compiler_options(struct 
>> ir3_compiler *compiler);
>>  bool ir3_key_lowers_nir(const struct ir3_shader_key *key);
>> diff --git a/src/freedreno/ir3/ir3_nir_lower_io_offsets.c 
>> b/src/freedreno/ir3/ir3_nir_lower_io_offsets.c
>> new file mode 100644
>> index 000..a43b3895fd8
>> --- /dev/null
>> +++ b/src/freedreno/ir3/ir3_nir_lower_io_offsets.c
>> @@ -0,0 +1,334 @@
>> +/*
>> + * Copyright © 2018-2019 Igalia S.L.
>> + *
>> + * 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 "ir3_nir.h"
>> +#include "compiler/nir/nir_builder.h"
>> +
>> +/**
>> + * This pass moves to NIR certain offset computations for different I/O
>> + * ops that are currently implemented on the IR3 backend compiler, to
>> + * give NIR a chance to optimize them:
>> + *
>> + * - Byte-offset for image store and atomics: Emit instructions to
>> + *   compute (x*bpp) + y*y_stride + z*z_stride), and place the resulting
>> + *   SSA value in the 4th-component of the vec4 instruction that defines
>> + *   the offset.
>> + */
>> +
>> +
>> +static bool
>> +intrinsic_is_image_atomic(unsigned intrinsic)
>> +{
>> +   switch (intrinsic) {
>> +   case nir_intrinsic_image_deref_atomic_add:
>> +   case nir_intrinsic_image_deref_atomic_min:
>> +   case nir_intrinsic_image_deref_atomic_max:
>> +   case nir_intrinsic_image_deref_atomic_and:
>> +   case nir_intrinsic_image_deref_atomic_or:
>> +   case nir_intrinsic_image_deref_atomic_xor:
>> +   case nir_intrinsic_image_deref_atomic_exchange:
>> +   case nir_intrin

Re: [Mesa-dev] [PATCH 9/9] ir3/compiler: Handle the new ir3 intrinsics for SSBO

2019-02-18 Thread Eduardo Lima Mitev
On 2/13/19 10:29 PM, Eduardo Lima Mitev wrote:
> These intrinsics have the offset in dwords already computed in the last
> source, so the change here is basically using that instead of emitting
> the ir3_SHR to divide the byte-offset by 4.
> 
> The improvement in shader stats is dramatic, of up to ~15% in
> instruction count in some cases. Tested on a5xx.
> 
> shader-db is unfortunately not very useful here because shaders that use
> SSBO require GLSL versions that are not supported by freedreno yet.
> 
> For examples, most Khronos CTS tests under 'dEQP-GLES31.functional.ssbo.*'
> are helped.
> 
> A random case:
> 
> dEQP-GLES31.functional.ssbo.layout.2_level_array.packed.row_major_mat3x2
> 
> with current master:
> 
> ; CL prog 14/1: 1252 instructions, 0 half, 48 full
> ; 8 const, 8 constlen
> ; 61 (ss), 43 (sy)
> 
> with the SSBO dword-offset moved to NIR:
> 
> ; CL prog 14/1: 1053 instructions, 0 half, 45 full
> ; 7 const, 7 constlen
> ; 34 (ss), 73 (sy)
> 
> The SHR previously emitted for every single SSBO instruction disappears
> in most cases, and the dword-offset ends up embedded in the STGB
> instruction as immediate in many cases as well.
> 
> No regressions observed with relevant CTS and piglit tests.
> ---
>  src/freedreno/ir3/ir3_compiler_nir.c | 71 +++-
>  1 file changed, 48 insertions(+), 23 deletions(-)
> 
> diff --git a/src/freedreno/ir3/ir3_compiler_nir.c 
> b/src/freedreno/ir3/ir3_compiler_nir.c
> index 0e141f03181..c494913f254 100644
> --- a/src/freedreno/ir3/ir3_compiler_nir.c
> +++ b/src/freedreno/ir3/ir3_compiler_nir.c
> @@ -760,7 +760,12 @@ emit_intrinsic_load_ssbo(struct ir3_context *ctx, 
> nir_intrinsic_instr *intr,
>   offset,
>   create_immed(b, 0),
>   }, 2);
> - src1 = ir3_SHR_B(b, offset, 0, create_immed(b, 2), 0);
> +
> + /* intrinsic->src[2] holds the dword-offset as placed by
> +  * 'ir3_nir_lower_io_offsets' pass.
> +  */
> + assert(intr->intrinsic == nir_intrinsic_load_ssbo_ir3);

This should be debug_assert(). Fixed locally.

> + src1 = ir3_get_src(ctx, >src[2])[0];
>  
>   ldgb = ir3_LDGB(b, create_immed(b, const_offset->u32[0]), 0,
>   src0, 0, src1, 0);
> @@ -798,7 +803,13 @@ emit_intrinsic_store_ssbo(struct ir3_context *ctx, 
> nir_intrinsic_instr *intr)
>* nir already *= 4:
>*/
>   src0 = ir3_create_collect(ctx, ir3_get_src(ctx, >src[0]), ncomp);
> - src1 = ir3_SHR_B(b, offset, 0, create_immed(b, 2), 0);
> +
> + /* intrinsic->src[3] holds the dword-offset as placed by
> +  * 'ir3_nir_lower_io_offsets' pass.
> +  */
> + assert(intr->intrinsic == nir_intrinsic_store_ssbo_ir3);

Same here.

> + src1 = ir3_get_src(ctx, >src[3])[0];
> +
>   src2 = ir3_create_collect(ctx, (struct ir3_instruction*[]){
>   offset,
>   create_immed(b, 0),
> @@ -869,40 +880,50 @@ emit_intrinsic_atomic_ssbo(struct ir3_context *ctx, 
> nir_intrinsic_instr *intr)
>* Note that nir already multiplies the offset by four
>*/
>   src0 = ir3_get_src(ctx, >src[2])[0];
> - src1 = ir3_SHR_B(b, offset, 0, create_immed(b, 2), 0);
> +
> + /* intrinsic->src[3] holds the dword-offset as placed by
> +  * 'ir3_nir_lower_io_offsets' pass. It doesn't handle
> +  * 'atomic_comp_swap', though, because that intrinsic already used
> +  * all its 4 sources.
> +  */
> + if (intr->intrinsic == nir_intrinsic_ssbo_atomic_comp_swap)
> + src1 = ir3_SHR_B(b, offset, 0, create_immed(b, 2), 0);
> + else
> + src1 = ir3_get_src(ctx, >src[3])[0];
> +
>   src2 = ir3_create_collect(ctx, (struct ir3_instruction*[]){
>   offset,
>   create_immed(b, 0),
>   }, 2);
>  
>   switch (intr->intrinsic) {
> - case nir_intrinsic_ssbo_atomic_add:
> + case nir_intrinsic_ssbo_atomic_add_ir3:
>   atomic = ir3_ATOMIC_ADD_G(b, ssbo, 0, src0, 0, src1, 0, src2, 
> 0);
>   break;
> - case nir_intrinsic_ssbo_atomic_imin:
> + case nir_intrinsic_ssbo_atomic_imin_ir3:
>   atomic = ir3_ATOMIC_MIN_G(b, ssbo, 0, src0, 0, src1, 0, src2, 
> 0);
>   type = TYPE_S32;
>   break;
> - case nir_intrinsic_ssbo_atomic_umin:
> + case nir_intrinsic_ssbo_atomic_umin_ir3:
>   atomic = ir3_ATOMIC_MIN_G(b, ssbo, 0, src0, 0, src1, 0, src2, 
> 0);
>   break;
> - case nir_intrinsic_ssbo_atomic_imax:
> + case nir_intrinsic_ssbo_atomic_imax_ir3:
>   atomic = ir3_ATOMIC_MAX_G(b, s

[Mesa-dev] [PATCH 8/9] ir3: Extend lower_io_offsets pass to lower SSBO dword offset computation

2019-02-13 Thread Eduardo Lima Mitev
The lowering will take an SSBO intrinsic and replace it with the new
ir3-specific version that adds an extra source. That source will hold
the SSA value resulting from inserting a division by 4 (an SHR op) of
the original byte-offset source of the intrinsic.
---
 src/freedreno/ir3/ir3_nir_lower_io_offsets.c | 170 ++-
 1 file changed, 164 insertions(+), 6 deletions(-)

diff --git a/src/freedreno/ir3/ir3_nir_lower_io_offsets.c 
b/src/freedreno/ir3/ir3_nir_lower_io_offsets.c
index a43b3895fd8..d03dc6048cb 100644
--- a/src/freedreno/ir3/ir3_nir_lower_io_offsets.c
+++ b/src/freedreno/ir3/ir3_nir_lower_io_offsets.c
@@ -33,6 +33,12 @@
  *   compute (x*bpp) + y*y_stride + z*z_stride), and place the resulting
  *   SSA value in the 4th-component of the vec4 instruction that defines
  *   the offset.
+ *
+ * - Dword-offset for SSBO load, store and atomics: A new, similar intrinsic
+ *   is emitted that replaces the original one, adding a new source that
+ *   holds the result of the original byte-offset source divided by 4.
+ *   'ssbo_atomic_[f]comp_swap' are excluded because those already use
+ *   the 4 sources.
  */
 
 
@@ -65,6 +71,32 @@ intrinsic_is_image_store_or_atomic(unsigned intrinsic)
return intrinsic_is_image_atomic(intrinsic);
 }
 
+static bool
+intrinsic_is_ssbo(unsigned intrinsic)
+{
+   switch (intrinsic) {
+   case nir_intrinsic_store_ssbo:
+   case nir_intrinsic_load_ssbo:
+   case nir_intrinsic_ssbo_atomic_add:
+   case nir_intrinsic_ssbo_atomic_imin:
+   case nir_intrinsic_ssbo_atomic_umin:
+   case nir_intrinsic_ssbo_atomic_imax:
+   case nir_intrinsic_ssbo_atomic_umax:
+   case nir_intrinsic_ssbo_atomic_and:
+   case nir_intrinsic_ssbo_atomic_or:
+   case nir_intrinsic_ssbo_atomic_xor:
+   case nir_intrinsic_ssbo_atomic_exchange:
+   case nir_intrinsic_ssbo_atomic_fadd:
+   case nir_intrinsic_ssbo_atomic_fmin:
+   case nir_intrinsic_ssbo_atomic_fmax:
+   return true;
+   default:
+   break;
+   }
+
+   return false;
+}
+
 /*
  * FIXME: shamelessly copied from ir3_compiler_nir until it gets factorized
  * out at some point.
@@ -279,6 +311,131 @@ 
lower_offset_for_image_store_or_atomic(nir_intrinsic_instr *intrinsic,
return true;
 }
 
+/* Returns the ir3 version of a given SSBO intrinsic. It also conveniently
+ * returns the index of the offset source in 'offset_src_indx'.
+ */
+unsigned
+get_ir3_intrinsic_for_ssbo_intrinsic(unsigned intrinsic,
+
uint8_t *offset_src_idx)
+{
+   debug_assert(offset_src_idx);
+
+   *offset_src_idx = 1;
+
+   switch (intrinsic) {
+   case nir_intrinsic_store_ssbo:
+   *offset_src_idx = 2;
+   return nir_intrinsic_store_ssbo_ir3;
+   case nir_intrinsic_load_ssbo:
+   return nir_intrinsic_load_ssbo_ir3;
+   case nir_intrinsic_ssbo_atomic_add:
+   return nir_intrinsic_ssbo_atomic_add_ir3;
+   case nir_intrinsic_ssbo_atomic_imin:
+   return nir_intrinsic_ssbo_atomic_imin_ir3;
+   case nir_intrinsic_ssbo_atomic_umin:
+   return nir_intrinsic_ssbo_atomic_umin_ir3;
+   case nir_intrinsic_ssbo_atomic_imax:
+   return nir_intrinsic_ssbo_atomic_imax_ir3;
+   case nir_intrinsic_ssbo_atomic_umax:
+   return nir_intrinsic_ssbo_atomic_umax_ir3;
+   case nir_intrinsic_ssbo_atomic_and:
+   return nir_intrinsic_ssbo_atomic_and_ir3;
+   case nir_intrinsic_ssbo_atomic_or:
+   return nir_intrinsic_ssbo_atomic_or_ir3;
+   case nir_intrinsic_ssbo_atomic_xor:
+   return nir_intrinsic_ssbo_atomic_xor_ir3;
+   case nir_intrinsic_ssbo_atomic_exchange:
+   return nir_intrinsic_ssbo_atomic_exchange_ir3;
+   case nir_intrinsic_ssbo_atomic_fadd:
+   return nir_intrinsic_ssbo_atomic_fadd_ir3;
+   case nir_intrinsic_ssbo_atomic_fmin:
+   return nir_intrinsic_ssbo_atomic_fmin_ir3;
+   case nir_intrinsic_ssbo_atomic_fmax:
+   return nir_intrinsic_ssbo_atomic_fmax_ir3;
+   default:
+   debug_assert(!"Unhandled SSBO intrinsic");
+   break;
+   }
+
+   return 0;
+}
+
+static bool
+lower_offset_for_ssbo(nir_intrinsic_instr *intrinsic, nir_builder *b,
+ void *mem_ctx)
+{
+   unsigned num_srcs = nir_intrinsic_infos[intrinsic->intrinsic].num_srcs;
+   debug_assert(num_srcs < 4);
+
+   bool has_dest = nir_intrinsic_infos[intrinsic->intrinsic].has_dest;
+   nir_ssa_def *new_dest = NULL;
+
+   /* Here we create a new intrinsic and copy over all contents from the 
old one. */
+
+   nir_intrinsic_instr *new_intrinsic;
+   nir_src *target_src;
+   uint8_t offset_src_idx;
+
+   unsigned ir3_intrinsic_opcode =
+   

[Mesa-dev] [PATCH 9/9] ir3/compiler: Handle the new ir3 intrinsics for SSBO

2019-02-13 Thread Eduardo Lima Mitev
These intrinsics have the offset in dwords already computed in the last
source, so the change here is basically using that instead of emitting
the ir3_SHR to divide the byte-offset by 4.

The improvement in shader stats is dramatic, of up to ~15% in
instruction count in some cases. Tested on a5xx.

shader-db is unfortunately not very useful here because shaders that use
SSBO require GLSL versions that are not supported by freedreno yet.

For examples, most Khronos CTS tests under 'dEQP-GLES31.functional.ssbo.*'
are helped.

A random case:

dEQP-GLES31.functional.ssbo.layout.2_level_array.packed.row_major_mat3x2

with current master:

; CL prog 14/1: 1252 instructions, 0 half, 48 full
; 8 const, 8 constlen
; 61 (ss), 43 (sy)

with the SSBO dword-offset moved to NIR:

; CL prog 14/1: 1053 instructions, 0 half, 45 full
; 7 const, 7 constlen
; 34 (ss), 73 (sy)

The SHR previously emitted for every single SSBO instruction disappears
in most cases, and the dword-offset ends up embedded in the STGB
instruction as immediate in many cases as well.

No regressions observed with relevant CTS and piglit tests.
---
 src/freedreno/ir3/ir3_compiler_nir.c | 71 +++-
 1 file changed, 48 insertions(+), 23 deletions(-)

diff --git a/src/freedreno/ir3/ir3_compiler_nir.c 
b/src/freedreno/ir3/ir3_compiler_nir.c
index 0e141f03181..c494913f254 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -760,7 +760,12 @@ emit_intrinsic_load_ssbo(struct ir3_context *ctx, 
nir_intrinsic_instr *intr,
offset,
create_immed(b, 0),
}, 2);
-   src1 = ir3_SHR_B(b, offset, 0, create_immed(b, 2), 0);
+
+   /* intrinsic->src[2] holds the dword-offset as placed by
+* 'ir3_nir_lower_io_offsets' pass.
+*/
+   assert(intr->intrinsic == nir_intrinsic_load_ssbo_ir3);
+   src1 = ir3_get_src(ctx, >src[2])[0];
 
ldgb = ir3_LDGB(b, create_immed(b, const_offset->u32[0]), 0,
src0, 0, src1, 0);
@@ -798,7 +803,13 @@ emit_intrinsic_store_ssbo(struct ir3_context *ctx, 
nir_intrinsic_instr *intr)
 * nir already *= 4:
 */
src0 = ir3_create_collect(ctx, ir3_get_src(ctx, >src[0]), ncomp);
-   src1 = ir3_SHR_B(b, offset, 0, create_immed(b, 2), 0);
+
+   /* intrinsic->src[3] holds the dword-offset as placed by
+* 'ir3_nir_lower_io_offsets' pass.
+*/
+   assert(intr->intrinsic == nir_intrinsic_store_ssbo_ir3);
+   src1 = ir3_get_src(ctx, >src[3])[0];
+
src2 = ir3_create_collect(ctx, (struct ir3_instruction*[]){
offset,
create_immed(b, 0),
@@ -869,40 +880,50 @@ emit_intrinsic_atomic_ssbo(struct ir3_context *ctx, 
nir_intrinsic_instr *intr)
 * Note that nir already multiplies the offset by four
 */
src0 = ir3_get_src(ctx, >src[2])[0];
-   src1 = ir3_SHR_B(b, offset, 0, create_immed(b, 2), 0);
+
+   /* intrinsic->src[3] holds the dword-offset as placed by
+* 'ir3_nir_lower_io_offsets' pass. It doesn't handle
+* 'atomic_comp_swap', though, because that intrinsic already used
+* all its 4 sources.
+*/
+   if (intr->intrinsic == nir_intrinsic_ssbo_atomic_comp_swap)
+   src1 = ir3_SHR_B(b, offset, 0, create_immed(b, 2), 0);
+   else
+   src1 = ir3_get_src(ctx, >src[3])[0];
+
src2 = ir3_create_collect(ctx, (struct ir3_instruction*[]){
offset,
create_immed(b, 0),
}, 2);
 
switch (intr->intrinsic) {
-   case nir_intrinsic_ssbo_atomic_add:
+   case nir_intrinsic_ssbo_atomic_add_ir3:
atomic = ir3_ATOMIC_ADD_G(b, ssbo, 0, src0, 0, src1, 0, src2, 
0);
break;
-   case nir_intrinsic_ssbo_atomic_imin:
+   case nir_intrinsic_ssbo_atomic_imin_ir3:
atomic = ir3_ATOMIC_MIN_G(b, ssbo, 0, src0, 0, src1, 0, src2, 
0);
type = TYPE_S32;
break;
-   case nir_intrinsic_ssbo_atomic_umin:
+   case nir_intrinsic_ssbo_atomic_umin_ir3:
atomic = ir3_ATOMIC_MIN_G(b, ssbo, 0, src0, 0, src1, 0, src2, 
0);
break;
-   case nir_intrinsic_ssbo_atomic_imax:
+   case nir_intrinsic_ssbo_atomic_imax_ir3:
atomic = ir3_ATOMIC_MAX_G(b, ssbo, 0, src0, 0, src1, 0, src2, 
0);
type = TYPE_S32;
break;
-   case nir_intrinsic_ssbo_atomic_umax:
+   case nir_intrinsic_ssbo_atomic_umax_ir3:
atomic = ir3_ATOMIC_MAX_G(b, ssbo, 0, src0, 0, src1, 0, src2, 
0);
break;
-   case nir_intrinsic_ssbo_atomic_and:
+   case nir_intrinsic_ssbo_atomic_and_ir3:
atomic = ir3_ATOMIC_AND_G(b, ssbo, 0, src0, 0, src1, 0, src2, 
0);
break;
-   case nir_intrinsic_ssbo_atomic_or:
+   case nir_intrinsic_ssbo_atomic_or_ir3:
atomic = ir3_ATOMIC_OR_G(b, 

[Mesa-dev] [PATCH 2/9] ir3/compiler: Handle newly added intrinsic image_deref_load_param_ir3

2019-02-13 Thread Eduardo Lima Mitev
Compiler will emit an uniform value corresponding to the requested
parameter (bpp, y-stride or z-stride) for the dereferenced image.
---
 src/freedreno/ir3/ir3_compiler_nir.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/src/freedreno/ir3/ir3_compiler_nir.c 
b/src/freedreno/ir3/ir3_compiler_nir.c
index fd641735620..df948995000 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -1719,6 +1719,24 @@ emit_intrinsic(struct ir3_context *ctx, 
nir_intrinsic_instr *intr)
case nir_intrinsic_image_deref_atomic_comp_swap:
dst[0] = emit_intrinsic_atomic_image(ctx, intr);
break;
+   case nir_intrinsic_image_deref_load_param_ir3: {
+   const nir_variable *var = nir_intrinsic_get_var(intr, 0);
+   compile_assert(ctx, var);
+   idx = var->data.driver_location;
+
+   /* this is the index into image_dims offsets, which can take
+* values 0, 1 or 2 (bpp, y-stride, z-stride respectively).
+*/
+   uint8_t off = intr->const_index[0];
+   compile_assert(ctx, off <= 2);
+
+   unsigned cb = regid(ctx->so->constbase.image_dims, 0) +
+   ctx->so->const_layout.image_dims.off[idx];
+   compile_assert(ctx, ctx->so->const_layout.image_dims.mask & (1 
<< idx));
+
+   dst[0] = create_uniform(b, cb + off);
+   break;
+   }
case nir_intrinsic_barrier:
case nir_intrinsic_memory_barrier:
case nir_intrinsic_group_memory_barrier:
-- 
2.20.1

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

[Mesa-dev] [PATCH 1/9] nir: Add a new intrinsic 'image_deref_load_param_ir3'

2019-02-13 Thread Eduardo Lima Mitev
This is a freedreno specific intrinsic intended to be injected by a
'ir3_nir_lower_sampler_io' pass that will be introduced later in this
series, and consumed by ir3_compiler_nir.

The intrinsic will load-in SSA values for various image constants
(from image_dims), namely the format's bytes-per-pixel, y-stride and
z-stride; for which the backend compiler will emit the corresponding
uniforms.

The single source src0 is the image deref.

const_index[0] is the index into image_dims' register file for
a given image: 0 for bpp, 1 for y-stride and 2 for z-stride.
---
 src/compiler/nir/nir_intrinsics.py | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/src/compiler/nir/nir_intrinsics.py 
b/src/compiler/nir/nir_intrinsics.py
index 90d347f7331..f79a8cebc54 100644
--- a/src/compiler/nir/nir_intrinsics.py
+++ b/src/compiler/nir/nir_intrinsics.py
@@ -644,3 +644,18 @@ store("shared", 2, [BASE, WRMASK, ALIGN_MUL, ALIGN_OFFSET])
 # src[] = { value, address }.
 # const_index[] = { write_mask, align_mul, align_offset }
 store("global", 2, [WRMASK, ACCESS, ALIGN_MUL, ALIGN_OFFSET])
+
+
+# IR3-specifc query for loading image parameters at shader compile-time
+# (bytes-per-pixel, y-stride and z-stride), that will be emitted as
+# uniforms during shader run-time.
+#
+# src0 is the image deref. const-index[0] represents the specific
+# parameter being loaded (in ir3 compiler context, it is the offset
+# into image_dims register file): 0 for BPP, 1 for y-stride and 2 for
+# z-stride.
+#
+# @FIXME: Should this be merged with 'image_deref_load_param_intel'?
+# Both seem semantically similar.
+intrinsic("image_deref_load_param_ir3", src_comp=[1], dest_comp=0,
+  indices=[BASE], flags=[CAN_ELIMINATE, CAN_REORDER])
-- 
2.20.1

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

[Mesa-dev] [PATCH 0/9] freedreno: Add a NIR pass to lower backend IO offset computations

2019-02-13 Thread Eduardo Lima Mitev
This series introduces a new ir3-specific NIR pass that moves offset
computations for different IO ops that currently occur in the backend,
to NIR.

For now, it handles image store/atomics, and SSBO load/store/atomics.

Lowering UBO offsets is WIP and will probably be sent as follow up
patches.

The lowering for image ops doesn't seem to help much in shader
instruction stats, but it does simplify backend code.

The lowering for SSBO however helps significantly. It saves potentially
one or more instructions for each SSBO load, store or atomic access in a
shader.

Quite a few freedreno specific intrinsics are added, which is not new
(intel has some) but uncommon. I guess we will have to live with it
while NIR doesn't offer all the flexibility needed by backends.

A git tree of this series can be checked out at:

https://gitlab.freedesktop.org/elima/mesa/tree/fd/lower-io-offsets

We have only tested it on a5xx.

Eduardo Lima Mitev (9):
  nir: Add a new intrinsic 'image_deref_load_param_ir3'
  ir3/compiler: Handle newly added intrinsic image_deref_load_param_ir3
  nir: Add a new ALU nir_op_imad24_ir3
  ir3_compiler/nir: Handle newly added opcode nir_op_imad24_ir3
  ir3/nir: Add a new pass 'ir3_nir_lower_io_offsets'
  ir3/compiler: Use the new lower_io_offsets pass
  nir: Add ir3-specific version of most SSBO intrinsics
  ir3: Extend lower_io_offsets pass to lower SSBO dword offset
computation
  ir3/compiler: Handle the new ir3 intrinsics for SSBO

 src/compiler/nir/nir_intrinsics.py   |  43 ++
 src/compiler/nir/nir_opcodes.py  |  16 +
 src/freedreno/Makefile.sources   |   1 +
 src/freedreno/ir3/ir3_compiler_nir.c | 133 ++---
 src/freedreno/ir3/ir3_nir.c  |   1 +
 src/freedreno/ir3/ir3_nir.h  |   1 +
 src/freedreno/ir3/ir3_nir_lower_io_offsets.c | 492 +++
 7 files changed, 631 insertions(+), 56 deletions(-)
 create mode 100644 src/freedreno/ir3/ir3_nir_lower_io_offsets.c

-- 
2.20.1

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

[Mesa-dev] [PATCH 7/9] nir: Add ir3-specific version of most SSBO intrinsics

2019-02-13 Thread Eduardo Lima Mitev
These are Freedreno specific versions of SSBO intrinsics that add an
extra source to hold the dword-offset, which is needed by the backend
apart from the byte-offset already provided by NIR in one of the
sources.

NIR lowering pass 'ir3_nir_lower_io_offset' will replace the original
SSBO intrinsics by these, placing the computed dword-offset always in
the last source.

'ssbo_atomic_[f]comp_swap' are not handled because those already use
the 4 sources.
---
 src/compiler/nir/nir_intrinsics.py | 28 
 1 file changed, 28 insertions(+)

diff --git a/src/compiler/nir/nir_intrinsics.py 
b/src/compiler/nir/nir_intrinsics.py
index f79a8cebc54..2eb88c290a6 100644
--- a/src/compiler/nir/nir_intrinsics.py
+++ b/src/compiler/nir/nir_intrinsics.py
@@ -659,3 +659,31 @@ store("global", 2, [WRMASK, ACCESS, ALIGN_MUL, 
ALIGN_OFFSET])
 # Both seem semantically similar.
 intrinsic("image_deref_load_param_ir3", src_comp=[1], dest_comp=0,
   indices=[BASE], flags=[CAN_ELIMINATE, CAN_REORDER])
+
+# IR3-specific version of most SSBO intrinsics. The only different
+# compare to the originals is that they add an extra source to hold
+# the dword-offset, which is needed by the backend code apart from
+# the byte-offset already provided by NIR in one of the sources.
+#
+# NIR lowering pass 'ir3_nir_lower_io_offset' will replace the
+# original SSBO intrinsics by these, placing the computed
+# dword-offset always in the last source.
+#
+# 'ssbo_atomic_[f]comp_swap' are not handled because those already use
+# the 4 sources.
+intrinsic("store_ssbo_ir3",  src_comp=[0, 1, 1, 1],
+  indices=[WRMASK, ACCESS, ALIGN_MUL, ALIGN_OFFSET])
+intrinsic("load_ssbo_ir3",  src_comp=[1, 1, 1], dest_comp=0,
+  indices=[ACCESS, ALIGN_MUL, ALIGN_OFFSET], flags=[CAN_ELIMINATE])
+intrinsic("ssbo_atomic_add_ir3",  src_comp=[1, 1, 1, 1], dest_comp=1)
+intrinsic("ssbo_atomic_imin_ir3", src_comp=[1, 1, 1, 1], dest_comp=1)
+intrinsic("ssbo_atomic_umin_ir3", src_comp=[1, 1, 1, 1], dest_comp=1)
+intrinsic("ssbo_atomic_imax_ir3", src_comp=[1, 1, 1, 1], dest_comp=1)
+intrinsic("ssbo_atomic_umax_ir3", src_comp=[1, 1, 1, 1], dest_comp=1)
+intrinsic("ssbo_atomic_and_ir3",  src_comp=[1, 1, 1, 1], dest_comp=1)
+intrinsic("ssbo_atomic_or_ir3",   src_comp=[1, 1, 1, 1], dest_comp=1)
+intrinsic("ssbo_atomic_xor_ir3",  src_comp=[1, 1, 1, 1], dest_comp=1)
+intrinsic("ssbo_atomic_exchange_ir3", src_comp=[1, 1, 1, 1], dest_comp=1)
+intrinsic("ssbo_atomic_fadd_ir3", src_comp=[1, 1, 1, 1], dest_comp=1)
+intrinsic("ssbo_atomic_fmin_ir3", src_comp=[1, 1, 1, 1], dest_comp=1)
+intrinsic("ssbo_atomic_fmax_ir3", src_comp=[1, 1, 1, 1], dest_comp=1)
-- 
2.20.1

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

[Mesa-dev] [PATCH 3/9] nir: Add a new ALU nir_op_imad24_ir3

2019-02-13 Thread Eduardo Lima Mitev
ir3 compiler has an integer multiply-add instruction (MAD_S24)
that is used for different offset calculations in the backend.
Since we intend to move some of these calculations to NIR, we need
a new ALU op that can directly represent it.
---
 src/compiler/nir/nir_opcodes.py | 16 
 1 file changed, 16 insertions(+)

diff --git a/src/compiler/nir/nir_opcodes.py b/src/compiler/nir/nir_opcodes.py
index d32005846a6..abbb3627a33 100644
--- a/src/compiler/nir/nir_opcodes.py
+++ b/src/compiler/nir/nir_opcodes.py
@@ -892,3 +892,19 @@ dst.w = src3.x;
 """)
 
 
+# Freedreno-specific opcode that maps directly to ir3_MAD_S24.
+# It is emitted by ir3_nir_lower_io_offsets pass when computing
+# byte-offsets for image store and atomics.
+#
+# The nir_algebraic expression below is: get 23 bits of the
+# two factors as unsigned and multiply them. If either of the
+# two was negative, invert sign of the product. Then add it src2.
+# @FIXME: I suspect there is a simpler expression for this.
+triop("imad24_ir3", tint, """
+unsigned f0 = ((unsigned) src0) & 0x7f;
+unsigned f1 = ((unsigned) src1) & 0x7f;
+dst = f0 * f1;
+if (src0 * src1 < 0)
+   dst = -dst;
+dst += src2;
+""")
-- 
2.20.1

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

[Mesa-dev] [PATCH 5/9] ir3/nir: Add a new pass 'ir3_nir_lower_io_offsets'

2019-02-13 Thread Eduardo Lima Mitev
This pass moves to NIR some offset computations that are currently
implemented on the IR3 backend compiler, to allow NIR to possibly
optimize them.

For now, it only supports lowering byte-offset computation for image
store and atomics.
---
 src/freedreno/Makefile.sources   |   1 +
 src/freedreno/ir3/ir3_nir.h  |   1 +
 src/freedreno/ir3/ir3_nir_lower_io_offsets.c | 334 +++
 3 files changed, 336 insertions(+)
 create mode 100644 src/freedreno/ir3/ir3_nir_lower_io_offsets.c

diff --git a/src/freedreno/Makefile.sources b/src/freedreno/Makefile.sources
index 7fea9de39ef..235fec1c4f2 100644
--- a/src/freedreno/Makefile.sources
+++ b/src/freedreno/Makefile.sources
@@ -31,6 +31,7 @@ ir3_SOURCES := \
ir3/ir3_legalize.c \
ir3/ir3_nir.c \
ir3/ir3_nir.h \
+   ir3/ir3_nir_lower_io_offsets.c \
ir3/ir3_nir_lower_tg4_to_tex.c \
ir3/ir3_print.c \
ir3/ir3_ra.c \
diff --git a/src/freedreno/ir3/ir3_nir.h b/src/freedreno/ir3/ir3_nir.h
index 74201d34160..7983b74af2c 100644
--- a/src/freedreno/ir3/ir3_nir.h
+++ b/src/freedreno/ir3/ir3_nir.h
@@ -36,6 +36,7 @@ void ir3_nir_scan_driver_consts(nir_shader *shader, struct 
ir3_driver_const_layo
 
 bool ir3_nir_apply_trig_workarounds(nir_shader *shader);
 bool ir3_nir_lower_tg4_to_tex(nir_shader *shader);
+bool ir3_nir_lower_io_offsets(nir_shader *shader);
 
 const nir_shader_compiler_options * ir3_get_compiler_options(struct 
ir3_compiler *compiler);
 bool ir3_key_lowers_nir(const struct ir3_shader_key *key);
diff --git a/src/freedreno/ir3/ir3_nir_lower_io_offsets.c 
b/src/freedreno/ir3/ir3_nir_lower_io_offsets.c
new file mode 100644
index 000..a43b3895fd8
--- /dev/null
+++ b/src/freedreno/ir3/ir3_nir_lower_io_offsets.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright © 2018-2019 Igalia S.L.
+ *
+ * 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 "ir3_nir.h"
+#include "compiler/nir/nir_builder.h"
+
+/**
+ * This pass moves to NIR certain offset computations for different I/O
+ * ops that are currently implemented on the IR3 backend compiler, to
+ * give NIR a chance to optimize them:
+ *
+ * - Byte-offset for image store and atomics: Emit instructions to
+ *   compute (x*bpp) + y*y_stride + z*z_stride), and place the resulting
+ *   SSA value in the 4th-component of the vec4 instruction that defines
+ *   the offset.
+ */
+
+
+static bool
+intrinsic_is_image_atomic(unsigned intrinsic)
+{
+   switch (intrinsic) {
+   case nir_intrinsic_image_deref_atomic_add:
+   case nir_intrinsic_image_deref_atomic_min:
+   case nir_intrinsic_image_deref_atomic_max:
+   case nir_intrinsic_image_deref_atomic_and:
+   case nir_intrinsic_image_deref_atomic_or:
+   case nir_intrinsic_image_deref_atomic_xor:
+   case nir_intrinsic_image_deref_atomic_exchange:
+   case nir_intrinsic_image_deref_atomic_comp_swap:
+   return true;
+   default:
+   break;
+   }
+
+   return false;
+}
+
+static bool
+intrinsic_is_image_store_or_atomic(unsigned intrinsic)
+{
+   if (intrinsic == nir_intrinsic_image_deref_store)
+   return true;
+   else
+   return intrinsic_is_image_atomic(intrinsic);
+}
+
+/*
+ * FIXME: shamelessly copied from ir3_compiler_nir until it gets factorized
+ * out at some point.
+ */
+static unsigned
+get_image_coords(const nir_variable *var)
+{
+   const struct glsl_type *type = glsl_without_array(var->type);
+   unsigned coords;
+
+   switch (glsl_get_sampler_dim(type)) {
+   case GLSL_SAMPLER_DIM_1D:
+   case GLSL_SAMPLER_DIM_BUF:
+   coords = 1;
+   break;
+   case GLSL_SAMPLER_DIM_2D:
+   case GLSL_SAMPLER_DIM_RECT:
+   case GLSL_SAMPLER_DIM_EXTERNAL:
+   case GLSL_SAMPLER_DIM_MS:
+   coords = 2;
+   break;
+   case GLSL_SAMPLER_DIM_3D:
+   

[Mesa-dev] [PATCH 6/9] ir3/compiler: Use the new lower_io_offsets pass

2019-02-13 Thread Eduardo Lima Mitev
This effectively removes all offset calculations in
ir3_compiler_nir::get_image_offset().

No regressions observed on affected tests from Khronos CTS and piglit
suites, compared to master.

Unfortunately shader-db is not helpful for stats in this case. Few
shaders there exercise image store or image atomic, and of those that
do, most require higher versions of GLSL than 3.10, so they get skipped.

Since the emitted instructions are the same as before in the worse case,
there shouldn't be shaders hurt by this pass.
---
 src/freedreno/ir3/ir3_compiler_nir.c | 41 ++--
 src/freedreno/ir3/ir3_nir.c  |  1 +
 2 files changed, 9 insertions(+), 33 deletions(-)

diff --git a/src/freedreno/ir3/ir3_compiler_nir.c 
b/src/freedreno/ir3/ir3_compiler_nir.c
index 05dc5ef7cf6..0e141f03181 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -1175,44 +1175,19 @@ get_image_type(const nir_variable *var)
 
 static struct ir3_instruction *
 get_image_offset(struct ir3_context *ctx, const nir_variable *var,
-   struct ir3_instruction * const *coords, bool byteoff)
+   struct ir3_instruction * const *coords)
 {
struct ir3_block *b = ctx->block;
-   struct ir3_instruction *offset;
-   unsigned ncoords = get_image_coords(var, NULL);
-
-   /* to calculate the byte offset (yes, uggg) we need (up to) three
-* const values to know the bytes per pixel, and y and z stride:
-*/
-   unsigned cb = regid(ctx->so->constbase.image_dims, 0) +
-   ctx->so->const_layout.image_dims.off[var->data.driver_location];
 
debug_assert(ctx->so->const_layout.image_dims.mask &
(1 << var->data.driver_location));
 
-   /* offset = coords.x * bytes_per_pixel: */
-   offset = ir3_MUL_S(b, coords[0], 0, create_uniform(b, cb + 0), 0);
-   if (ncoords > 1) {
-   /* offset += coords.y * y_pitch: */
-   offset = ir3_MAD_S24(b, create_uniform(b, cb + 1), 0,
-   coords[1], 0, offset, 0);
-   }
-   if (ncoords > 2) {
-   /* offset += coords.z * z_pitch: */
-   offset = ir3_MAD_S24(b, create_uniform(b, cb + 2), 0,
-   coords[2], 0, offset, 0);
-   }
-
-   if (!byteoff) {
-   /* Some cases, like atomics, seem to use dword offset instead
-* of byte offsets.. blob just puts an extra shr.b in there
-* in those cases:
-*/
-   offset = ir3_SHR_B(b, offset, 0, create_immed(b, 2), 0);
-   }
-
+   /* ir3_nir_lower_sampler_io pass should have placed the final
+* byte-offset (or dword offset for atomics) at the 4th component
+* of the coordinate vector.
+*/
return ir3_create_collect(ctx, (struct ir3_instruction*[]){
-   offset,
+   coords[3],
create_immed(b, 0),
}, 2);
 }
@@ -1344,7 +1319,7 @@ emit_intrinsic_store_image(struct ir3_context *ctx, 
nir_intrinsic_instr *intr)
 * src2 is 64b byte offset
 */
 
-   offset = get_image_offset(ctx, var, coords, true);
+   offset = get_image_offset(ctx, var, coords);
 
/* NOTE: stib seems to take byte offset, but stgb.typed can be used
 * too and takes a dword offset.. not quite sure yet why blob uses
@@ -1446,7 +1421,7 @@ emit_intrinsic_atomic_image(struct ir3_context *ctx, 
nir_intrinsic_instr *intr)
 */
src0 = ir3_get_src(ctx, >src[3])[0];
src1 = ir3_create_collect(ctx, coords, ncoords);
-   src2 = get_image_offset(ctx, var, coords, false);
+   src2 = get_image_offset(ctx, var, coords);
 
switch (intr->intrinsic) {
case nir_intrinsic_image_deref_atomic_add:
diff --git a/src/freedreno/ir3/ir3_nir.c b/src/freedreno/ir3/ir3_nir.c
index d9fcf798b3d..5cd3116b994 100644
--- a/src/freedreno/ir3/ir3_nir.c
+++ b/src/freedreno/ir3/ir3_nir.c
@@ -160,6 +160,7 @@ ir3_optimize_nir(struct ir3_shader *shader, nir_shader *s,
 
OPT_V(s, nir_opt_global_to_local);
OPT_V(s, nir_lower_regs_to_ssa);
+   OPT_V(s, ir3_nir_lower_io_offsets);
 
if (key) {
if (s->info.stage == MESA_SHADER_VERTEX) {
-- 
2.20.1

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

[Mesa-dev] [PATCH 4/9] ir3_compiler/nir: Handle newly added opcode nir_op_imad24_ir3

2019-02-13 Thread Eduardo Lima Mitev
It simply emits an ir3_MAD_S24.
---
 src/freedreno/ir3/ir3_compiler_nir.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/freedreno/ir3/ir3_compiler_nir.c 
b/src/freedreno/ir3/ir3_compiler_nir.c
index df948995000..05dc5ef7cf6 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -548,6 +548,9 @@ emit_alu(struct ir3_context *ctx, nir_alu_instr *alu)
ir3_MADSH_M16(b, src[0], 0, src[1], 0,
ir3_MULL_U(b, src[0], 0, 
src[1], 0), 0), 0);
break;
+   case nir_op_imad24_ir3:
+   dst[0] = ir3_MAD_S24(b, src[0], 0, src[1], 0, src[2], 0);
+   break;
case nir_op_ineg:
dst[0] = ir3_ABSNEG_S(b, src[0], IR3_REG_SNEG);
break;
-- 
2.20.1

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

Re: [Mesa-dev] [RFC 1/4] nir: Add a new intrinsic 'load_image_stride'

2019-01-28 Thread Eduardo Lima Mitev
On 1/28/19 10:16 AM, Eduardo Lima Mitev wrote:
> On 1/28/19 9:56 AM, Bas Nieuwenhuizen wrote:
>> On Mon, Jan 28, 2019 at 9:38 AM Eduardo Lima Mitev  wrote:
>>>
>>> On 1/26/19 5:34 PM, Jason Ekstrand wrote:
>>>> Mind suffixing it with _ir3 or something since it's a back-end-specific
>>>> intrinsic?  Incidentally, this looks a lot like load_image_param_intel.
>>>>
>>>
>>> Yes, I felt inclined to add the suffix but wasn't sure how good/bad a
>>> practice it is, so I deferred it to review :).
>>>
>>> Now, I did a quick experiment and it turns out I can reuse
>>> image_deref_load_param_intel as-is. The semantics are a bit different so
>>> I would have to fork the comment to explain ir3 too.
>>>
>>> So, what about I remove the '_intel' suffix to that one and use if for
>>> this ir3?
>>
>> Instructions that have different semantics for different drivers sound
>> like a lot of potential for confusion and latent bugs to me. Is it
>> really a problem to have both?
>>
> 
> It is not a problem at all, but I think it is preferable not to
> duplicate this intrinsic if it serves the same purpose on both backends,
> and only slightly differ in the specific set of params it holds:
> 
> On both backends the intrinsic is used to represent registers at compile
> time, that will be resolved to uniforms at shader run time.
> 
> On intel, the params are offset, tiling, stride and swizzling; on ir3
> they are bytes-per-pixel, y-stride and z-stride. That's what I mean by
> different semantics, and I think the difference is not enough to justify
> forking it.
> 

Actually, one can argue there is no semantic difference at all from
NIR's point of view. The intrinsic just load certain image params on
both backends, and it is only backend-specific what those params are.

> I'm ok either way, though.
> 
> Eduardo
> 
>>>
>>> Thanks for the feedback and the tip!
>>>
>>> Eduardo
>>>
>>>> On January 25, 2019 07:48:54 Eduardo Lima Mitev  wrote:
>>>>
>>>>> This is an internal intrinsic intended to be injected by a
>>>>> (freedreno-specific) 'lower_sampler_io' pass that will be introduced
>>>>> later in this series; and consumed by ir3_compiler_nir.
>>>>>
>>>>> The intrinsic will load in SSA values for various constants
>>>>> for images (image_dims), namely the format's bytes-per-pixel,
>>>>> y-stride and z-stride; for which the backend compiler will emit
>>>>> the corresponding uniforms.
>>>>>
>>>>> const_index[0] is the image index, and const_index[1] is the index
>>>>> into image_dims' register file for a given image: 0 for bpp, 1 to
>>>>> y-stride and 2 for z-stride.
>>>>> ---
>>>>> src/compiler/nir/nir_intrinsics.py | 2 ++
>>>>> 1 file changed, 2 insertions(+)
>>>>>
>>>>> diff --git a/src/compiler/nir/nir_intrinsics.py
>>>>> b/src/compiler/nir/nir_intrinsics.py
>>>>> index a5cc3f7401c..169c835d746 100644
>>>>> --- a/src/compiler/nir/nir_intrinsics.py
>>>>> +++ b/src/compiler/nir/nir_intrinsics.py
>>>>> @@ -590,6 +590,8 @@ load("shared", 1, [BASE, ALIGN_MUL, ALIGN_OFFSET],
>>>>> [CAN_ELIMINATE])
>>>>> load("push_constant", 1, [BASE, RANGE], [CAN_ELIMINATE, CAN_REORDER])
>>>>> # src[] = { offset }. const_index[] = { base, range }
>>>>> load("constant", 1, [BASE, RANGE], [CAN_ELIMINATE, CAN_REORDER])
>>>>> +# src[] = { offset }. const_index[] = { image_idx, dim_idx }
>>>>> +load("image_stride", 1, [], [CAN_REORDER])
>>>>>
>>>>> # Stores work the same way as loads, except now the first source is
>>>>> the value
>>>>> # to store and the second (and possibly third) source specify where to
>>>>> store
>>>>> --
>>>>> 2.20.1
>>>>>
>>>>> ___
>>>>> mesa-dev mailing list
>>>>> mesa-dev@lists.freedesktop.org
>>>>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>>>>
>>>>
>>>>
>>>>
>>> ___
>>> mesa-dev mailing list
>>> mesa-dev@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>>
> ___
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [RFC 1/4] nir: Add a new intrinsic 'load_image_stride'

2019-01-28 Thread Eduardo Lima Mitev
On 1/28/19 9:56 AM, Bas Nieuwenhuizen wrote:
> On Mon, Jan 28, 2019 at 9:38 AM Eduardo Lima Mitev  wrote:
>>
>> On 1/26/19 5:34 PM, Jason Ekstrand wrote:
>>> Mind suffixing it with _ir3 or something since it's a back-end-specific
>>> intrinsic?  Incidentally, this looks a lot like load_image_param_intel.
>>>
>>
>> Yes, I felt inclined to add the suffix but wasn't sure how good/bad a
>> practice it is, so I deferred it to review :).
>>
>> Now, I did a quick experiment and it turns out I can reuse
>> image_deref_load_param_intel as-is. The semantics are a bit different so
>> I would have to fork the comment to explain ir3 too.
>>
>> So, what about I remove the '_intel' suffix to that one and use if for
>> this ir3?
> 
> Instructions that have different semantics for different drivers sound
> like a lot of potential for confusion and latent bugs to me. Is it
> really a problem to have both?
>

It is not a problem at all, but I think it is preferable not to
duplicate this intrinsic if it serves the same purpose on both backends,
and only slightly differ in the specific set of params it holds:

On both backends the intrinsic is used to represent registers at compile
time, that will be resolved to uniforms at shader run time.

On intel, the params are offset, tiling, stride and swizzling; on ir3
they are bytes-per-pixel, y-stride and z-stride. That's what I mean by
different semantics, and I think the difference is not enough to justify
forking it.

I'm ok either way, though.

Eduardo

>>
>> Thanks for the feedback and the tip!
>>
>> Eduardo
>>
>>> On January 25, 2019 07:48:54 Eduardo Lima Mitev  wrote:
>>>
>>>> This is an internal intrinsic intended to be injected by a
>>>> (freedreno-specific) 'lower_sampler_io' pass that will be introduced
>>>> later in this series; and consumed by ir3_compiler_nir.
>>>>
>>>> The intrinsic will load in SSA values for various constants
>>>> for images (image_dims), namely the format's bytes-per-pixel,
>>>> y-stride and z-stride; for which the backend compiler will emit
>>>> the corresponding uniforms.
>>>>
>>>> const_index[0] is the image index, and const_index[1] is the index
>>>> into image_dims' register file for a given image: 0 for bpp, 1 to
>>>> y-stride and 2 for z-stride.
>>>> ---
>>>> src/compiler/nir/nir_intrinsics.py | 2 ++
>>>> 1 file changed, 2 insertions(+)
>>>>
>>>> diff --git a/src/compiler/nir/nir_intrinsics.py
>>>> b/src/compiler/nir/nir_intrinsics.py
>>>> index a5cc3f7401c..169c835d746 100644
>>>> --- a/src/compiler/nir/nir_intrinsics.py
>>>> +++ b/src/compiler/nir/nir_intrinsics.py
>>>> @@ -590,6 +590,8 @@ load("shared", 1, [BASE, ALIGN_MUL, ALIGN_OFFSET],
>>>> [CAN_ELIMINATE])
>>>> load("push_constant", 1, [BASE, RANGE], [CAN_ELIMINATE, CAN_REORDER])
>>>> # src[] = { offset }. const_index[] = { base, range }
>>>> load("constant", 1, [BASE, RANGE], [CAN_ELIMINATE, CAN_REORDER])
>>>> +# src[] = { offset }. const_index[] = { image_idx, dim_idx }
>>>> +load("image_stride", 1, [], [CAN_REORDER])
>>>>
>>>> # Stores work the same way as loads, except now the first source is
>>>> the value
>>>> # to store and the second (and possibly third) source specify where to
>>>> store
>>>> --
>>>> 2.20.1
>>>>
>>>> ___
>>>> mesa-dev mailing list
>>>> mesa-dev@lists.freedesktop.org
>>>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>>>
>>>
>>>
>>>
>> ___
>> mesa-dev mailing list
>> mesa-dev@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [RFC 1/4] nir: Add a new intrinsic 'load_image_stride'

2019-01-28 Thread Eduardo Lima Mitev
On 1/26/19 5:34 PM, Jason Ekstrand wrote:
> Mind suffixing it with _ir3 or something since it's a back-end-specific
> intrinsic?  Incidentally, this looks a lot like load_image_param_intel.
> 

Yes, I felt inclined to add the suffix but wasn't sure how good/bad a
practice it is, so I deferred it to review :).

Now, I did a quick experiment and it turns out I can reuse
image_deref_load_param_intel as-is. The semantics are a bit different so
I would have to fork the comment to explain ir3 too.

So, what about I remove the '_intel' suffix to that one and use if for
this ir3?

Thanks for the feedback and the tip!

Eduardo

> On January 25, 2019 07:48:54 Eduardo Lima Mitev  wrote:
> 
>> This is an internal intrinsic intended to be injected by a
>> (freedreno-specific) 'lower_sampler_io' pass that will be introduced
>> later in this series; and consumed by ir3_compiler_nir.
>>
>> The intrinsic will load in SSA values for various constants
>> for images (image_dims), namely the format's bytes-per-pixel,
>> y-stride and z-stride; for which the backend compiler will emit
>> the corresponding uniforms.
>>
>> const_index[0] is the image index, and const_index[1] is the index
>> into image_dims' register file for a given image: 0 for bpp, 1 to
>> y-stride and 2 for z-stride.
>> ---
>> src/compiler/nir/nir_intrinsics.py | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/src/compiler/nir/nir_intrinsics.py
>> b/src/compiler/nir/nir_intrinsics.py
>> index a5cc3f7401c..169c835d746 100644
>> --- a/src/compiler/nir/nir_intrinsics.py
>> +++ b/src/compiler/nir/nir_intrinsics.py
>> @@ -590,6 +590,8 @@ load("shared", 1, [BASE, ALIGN_MUL, ALIGN_OFFSET],
>> [CAN_ELIMINATE])
>> load("push_constant", 1, [BASE, RANGE], [CAN_ELIMINATE, CAN_REORDER])
>> # src[] = { offset }. const_index[] = { base, range }
>> load("constant", 1, [BASE, RANGE], [CAN_ELIMINATE, CAN_REORDER])
>> +# src[] = { offset }. const_index[] = { image_idx, dim_idx }
>> +load("image_stride", 1, [], [CAN_REORDER])
>>
>> # Stores work the same way as loads, except now the first source is
>> the value
>> # to store and the second (and possibly third) source specify where to
>> store
>> -- 
>> 2.20.1
>>
>> ___
>> mesa-dev mailing list
>> mesa-dev@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 
> 
> 
> 
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [Freedreno] [RFC 0/4] freedreno: Move some compiler offset computations to NIR

2019-01-28 Thread Eduardo Lima Mitev
On 1/26/19 12:42 AM, Rob Clark wrote:
> On Fri, Jan 25, 2019 at 10:48 AM Eduardo Lima Mitev  wrote:
>>
>> There are a bunch of instructions emitted on ir3_compiler_nir related to
>> offset computations for IO opcodes (ssbo, image, etc). This small series
>> explores the possibility of moving these instructions to NIR, where we
>> have higher chances of optimizing them.
>>
>> The series introduces a new, freedreno specific NIR pass,
>> 'ir3_nir_lower_sampler_io' (final name not set). The pass is executed
>> early on ir3_optimize_nir(), and the goal is to centralize all these
>> computations there, hoping that later NIR passes will produce better
>> code than what is currently emitted.
> 
> I can think of a few other things that would be interesting to lower
> to driver specific nir opcodes (imul and various lowering for tex
> instructions come to mind.. but probably also ubo and ssbo address
> calculation.. maybe it could even make sense for some of the single
> src alu instructions that translate into multiple ir3 instructions,
> not sure)..
> 

Yes, the plan is to abstract to NIR whatever brings us a benefit in
instruction stats. There is also the question of just simplifying the
backend compiler, provided we don't hurt produced code.

> Are you thinking about having separate passes for each?  I guess at
> least for alu instructions we might able to use nir_algebraic so
> having things split up might be easier.
> 

I haven't thought too much about this yet, but it seems to make sense
having at least 2 passes, one for I/O and one for ALUs.

>> So far, we have just implemented byte-offset computation for image store
>> and atomics. This seemed like a good first target given the amount of
>> instructions being emitted for it by the backend.
>>
>> This is an RFC series because there are a few open questions, but we
>> wanted to gather feedback already now, in case this effort is something
>> not worth it; and also hoping that somebody else will give it a try
>> against other shaders and on other gens (we have just tried this on
>> a5xx).
>>
>> * We have so far been unable to see any improvement in generated code
>> (not a penalty either). shader-db has not been specially useful. Few
>> shaders there exercise image store or image atomic ops, and of those
>> that do, most require higher versions of GLSL than what freedreno
>> supports, so they get skipped. The few that do actually run, don't
>> show any meaningful difference.
> 
> I guess it would be easy enough to construct shaders that would
> benefit from this, but maybe that is cheating..
> 
> Possibly UBO and SSBO is a better target, I guess there you might be
> more likely to see patterns of access of successive elements (ie.
> foo[idx], foo[idx+1], etc)?
> 

I took a first stab at SSBO's load/store/atomic, where the offset is
divided by 4 in the backend, but was bitten by IR3_STGB requiring both
the original byte-offset and the dword-offset (in src1 and src2
respectively). So trivially emitting a nir_shr on the offset didn't buy
us anything. I have in the backlog to revisit this, turning the offset
into a 2-component reg so we can hold the original byte-offset and the
offset divided by 4.

> Anyways, since we don't try to do (and I'd rather not do) any sort of
> CSE post nir->ir3 I think starting to introduce more ir3 specific
> nir->nir lowering seems like a thing we need, so I'm pretty happy that
> someone is looking at this :-)
> 

Thanks, that's encouraging. Lets see how far we can get :).

Eduardo

> BR,
> -R
> 
>> Then other shaders picked from tests suites are simple enough not to
>> produce any difference in code either.
>>
>> There is still on-going work looking for cases where the pass helps
>> instruction stats, whether writing custom shaders or porting complex
>> shader from shader-db to run on GLES 310.
>>
>> There is though an open question here as to whether moving backend
>> code to NIR is a benefit in and of itself.
>>
>> * The series adds a nir_op_imad opcode that didn't exist before, and
>> perhaps not generally useful even for freedreno outside this pass,
>> because it maps to IR3_MAD_S24 which is probably not suitable for
>> generic integer multiply-add.
>>
>> * The pass currently has 2 alternative code-paths to emit the
>> multiplication by the bytes-per-pixel of an image format. In one
>> case, since this value can be obtained at compile time, it is
>> emitted as an immediate by nir_imul_imm. The other alternative is
>> emitting an nir_imul with an SSA value that will map to
>> image_dims[0] at shader runtime.
>>
>> The former case is uglier but

Re: [Mesa-dev] [RFC 2/4] nir: Add a new ALU nir_op_imad

2019-01-26 Thread Eduardo Lima Mitev
On 1/25/19 6:46 PM, Eric Anholt wrote:
> Eduardo Lima Mitev  writes:
> 
>> ir3 compiler has an integer multiply-add instruction (IMAD_S24)
>> that is used for different offset calculations in the backend.
>> Since we intend to move some of these calculations to NIR, we need
>> a new ALU op that can represent it.
>> ---
>>  src/compiler/nir/nir_opcodes.py | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/src/compiler/nir/nir_opcodes.py 
>> b/src/compiler/nir/nir_opcodes.py
>> index d32005846a6..b61845fd514 100644
>> --- a/src/compiler/nir/nir_opcodes.py
>> +++ b/src/compiler/nir/nir_opcodes.py
>> @@ -754,6 +754,7 @@ def triop_horiz(name, output_size, src1_size, src2_size, 
>> src3_size, const_expr):
>> [tuint, tuint, tuint], "", const_expr)
>>  
>>  triop("ffma", tfloat, "src0 * src1 + src2")
>> +triop("imad", tint, "src0 * src1 + src2")
> 
> The constant-folding expression should be corrected to what the backend
> operation actually does, and you should probably call it imad24 or
> something in that case.
> 

Roger. Got similar feedback from Ilia. Will fix that.

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


Re: [Mesa-dev] [RFC 1/4] nir: Add a new intrinsic 'load_image_stride'

2019-01-26 Thread Eduardo Lima Mitev
On 1/25/19 6:42 PM, Eric Anholt wrote:
> Eduardo Lima Mitev  writes:
> 
>> This is an internal intrinsic intended to be injected by a
>> (freedreno-specific) 'lower_sampler_io' pass that will be introduced
>> later in this series; and consumed by ir3_compiler_nir.
>>
>> The intrinsic will load in SSA values for various constants
>> for images (image_dims), namely the format's bytes-per-pixel,
>> y-stride and z-stride; for which the backend compiler will emit
>> the corresponding uniforms.
>>
>> const_index[0] is the image index, and const_index[1] is the index
>> into image_dims' register file for a given image: 0 for bpp, 1 to
>> y-stride and 2 for z-stride.
> 
> Can you move this documentation of the meaning of the intrinsic into a
> comment in the file?
> 

Yes, will do that.
Thanks!
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [RFC 0/4] freedreno: Move some compiler offset computations to NIR

2019-01-25 Thread Eduardo Lima Mitev
There are a bunch of instructions emitted on ir3_compiler_nir related to
offset computations for IO opcodes (ssbo, image, etc). This small series
explores the possibility of moving these instructions to NIR, where we
have higher chances of optimizing them.

The series introduces a new, freedreno specific NIR pass,
'ir3_nir_lower_sampler_io' (final name not set). The pass is executed
early on ir3_optimize_nir(), and the goal is to centralize all these
computations there, hoping that later NIR passes will produce better
code than what is currently emitted.

So far, we have just implemented byte-offset computation for image store
and atomics. This seemed like a good first target given the amount of
instructions being emitted for it by the backend.

This is an RFC series because there are a few open questions, but we
wanted to gather feedback already now, in case this effort is something
not worth it; and also hoping that somebody else will give it a try
against other shaders and on other gens (we have just tried this on
a5xx).

* We have so far been unable to see any improvement in generated code
(not a penalty either). shader-db has not been specially useful. Few
shaders there exercise image store or image atomic ops, and of those
that do, most require higher versions of GLSL than what freedreno
supports, so they get skipped. The few that do actually run, don't
show any meaningful difference.

Then other shaders picked from tests suites are simple enough not to
produce any difference in code either.

There is still on-going work looking for cases where the pass helps
instruction stats, whether writing custom shaders or porting complex
shader from shader-db to run on GLES 310.

There is though an open question here as to whether moving backend
code to NIR is a benefit in and of itself.

* The series adds a nir_op_imad opcode that didn't exist before, and
perhaps not generally useful even for freedreno outside this pass,
because it maps to IR3_MAD_S24 which is probably not suitable for
generic integer multiply-add.

* The pass currently has 2 alternative code-paths to emit the
multiplication by the bytes-per-pixel of an image format. In one
case, since this value can be obtained at compile time, it is
emitted as an immediate by nir_imul_imm. The other alternative is
emitting an nir_imul with an SSA value that will map to
image_dims[0] at shader runtime.

The former case is uglier but produces better code (a single SHL
instruction), whereas the latter involves a generic imul, for which
the backend emits a lot of code to cover for overflow.

The doubt here is whether we should introduce a (lower precision)
version of imul that maps directly to IR3_IMUL_S.


A live (WIP) tree of the series can be found at:
<https://gitlab.freedesktop.org/elima/mesa/commits/wip/fd-compiler-io>

We plan to continue moving computations to the pass if we see
good opportunities.

Feedback very welcome,

cheers,
Eduardo

Eduardo Lima Mitev (4):
  nir: Add a new intrinsic 'load_image_stride'
  nir: Add a new ALU nir_op_imad
  ir3/nir: Add a new pass 'ir3_nir_lower_sampler_io'
  ir3: Use ir3_nir_lower_sampler_io pass

 src/compiler/nir/nir_intrinsics.py   |   2 +
 src/compiler/nir/nir_opcodes.py  |   1 +
 src/freedreno/Makefile.sources   |   1 +
 src/freedreno/ir3/ir3_compiler_nir.c |  61 ++--
 src/freedreno/ir3/ir3_nir.c  |   1 +
 src/freedreno/ir3/ir3_nir.h  |   1 +
 src/freedreno/ir3/ir3_nir_lower_sampler_io.c | 349 +++
 7 files changed, 383 insertions(+), 33 deletions(-)
 create mode 100644 src/freedreno/ir3/ir3_nir_lower_sampler_io.c

-- 
2.20.1

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


[Mesa-dev] [RFC 4/4] ir3: Use ir3_nir_lower_sampler_io pass

2019-01-25 Thread Eduardo Lima Mitev
This effectively removes all offset calculations in
ir3_compiler_nir::get_image_offset().

No regressions observed on affected tests from Khronos CTS and piglit
suites, compared to master.

Collecting useful stats on helps/hurts caused by this pass is WIP. Very
few shaders in shader-db data-base exercise image store or image
atomic ops, and of those that do, most require higher versions of
GLSL than what freedreno supports, so they get skipped.

There is on-going work writing/porting shaders to collect useful
stats. So far, all tested show no meaningful difference compared
to master.
---
 src/freedreno/ir3/ir3_compiler_nir.c | 61 +---
 src/freedreno/ir3/ir3_nir.c  |  1 +
 2 files changed, 29 insertions(+), 33 deletions(-)

diff --git a/src/freedreno/ir3/ir3_compiler_nir.c 
b/src/freedreno/ir3/ir3_compiler_nir.c
index fd641735620..fe329db658c 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -548,6 +548,9 @@ emit_alu(struct ir3_context *ctx, nir_alu_instr *alu)
ir3_MADSH_M16(b, src[0], 0, src[1], 0,
ir3_MULL_U(b, src[0], 0, 
src[1], 0), 0), 0);
break;
+   case nir_op_imad:
+   dst[0] = ir3_MAD_S24(b, src[0], 0, src[1], 0, src[2], 0);
+   break;
case nir_op_ineg:
dst[0] = ir3_ABSNEG_S(b, src[0], IR3_REG_SNEG);
break;
@@ -1172,44 +1175,19 @@ get_image_type(const nir_variable *var)
 
 static struct ir3_instruction *
 get_image_offset(struct ir3_context *ctx, const nir_variable *var,
-   struct ir3_instruction * const *coords, bool byteoff)
+   struct ir3_instruction * const *coords)
 {
struct ir3_block *b = ctx->block;
-   struct ir3_instruction *offset;
-   unsigned ncoords = get_image_coords(var, NULL);
-
-   /* to calculate the byte offset (yes, uggg) we need (up to) three
-* const values to know the bytes per pixel, and y and z stride:
-*/
-   unsigned cb = regid(ctx->so->constbase.image_dims, 0) +
-   ctx->so->const_layout.image_dims.off[var->data.driver_location];
 
debug_assert(ctx->so->const_layout.image_dims.mask &
(1 << var->data.driver_location));
 
-   /* offset = coords.x * bytes_per_pixel: */
-   offset = ir3_MUL_S(b, coords[0], 0, create_uniform(b, cb + 0), 0);
-   if (ncoords > 1) {
-   /* offset += coords.y * y_pitch: */
-   offset = ir3_MAD_S24(b, create_uniform(b, cb + 1), 0,
-   coords[1], 0, offset, 0);
-   }
-   if (ncoords > 2) {
-   /* offset += coords.z * z_pitch: */
-   offset = ir3_MAD_S24(b, create_uniform(b, cb + 2), 0,
-   coords[2], 0, offset, 0);
-   }
-
-   if (!byteoff) {
-   /* Some cases, like atomics, seem to use dword offset instead
-* of byte offsets.. blob just puts an extra shr.b in there
-* in those cases:
-*/
-   offset = ir3_SHR_B(b, offset, 0, create_immed(b, 2), 0);
-   }
-
+   /* ir3_nir_lower_sampler_io pass should have placed the final
+* byte-offset (or dword offset for atomics) at the 4th component
+* of the coordinate vector.
+*/
return ir3_create_collect(ctx, (struct ir3_instruction*[]){
-   offset,
+   coords[3],
create_immed(b, 0),
}, 2);
 }
@@ -1341,7 +1319,7 @@ emit_intrinsic_store_image(struct ir3_context *ctx, 
nir_intrinsic_instr *intr)
 * src2 is 64b byte offset
 */
 
-   offset = get_image_offset(ctx, var, coords, true);
+   offset = get_image_offset(ctx, var, coords);
 
/* NOTE: stib seems to take byte offset, but stgb.typed can be used
 * too and takes a dword offset.. not quite sure yet why blob uses
@@ -1443,7 +1421,7 @@ emit_intrinsic_atomic_image(struct ir3_context *ctx, 
nir_intrinsic_instr *intr)
 */
src0 = ir3_get_src(ctx, >src[3])[0];
src1 = ir3_create_collect(ctx, coords, ncoords);
-   src2 = get_image_offset(ctx, var, coords, false);
+   src2 = get_image_offset(ctx, var, coords);
 
switch (intr->intrinsic) {
case nir_intrinsic_image_deref_atomic_add:
@@ -1612,6 +1590,23 @@ emit_intrinsic(struct ir3_context *ctx, 
nir_intrinsic_instr *intr)
}
 
switch (intr->intrinsic) {
+   case nir_intrinsic_load_image_stride: {
+   idx = intr->const_index[0];
+
+   /* this is the index into image_dims offsets, which can take
+* values 0, 1 or 2 (bpp, y-stride, z-stride respectively).
+*/
+   uint8_t off = intr->const_index[1];
+   debug_assert(off <= 2);
+
+   unsigned cb = regid(ctx->so->constbase.image_dims, 0) +
+  

[Mesa-dev] [RFC 1/4] nir: Add a new intrinsic 'load_image_stride'

2019-01-25 Thread Eduardo Lima Mitev
This is an internal intrinsic intended to be injected by a
(freedreno-specific) 'lower_sampler_io' pass that will be introduced
later in this series; and consumed by ir3_compiler_nir.

The intrinsic will load in SSA values for various constants
for images (image_dims), namely the format's bytes-per-pixel,
y-stride and z-stride; for which the backend compiler will emit
the corresponding uniforms.

const_index[0] is the image index, and const_index[1] is the index
into image_dims' register file for a given image: 0 for bpp, 1 to
y-stride and 2 for z-stride.
---
 src/compiler/nir/nir_intrinsics.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/compiler/nir/nir_intrinsics.py 
b/src/compiler/nir/nir_intrinsics.py
index a5cc3f7401c..169c835d746 100644
--- a/src/compiler/nir/nir_intrinsics.py
+++ b/src/compiler/nir/nir_intrinsics.py
@@ -590,6 +590,8 @@ load("shared", 1, [BASE, ALIGN_MUL, ALIGN_OFFSET], 
[CAN_ELIMINATE])
 load("push_constant", 1, [BASE, RANGE], [CAN_ELIMINATE, CAN_REORDER])
 # src[] = { offset }. const_index[] = { base, range }
 load("constant", 1, [BASE, RANGE], [CAN_ELIMINATE, CAN_REORDER])
+# src[] = { offset }. const_index[] = { image_idx, dim_idx }
+load("image_stride", 1, [], [CAN_REORDER])
 
 # Stores work the same way as loads, except now the first source is the value
 # to store and the second (and possibly third) source specify where to store
-- 
2.20.1

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


[Mesa-dev] [RFC 3/4] ir3/nir: Add a new pass 'ir3_nir_lower_sampler_io'

2019-01-25 Thread Eduardo Lima Mitev
This pass moves to NIR some offset calculations that are currently
implemented on the backend compiler, to allow NIR to possibly
optimize them.

For now, only coordinate byte-offset calculations for imageStore
and image atomic operations are implemented.
---
 src/freedreno/Makefile.sources   |   1 +
 src/freedreno/ir3/ir3_nir.h  |   1 +
 src/freedreno/ir3/ir3_nir_lower_sampler_io.c | 349 +++
 3 files changed, 351 insertions(+)
 create mode 100644 src/freedreno/ir3/ir3_nir_lower_sampler_io.c

diff --git a/src/freedreno/Makefile.sources b/src/freedreno/Makefile.sources
index 7fea9de39ef..fd4f7f294cd 100644
--- a/src/freedreno/Makefile.sources
+++ b/src/freedreno/Makefile.sources
@@ -31,6 +31,7 @@ ir3_SOURCES := \
ir3/ir3_legalize.c \
ir3/ir3_nir.c \
ir3/ir3_nir.h \
+   ir3/ir3_nir_lower_sampler_io.c \
ir3/ir3_nir_lower_tg4_to_tex.c \
ir3/ir3_print.c \
ir3/ir3_ra.c \
diff --git a/src/freedreno/ir3/ir3_nir.h b/src/freedreno/ir3/ir3_nir.h
index 74201d34160..52809ba099e 100644
--- a/src/freedreno/ir3/ir3_nir.h
+++ b/src/freedreno/ir3/ir3_nir.h
@@ -36,6 +36,7 @@ void ir3_nir_scan_driver_consts(nir_shader *shader, struct 
ir3_driver_const_layo
 
 bool ir3_nir_apply_trig_workarounds(nir_shader *shader);
 bool ir3_nir_lower_tg4_to_tex(nir_shader *shader);
+bool ir3_nir_lower_sampler_io(nir_shader *shader);
 
 const nir_shader_compiler_options * ir3_get_compiler_options(struct 
ir3_compiler *compiler);
 bool ir3_key_lowers_nir(const struct ir3_shader_key *key);
diff --git a/src/freedreno/ir3/ir3_nir_lower_sampler_io.c 
b/src/freedreno/ir3/ir3_nir_lower_sampler_io.c
new file mode 100644
index 000..e2910d8906d
--- /dev/null
+++ b/src/freedreno/ir3/ir3_nir_lower_sampler_io.c
@@ -0,0 +1,349 @@
+/*
+ * Copyright © 2018 Igalia S.L.
+ *
+ * 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 "ir3_nir.h"
+#include "compiler/nir/nir_builder.h"
+
+/**
+ * The goal of this pass is to move to NIR some offset calculations for
+ * different I/O that are currently implemented on the backend compiler,
+ * to allow NIR to possibly optimize them.
+ *
+ * Currently, only offset calculations for image store and image
+ * atomic operations are implemented.
+ */
+
+
+/* This flag enables/disables a code-path where the bytes-per-pixel of
+ * an image is obtained directly from the format, which is known
+ * at shader compile time; as opposed to using image_dims[0] constant
+ * available only at shader runtime.
+ *
+ * Inlining the bytes-per-pixel here as an immediate has the advantage
+ * that it gets converted to a single (SHL) instruction (because all
+ * possible values are powers of two); while loading it as a uniform and
+ * emitting an IMUL will cause the backend to expand it to quite a few
+ * instructions (see ir3_compiler_nir for imul), thus ultimately hurting
+ * instruction count.
+ */
+#define INLINE_BPP 1
+
+
+static bool
+intrinsic_is_image_atomic(unsigned intrinsic)
+{
+   switch (intrinsic) {
+   case nir_intrinsic_image_deref_atomic_add:
+   case nir_intrinsic_image_deref_atomic_min:
+   case nir_intrinsic_image_deref_atomic_max:
+   case nir_intrinsic_image_deref_atomic_and:
+   case nir_intrinsic_image_deref_atomic_or:
+   case nir_intrinsic_image_deref_atomic_xor:
+   case nir_intrinsic_image_deref_atomic_exchange:
+   case nir_intrinsic_image_deref_atomic_comp_swap:
+   return true;
+   default:
+   break;
+   }
+
+   return false;
+}
+
+static bool
+intrinsic_is_image_store_or_atomic(unsigned intrinsic)
+{
+   if (intrinsic == nir_intrinsic_image_deref_store)
+   return true;
+   else
+   return intrinsic_is_image_atomic(intrinsic);
+}
+
+/*
+ * FIXME: shamelessly copied from ir3_compiler_nir until it gets factorized
+ * out at some point.
+ */

[Mesa-dev] [RFC 2/4] nir: Add a new ALU nir_op_imad

2019-01-25 Thread Eduardo Lima Mitev
ir3 compiler has an integer multiply-add instruction (IMAD_S24)
that is used for different offset calculations in the backend.
Since we intend to move some of these calculations to NIR, we need
a new ALU op that can represent it.
---
 src/compiler/nir/nir_opcodes.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/compiler/nir/nir_opcodes.py b/src/compiler/nir/nir_opcodes.py
index d32005846a6..b61845fd514 100644
--- a/src/compiler/nir/nir_opcodes.py
+++ b/src/compiler/nir/nir_opcodes.py
@@ -754,6 +754,7 @@ def triop_horiz(name, output_size, src1_size, src2_size, 
src3_size, const_expr):
[tuint, tuint, tuint], "", const_expr)
 
 triop("ffma", tfloat, "src0 * src1 + src2")
+triop("imad", tint, "src0 * src1 + src2")
 
 triop("flrp", tfloat, "src0 * (1 - src2) + src1 * src2")
 
-- 
2.20.1

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


Re: [Mesa-dev] [PATCH] freedreno/ir3: Handle GL_NONE in get_num_components_for_glformat()

2018-12-19 Thread Eduardo Lima Mitev
On 12/19/18 9:23 PM, Ilia Mirkin wrote:
> On Wed, Dec 19, 2018 at 3:18 AM Eduardo Lima Mitev  wrote:
>>
>> An earlier patch that introduced the function failed to handle the case
>> where an image format layout qualifier is not specified, which is allowed
>> in Core profiles. In these cases, nir_variable's image format is
>> GL_NONE, and we don't need to print a debug message for those.
>> ---
>>  src/freedreno/ir3/ir3_compiler_nir.c | 11 ---
>>  1 file changed, 8 insertions(+), 3 deletions(-)
>>
>> diff --git a/src/freedreno/ir3/ir3_compiler_nir.c 
>> b/src/freedreno/ir3/ir3_compiler_nir.c
>> index 19aef3eb27e..4b309fb3c84 100644
>> --- a/src/freedreno/ir3/ir3_compiler_nir.c
>> +++ b/src/freedreno/ir3/ir3_compiler_nir.c
>> @@ -1306,11 +1306,16 @@ get_num_components_for_glformat(GLuint format)
>> case GL_RGB10_A2:
>> return 4;
>>
>> +   case GL_NONE:
>> +   /* Omitting the image format qualifier is allowed on GL 
>> profiles.
> 
> I realize you're trying to make the distinction against GL ES, but
> that may not be clear. You could say "... on desktop GL profiles", for
> example. Your call. Either way,
> 

Yeah, I use GL vs. GLES profiles to make that distinction, but agree it
might not be clear outside my head, so I will clarify the comment before
pushing.

Thanks!

> Reviewed-by: Ilia Mirkin 
> 
>> +* Assuming 4 components is always safe.
>> +*/
>> +   return 4;
>> +
>> default:
>> /* Return 4 components also for all other formats we don't 
>> know
>> -* about. This is always safe. Also, the format should have 
>> been
>> -* validated already by the higher level API. Drop a debug 
>> message
>> -* just in case.
>> +* about. The format should have been validated already by
>> +* the higher level API, but drop a debug message just in 
>> case.
>>  */
>> debug_printf("Unhandled GL format %u while emitting 
>> imageStore()\n",
>>  format);
>> --
>> 2.19.2
>>
> 
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH] freedreno/ir3: Handle GL_NONE in get_num_components_for_glformat()

2018-12-19 Thread Eduardo Lima Mitev
An earlier patch that introduced the function failed to handle the case
where an image format layout qualifier is not specified, which is allowed
in Core profiles. In these cases, nir_variable's image format is
GL_NONE, and we don't need to print a debug message for those.
---
 src/freedreno/ir3/ir3_compiler_nir.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/freedreno/ir3/ir3_compiler_nir.c 
b/src/freedreno/ir3/ir3_compiler_nir.c
index 19aef3eb27e..4b309fb3c84 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -1306,11 +1306,16 @@ get_num_components_for_glformat(GLuint format)
case GL_RGB10_A2:
return 4;
 
+   case GL_NONE:
+   /* Omitting the image format qualifier is allowed on GL 
profiles.
+* Assuming 4 components is always safe.
+*/
+   return 4;
+
default:
/* Return 4 components also for all other formats we don't know
-* about. This is always safe. Also, the format should have been
-* validated already by the higher level API. Drop a debug 
message
-* just in case.
+* about. The format should have been validated already by
+* the higher level API, but drop a debug message just in case.
 */
debug_printf("Unhandled GL format %u while emitting 
imageStore()\n",
 format);
-- 
2.19.2

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


[Mesa-dev] [PATCH v3] freedreno/ir3: Make imageStore use num components from image format

2018-12-18 Thread Eduardo Lima Mitev
emit_intrinsic_store_image() is always using 4 components when
collecting registers for the value. When image has less than
4 components (e.g, r32f, r32i, r32ui) this results in extra mov
instructions.

This patch uses the actual number of components from the image format.

For example, in a shader like:

layout (r32f, binding=0) writeonly uniform imageBuffer u_image;
...
void main(void) {
   ...
   imageStore (u_image, some_offset, vec4(1.0));
   ...
}

instruction count is reduced in at least 3 instructions (note image
format is r32f, 1 component only).

This obviously reduces register pressure as well.

v2: - Added support for image formats from NV_image_format extension
(Ilia Mirkin).
- Return 4 components by default instead of asserting. (Rob Clark).

v3: Added more missing formats (Ilia Mirkin).
---
 src/freedreno/ir3/ir3_compiler_nir.c | 69 +++-
 1 file changed, 67 insertions(+), 2 deletions(-)

diff --git a/src/freedreno/ir3/ir3_compiler_nir.c 
b/src/freedreno/ir3/ir3_compiler_nir.c
index 85f14f354d2..80f6f70475d 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -1251,6 +1251,70 @@ emit_intrinsic_load_image(struct ir3_context *ctx, 
nir_intrinsic_instr *intr,
ir3_split_dest(b, dst, sam, 0, 4);
 }
 
+/* Returns the number of components for the different image formats
+ * supported by the GLES 3.1 spec, plus those added by the
+ * GL_NV_image_formats extension.
+ */
+static unsigned
+get_num_components_for_glformat(GLuint format)
+{
+   switch (format) {
+   case GL_R32F:
+   case GL_R32I:
+   case GL_R32UI:
+   case GL_R16F:
+   case GL_R16I:
+   case GL_R16UI:
+   case GL_R16:
+   case GL_R16_SNORM:
+   case GL_R8I:
+   case GL_R8UI:
+   case GL_R8:
+   case GL_R8_SNORM:
+   return 1;
+
+   case GL_RG32F:
+   case GL_RG32I:
+   case GL_RG32UI:
+   case GL_RG16F:
+   case GL_RG16I:
+   case GL_RG16UI:
+   case GL_RG16:
+   case GL_RG16_SNORM:
+   case GL_RG8I:
+   case GL_RG8UI:
+   case GL_RG8:
+   case GL_RG8_SNORM:
+   return 2;
+
+   case GL_R11F_G11F_B10F:
+   return 3;
+
+   case GL_RGBA32F:
+   case GL_RGBA32I:
+   case GL_RGBA32UI:
+   case GL_RGBA16F:
+   case GL_RGBA16I:
+   case GL_RGBA16UI:
+   case GL_RGBA16:
+   case GL_RGBA16_SNORM:
+   case GL_RGBA8:
+   case GL_RGBA8I:
+   case GL_RGBA8UI:
+   case GL_RGBA8_SNORM:
+   case GL_RGB10_A2UI:
+   case GL_RGB10_A2:
+   return 4;
+
+   default:
+   /* Return 4 components also for all other formats we don't know
+* about. This is always safe. Also, the format should have been
+* validated already by the higher level API.
+*/
+   return 4;
+   }
+}
+
 /* src[] = { deref, coord, sample_index, value }. const_index[] = {} */
 static void
 emit_intrinsic_store_image(struct ir3_context *ctx, nir_intrinsic_instr *intr)
@@ -1262,6 +1326,7 @@ emit_intrinsic_store_image(struct ir3_context *ctx, 
nir_intrinsic_instr *intr)
struct ir3_instruction * const *coords = ir3_get_src(ctx, 
>src[1]);
unsigned ncoords = get_image_coords(var, NULL);
unsigned tex_idx = get_image_slot(ctx, nir_src_as_deref(intr->src[0]));
+   unsigned ncomp = 
get_num_components_for_glformat(var->data.image.format);
 
/* src0 is value
 * src1 is coords
@@ -1276,10 +1341,10 @@ emit_intrinsic_store_image(struct ir3_context *ctx, 
nir_intrinsic_instr *intr)
 */
 
stib = ir3_STIB(b, create_immed(b, tex_idx), 0,
-   ir3_create_collect(ctx, value, 4), 0,
+   ir3_create_collect(ctx, value, ncomp), 0,
ir3_create_collect(ctx, coords, ncoords), 0,
offset, 0);
-   stib->cat6.iim_val = 4;
+   stib->cat6.iim_val = ncomp;
stib->cat6.d = ncoords;
stib->cat6.type = get_image_type(var);
stib->cat6.typed = true;
-- 
2.19.2

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


[Mesa-dev] [PATCH v2] freedreno/ir3: Make imageStore use num components from image format

2018-12-18 Thread Eduardo Lima Mitev
emit_intrinsic_store_image() is always using 4 components when
collecting registers for the value. When image has less than
4 components (e.g, r32f, r32i, r32ui) this results in extra mov
instructions.

This patch uses the actual number of components from the image format.

For example, in a shader like:

layout (r32f, binding=0) writeonly uniform imageBuffer u_image;
...
void main(void) {
   ...
   imageStore (u_image, some_offset, vec4(1.0));
   ...
}

instruction count is reduced in at least 3 instructions (note image
format is r32f, 1 component only).

This obviously reduces register pressure as well.

v2: - Added support for image formats from NV_image_format extension
(Ilia Mirkin).
- Return 4 components by default instead of asserting. (Rob Clark).
---
 src/freedreno/ir3/ir3_compiler_nir.c | 63 +++-
 1 file changed, 61 insertions(+), 2 deletions(-)

diff --git a/src/freedreno/ir3/ir3_compiler_nir.c 
b/src/freedreno/ir3/ir3_compiler_nir.c
index 85f14f354d2..e33d2b8fd46 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -1251,6 +1251,64 @@ emit_intrinsic_load_image(struct ir3_context *ctx, 
nir_intrinsic_instr *intr,
ir3_split_dest(b, dst, sam, 0, 4);
 }
 
+/* Returns the number of components for the different image formats
+ * supported by the GLES 3.1 spec, plus those added by the
+ * GL_NV_image_formats extension.
+ */
+static unsigned
+get_num_components_for_glformat(GLuint format)
+{
+   switch (format) {
+   case GL_R32F:
+   case GL_R16F:
+   case GL_R32I:
+   case GL_R32UI:
+   case GL_R16I:
+   case GL_R16UI:
+   case GL_R8I:
+   case GL_R8UI:
+   case GL_R8:
+   case GL_R8_SNORM:
+   return 1;
+
+   case GL_RG32F:
+   case GL_RG16F:
+   case GL_RG32I:
+   case GL_RG32UI:
+   case GL_RG16I:
+   case GL_RG16UI:
+   case GL_RG8I:
+   case GL_RG8UI:
+   case GL_RG8:
+   case GL_RG8_SNORM:
+   return 2;
+
+   case GL_R11F_G11F_B10F:
+   return 3;
+
+   case GL_RGBA32F:
+   case GL_RGBA16F:
+   case GL_RGBA8:
+   case GL_RGBA8_SNORM:
+   case GL_RGBA32I:
+   case GL_RGBA16I:
+   case GL_RGBA8I:
+   case GL_RGBA32UI:
+   case GL_RGBA16UI:
+   case GL_RGBA8UI:
+   case GL_RGB10_A2UI:
+   case GL_RGB10_A2:
+   return 4;
+
+   default:
+   /* Return 4 components also for all other formats we don't know
+* about. This is always safe. Also, the format should have been
+* validated already by the higher level API.
+*/
+   return 4;
+   }
+}
+
 /* src[] = { deref, coord, sample_index, value }. const_index[] = {} */
 static void
 emit_intrinsic_store_image(struct ir3_context *ctx, nir_intrinsic_instr *intr)
@@ -1262,6 +1320,7 @@ emit_intrinsic_store_image(struct ir3_context *ctx, 
nir_intrinsic_instr *intr)
struct ir3_instruction * const *coords = ir3_get_src(ctx, 
>src[1]);
unsigned ncoords = get_image_coords(var, NULL);
unsigned tex_idx = get_image_slot(ctx, nir_src_as_deref(intr->src[0]));
+   unsigned ncomp = 
get_num_components_for_glformat(var->data.image.format);
 
/* src0 is value
 * src1 is coords
@@ -1276,10 +1335,10 @@ emit_intrinsic_store_image(struct ir3_context *ctx, 
nir_intrinsic_instr *intr)
 */
 
stib = ir3_STIB(b, create_immed(b, tex_idx), 0,
-   ir3_create_collect(ctx, value, 4), 0,
+   ir3_create_collect(ctx, value, ncomp), 0,
ir3_create_collect(ctx, coords, ncoords), 0,
offset, 0);
-   stib->cat6.iim_val = 4;
+   stib->cat6.iim_val = ncomp;
stib->cat6.d = ncoords;
stib->cat6.type = get_image_type(var);
stib->cat6.typed = true;
-- 
2.19.2

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


Re: [Mesa-dev] [Freedreno] [PATCH] freedreno/ir3: Make imageStore use num components from image format

2018-12-18 Thread Eduardo Lima Mitev
On 12/18/18 2:31 PM, Rob Clark wrote:
> On Mon, Dec 17, 2018 at 3:41 PM Eduardo Lima Mitev  wrote:
>>
>> emit_intrinsic_store_image() is always using 4 components when
>> collecting registers for the value. When image has less than
>> 4 components (e.g, r32f, r32i, r32ui) this results in extra mov
>> instructions.
>>
>> This patch uses the actual number of components from the image format.
>>
>> For example, in a shader like:
>>
>> layout (r32f, binding=0) writeonly uniform imageBuffer u_image;
>> ...
>> void main(void) {
>>...
>>imageStore (u_image, some_offset, vec4(1.0));
>>...
>> }
>>
>> instruction count is reduced in at least 3 instructions (note image
>> format is r32f, 1 component only).
>>
>> This obviously reduces register pressure as well.
>> ---
>>  src/freedreno/ir3/ir3_compiler_nir.c | 34 ++--
>>  1 file changed, 32 insertions(+), 2 deletions(-)
>>
>> diff --git a/src/freedreno/ir3/ir3_compiler_nir.c 
>> b/src/freedreno/ir3/ir3_compiler_nir.c
>> index 85f14f354d2..cc00602c249 100644
>> --- a/src/freedreno/ir3/ir3_compiler_nir.c
>> +++ b/src/freedreno/ir3/ir3_compiler_nir.c
>> @@ -1251,6 +1251,35 @@ emit_intrinsic_load_image(struct ir3_context *ctx, 
>> nir_intrinsic_instr *intr,
>> ir3_split_dest(b, dst, sam, 0, 4);
>>  }
>>
>> +/* Get the number of components of the different image formats supported
>> + * by the GLES 3.1 spec.
>> + */
>> +static unsigned
>> +get_num_components_for_glformat(GLuint format)
>> +{
>> +   switch (format) {
>> +   case GL_R32F:
>> +   case GL_R32I:
>> +   case GL_R32UI:
>> +   return 1;
>> +
>> +   case GL_RGBA32F:
>> +   case GL_RGBA16F:
>> +   case GL_RGBA8:
>> +   case GL_RGBA8_SNORM:
>> +   case GL_RGBA32I:
>> +   case GL_RGBA16I:
>> +   case GL_RGBA8I:
>> +   case GL_RGBA32UI:
>> +   case GL_RGBA16UI:
>> +   case GL_RGBA8UI:
>> +   return 4;
>> +
>> +   default:
>> +   assert(!"Unsupported GL format for image");
> 
> One thought, default could still return 4, at least for release
> builds.. that should always be a safe fallback.  But I suppose
> addition of new formats maybe doesn't happen so much.
>

All things considered I think is better to make 4 components the
default. After all, we should not be in the business of validating
internal state at this point. And the worse case is we emit a few
unnecessary instructions.

>
> (There is no glsl_types helper for this?)
> 

I couldn't find any helper :(. There is glsl_get_components() but it
expects a glsl_type, and we have a GLformat enum. Also, this is only a
subset of GL formats that can be image textures.

> If we do have an assert, compile_assert() or ir3_context_error() would
> be nice, since (at least for debug builds) should print out the nir
> annotated w/ location of error, which I find convenient for debugging.
> 

Doesn't apply now that I've chosen to remove the assert, but I have
taken note!

Thanks,

Eduardo

> BR,
> -R
> 
> 
>> +   }
>> +}
>> +
>>  /* src[] = { deref, coord, sample_index, value }. const_index[] = {} */
>>  static void
>>  emit_intrinsic_store_image(struct ir3_context *ctx, nir_intrinsic_instr 
>> *intr)
>> @@ -1262,6 +1291,7 @@ emit_intrinsic_store_image(struct ir3_context *ctx, 
>> nir_intrinsic_instr *intr)
>> struct ir3_instruction * const *coords = ir3_get_src(ctx, 
>> >src[1]);
>> unsigned ncoords = get_image_coords(var, NULL);
>> unsigned tex_idx = get_image_slot(ctx, 
>> nir_src_as_deref(intr->src[0]));
>> +   unsigned ncomp = 
>> get_num_components_for_glformat(var->data.image.format);
>>
>> /* src0 is value
>>  * src1 is coords
>> @@ -1276,10 +1306,10 @@ emit_intrinsic_store_image(struct ir3_context *ctx, 
>> nir_intrinsic_instr *intr)
>>  */
>>
>> stib = ir3_STIB(b, create_immed(b, tex_idx), 0,
>> -   ir3_create_collect(ctx, value, 4), 0,
>> +   ir3_create_collect(ctx, value, ncomp), 0,
>> ir3_create_collect(ctx, coords, ncoords), 0,
>> offset, 0);
>> -   stib->cat6.iim_val = 4;
>> +   stib->cat6.iim_val = ncomp;
>> stib->cat6.d = ncoords;
>> stib->cat6.type = get_image_type(var);
>> stib->cat6.typed = true;
>> --
>> 2.19.2
>>
>> ___
>> Freedreno mailing list
>> freedr...@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/freedreno
> ___
> Freedreno mailing list
> freedr...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/freedreno
> 
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] freedreno/ir3: Make imageStore use num components from image format

2018-12-18 Thread Eduardo Lima Mitev
On 12/18/18 11:18 AM, Ilia Mirkin wrote:
> Nv_image_formats adds all the core formats to gles.
> 
> It's pretty easy to add them all in, so I don't see why not.
> 

Ok, I didn't know about that extension, thanks for the pointer.

It then makes sense to support all these formats, yes. I will submit an
v2 including them.

Thanks, Ilia.

> On Tue, Dec 18, 2018, 03:17 Eduardo Lima Mitev  <mailto:el...@igalia.com> wrote:
> 
> 
> 
> On 12/18/18 9:05 AM, Eduardo Lima Mitev wrote:
> > On 12/17/18 10:02 PM, Ilia Mirkin wrote:
> >> Note that the format may not be known. I suspect that falls into your
> >> "default" case.
> >>
> >
> > Hi Ilia,
> >
> > while on GLES profiles the format qualifier must be declared for all
> > image variables, it is true that core profiles allow to omit it for
> > writeonly-qualified images.
> >
> > I guess we can add a special case for GL_NONE to the switch, that also
> > returns 4 components, to at least not break current behavior if image
> > format is not known. What do you think?
> >
> 
> Thinking a bit more about this, if we care about core profile then there
> are more GL formats to consider apart from those supported by GLES 3.1.
> 
> However, since image format layout qualifiers were introduced in core
> 4.20, I don't think we should care for now. So I would leave the patch
> as-is and fail the assert on unknown formats.
> 
> Eduardo
> 
> > Eduardo
> >
> >> On Mon, Dec 17, 2018 at 3:41 PM Eduardo Lima Mitev
> mailto:el...@igalia.com>> wrote:
> >>>
> >>> emit_intrinsic_store_image() is always using 4 components when
> >>> collecting registers for the value. When image has less than
> >>> 4 components (e.g, r32f, r32i, r32ui) this results in extra mov
> >>> instructions.
> >>>
> >>> This patch uses the actual number of components from the image
> format.
> >>>
> >>> For example, in a shader like:
> >>>
> >>> layout (r32f, binding=0) writeonly uniform imageBuffer u_image;
> >>> ...
> >>> void main(void) {
> >>>    ...
> >>>    imageStore (u_image, some_offset, vec4(1.0));
> >>>    ...
> >>> }
> >>>
> >>> instruction count is reduced in at least 3 instructions (note image
> >>> format is r32f, 1 component only).
> >>>
> >>> This obviously reduces register pressure as well.
> >>> ---
> >>>  src/freedreno/ir3/ir3_compiler_nir.c | 34
> ++--
> >>>  1 file changed, 32 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/src/freedreno/ir3/ir3_compiler_nir.c
> b/src/freedreno/ir3/ir3_compiler_nir.c
> >>> index 85f14f354d2..cc00602c249 100644
> >>> --- a/src/freedreno/ir3/ir3_compiler_nir.c
> >>> +++ b/src/freedreno/ir3/ir3_compiler_nir.c
> >>> @@ -1251,6 +1251,35 @@ emit_intrinsic_load_image(struct
> ir3_context *ctx, nir_intrinsic_instr *intr,
> >>>         ir3_split_dest(b, dst, sam, 0, 4);
> >>>  }
> >>>
> >>> +/* Get the number of components of the different image formats
> supported
> >>> + * by the GLES 3.1 spec.
> >>> + */
> >>> +static unsigned
> >>> +get_num_components_for_glformat(GLuint format)
> >>> +{
> >>> +       switch (format) {
> >>> +       case GL_R32F:
> >>> +       case GL_R32I:
> >>> +       case GL_R32UI:
> >>> +               return 1;
> >>> +
> >>> +       case GL_RGBA32F:
> >>> +       case GL_RGBA16F:
> >>> +       case GL_RGBA8:
> >>> +       case GL_RGBA8_SNORM:
> >>> +       case GL_RGBA32I:
> >>> +       case GL_RGBA16I:
> >>> +       case GL_RGBA8I:
> >>> +       case GL_RGBA32UI:
> >>> +       case GL_RGBA16UI:
> >>> +       case GL_RGBA8UI:
> >>> +               return 4;
> >>> +
> >>> +       default:
> >>> +               assert(!"Unsupported GL format for image");
> >>> +       }
> >>> +}
> >&

Re: [Mesa-dev] [PATCH] freedreno/ir3: Make imageStore use num components from image format

2018-12-18 Thread Eduardo Lima Mitev


On 12/18/18 9:05 AM, Eduardo Lima Mitev wrote:
> On 12/17/18 10:02 PM, Ilia Mirkin wrote:
>> Note that the format may not be known. I suspect that falls into your
>> "default" case.
>>
> 
> Hi Ilia,
> 
> while on GLES profiles the format qualifier must be declared for all
> image variables, it is true that core profiles allow to omit it for
> writeonly-qualified images.
> 
> I guess we can add a special case for GL_NONE to the switch, that also
> returns 4 components, to at least not break current behavior if image
> format is not known. What do you think?
> 

Thinking a bit more about this, if we care about core profile then there
are more GL formats to consider apart from those supported by GLES 3.1.

However, since image format layout qualifiers were introduced in core
4.20, I don't think we should care for now. So I would leave the patch
as-is and fail the assert on unknown formats.

Eduardo

> Eduardo
> 
>> On Mon, Dec 17, 2018 at 3:41 PM Eduardo Lima Mitev  wrote:
>>>
>>> emit_intrinsic_store_image() is always using 4 components when
>>> collecting registers for the value. When image has less than
>>> 4 components (e.g, r32f, r32i, r32ui) this results in extra mov
>>> instructions.
>>>
>>> This patch uses the actual number of components from the image format.
>>>
>>> For example, in a shader like:
>>>
>>> layout (r32f, binding=0) writeonly uniform imageBuffer u_image;
>>> ...
>>> void main(void) {
>>>...
>>>imageStore (u_image, some_offset, vec4(1.0));
>>>...
>>> }
>>>
>>> instruction count is reduced in at least 3 instructions (note image
>>> format is r32f, 1 component only).
>>>
>>> This obviously reduces register pressure as well.
>>> ---
>>>  src/freedreno/ir3/ir3_compiler_nir.c | 34 ++--
>>>  1 file changed, 32 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/src/freedreno/ir3/ir3_compiler_nir.c 
>>> b/src/freedreno/ir3/ir3_compiler_nir.c
>>> index 85f14f354d2..cc00602c249 100644
>>> --- a/src/freedreno/ir3/ir3_compiler_nir.c
>>> +++ b/src/freedreno/ir3/ir3_compiler_nir.c
>>> @@ -1251,6 +1251,35 @@ emit_intrinsic_load_image(struct ir3_context *ctx, 
>>> nir_intrinsic_instr *intr,
>>> ir3_split_dest(b, dst, sam, 0, 4);
>>>  }
>>>
>>> +/* Get the number of components of the different image formats supported
>>> + * by the GLES 3.1 spec.
>>> + */
>>> +static unsigned
>>> +get_num_components_for_glformat(GLuint format)
>>> +{
>>> +   switch (format) {
>>> +   case GL_R32F:
>>> +   case GL_R32I:
>>> +   case GL_R32UI:
>>> +   return 1;
>>> +
>>> +   case GL_RGBA32F:
>>> +   case GL_RGBA16F:
>>> +   case GL_RGBA8:
>>> +   case GL_RGBA8_SNORM:
>>> +   case GL_RGBA32I:
>>> +   case GL_RGBA16I:
>>> +   case GL_RGBA8I:
>>> +   case GL_RGBA32UI:
>>> +   case GL_RGBA16UI:
>>> +   case GL_RGBA8UI:
>>> +   return 4;
>>> +
>>> +   default:
>>> +   assert(!"Unsupported GL format for image");
>>> +   }
>>> +}
>>> +
>>>  /* src[] = { deref, coord, sample_index, value }. const_index[] = {} */
>>>  static void
>>>  emit_intrinsic_store_image(struct ir3_context *ctx, nir_intrinsic_instr 
>>> *intr)
>>> @@ -1262,6 +1291,7 @@ emit_intrinsic_store_image(struct ir3_context *ctx, 
>>> nir_intrinsic_instr *intr)
>>> struct ir3_instruction * const *coords = ir3_get_src(ctx, 
>>> >src[1]);
>>> unsigned ncoords = get_image_coords(var, NULL);
>>> unsigned tex_idx = get_image_slot(ctx, 
>>> nir_src_as_deref(intr->src[0]));
>>> +   unsigned ncomp = 
>>> get_num_components_for_glformat(var->data.image.format);
>>>
>>> /* src0 is value
>>>  * src1 is coords
>>> @@ -1276,10 +1306,10 @@ emit_intrinsic_store_image(struct ir3_context *ctx, 
>>> nir_intrinsic_instr *intr)
>>>  */
>>>
>>> stib = ir3_STIB(b, create_immed(b, tex_idx), 0,
>>> -   ir3_create_collect(ctx, value, 4), 0,
>>> +   ir3_create_collect(ctx, value, ncomp), 0,
>>> ir3_create_collect(ctx, coords, ncoords), 0,
>>> offset, 0);
>>> -   stib->cat6.iim_val = 4;
>>> +   stib->cat6.iim_val = ncomp;
>>> stib->cat6.d = ncoords;
>>> stib->cat6.type = get_image_type(var);
>>> stib->cat6.typed = true;
>>> --
>>> 2.19.2
>>>
>>> ___
>>> mesa-dev mailing list
>>> mesa-dev@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>>
> ___
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] freedreno/ir3: Make imageStore use num components from image format

2018-12-18 Thread Eduardo Lima Mitev
On 12/17/18 10:02 PM, Ilia Mirkin wrote:
> Note that the format may not be known. I suspect that falls into your
> "default" case.
>

Hi Ilia,

while on GLES profiles the format qualifier must be declared for all
image variables, it is true that core profiles allow to omit it for
writeonly-qualified images.

I guess we can add a special case for GL_NONE to the switch, that also
returns 4 components, to at least not break current behavior if image
format is not known. What do you think?

Eduardo

> On Mon, Dec 17, 2018 at 3:41 PM Eduardo Lima Mitev  wrote:
>>
>> emit_intrinsic_store_image() is always using 4 components when
>> collecting registers for the value. When image has less than
>> 4 components (e.g, r32f, r32i, r32ui) this results in extra mov
>> instructions.
>>
>> This patch uses the actual number of components from the image format.
>>
>> For example, in a shader like:
>>
>> layout (r32f, binding=0) writeonly uniform imageBuffer u_image;
>> ...
>> void main(void) {
>>...
>>imageStore (u_image, some_offset, vec4(1.0));
>>...
>> }
>>
>> instruction count is reduced in at least 3 instructions (note image
>> format is r32f, 1 component only).
>>
>> This obviously reduces register pressure as well.
>> ---
>>  src/freedreno/ir3/ir3_compiler_nir.c | 34 ++--
>>  1 file changed, 32 insertions(+), 2 deletions(-)
>>
>> diff --git a/src/freedreno/ir3/ir3_compiler_nir.c 
>> b/src/freedreno/ir3/ir3_compiler_nir.c
>> index 85f14f354d2..cc00602c249 100644
>> --- a/src/freedreno/ir3/ir3_compiler_nir.c
>> +++ b/src/freedreno/ir3/ir3_compiler_nir.c
>> @@ -1251,6 +1251,35 @@ emit_intrinsic_load_image(struct ir3_context *ctx, 
>> nir_intrinsic_instr *intr,
>> ir3_split_dest(b, dst, sam, 0, 4);
>>  }
>>
>> +/* Get the number of components of the different image formats supported
>> + * by the GLES 3.1 spec.
>> + */
>> +static unsigned
>> +get_num_components_for_glformat(GLuint format)
>> +{
>> +   switch (format) {
>> +   case GL_R32F:
>> +   case GL_R32I:
>> +   case GL_R32UI:
>> +   return 1;
>> +
>> +   case GL_RGBA32F:
>> +   case GL_RGBA16F:
>> +   case GL_RGBA8:
>> +   case GL_RGBA8_SNORM:
>> +   case GL_RGBA32I:
>> +   case GL_RGBA16I:
>> +   case GL_RGBA8I:
>> +   case GL_RGBA32UI:
>> +   case GL_RGBA16UI:
>> +   case GL_RGBA8UI:
>> +   return 4;
>> +
>> +   default:
>> +   assert(!"Unsupported GL format for image");
>> +   }
>> +}
>> +
>>  /* src[] = { deref, coord, sample_index, value }. const_index[] = {} */
>>  static void
>>  emit_intrinsic_store_image(struct ir3_context *ctx, nir_intrinsic_instr 
>> *intr)
>> @@ -1262,6 +1291,7 @@ emit_intrinsic_store_image(struct ir3_context *ctx, 
>> nir_intrinsic_instr *intr)
>> struct ir3_instruction * const *coords = ir3_get_src(ctx, 
>> >src[1]);
>> unsigned ncoords = get_image_coords(var, NULL);
>> unsigned tex_idx = get_image_slot(ctx, 
>> nir_src_as_deref(intr->src[0]));
>> +   unsigned ncomp = 
>> get_num_components_for_glformat(var->data.image.format);
>>
>> /* src0 is value
>>  * src1 is coords
>> @@ -1276,10 +1306,10 @@ emit_intrinsic_store_image(struct ir3_context *ctx, 
>> nir_intrinsic_instr *intr)
>>  */
>>
>> stib = ir3_STIB(b, create_immed(b, tex_idx), 0,
>> -   ir3_create_collect(ctx, value, 4), 0,
>> +   ir3_create_collect(ctx, value, ncomp), 0,
>> ir3_create_collect(ctx, coords, ncoords), 0,
>> offset, 0);
>> -   stib->cat6.iim_val = 4;
>> +   stib->cat6.iim_val = ncomp;
>> stib->cat6.d = ncoords;
>> stib->cat6.type = get_image_type(var);
>> stib->cat6.typed = true;
>> --
>> 2.19.2
>>
>> ___
>> mesa-dev mailing list
>> mesa-dev@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH] freedreno/ir3: Make imageStore use num components from image format

2018-12-17 Thread Eduardo Lima Mitev
emit_intrinsic_store_image() is always using 4 components when
collecting registers for the value. When image has less than
4 components (e.g, r32f, r32i, r32ui) this results in extra mov
instructions.

This patch uses the actual number of components from the image format.

For example, in a shader like:

layout (r32f, binding=0) writeonly uniform imageBuffer u_image;
...
void main(void) {
   ...
   imageStore (u_image, some_offset, vec4(1.0));
   ...
}

instruction count is reduced in at least 3 instructions (note image
format is r32f, 1 component only).

This obviously reduces register pressure as well.
---
 src/freedreno/ir3/ir3_compiler_nir.c | 34 ++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/src/freedreno/ir3/ir3_compiler_nir.c 
b/src/freedreno/ir3/ir3_compiler_nir.c
index 85f14f354d2..cc00602c249 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -1251,6 +1251,35 @@ emit_intrinsic_load_image(struct ir3_context *ctx, 
nir_intrinsic_instr *intr,
ir3_split_dest(b, dst, sam, 0, 4);
 }
 
+/* Get the number of components of the different image formats supported
+ * by the GLES 3.1 spec.
+ */
+static unsigned
+get_num_components_for_glformat(GLuint format)
+{
+   switch (format) {
+   case GL_R32F:
+   case GL_R32I:
+   case GL_R32UI:
+   return 1;
+
+   case GL_RGBA32F:
+   case GL_RGBA16F:
+   case GL_RGBA8:
+   case GL_RGBA8_SNORM:
+   case GL_RGBA32I:
+   case GL_RGBA16I:
+   case GL_RGBA8I:
+   case GL_RGBA32UI:
+   case GL_RGBA16UI:
+   case GL_RGBA8UI:
+   return 4;
+
+   default:
+   assert(!"Unsupported GL format for image");
+   }
+}
+
 /* src[] = { deref, coord, sample_index, value }. const_index[] = {} */
 static void
 emit_intrinsic_store_image(struct ir3_context *ctx, nir_intrinsic_instr *intr)
@@ -1262,6 +1291,7 @@ emit_intrinsic_store_image(struct ir3_context *ctx, 
nir_intrinsic_instr *intr)
struct ir3_instruction * const *coords = ir3_get_src(ctx, 
>src[1]);
unsigned ncoords = get_image_coords(var, NULL);
unsigned tex_idx = get_image_slot(ctx, nir_src_as_deref(intr->src[0]));
+   unsigned ncomp = 
get_num_components_for_glformat(var->data.image.format);
 
/* src0 is value
 * src1 is coords
@@ -1276,10 +1306,10 @@ emit_intrinsic_store_image(struct ir3_context *ctx, 
nir_intrinsic_instr *intr)
 */
 
stib = ir3_STIB(b, create_immed(b, tex_idx), 0,
-   ir3_create_collect(ctx, value, 4), 0,
+   ir3_create_collect(ctx, value, ncomp), 0,
ir3_create_collect(ctx, coords, ncoords), 0,
offset, 0);
-   stib->cat6.iim_val = 4;
+   stib->cat6.iim_val = ncomp;
stib->cat6.d = ncoords;
stib->cat6.type = get_image_type(var);
stib->cat6.typed = true;
-- 
2.19.2

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


Re: [Mesa-dev] [PATCH] mesa/glformats: Remove redundant helper _mesa_base_format_component_count

2018-10-23 Thread Eduardo Lima Mitev
On 10/23/2018 08:17 AM, Tapani Pälli wrote:
> 
> On 10/23/18 8:56 AM, Eduardo Lima Mitev wrote:
>> There exists _mesa_components_in_format() which already includes
>> all cases handled in _mesa_base_format_component_count().
> 
> I guess the idea here was that one function only covers 'base formats'
> and other one all formats. But I guess none of the users verify if 'base
> format' is sane this way? If this is the case and there are no regressions;
> 

Yes, this is the best explanation for adding the helper.
However, looking at the the two uses of this function, it is not
expected that it validates the format as a base format. Also,
_mesa_base_format_component_count() handle mostly base formats anyway.

I ran the patch through Intel CI with no regressions.

> Reviewed-by: Tapani Pälli 
> 

Thanks!

Eduardo

> 
>> ---
>>   src/mesa/drivers/dri/i965/brw_blorp.c |  2 +-
>>   src/mesa/main/glformats.c | 27 ---
>>   src/mesa/main/glformats.h |  3 ---
>>   src/mesa/main/teximage.c  |  4 ++--
>>   4 files changed, 3 insertions(+), 33 deletions(-)
>>
>> diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c
>> b/src/mesa/drivers/dri/i965/brw_blorp.c
>> index ad3a47ef035..b286b231537 100644
>> --- a/src/mesa/drivers/dri/i965/brw_blorp.c
>> +++ b/src/mesa/drivers/dri/i965/brw_blorp.c
>> @@ -1195,7 +1195,7 @@ set_write_disables(const struct
>> intel_renderbuffer *irb,
>>   * RGB we can treat alpha as not used and write whatever we like
>> into it.
>>   */
>>  const GLenum base_format = irb->Base.Base._BaseFormat;
>> -   const int components =
>> _mesa_base_format_component_count(base_format);
>> +   const int components = _mesa_components_in_format(base_format);
>>  bool disables = false;
>>    assert(components > 0);
>> diff --git a/src/mesa/main/glformats.c b/src/mesa/main/glformats.c
>> index bbeb6034dd7..6cb3435dea2 100644
>> --- a/src/mesa/main/glformats.c
>> +++ b/src/mesa/main/glformats.c
>> @@ -1630,33 +1630,6 @@ _mesa_base_format_has_channel(GLenum
>> base_format, GLenum pname)
>>   }
>>     -/**
>> - * Returns the number of channels/components for a base format.
>> - */
>> -GLint
>> -_mesa_base_format_component_count(GLenum base_format)
>> -{
>> -   switch (base_format) {
>> -   case GL_LUMINANCE:
>> -   case GL_RED:
>> -   case GL_ALPHA:
>> -   case GL_INTENSITY:
>> -   case GL_DEPTH_COMPONENT:
>> -  return 1;
>> -   case GL_RG:
>> -   case GL_LUMINANCE_ALPHA:
>> -   case GL_DEPTH_STENCIL:
>> -  return 2;
>> -   case GL_RGB:
>> -  return 3;
>> -   case GL_RGBA:
>> -  return 4;
>> -   default:
>> -  return -1;
>> -   }
>> -}
>> -
>> -
>>   /**
>>    * If format is a generic compressed format, return the corresponding
>>    * non-compressed format.  For other formats, return the format as-is.
>> diff --git a/src/mesa/main/glformats.h b/src/mesa/main/glformats.h
>> index 5a21317159d..0aefdf50fef 100644
>> --- a/src/mesa/main/glformats.h
>> +++ b/src/mesa/main/glformats.h
>> @@ -119,9 +119,6 @@ _mesa_unpack_format_to_base_format(GLenum format);
>>   extern GLboolean
>>   _mesa_base_format_has_channel(GLenum base_format, GLenum pname);
>>   -extern GLint
>> -_mesa_base_format_component_count(GLenum base_format);
>> -
>>   extern GLenum
>>   _mesa_generic_compressed_format_to_uncompressed_format(GLenum format);
>>   diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
>> index d45854bd17f..6805b47c728 100644
>> --- a/src/mesa/main/teximage.c
>> +++ b/src/mesa/main/teximage.c
>> @@ -2407,8 +2407,8 @@ copytexture_error_check( struct gl_context *ctx,
>> GLuint dimensions,
>>    if (_mesa_is_gles(ctx)) {
>>     bool valid = true;
>> -  if (_mesa_base_format_component_count(baseFormat) >
>> -  _mesa_base_format_component_count(rb_base_format)) {
>> +  if (_mesa_components_in_format(baseFormat) >
>> +  _mesa_components_in_format(rb_base_format)) {
>>    valid = false;
>>     }
>>     if (baseFormat == GL_DEPTH_COMPONENT ||
>>
> 
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH] mesa/glformats: Remove redundant helper _mesa_base_format_component_count

2018-10-22 Thread Eduardo Lima Mitev
There exists _mesa_components_in_format() which already includes
all cases handled in _mesa_base_format_component_count().
---
 src/mesa/drivers/dri/i965/brw_blorp.c |  2 +-
 src/mesa/main/glformats.c | 27 ---
 src/mesa/main/glformats.h |  3 ---
 src/mesa/main/teximage.c  |  4 ++--
 4 files changed, 3 insertions(+), 33 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c 
b/src/mesa/drivers/dri/i965/brw_blorp.c
index ad3a47ef035..b286b231537 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.c
+++ b/src/mesa/drivers/dri/i965/brw_blorp.c
@@ -1195,7 +1195,7 @@ set_write_disables(const struct intel_renderbuffer *irb,
 * RGB we can treat alpha as not used and write whatever we like into it.
 */
const GLenum base_format = irb->Base.Base._BaseFormat;
-   const int components = _mesa_base_format_component_count(base_format);
+   const int components = _mesa_components_in_format(base_format);
bool disables = false;
 
assert(components > 0);
diff --git a/src/mesa/main/glformats.c b/src/mesa/main/glformats.c
index bbeb6034dd7..6cb3435dea2 100644
--- a/src/mesa/main/glformats.c
+++ b/src/mesa/main/glformats.c
@@ -1630,33 +1630,6 @@ _mesa_base_format_has_channel(GLenum base_format, GLenum 
pname)
 }
 
 
-/**
- * Returns the number of channels/components for a base format.
- */
-GLint
-_mesa_base_format_component_count(GLenum base_format)
-{
-   switch (base_format) {
-   case GL_LUMINANCE:
-   case GL_RED:
-   case GL_ALPHA:
-   case GL_INTENSITY:
-   case GL_DEPTH_COMPONENT:
-  return 1;
-   case GL_RG:
-   case GL_LUMINANCE_ALPHA:
-   case GL_DEPTH_STENCIL:
-  return 2;
-   case GL_RGB:
-  return 3;
-   case GL_RGBA:
-  return 4;
-   default:
-  return -1;
-   }
-}
-
-
 /**
  * If format is a generic compressed format, return the corresponding
  * non-compressed format.  For other formats, return the format as-is.
diff --git a/src/mesa/main/glformats.h b/src/mesa/main/glformats.h
index 5a21317159d..0aefdf50fef 100644
--- a/src/mesa/main/glformats.h
+++ b/src/mesa/main/glformats.h
@@ -119,9 +119,6 @@ _mesa_unpack_format_to_base_format(GLenum format);
 extern GLboolean
 _mesa_base_format_has_channel(GLenum base_format, GLenum pname);
 
-extern GLint
-_mesa_base_format_component_count(GLenum base_format);
-
 extern GLenum
 _mesa_generic_compressed_format_to_uncompressed_format(GLenum format);
 
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index d45854bd17f..6805b47c728 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -2407,8 +2407,8 @@ copytexture_error_check( struct gl_context *ctx, GLuint 
dimensions,
 
if (_mesa_is_gles(ctx)) {
   bool valid = true;
-  if (_mesa_base_format_component_count(baseFormat) >
-  _mesa_base_format_component_count(rb_base_format)) {
+  if (_mesa_components_in_format(baseFormat) >
+  _mesa_components_in_format(rb_base_format)) {
  valid = false;
   }
   if (baseFormat == GL_DEPTH_COMPONENT ||
-- 
2.19.1

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


Re: [Mesa-dev] [PATCH 09/12] compiler: All leaf Makefile.am should use +=

2017-12-25 Thread Eduardo Lima Mitev
Patches 06 to 09 are:

Reviewed-by: Eduardo Lima Mitev <el...@igalia.com>

However, I could not test 06 and 07 because they depend on applying 05
which needs update. Both look good, though.

Eduardo

On 11/21/2017 02:24 AM, Ian Romanick wrote:
> From: Ian Romanick <ian.d.roman...@intel.com>
>
> This slightly simplifies later changes that add more Makefile.*.am
> files.
>
> Signed-off-by: Ian Romanick <ian.d.roman...@intel.com>
> ---
>  src/compiler/Makefile.am  | 1 +
>  src/compiler/Makefile.glsl.am | 2 +-
>  2 files changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/src/compiler/Makefile.am b/src/compiler/Makefile.am
> index 45b9cc5..1f7a80b 100644
> --- a/src/compiler/Makefile.am
> +++ b/src/compiler/Makefile.am
> @@ -53,6 +53,7 @@ noinst_LTLIBRARIES = libcompiler.la
>  
>  libcompiler_la_SOURCES = $(LIBCOMPILER_FILES)
>  
> +noinst_PROGRAMS =
>  check_PROGRAMS =
>  TESTS =
>  BUILT_SOURCES =
> diff --git a/src/compiler/Makefile.glsl.am b/src/compiler/Makefile.glsl.am
> index 179f415..ad19b14 100644
> --- a/src/compiler/Makefile.glsl.am
> +++ b/src/compiler/Makefile.glsl.am
> @@ -54,7 +54,7 @@ check_PROGRAMS +=   \
>   glsl/tests/sampler-types-test   \
>   glsl/tests/uniform-initializer-test
>  
> -noinst_PROGRAMS = glsl_compiler
> +noinst_PROGRAMS += glsl_compiler
>  
>  glsl_tests_blob_test_SOURCES =   \
>   glsl/tests/blob_test.c

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


Re: [Mesa-dev] [PATCH 05/12] util: Move util_is_power_of_two to bitscan.h and rename to util_is_power_of_two_or_zero

2017-12-25 Thread Eduardo Lima Mitev
Ian, this patch 05 and 10 need update due to conflicts applying in
current master.

Eduardo


On 11/21/2017 02:24 AM, Ian Romanick wrote:
> From: Ian Romanick 
>
> The new name make the zero-input behavior more obvious.  The next
> patch adds a new function with different zero-input behavior.
>
> Signed-off-by: Ian Romanick 
> Suggested-by: Matt Turner 
> ---
>  src/amd/common/ac_gpu_info.c |  4 ++--
>  src/amd/common/ac_surface.c  |  2 +-
>  src/amd/vulkan/radv_formats.c|  4 ++--
>  src/broadcom/compiler/nir_to_vir.c   |  4 ++--
>  src/gallium/auxiliary/gallivm/lp_bld_arit.c  |  2 +-
>  src/gallium/auxiliary/gallivm/lp_bld_debug.cpp   |  2 +-
>  src/gallium/auxiliary/gallivm/lp_bld_format_aos.c|  4 ++--
>  src/gallium/auxiliary/gallivm/lp_bld_gather.c|  8 
>  src/gallium/auxiliary/gallivm/lp_bld_pack.c  |  2 +-
>  src/gallium/auxiliary/gallivm/lp_bld_sample.c|  6 +++---
>  src/gallium/auxiliary/util/u_math.h  | 10 +-
>  src/gallium/auxiliary/util/u_ringbuffer.c|  2 +-
>  src/gallium/drivers/etnaviv/etnaviv_texture.c|  2 +-
>  src/gallium/drivers/freedreno/freedreno_query_hw.c   |  2 +-
>  src/gallium/drivers/i915/i915_state_sampler.c|  3 ++-
>  src/gallium/drivers/llvmpipe/lp_state_fs.c   |  2 +-
>  src/gallium/drivers/llvmpipe/lp_texture.c|  2 +-
>  src/gallium/drivers/nouveau/codegen/nv50_ir.cpp  |  2 +-
>  src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp |  4 ++--
>  src/gallium/drivers/nouveau/nv30/nv30_miptree.c  |  6 +++---
>  src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c   |  2 +-
>  src/gallium/drivers/r300/r300_texture_desc.c |  6 +++---
>  src/gallium/drivers/r600/r600_texture.c  |  2 +-
>  src/gallium/drivers/radeon/r600_texture.c|  2 +-
>  src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c  |  2 +-
>  src/gallium/drivers/softpipe/sp_texture.c| 12 ++--
>  src/gallium/drivers/swr/swr_screen.cpp   |  4 ++--
>  src/gallium/drivers/vc4/vc4_program.c|  4 ++--
>  src/intel/vulkan/anv_allocator.c |  6 +++---
>  src/intel/vulkan/anv_formats.c   |  4 ++--
>  src/intel/vulkan/anv_nir_lower_multiview.c   |  2 +-
>  src/mesa/state_tracker/st_cb_readpixels.c|  4 ++--
>  src/mesa/state_tracker/st_cb_texture.c   |  6 +++---
>  src/util/bitscan.h   | 12 
>  src/util/u_vector.c  |  4 ++--
>  35 files changed, 75 insertions(+), 70 deletions(-)
>
> diff --git a/src/amd/common/ac_gpu_info.c b/src/amd/common/ac_gpu_info.c
> index 6e34a07..8e44b90 100644
> --- a/src/amd/common/ac_gpu_info.c
> +++ b/src/amd/common/ac_gpu_info.c
> @@ -297,8 +297,8 @@ bool ac_query_gpu_info(int fd, amdgpu_device_handle dev,
>   }
>   info->has_virtual_memory = true;
>  
> - assert(util_is_power_of_two(dma.available_rings + 1));
> - assert(util_is_power_of_two(compute.available_rings + 1));
> + assert(util_is_power_of_two_or_zero(dma.available_rings + 1));
> + assert(util_is_power_of_two_or_zero(compute.available_rings + 1));
>  
>   info->num_sdma_rings = util_bitcount(dma.available_rings);
>   info->num_compute_rings = util_bitcount(compute.available_rings);
> diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c
> index f7600a3..0ee7e65 100644
> --- a/src/amd/common/ac_surface.c
> +++ b/src/amd/common/ac_surface.c
> @@ -271,7 +271,7 @@ static int gfx6_compute_level(ADDR_HANDLE addrlib,
>   AddrSurfInfoIn->bpp) {
>   unsigned alignment = 256 / (AddrSurfInfoIn->bpp / 8);
>  
> - assert(util_is_power_of_two(AddrSurfInfoIn->bpp));
> + assert(util_is_power_of_two_or_zero(AddrSurfInfoIn->bpp));
>   AddrSurfInfoIn->width = align(AddrSurfInfoIn->width, alignment);
>   }
>  
> diff --git a/src/amd/vulkan/radv_formats.c b/src/amd/vulkan/radv_formats.c
> index 5c79ea7..587be9b 100644
> --- a/src/amd/vulkan/radv_formats.c
> +++ b/src/amd/vulkan/radv_formats.c
> @@ -602,13 +602,13 @@ radv_physical_device_get_format_properties(struct 
> radv_physical_device *physical
>   tiled |= 
> VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
>   }
>   }
> - if (tiled && 
> util_is_power_of_two(vk_format_get_blocksize(format)) && !scaled) {
> + if (tiled && 
> util_is_power_of_two_or_zero(vk_format_get_blocksize(format)) && !scaled) {
>   tiled |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR |
>   

Re: [Mesa-dev] [PATCH 04/12] spirv: Add SubgroupBallotKHR capability to SubgroupSize and SubgroupLocalInvocationId

2017-12-25 Thread Eduardo Lima Mitev
Patches 1 to 4 are:

Reviewed-by: Eduardo Lima Mitev <el...@igalia.com>

On 11/21/2017 02:24 AM, Ian Romanick wrote:
> From: Ian Romanick <ian.d.roman...@intel.com>
>
> The SPV_KHR_shader_ballot spec says:
>
> (Add the SubgroupBallotKHR capability to SubgroupSize.)
>
> (Add the SubgroupBallotKHR capability to SubgroupLocalInvocationId.)
>
> Yet the annotations are missing from the JSON.  See also
> https://github.com/KhronosGroup/SPIRV-Headers/issues/44.
> ---
>  src/compiler/spirv/spirv.core.grammar.json | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/src/compiler/spirv/spirv.core.grammar.json 
> b/src/compiler/spirv/spirv.core.grammar.json
> index 9a9b903..67903d5 100644
> --- a/src/compiler/spirv/spirv.core.grammar.json
> +++ b/src/compiler/spirv/spirv.core.grammar.json
> @@ -5210,7 +5210,7 @@
>  {
>"enumerant" : "SubgroupSize",
>"value" : 36,
> -  "capabilities" : [ "Kernel" ]
> +  "capabilities" : [ "Kernel", "SubgroupBallotKHR" ]
>  },
>  {
>"enumerant" : "SubgroupMaxSize",
> @@ -5235,7 +5235,7 @@
>  {
>"enumerant" : "SubgroupLocalInvocationId",
>"value" : 41,
> -  "capabilities" : [ "Kernel" ]
> +  "capabilities" : [ "Kernel", "SubgroupBallotKHR" ]
>  },
>  {
>"enumerant" : "VertexIndex",

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


Re: [Mesa-dev] [PATCH v3 00/10] Initial gl_spirv support in Mesa and i965

2017-12-14 Thread Eduardo Lima Mitev
Any chance to wrap up this review?

Thanks!

Eduardo


On 12/13/2017 08:32 PM, Eduardo Lima Mitev wrote:
> Hi,
>
> This is the 3rd version of the series adding initial support for ARB_gl_spirv.
>
> Previous versions of this series included also support for 
> ARB_spirv_extensions, but we have decided to split the two to ease review. So 
> I will be sending a second series with only the patches for spirv_extensions.
>
> Notice also that some patches from version 2 were merged in master. These 
> were already reviewed favorably and were fairly independent from the rest of 
> the series.
>
> There are still some patches in this new series with a Reviewed-by tag that 
> we didn't merge yet because we consider they should go in with the rest of 
> the series. The patches missing review are 01, 02, 03, 04 and 07.
>
> As usual, a git tree containing this series can be found at 
> <https://github.com/Igalia/mesa/tree/arb_gl_spirv-series1-v3> and the larger, 
> work-in-progress series at 
> <https://github.com/Igalia/mesa/tree/wip/igalia/arb_gl_spirv>.
>
> Thanks for reviewing!
>
> cheers,
> Eduardo
>
> Alejandro Piñeiro (2):
>   i965: initialize SPIR-V capabilities
>   nir/spirv: add gl_spirv_validation method
>
> Eduardo Lima Mitev (6):
>   mesa: Add a reference to gl_shader_spirv_data to gl_linked_shader
>   mesa/glspirv: Add _mesa_spirv_link_shaders() function
>   mesa/program: Link SPIR-V shaders using the SPIR-V code-path
>   mesa/glspirv: Add a _mesa_spirv_to_nir() function
>   i965: Call spirv_to_nir() instead of glsl_to_nir() for SPIR-V shaders
>   i965: Don't call process_glsl_ir() for SPIR-V shaders
>
> Nicolai Hähnle (2):
>   mesa: add gl_constants::SpirVCapabilities
>   mesa: Implement glSpecializeShaderARB
>
>  src/compiler/spirv/nir_spirv.h  |   5 +
>  src/compiler/spirv/spirv_to_nir.c   | 191 +++---
>  src/mesa/drivers/dri/i965/brw_context.c |  20 +++
>  src/mesa/drivers/dri/i965/brw_link.cpp  |   3 +-
>  src/mesa/drivers/dri/i965/brw_program.c |  10 +-
>  src/mesa/main/glspirv.c | 236 
> +++-
>  src/mesa/main/glspirv.h |  11 ++
>  src/mesa/main/mtypes.h  |  11 ++
>  src/mesa/main/shaderobj.c   |   1 +
>  src/mesa/program/ir_to_mesa.cpp |   6 +-
>  10 files changed, 472 insertions(+), 22 deletions(-)
>

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


Re: [Mesa-dev] [PATCH v2 00/25] Initial gl_spirv and spirv_extensions support in Mesa and i965

2017-12-14 Thread Eduardo Lima Mitev
Oops, sorry, wrong thread.

This is version 2 of the series and there is a version 3 which is the
one that needs review.

Eduardo


On 12/15/2017 08:13 AM, Eduardo Lima Mitev wrote:
> Any chance to wrap up this review?
>
> Thanks!
>
> Eduardo
>
> On 11/30/2017 06:28 PM, Eduardo Lima Mitev wrote:
>> Hello,
>>
>> This is the second version of the series providing initial support for 
>> ARB_gl_spirv and ARB_spirv_extensions in Mesa and i965.
>>
>> First version of the series can be found at 
>> <https://lists.freedesktop.org/archives/mesa-dev/2017-November/177004.html>.
>>
>> In this series we hope we have addressed all issues detected during the 
>> initial review. Thank you all who participated!
>>
>> Taking the nitpicks and minor fixes apart, most important changes compared 
>> to the first version are:
>>
>> * A dedicated 'spirv' flag was removed from gl_shader struct. Now we use the 
>> nulness of 'spirv_data' member for the same purpose.
>>
>> * The per-program 'spirv' flag was moved out of this series, but will likely 
>> be re-introduced in the next delivery, because it will become necessary.
>>
>> * We enforce one SPIR-V shader per stage, and fail linking if this condition 
>> is not met.
>>
>> * 'SpirVCapabilities' struct of GL context constants is no longer a pointer 
>> but a static struct.
>>
>> As usual, a tree of this series can be found at 
>> <https://github.com/Igalia/mesa/commits/arb_gl_spirv-series1-v2>.
>>
>> A tree of the larger WIP branch from which this series is taken: 
>> <https://github.com/Igalia/mesa/commits/wip/igalia/arb_gl_spirv>.
>>
>> Thanks in advance for the reviews!
>>
>> cheers,
>> Eduardo
>>
>> Alejandro Piñeiro (9):
>>   spirv_extensions: rename nir_spirv_supported_extensions
>>   mesa: move nir_spirv_supported_capabilities definition
>>   i965: initialize SPIR-V capabilities
>>   spirv_extensions: add GL_ARB_spirv_extensions boilerplate
>>   spirv_extensions: add list of extensions and to_string method
>>   spirv_extensions: define spirv_extensions_supported
>>   spirv_extensions: add spirv_supported_extensions on gl_constants
>>   spirv_extensions: i965: initialize SPIR-V extensions
>>   nir/spirv: add gl_spirv_validation method
>>
>> Eduardo Lima Mitev (8):
>>   mesa/glspirv: Add struct gl_shader_spirv_data
>>   mesa/glspirv: Add a _mesa_spirv_link_shaders() placeholder
>>   mesa/program: Link SPIR-V shaders using the SPIR-V code-path
>>   mesa: Add a reference to gl_shader_spirv_data to gl_linked_shader
>>   mesa/glspirv: Create gl_linked_shader objects for a SPIR-V program
>>   mesa/glspirv: Add a _mesa_spirv_to_nir() function
>>   i965: Call spirv_to_nir() instead of glsl_to_nir() for SPIR-V shaders
>>   i965: Don't call process_glsl_ir() for SPIR-V shaders
>>
>> Neil Roberts (1):
>>   mesa: Add boilerplate for the GL 4.6 alias of glSpecializeShaderARB
>>
>> Nicolai Hähnle (7):
>>   mesa: add GL_ARB_gl_spirv boilerplate
>>   mesa/glspirv: Add struct gl_spirv_module
>>   mesa: implement SPIR-V loading in glShaderBinary
>>   mesa/shaderapi: add a getter for GL_SPIR_V_BINARY_ARB
>>   mesa: refuse to compile SPIR-V shaders or link mixed shaders
>>   mesa: add gl_constants::SpirVCapabilities
>>   mesa: Implement glSpecializeShaderARB
>>
>>  src/amd/vulkan/radv_shader.c|   4 +-
>>  src/compiler/Makefile.sources   |   2 +
>>  src/compiler/spirv/nir_spirv.h  |  21 +-
>>  src/compiler/spirv/spirv_extensions.c   |  77 +++
>>  src/compiler/spirv/spirv_extensions.h   |  63 ++
>>  src/compiler/spirv/spirv_to_nir.c   | 160 +-
>>  src/compiler/spirv/vtn_private.h|   2 +-
>>  src/intel/vulkan/anv_pipeline.c |   4 +-
>>  src/mapi/glapi/gen/ARB_gl_spirv.xml |  21 ++
>>  src/mapi/glapi/gen/ARB_spirv_extensions.xml |  13 ++
>>  src/mapi/glapi/gen/GL4x.xml |  11 +
>>  src/mapi/glapi/gen/Makefile.am  |   2 +
>>  src/mapi/glapi/gen/gl_API.xml   |   8 +
>>  src/mapi/glapi/gen/gl_genexec.py|   1 +
>>  src/mapi/glapi/gen/meson.build  |   2 +
>>  src/mesa/Makefile.sources   |   4 +
>>  src/mesa/drivers/dri/i965/brw_context.c |  26 +++
>>  src/mesa/drivers/dri/i965/brw_link.cpp  |   3 +-
>>  src/mesa/drivers/dri/i965/brw_program.c |  14 +-
>>  src/mesa/main/context.c |   2 +
>>  src/mesa/main

Re: [Mesa-dev] [PATCH v2 00/25] Initial gl_spirv and spirv_extensions support in Mesa and i965

2017-12-14 Thread Eduardo Lima Mitev
Any chance to wrap up this review?

Thanks!

Eduardo

On 11/30/2017 06:28 PM, Eduardo Lima Mitev wrote:
> Hello,
>
> This is the second version of the series providing initial support for 
> ARB_gl_spirv and ARB_spirv_extensions in Mesa and i965.
>
> First version of the series can be found at 
> <https://lists.freedesktop.org/archives/mesa-dev/2017-November/177004.html>.
>
> In this series we hope we have addressed all issues detected during the 
> initial review. Thank you all who participated!
>
> Taking the nitpicks and minor fixes apart, most important changes compared to 
> the first version are:
>
> * A dedicated 'spirv' flag was removed from gl_shader struct. Now we use the 
> nulness of 'spirv_data' member for the same purpose.
>
> * The per-program 'spirv' flag was moved out of this series, but will likely 
> be re-introduced in the next delivery, because it will become necessary.
>
> * We enforce one SPIR-V shader per stage, and fail linking if this condition 
> is not met.
>
> * 'SpirVCapabilities' struct of GL context constants is no longer a pointer 
> but a static struct.
>
> As usual, a tree of this series can be found at 
> <https://github.com/Igalia/mesa/commits/arb_gl_spirv-series1-v2>.
>
> A tree of the larger WIP branch from which this series is taken: 
> <https://github.com/Igalia/mesa/commits/wip/igalia/arb_gl_spirv>.
>
> Thanks in advance for the reviews!
>
> cheers,
> Eduardo
>
> Alejandro Piñeiro (9):
>   spirv_extensions: rename nir_spirv_supported_extensions
>   mesa: move nir_spirv_supported_capabilities definition
>   i965: initialize SPIR-V capabilities
>   spirv_extensions: add GL_ARB_spirv_extensions boilerplate
>   spirv_extensions: add list of extensions and to_string method
>   spirv_extensions: define spirv_extensions_supported
>   spirv_extensions: add spirv_supported_extensions on gl_constants
>   spirv_extensions: i965: initialize SPIR-V extensions
>   nir/spirv: add gl_spirv_validation method
>
> Eduardo Lima Mitev (8):
>   mesa/glspirv: Add struct gl_shader_spirv_data
>   mesa/glspirv: Add a _mesa_spirv_link_shaders() placeholder
>   mesa/program: Link SPIR-V shaders using the SPIR-V code-path
>   mesa: Add a reference to gl_shader_spirv_data to gl_linked_shader
>   mesa/glspirv: Create gl_linked_shader objects for a SPIR-V program
>   mesa/glspirv: Add a _mesa_spirv_to_nir() function
>   i965: Call spirv_to_nir() instead of glsl_to_nir() for SPIR-V shaders
>   i965: Don't call process_glsl_ir() for SPIR-V shaders
>
> Neil Roberts (1):
>   mesa: Add boilerplate for the GL 4.6 alias of glSpecializeShaderARB
>
> Nicolai Hähnle (7):
>   mesa: add GL_ARB_gl_spirv boilerplate
>   mesa/glspirv: Add struct gl_spirv_module
>   mesa: implement SPIR-V loading in glShaderBinary
>   mesa/shaderapi: add a getter for GL_SPIR_V_BINARY_ARB
>   mesa: refuse to compile SPIR-V shaders or link mixed shaders
>   mesa: add gl_constants::SpirVCapabilities
>   mesa: Implement glSpecializeShaderARB
>
>  src/amd/vulkan/radv_shader.c|   4 +-
>  src/compiler/Makefile.sources   |   2 +
>  src/compiler/spirv/nir_spirv.h  |  21 +-
>  src/compiler/spirv/spirv_extensions.c   |  77 +++
>  src/compiler/spirv/spirv_extensions.h   |  63 ++
>  src/compiler/spirv/spirv_to_nir.c   | 160 +-
>  src/compiler/spirv/vtn_private.h|   2 +-
>  src/intel/vulkan/anv_pipeline.c |   4 +-
>  src/mapi/glapi/gen/ARB_gl_spirv.xml |  21 ++
>  src/mapi/glapi/gen/ARB_spirv_extensions.xml |  13 ++
>  src/mapi/glapi/gen/GL4x.xml |  11 +
>  src/mapi/glapi/gen/Makefile.am  |   2 +
>  src/mapi/glapi/gen/gl_API.xml   |   8 +
>  src/mapi/glapi/gen/gl_genexec.py|   1 +
>  src/mapi/glapi/gen/meson.build  |   2 +
>  src/mesa/Makefile.sources   |   4 +
>  src/mesa/drivers/dri/i965/brw_context.c |  26 +++
>  src/mesa/drivers/dri/i965/brw_link.cpp  |   3 +-
>  src/mesa/drivers/dri/i965/brw_program.c |  14 +-
>  src/mesa/main/context.c |   2 +
>  src/mesa/main/extensions_table.h|   2 +
>  src/mesa/main/get.c |   7 +
>  src/mesa/main/get_hash_params.py|   3 +
>  src/mesa/main/getstring.c   |  12 +
>  src/mesa/main/glspirv.c | 331 
> 
>  src/mesa/main/glspirv.h | 108 +
>  src/mesa/main/mtypes.h  |  31 +++
>  src/mesa/main/shaderapi.c   |  60 -
>  src/mesa/main/shaderobj.c   |   3 +
>  src/mesa/main/spirv_extensions

[Mesa-dev] [PATCH v3 6/6] i965: enable ARB_spirv_extensions for gen8+

2017-12-13 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

---
 src/mesa/drivers/dri/i965/intel_extensions.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/mesa/drivers/dri/i965/intel_extensions.c 
b/src/mesa/drivers/dri/i965/intel_extensions.c
index 4d17393948a..39680ed194a 100644
--- a/src/mesa/drivers/dri/i965/intel_extensions.c
+++ b/src/mesa/drivers/dri/i965/intel_extensions.c
@@ -280,6 +280,7 @@ intelInitExtensions(struct gl_context *ctx)
   ctx->Extensions.ARB_gpu_shader_int64 = true;
   ctx->Extensions.ARB_shader_ballot = true; /* requires 
ARB_gpu_shader_int64 */
   ctx->Extensions.ARB_ES3_2_compatibility = true;
+  ctx->Extensions.ARB_spirv_extensions = true;
}
 
if (devinfo->gen >= 9) {
-- 
2.15.1

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


[Mesa-dev] [PATCH v3 5/6] spirv_extensions: i965: initialize SPIR-V extensions

2017-12-13 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

v2: Rebase update after changes on previous patches.
---
 src/mesa/drivers/dri/i965/brw_context.c | 9 -
 src/mesa/main/context.c | 2 ++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.c 
b/src/mesa/drivers/dri/i965/brw_context.c
index a37bbb753d8..ea5892a8abf 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -76,6 +76,7 @@
 #include "isl/isl.h"
 
 #include "compiler/spirv/nir_spirv.h"
+#include "compiler/spirv/spirv_extensions.h"
 /***
  * Mesa's Driver Functions
  ***/
@@ -1084,9 +1085,15 @@ brwCreateContext(gl_api api,
_mesa_compute_version(ctx);
 
/* GL_ARB_gl_spirv */
-   if (ctx->Version >= 33)
+   if (ctx->Version >= 33) {
   brw_initialize_spirv_supported_capabilities(brw);
 
+  /* GL_ARB_spirv_extensions */
+  ctx->Const.SpirVExtensions = MALLOC_STRUCT(spirv_supported_extensions);
+  spirv_fill_supported_spirv_extensions(ctx->Const.SpirVExtensions,
+ >Const.SpirVCapabilities);
+   }
+
_mesa_initialize_dispatch_tables(ctx);
_mesa_initialize_vbo_vtxfmt(ctx);
 
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 3fa9f69f883..b48481d4372 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -1377,6 +1377,8 @@ _mesa_free_context_data( struct gl_context *ctx )
if (ctx == _mesa_get_current_context()) {
   _mesa_make_current(NULL, NULL, NULL);
}
+
+   free(ctx->Const.SpirVExtensions);
 }
 
 
-- 
2.15.1

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


[Mesa-dev] [PATCH v3 4/6] spirv_extensions: add spirv_supported_extensions on gl_constants

2017-12-13 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

We can use it to get real values for ARB_spirv_extensions methods.

v2: Rebase update after changes on previous patches.
---
 src/mesa/main/mtypes.h   |  3 +++
 src/mesa/main/spirv_extensions.c | 20 +++-
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 36534c3de81..cba12008599 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -4040,6 +4040,9 @@ struct gl_constants
 
/** GL_ARB_gl_spirv */
struct spirv_supported_capabilities SpirVCapabilities;
+
+   /** GL_ARB_spirv_extensions */
+   struct spirv_supported_extensions *SpirVExtensions;
 };
 
 
diff --git a/src/mesa/main/spirv_extensions.c b/src/mesa/main/spirv_extensions.c
index 40a89c133aa..2bb29461fd4 100644
--- a/src/mesa/main/spirv_extensions.c
+++ b/src/mesa/main/spirv_extensions.c
@@ -27,16 +27,34 @@
  */
 
 #include "spirv_extensions.h"
+#include "compiler/spirv/spirv_extensions.h"
 
 GLuint
 _mesa_get_spirv_extension_count(struct gl_context *ctx)
 {
-   return 0;
+   if (ctx->Const.SpirVExtensions == NULL)
+  return 0;
+
+   return ctx->Const.SpirVExtensions->count;
 }
 
 const GLubyte *
 _mesa_get_enabled_spirv_extension(struct gl_context *ctx,
   GLuint index)
 {
+   unsigned int n = 0;
+
+   if (ctx->Const.SpirVExtensions == NULL)
+  return (const GLubyte *) 0;
+
+   for (unsigned int i = 0; i < SPV_EXTENSIONS_COUNT; i++) {
+  if (ctx->Const.SpirVExtensions->supported[i]) {
+ if (n == index)
+return (const GLubyte *) spirv_extensions_to_string(i);
+ else
+n++;
+  }
+   }
+
return (const GLubyte *) 0;
 }
-- 
2.15.1

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


[Mesa-dev] [PATCH v3 3/6] spirv_extensions: define spirv_extensions_supported

2017-12-13 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

Add a struct to maintain which SPIR-V extensions are supported, and an
utility method to initialize it based on
nir_spirv_supported_capabilities.

v2:
  * Fixing code style (Ian Romanick)
  * Adding a prefix (spirv) to fill_supported_spirv_extensions (Ian Romanick)

v3: rebase update (nir_spirv_supported_extensions renamed)
---
 src/compiler/spirv/spirv_extensions.c | 32 
 src/compiler/spirv/spirv_extensions.h | 13 +
 2 files changed, 45 insertions(+)

diff --git a/src/compiler/spirv/spirv_extensions.c 
b/src/compiler/spirv/spirv_extensions.c
index 3acbe28408a..dd8df817c8c 100644
--- a/src/compiler/spirv/spirv_extensions.c
+++ b/src/compiler/spirv/spirv_extensions.c
@@ -21,6 +21,7 @@
  * IN THE SOFTWARE.
  */
 
+#include 
 #include "spirv_extensions.h"
 #include "util/macros.h"
 
@@ -44,3 +45,34 @@ spirv_extensions_to_string(enum SpvExtension ext)
 
return "unknown";
 }
+
+/**
+ * Sets the supported flags for known SPIR-V extensions based on the
+ * capabilites supported (spirv capabilities based on the spirv to nir
+ * support).
+ *
+ * One could argue that makes more sense in the other way around, as from the
+ * spec pov capabilities are enable for a given extension. But from our pov,
+ * we support or not (depending on the driver) some given capability, and
+ * spirv_to_nir check for capabilities not extensions. Also we usually fill
+ * first the supported capabilities, that are not always related to an
+ * extension.
+ */
+void
+spirv_fill_supported_spirv_extensions(struct spirv_supported_extensions *ext,
+  const struct 
spirv_supported_capabilities *cap)
+{
+   for (unsigned i = 0; i < SPV_EXTENSIONS_COUNT; i++)
+  ext->supported[i] = false;
+
+   ext->count = 0;
+
+   ext->supported[SPV_KHR_shader_draw_parameters] = cap->draw_parameters;
+   ext->supported[SPV_KHR_multiview] = cap->multiview;
+   ext->supported[SPV_KHR_variable_pointers] = cap->variable_pointers;
+
+   for (unsigned i = 0; i < SPV_EXTENSIONS_COUNT; i++) {
+  if (ext->supported[i])
+ ext->count++;
+   }
+}
diff --git a/src/compiler/spirv/spirv_extensions.h 
b/src/compiler/spirv/spirv_extensions.h
index 478b128e1da..d26882a8d4c 100644
--- a/src/compiler/spirv/spirv_extensions.h
+++ b/src/compiler/spirv/spirv_extensions.h
@@ -24,6 +24,8 @@
 #ifndef _SPIRV_EXTENSIONS_H_
 #define _SPIRV_EXTENSIONS_H_
 
+#include "compiler/shader_info.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -40,8 +42,19 @@ enum SpvExtension {
SPV_EXTENSIONS_COUNT
 };
 
+struct spirv_supported_extensions {
+   /** Flags the supported extensions. Array to make it easier to iterate. */
+   bool supported[SPV_EXTENSIONS_COUNT];
+
+   /** Number of supported extensions */
+   unsigned int count;
+};
+
 const char *spirv_extensions_to_string(enum SpvExtension ext);
 
+void spirv_fill_supported_spirv_extensions(struct spirv_supported_extensions 
*ext,
+   const struct 
spirv_supported_capabilities *cap);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.15.1

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


[Mesa-dev] [PATCH v3 2/6] spirv_extensions: add list of extensions and to_string method

2017-12-13 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

Ideally this should be generated somehow. One option would be gather
all the extension dependencies listed on the core grammar, but there
would be the possibility of not including some of the extensions.

Note that spirv-tools is doing it just slightly better, as it has a
hardcoded list of extensions manually took from the registry, that
they parse to get the enum and the to_string method (see
generate_grammar_tables.py).

v2:
  * Use a macro to improve readability. (Tapani Pälli)
  * Add unreachable on the switch, no default (Eric Engestrom)
  * No typedef enum (Ian Romanick)
  * Sort extensions names (Ian Romanick)
  * Don't add extensions unlikely to be supported by Mesa at any point
(Ian Romanick)

v3: rebase update
---
 src/compiler/Makefile.sources |  2 ++
 src/compiler/nir/meson.build  |  2 ++
 src/compiler/spirv/spirv_extensions.c | 46 
 src/compiler/spirv/spirv_extensions.h | 49 +++
 4 files changed, 99 insertions(+)
 create mode 100644 src/compiler/spirv/spirv_extensions.c
 create mode 100644 src/compiler/spirv/spirv_extensions.h

diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources
index d3f746f5f94..7961841bc79 100644
--- a/src/compiler/Makefile.sources
+++ b/src/compiler/Makefile.sources
@@ -297,6 +297,8 @@ SPIRV_FILES = \
spirv/GLSL.std.450.h \
spirv/nir_spirv.h \
spirv/spirv.h \
+   spirv/spirv_extensions.c \
+   spirv/spirv_extensions.h \
spirv/spirv_info.h \
spirv/spirv_to_nir.c \
spirv/vtn_alu.c \
diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build
index 5dd21e6652f..e3e4398e28b 100644
--- a/src/compiler/nir/meson.build
+++ b/src/compiler/nir/meson.build
@@ -185,6 +185,8 @@ files_libnir = files(
   '../spirv/GLSL.std.450.h',
   '../spirv/nir_spirv.h',
   '../spirv/spirv.h',
+  '../spirv/spirv_extensions.c',
+  '../spirv/spirv_extensions.h',
   '../spirv/spirv_info.h',
   '../spirv/spirv_to_nir.c',
   '../spirv/vtn_alu.c',
diff --git a/src/compiler/spirv/spirv_extensions.c 
b/src/compiler/spirv/spirv_extensions.c
new file mode 100644
index 000..3acbe28408a
--- /dev/null
+++ b/src/compiler/spirv/spirv_extensions.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * 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 "spirv_extensions.h"
+#include "util/macros.h"
+
+const char *
+spirv_extensions_to_string(enum SpvExtension ext)
+{
+#define STR(x) case x: return #x;
+   switch (ext) {
+   STR(SPV_KHR_16bit_storage);
+   STR(SPV_KHR_device_group);
+   STR(SPV_KHR_multiview);
+   STR(SPV_KHR_shader_ballot);
+   STR(SPV_KHR_shader_draw_parameters);
+   STR(SPV_KHR_storage_buffer_storage_class);
+   STR(SPV_KHR_subgroup_vote);
+   STR(SPV_KHR_variable_pointers);
+   case SPV_EXTENSIONS_COUNT:
+  unreachable("Unknown SPIR-V extension");
+   }
+#undef STR
+
+   return "unknown";
+}
diff --git a/src/compiler/spirv/spirv_extensions.h 
b/src/compiler/spirv/spirv_extensions.h
new file mode 100644
index 000..478b128e1da
--- /dev/null
+++ b/src/compiler/spirv/spirv_extensions.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * 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 

[Mesa-dev] [PATCH v3 1/6] spirv_extensions: add GL_ARB_spirv_extensions boilerplate

2017-12-13 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

v2:
  * Mention extension gap at gl_API.xml (Emil Velikov)
  * Bail with INVALID_ENUM if extension not available on getStringi (Emil 
Velikov)
  * Use EXTRA_EXT macro when defining the extension at
get.c/get_hash_params.py (Emil Velikov)
  * Rename source files (spirvextensions.[ch] -> spirv_extensions.[ch]) (Ian)

Reviewed-by: Ian Romanick 
---
 src/mapi/glapi/gen/ARB_spirv_extensions.xml | 13 
 src/mapi/glapi/gen/Makefile.am  |  1 +
 src/mapi/glapi/gen/gl_API.xml   |  4 +++
 src/mapi/glapi/gen/meson.build  |  1 +
 src/mesa/Makefile.sources   |  2 ++
 src/mesa/main/extensions_table.h|  1 +
 src/mesa/main/get.c |  6 
 src/mesa/main/get_hash_params.py|  3 ++
 src/mesa/main/getstring.c   | 12 +++
 src/mesa/main/mtypes.h  |  1 +
 src/mesa/main/spirv_extensions.c| 42 +
 src/mesa/main/spirv_extensions.h| 49 +
 src/mesa/meson.build|  2 ++
 13 files changed, 137 insertions(+)
 create mode 100644 src/mapi/glapi/gen/ARB_spirv_extensions.xml
 create mode 100644 src/mesa/main/spirv_extensions.c
 create mode 100644 src/mesa/main/spirv_extensions.h

diff --git a/src/mapi/glapi/gen/ARB_spirv_extensions.xml 
b/src/mapi/glapi/gen/ARB_spirv_extensions.xml
new file mode 100644
index 000..103393104c2
--- /dev/null
+++ b/src/mapi/glapi/gen/ARB_spirv_extensions.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/mapi/glapi/gen/Makefile.am b/src/mapi/glapi/gen/Makefile.am
index 35e37e95a9f..9a7a268adbf 100644
--- a/src/mapi/glapi/gen/Makefile.am
+++ b/src/mapi/glapi/gen/Makefile.am
@@ -167,6 +167,7 @@ API_XML = \
ARB_shader_subroutine.xml \
ARB_shader_storage_buffer_object.xml \
ARB_sparse_buffer.xml \
+   ARB_spirv_extensions.xml \
ARB_sync.xml \
ARB_tessellation_shader.xml \
ARB_texture_barrier.xml \
diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index d3594cfe195..00cf83eca03 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -8404,6 +8404,10 @@
 
 http://www.w3.org/2001/XInclude"/>
 
+
+
+http://www.w3.org/2001/XInclude"/>
+
 
 
 
diff --git a/src/mapi/glapi/gen/meson.build b/src/mapi/glapi/gen/meson.build
index a6a93cc83be..bfc766f7944 100644
--- a/src/mapi/glapi/gen/meson.build
+++ b/src/mapi/glapi/gen/meson.build
@@ -75,6 +75,7 @@ api_xml_files = files(
   'ARB_shader_subroutine.xml',
   'ARB_shader_storage_buffer_object.xml',
   'ARB_sparse_buffer.xml',
+  'ARB_spirv_extensions.xml',
   'ARB_sync.xml',
   'ARB_tessellation_shader.xml',
   'ARB_texture_barrier.xml',
diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources
index 53fa486364d..8a41ed1eeef 100644
--- a/src/mesa/Makefile.sources
+++ b/src/mesa/Makefile.sources
@@ -205,6 +205,8 @@ MAIN_FILES = \
main/shader_query.cpp \
main/shared.c \
main/shared.h \
+   main/spirv_extensions.c \
+   main/spirv_extensions.h \
main/state.c \
main/state.h \
main/stencil.c \
diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h
index ab15ceb9414..06deabd0640 100644
--- a/src/mesa/main/extensions_table.h
+++ b/src/mesa/main/extensions_table.h
@@ -129,6 +129,7 @@ EXT(ARB_shading_language_420pack, 
ARB_shading_language_420pack
 EXT(ARB_shading_language_packing, ARB_shading_language_packing 
  , GLL, GLC,  x ,  x , 2011)
 EXT(ARB_shadow  , ARB_shadow   
  , GLL,  x ,  x ,  x , 2001)
 EXT(ARB_sparse_buffer   , ARB_sparse_buffer
  , GLL, GLC,  x ,  x , 2014)
+EXT(ARB_spirv_extensions, ARB_spirv_extensions 
  ,  x,  GLC,  x ,  x , 2016)
 EXT(ARB_stencil_texturing   , ARB_stencil_texturing
  , GLL, GLC,  x ,  x , 2012)
 EXT(ARB_sync, ARB_sync 
  , GLL, GLC,  x ,  x , 2003)
 EXT(ARB_tessellation_shader , ARB_tessellation_shader  
  ,  x , GLC,  x ,  x , 2009)
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index c1b1a89ee05..0d3302dd962 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -34,6 +34,7 @@
 #include "get.h"
 #include "macros.h"
 #include "mtypes.h"
+#include "spirv_extensions.h"
 #include "state.h"
 #include "texcompress.h"
 #include "texstate.h"
@@ -501,6 +502,7 @@ EXTRA_EXT(OES_primitive_bounding_box);
 EXTRA_EXT(ARB_compute_variable_group_size);
 EXTRA_EXT(KHR_robustness);
 EXTRA_EXT(ARB_sparse_buffer);
+EXTRA_EXT(ARB_spirv_extensions);
 
 static const int
 extra_ARB_color_buffer_float_or_glcore[] = {
@@ -1159,6 +1161,10 @@ 

[Mesa-dev] [PATCH v3 0/6] ARB_spirv_extensions support in Mesa and i965

2017-12-13 Thread Eduardo Lima Mitev
Hi,

This series is the latest version of the support for ARB_spirv_extensions on 
i965.

It was split from a previous series that included also support for gl_spirv, 
but since this is an independent extension, we have chosen to send it 
separately to streamline review of the two series.

This extension however depends on gl_spirv, so it should be applied on top of 
the v3 series I just sent for gl_spirv 
 if 
someone wants to try it.

A tree of this series can be found at 
.

Thanks for reviewing!

cheers,
Eduardo

Alejandro Piñeiro (6):
  spirv_extensions: add GL_ARB_spirv_extensions boilerplate
  spirv_extensions: add list of extensions and to_string method
  spirv_extensions: define spirv_extensions_supported
  spirv_extensions: add spirv_supported_extensions on gl_constants
  spirv_extensions: i965: initialize SPIR-V extensions
  i965: enable ARB_spirv_extensions for gen8+

 src/compiler/Makefile.sources|  2 +
 src/compiler/nir/meson.build |  2 +
 src/compiler/spirv/spirv_extensions.c| 78 
 src/compiler/spirv/spirv_extensions.h| 62 ++
 src/mapi/glapi/gen/ARB_spirv_extensions.xml  | 13 +
 src/mapi/glapi/gen/Makefile.am   |  1 +
 src/mapi/glapi/gen/gl_API.xml|  4 ++
 src/mapi/glapi/gen/meson.build   |  1 +
 src/mesa/Makefile.sources|  2 +
 src/mesa/drivers/dri/i965/brw_context.c  |  9 +++-
 src/mesa/drivers/dri/i965/intel_extensions.c |  1 +
 src/mesa/main/context.c  |  2 +
 src/mesa/main/extensions_table.h |  1 +
 src/mesa/main/get.c  |  6 +++
 src/mesa/main/get_hash_params.py |  3 ++
 src/mesa/main/getstring.c| 12 +
 src/mesa/main/mtypes.h   |  4 ++
 src/mesa/main/spirv_extensions.c | 60 +
 src/mesa/main/spirv_extensions.h | 49 +
 src/mesa/meson.build |  2 +
 20 files changed, 313 insertions(+), 1 deletion(-)
 create mode 100644 src/compiler/spirv/spirv_extensions.c
 create mode 100644 src/compiler/spirv/spirv_extensions.h
 create mode 100644 src/mapi/glapi/gen/ARB_spirv_extensions.xml
 create mode 100644 src/mesa/main/spirv_extensions.c
 create mode 100644 src/mesa/main/spirv_extensions.h

-- 
2.15.1

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


[Mesa-dev] [PATCH v3 07/10] mesa/program: Link SPIR-V shaders using the SPIR-V code-path

2017-12-13 Thread Eduardo Lima Mitev
---
 src/mesa/program/ir_to_mesa.cpp | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 29198509a6c..5d56c2ef44a 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -36,6 +36,7 @@
 #include "main/shaderapi.h"
 #include "main/shaderobj.h"
 #include "main/uniforms.h"
+#include "main/glspirv.h"
 #include "compiler/glsl/ast.h"
 #include "compiler/glsl/ir.h"
 #include "compiler/glsl/ir_expression_flattening.h"
@@ -3112,7 +3113,10 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct 
gl_shader_program *prog)
}
 
if (prog->data->LinkStatus) {
-  link_shaders(ctx, prog);
+  if (!spirv)
+ link_shaders(ctx, prog);
+  else
+ _mesa_spirv_link_shaders(ctx, prog);
}
 
/* If LinkStatus is linking_success, then reset sampler validated to true.
-- 
2.15.1

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


[Mesa-dev] [PATCH v3 09/10] i965: Call spirv_to_nir() instead of glsl_to_nir() for SPIR-V shaders

2017-12-13 Thread Eduardo Lima Mitev
This is the main fork of the shader compilation code-path, where a NIR
shader is obtained by calling spirv_to_nir() or glsl_to_nir(),
depending on its nature..

v2: Use 'spirv_data' member from gl_linked_shader to know which method
   to call. (Timothy Arceri)

Reviewed-by: Timothy Arceri 
---
 src/mesa/drivers/dri/i965/brw_program.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_program.c 
b/src/mesa/drivers/dri/i965/brw_program.c
index 5b168c25e3d..5f564541cb2 100644
--- a/src/mesa/drivers/dri/i965/brw_program.c
+++ b/src/mesa/drivers/dri/i965/brw_program.c
@@ -31,6 +31,7 @@
 
 #include 
 #include "main/imports.h"
+#include "main/glspirv.h"
 #include "program/prog_parameter.h"
 #include "program/prog_print.h"
 #include "program/prog_to_nir.h"
@@ -74,9 +75,14 @@ brw_create_nir(struct brw_context *brw,
   ctx->Const.ShaderCompilerOptions[stage].NirOptions;
nir_shader *nir;
 
-   /* First, lower the GLSL IR or Mesa IR to NIR */
+   /* First, lower the GLSL/Mesa IR or SPIR-V to NIR */
if (shader_prog) {
-  nir = glsl_to_nir(shader_prog, stage, options);
+  if (shader_prog->_LinkedShaders[stage]->spirv_data)
+ nir = _mesa_spirv_to_nir(ctx, shader_prog, stage, options);
+  else
+ nir = glsl_to_nir(shader_prog, stage, options);
+  assert (nir);
+
   nir_remove_dead_variables(nir, nir_var_shader_in | nir_var_shader_out);
   nir_lower_returns(nir);
   nir_validate_shader(nir);
-- 
2.15.1

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


[Mesa-dev] [PATCH v3 06/10] mesa/glspirv: Add _mesa_spirv_link_shaders() function

2017-12-13 Thread Eduardo Lima Mitev
This is the equivalent to link_shaders() from
src/compiler/glsl/linker.cpp, but for SPIR-V programs. It just
creates the program and its gl_linked_shader objects, giving drivers
the opportunity to implement any linking of SPIR-V shaders they choose,
at a later stage.

v2: Bail out if we see more that one shader for the same stage, and add
   a corresponding comment. (Timothy Arceri)

v3: * Adds also a linker error log to the condition above, with a reference
   to the specification issue. (Timothy Arceri)
* Squash with the patch adding the function boilerplate (Timothy Arceri)

Reviewed-by: Timothy Arceri 
---
 src/mesa/main/glspirv.c | 71 +
 src/mesa/main/glspirv.h |  4 +++
 2 files changed, 75 insertions(+)

diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
index e8370e4c6f2..baed58380a8 100644
--- a/src/mesa/main/glspirv.c
+++ b/src/mesa/main/glspirv.c
@@ -28,6 +28,8 @@
 #include "compiler/nir/nir.h"
 #include "compiler/spirv/nir_spirv.h"
 
+#include "program/program.h"
+
 #include "util/u_atomic.h"
 
 void
@@ -103,6 +105,75 @@ _mesa_spirv_shader_binary(struct gl_context *ctx,
}
 }
 
+/**
+ * This is the equivalent to compiler/glsl/linker.cpp::link_shaders()
+ * but for SPIR-V programs.
+ *
+ * This method just creates the gl_linked_shader structs with a reference to
+ * the SPIR-V data collected during previous steps.
+ *
+ * The real linking happens later in the driver-specifc call LinkShader().
+ * This is so backends can implement different linking strategies for
+ * SPIR-V programs.
+ */
+void
+_mesa_spirv_link_shaders(struct gl_context *ctx, struct gl_shader_program 
*prog)
+{
+   prog->data->LinkStatus = linking_success;
+   prog->data->Validated = false;
+
+   for (unsigned i = 0; i < prog->NumShaders; i++) {
+  struct gl_shader *shader = prog->Shaders[i];
+  gl_shader_stage shader_type = shader->Stage;
+
+  /* We only support one shader per stage. The gl_spirv spec doesn't seem
+   * to prevent this, but the way the API is designed, requiring all 
shaders
+   * to be specialized with an entry point, makes supporting this quite
+   * undefined.
+   *
+   * TODO: Turn this into a proper error once the spec bug
+   *  is resolved.
+   */
+  if (prog->_LinkedShaders[shader_type]) {
+ ralloc_strcat(>data->InfoLog,
+   "\nError trying to link more than one SPIR-V shader "
+   "per stage.\n");
+ prog->data->LinkStatus = linking_failure;
+ return;
+  }
+
+  assert(shader->spirv_data);
+
+  struct gl_linked_shader *linked = rzalloc(NULL, struct gl_linked_shader);
+  linked->Stage = shader_type;
+
+  /* Create program and attach it to the linked shader */
+  struct gl_program *gl_prog =
+ ctx->Driver.NewProgram(ctx,
+_mesa_shader_stage_to_program(shader_type),
+prog->Name, false);
+  if (!gl_prog) {
+ prog->data->LinkStatus = linking_failure;
+ _mesa_delete_linked_shader(ctx, linked);
+ return;
+  }
+
+  _mesa_reference_shader_program_data(ctx,
+  _prog->sh.data,
+  prog->data);
+
+  /* Don't use _mesa_reference_program() just take ownership */
+  linked->Program = gl_prog;
+
+  /* Reference the SPIR-V data from shader to the linked shader */
+  _mesa_shader_spirv_data_reference(>spirv_data,
+shader->spirv_data);
+
+  prog->_LinkedShaders[shader_type] = linked;
+  prog->data->linked_stages |= 1 << shader_type;
+   }
+}
+
 void GLAPIENTRY
 _mesa_SpecializeShaderARB(GLuint shader,
   const GLchar *pEntryPoint,
diff --git a/src/mesa/main/glspirv.h b/src/mesa/main/glspirv.h
index ba281f68bef..0f03b75c111 100644
--- a/src/mesa/main/glspirv.h
+++ b/src/mesa/main/glspirv.h
@@ -76,6 +76,10 @@ _mesa_spirv_shader_binary(struct gl_context *ctx,
   unsigned n, struct gl_shader **shaders,
   const void* binary, size_t length);
 
+void
+_mesa_spirv_link_shaders(struct gl_context *ctx,
+ struct gl_shader_program *prog);
+
 /**
  * \name API functions
  */
-- 
2.15.1

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


[Mesa-dev] [PATCH v3 05/10] mesa: Add a reference to gl_shader_spirv_data to gl_linked_shader

2017-12-13 Thread Eduardo Lima Mitev
This is a reference to the spirv_data object stored in gl_shader, which
stores shader SPIR-V data that is needed during linking too.

Reviewed-by: Timothy Arceri 
---
 src/mesa/main/mtypes.h| 8 
 src/mesa/main/shaderobj.c | 1 +
 2 files changed, 9 insertions(+)

diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 2cc844da1d0..4ec60e25204 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2541,6 +2541,14 @@ struct gl_linked_shader
struct exec_list *packed_varyings;
struct exec_list *fragdata_arrays;
struct glsl_symbol_table *symbols;
+
+   /**
+* ARB_gl_spirv related data.
+*
+* This is actually a reference to the gl_shader::spirv_data, which
+* stores information that is also needed during linking.
+*/
+   struct gl_shader_spirv_data *spirv_data;
 };
 
 
diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
index 5c1cdd6b27a..834e2a92ec4 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -137,6 +137,7 @@ void
 _mesa_delete_linked_shader(struct gl_context *ctx,
struct gl_linked_shader *sh)
 {
+   _mesa_shader_spirv_data_reference(>spirv_data, NULL);
_mesa_reference_program(ctx, >Program, NULL);
ralloc_free(sh);
 }
-- 
2.15.1

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


[Mesa-dev] [PATCH v3 10/10] i965: Don't call process_glsl_ir() for SPIR-V shaders

2017-12-13 Thread Eduardo Lima Mitev
v2: Use 'spirv_data' from gl_linked_shader instead, to check if shader
   is SPIR-V. (Timothy Arceri)

Reviewed-by: Timothy Arceri 
---
 src/mesa/drivers/dri/i965/brw_link.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/mesa/drivers/dri/i965/brw_link.cpp 
b/src/mesa/drivers/dri/i965/brw_link.cpp
index 64267671c05..a010aadf2a5 100644
--- a/src/mesa/drivers/dri/i965/brw_link.cpp
+++ b/src/mesa/drivers/dri/i965/brw_link.cpp
@@ -236,7 +236,8 @@ brw_link_shader(struct gl_context *ctx, struct 
gl_shader_program *shProg)
   struct gl_program *prog = shader->Program;
   prog->Parameters = _mesa_new_parameter_list();
 
-  process_glsl_ir(brw, shProg, shader);
+  if (!shader->spirv_data)
+ process_glsl_ir(brw, shProg, shader);
 
   _mesa_copy_linked_program_data(shProg, shader);
 
-- 
2.15.1

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


[Mesa-dev] [PATCH v3 03/10] nir/spirv: add gl_spirv_validation method

2017-12-13 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

ARB_gl_spirv adds the ability to use SPIR-V binaries, and a new
method, glSpecializeShader. From OpenGL 4.6 spec, section 7.2.1
"Shader Specialization", error table:

   INVALID_VALUE is generated if  does not name a valid
   entry point for .

   INVALID_VALUE is generated if any element of 
   refers to a specialization constant that does not exist in the
   shader module contained in .""

But we are not really interested on creating the nir shader at that
point, and adding nir structures on the gl_program, so at that point
we are just interested on the error checking.

So we add a new method focused on just checking those errors. It still
needs to parse the binary, but skips what it is not needed, and
doesn't create the nir shader.

v2: rebase update (spirv_to_nir options added, changes on the warning
logging, and others)
v3: include passing options on common initialization, doesn't call
setjmp on common_initialization
---
 src/compiler/spirv/nir_spirv.h|   5 +
 src/compiler/spirv/spirv_to_nir.c | 191 ++
 2 files changed, 180 insertions(+), 16 deletions(-)

diff --git a/src/compiler/spirv/nir_spirv.h b/src/compiler/spirv/nir_spirv.h
index a2c40e57d18..d2766abb7f9 100644
--- a/src/compiler/spirv/nir_spirv.h
+++ b/src/compiler/spirv/nir_spirv.h
@@ -41,6 +41,7 @@ struct nir_spirv_specialization {
   uint32_t data32;
   uint64_t data64;
};
+   bool defined_on_module;
 };
 
 enum nir_spirv_debug_level {
@@ -69,6 +70,10 @@ struct spirv_to_nir_options {
} debug;
 };
 
+bool gl_spirv_validation(const uint32_t *words, size_t word_count,
+ struct nir_spirv_specialization *spec, unsigned 
num_spec,
+ gl_shader_stage stage, const char *entry_point_name);
+
 nir_function *spirv_to_nir(const uint32_t *words, size_t word_count,
struct nir_spirv_specialization *specializations,
unsigned num_specializations,
diff --git a/src/compiler/spirv/spirv_to_nir.c 
b/src/compiler/spirv/spirv_to_nir.c
index 0493dd3a8b1..7f959711be6 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -1227,6 +1227,7 @@ spec_constant_decoration_cb(struct vtn_builder *b, struct 
vtn_value *v,
 const_value->data64 = b->specializations[i].data64;
  else
 const_value->data32 = b->specializations[i].data32;
+ b->specializations[i].defined_on_module = true;
  return;
   }
}
@@ -1261,7 +1262,13 @@ handle_workgroup_size_decoration_cb(struct vtn_builder 
*b,
 const struct vtn_decoration *dec,
 void *data)
 {
+   /* This can happens if we are gl_spirv_validation. We can return safely, as
+* we don't need the workgroup info for such validation. */
+   if (b->shader == NULL)
+  return;
+
vtn_assert(member == -1);
+
if (dec->decoration != SpvDecorationBuiltIn ||
dec->literals[0] != SpvBuiltInWorkgroupSize)
   return;
@@ -3162,6 +3169,49 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, 
SpvOp opcode,
return true;
 }
 
+/*
+ * gl_spirv validation. Just need to check for the entry point.
+ */
+static bool
+vtn_validate_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
+  const uint32_t *w, unsigned count)
+{
+   switch (opcode) {
+   /* The following opcodes are not needed for gl_spirv, so we can skip
+* them.
+*/
+   case SpvOpSource:
+   case SpvOpSourceExtension:
+   case SpvOpSourceContinued:
+   case SpvOpExtension:
+   case SpvOpCapability:
+   case SpvOpExtInstImport:
+   case SpvOpMemoryModel:
+   case SpvOpString:
+   case SpvOpName:
+   case SpvOpMemberName:
+   case SpvOpExecutionMode:
+   case SpvOpDecorationGroup:
+   case SpvOpMemberDecorate:
+   case SpvOpGroupDecorate:
+   case SpvOpGroupMemberDecorate:
+  break;
+
+   case SpvOpEntryPoint:
+  vtn_handle_preamble_instruction(b, opcode, w, count);
+  break;
+
+   case SpvOpDecorate:
+  vtn_handle_decoration(b, opcode, w, count);
+  break;
+
+   default:
+  return false; /* End of preamble */
+   }
+
+   return true;
+}
+
 static void
 vtn_handle_execution_mode(struct vtn_builder *b, struct vtn_value *entry_point,
   const struct vtn_decoration *mode, void *data)
@@ -3371,6 +3421,22 @@ vtn_handle_variable_or_type_instruction(struct 
vtn_builder *b, SpvOp opcode,
return true;
 }
 
+static bool
+vtn_handle_constant_or_type_instruction(struct vtn_builder *b, SpvOp opcode,
+const uint32_t *w, unsigned count)
+{
+   switch (opcode) {
+   case SpvOpUndef:
+   case SpvOpVariable:
+  break;
+
+   default:
+  return vtn_handle_variable_or_type_instruction(b, opcode, w, count);
+   }
+
+   return true;
+}
+
 static bool
 

[Mesa-dev] [PATCH v3 04/10] mesa: Implement glSpecializeShaderARB

2017-12-13 Thread Eduardo Lima Mitev
From: Nicolai Hähnle 

v2: * Use gl_spirv_validation instead of spirv_to_nir.
   This method just validates the shader. The conversion to NIR will
   happen later, during linking. (Alejandro Piñeiro)

* Use gl_shader_spirv_data struct to store the SPIR-V data.
   (Eduardo Lima)

* Use the 'spirv_data' member to tell if the gl_shader is
   a SPIR-V shader, instead of a dedicated flag. (Timothy Arceri)
---
 src/mesa/main/glspirv.c | 107 +++-
 1 file changed, 105 insertions(+), 2 deletions(-)

diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
index 81303057d05..e8370e4c6f2 100644
--- a/src/mesa/main/glspirv.c
+++ b/src/mesa/main/glspirv.c
@@ -23,6 +23,11 @@
 
 #include "glspirv.h"
 #include "errors.h"
+#include "shaderobj.h"
+
+#include "compiler/nir/nir.h"
+#include "compiler/spirv/nir_spirv.h"
+
 #include "util/u_atomic.h"
 
 void
@@ -106,7 +111,105 @@ _mesa_SpecializeShaderARB(GLuint shader,
   const GLuint *pConstantValue)
 {
GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader *sh;
+   bool has_entry_point;
+   struct nir_spirv_specialization *spec_entries = NULL;
+
+   if (!ctx->Extensions.ARB_gl_spirv) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, "glSpecializeShaderARB");
+  return;
+   }
+
+   sh = _mesa_lookup_shader_err(ctx, shader, "glSpecializeShaderARB");
+   if (!sh)
+  return;
+
+   if (!sh->spirv_data) {
+  _mesa_error(ctx, GL_INVALID_OPERATION,
+  "glSpecializeShaderARB(not SPIR-V)");
+  return;
+   }
+
+   if (sh->CompileStatus) {
+  _mesa_error(ctx, GL_INVALID_OPERATION,
+  "glSpecializeShaderARB(already specialized)");
+  return;
+   }
+
+   struct gl_shader_spirv_data *spirv_data = sh->spirv_data;
+
+   /* From the GL_ARB_gl_spirv spec:
+*
+*"The OpenGL API expects the SPIR-V module to have already been
+* validated, and can return an error if it discovers anything invalid
+* in the module. An invalid SPIR-V module is allowed to result in
+* undefined behavior."
+*
+* However, the following errors still need to be detected (from the same
+* spec):
+*
+*"INVALID_VALUE is generated if  does not name a valid
+* entry point for .
+*
+* INVALID_VALUE is generated if any element of 
+* refers to a specialization constant that does not exist in the
+* shader module contained in ."
+*
+* We cannot flag those errors a-priori because detecting them requires
+* parsing the module. However, flagging them during specialization is okay,
+* since it makes no difference in terms of application-visible state.
+*/
+   spec_entries = calloc(sizeof(*spec_entries), numSpecializationConstants);
+
+   for (unsigned i = 0; i < numSpecializationConstants; ++i) {
+  spec_entries[i].id = pConstantIndex[i];
+  spec_entries[i].data32 = pConstantValue[i];
+  spec_entries[i].defined_on_module = false;
+   }
+
+   has_entry_point =
+  gl_spirv_validation((uint32_t *)_data->SpirVModule->Binary[0],
+  spirv_data->SpirVModule->Length / 4,
+  spec_entries, numSpecializationConstants,
+  sh->Stage, pEntryPoint);
+
+   /* See previous spec comment */
+   if (!has_entry_point) {
+  _mesa_error(ctx, GL_INVALID_VALUE,
+  "glSpecializeShaderARB(\"%s\" is not a valid entry point"
+  " for shader)", pEntryPoint);
+  goto end;
+   }
+
+   for (unsigned i = 0; i < numSpecializationConstants; ++i) {
+  if (spec_entries[i].defined_on_module == false) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glSpecializeShaderARB(constant \"%i\" does not exist "
+ "in shader)", spec_entries[i].id);
+ goto end;
+  }
+   }
+
+   spirv_data->SpirVEntryPoint = ralloc_strdup(spirv_data, pEntryPoint);
+
+   /* Note that we didn't make a real compilation of the module (spirv_to_nir),
+* but just checked some error conditions. Real "compilation" will be done
+* later, upon linking.
+*/
+   sh->CompileStatus = compile_success;
+
+   spirv_data->NumSpecializationConstants = numSpecializationConstants;
+   spirv_data->SpecializationConstantsIndex =
+  rzalloc_array_size(spirv_data, sizeof(GLuint),
+ numSpecializationConstants);
+   spirv_data->SpecializationConstantsValue =
+  rzalloc_array_size(spirv_data, sizeof(GLuint),
+ numSpecializationConstants);
+   for (unsigned i = 0; i < numSpecializationConstants; ++i) {
+  spirv_data->SpecializationConstantsIndex[i] = pConstantIndex[i];
+  spirv_data->SpecializationConstantsValue[i] = pConstantValue[i];
+   }
 
-   /* Just return GL_INVALID_OPERATION error while this is boilerplate */
-   _mesa_error(ctx, GL_INVALID_OPERATION, "SpecializeShaderARB");
+ end:
+   

[Mesa-dev] [PATCH v3 01/10] mesa: add gl_constants::SpirVCapabilities

2017-12-13 Thread Eduardo Lima Mitev
From: Nicolai Hähnle 

For drivers to declare which SPIR-V features they support.

v2: Don't use a pointer (Ian Romanick)
---
 src/mesa/main/mtypes.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index b372921e9f0..2cc844da1d0 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -4029,6 +4029,9 @@ struct gl_constants
 
/** GL_ARB_get_program_binary */
GLuint NumProgramBinaryFormats;
+
+   /** GL_ARB_gl_spirv */
+   struct spirv_supported_capabilities SpirVCapabilities;
 };
 
 
-- 
2.15.1

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


[Mesa-dev] [PATCH v3 02/10] i965: initialize SPIR-V capabilities

2017-12-13 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

Needed for ARB_gl_spirv. Right now those are the same that the intel
vulkan driver, but those are not shared. From the ARB_spirv_extensions
spec:

   "3. If a new GL extension is added that includes SPIR-V support via
   a new SPIR-V extension does it's SPIR-V extension also get
   enumerated by the SPIR_V_EXTENSIONS_ARB query?.

   RESOLVED. Yes. It's good to include it for consistency. Any SPIR-V
   functionality supported beyond the SPIR-V version that is required
   for the GL API version should be enumerated."

Reading between lines, there is the possibility of specific GL
extensions enabling specific SPIR-V extensions (so capabilities). That
would mean that it is possible that OpenGL and Vulkan not having the
same capabilities supported, even for the same driver. So for now we
keep them separate. Perhaps in the future it is better to keep them
the same and synced.

Note: we initialize SPIR-V capabilities at brwCreateContext instead of
the usual brw_initialize_context_constants because we want to do that
only for version >= 3.3. At brw_initialize_context_constans GL version
is still not computed.

v2:
   * Rebase update (SpirVCapabilities not a pointer anymore)
   * Fill spirv capabilities for OpenGL >= 3.3 (Ian Romanick)
---
 src/mesa/drivers/dri/i965/brw_context.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_context.c 
b/src/mesa/drivers/dri/i965/brw_context.c
index 126c187f629..a37bbb753d8 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -75,6 +75,7 @@
 #include "util/debug.h"
 #include "isl/isl.h"
 
+#include "compiler/spirv/nir_spirv.h"
 /***
  * Mesa's Driver Functions
  ***/
@@ -338,6 +339,21 @@ brw_init_driver_functions(struct brw_context *brw,
   brw_deserialize_program_binary;
 }
 
+static void
+brw_initialize_spirv_supported_capabilities(struct brw_context *brw)
+{
+   const struct gen_device_info *devinfo = >screen->devinfo;
+   struct gl_context *ctx = >ctx;
+
+   ctx->Const.SpirVCapabilities.float64 = devinfo->gen >= 8;
+   ctx->Const.SpirVCapabilities.int64 = devinfo->gen >= 8;
+   ctx->Const.SpirVCapabilities.tessellation = true;
+   ctx->Const.SpirVCapabilities.draw_parameters = true;
+   ctx->Const.SpirVCapabilities.image_write_without_format = true;
+   ctx->Const.SpirVCapabilities.multiview = true;
+   ctx->Const.SpirVCapabilities.variable_pointers = true;
+}
+
 static void
 brw_initialize_context_constants(struct brw_context *brw)
 {
@@ -1067,6 +1083,10 @@ brwCreateContext(gl_api api,
_mesa_override_extensions(ctx);
_mesa_compute_version(ctx);
 
+   /* GL_ARB_gl_spirv */
+   if (ctx->Version >= 33)
+  brw_initialize_spirv_supported_capabilities(brw);
+
_mesa_initialize_dispatch_tables(ctx);
_mesa_initialize_vbo_vtxfmt(ctx);
 
-- 
2.15.1

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


[Mesa-dev] [PATCH v3 08/10] mesa/glspirv: Add a _mesa_spirv_to_nir() function

2017-12-13 Thread Eduardo Lima Mitev
This is basically a wrapper around spirv_to_nir() that includes
arguments setup and post-conversion validation.

v2: * Rebase update (SpirVCapabilities not a pointer anymore,
spirv_to_nir_options added, and others).
* Code-style improvements and remove debug hunk. (Timothy Arceri)

Reviewed-by: Timothy Arceri 
---
 src/mesa/main/glspirv.c | 58 +
 src/mesa/main/glspirv.h |  7 ++
 2 files changed, 65 insertions(+)

diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
index baed58380a8..a5a2254bf9c 100644
--- a/src/mesa/main/glspirv.c
+++ b/src/mesa/main/glspirv.c
@@ -174,6 +174,64 @@ _mesa_spirv_link_shaders(struct gl_context *ctx, struct 
gl_shader_program *prog)
}
 }
 
+nir_shader *
+_mesa_spirv_to_nir(struct gl_context *ctx,
+   const struct gl_shader_program *prog,
+   gl_shader_stage stage,
+   const nir_shader_compiler_options *options)
+{
+   nir_shader *nir = NULL;
+
+   struct gl_linked_shader *linked_shader = prog->_LinkedShaders[stage];
+   assert (linked_shader);
+
+   struct gl_shader_spirv_data *spirv_data = linked_shader->spirv_data;
+   assert(spirv_data);
+
+   struct gl_spirv_module *spirv_module = spirv_data->SpirVModule;
+   assert (spirv_module != NULL);
+
+   const char *entry_point_name = spirv_data->SpirVEntryPoint;
+   assert(entry_point_name);
+
+   struct nir_spirv_specialization *spec_entries =
+  calloc(sizeof(*spec_entries),
+ spirv_data->NumSpecializationConstants);
+
+   for (unsigned i = 0; i < spirv_data->NumSpecializationConstants; ++i) {
+  spec_entries[i].id = spirv_data->SpecializationConstantsIndex[i];
+  spec_entries[i].data32 = spirv_data->SpecializationConstantsValue[i];
+  spec_entries[i].defined_on_module = false;
+   }
+
+   const struct spirv_to_nir_options spirv_options = {
+  .caps = ctx->Const.SpirVCapabilities
+   };
+
+   nir_function *entry_point =
+  spirv_to_nir((const uint32_t *) _module->Binary[0],
+   spirv_module->Length / 4,
+   spec_entries, spirv_data->NumSpecializationConstants,
+   stage, entry_point_name,
+   _options,
+   options);
+   free(spec_entries);
+
+   assert (entry_point);
+   nir = entry_point->shader;
+   assert(nir->info.stage == stage);
+
+   nir->options = options;
+
+   nir->info.name =
+  ralloc_asprintf(nir, "SPIRV:%s:%d",
+  _mesa_shader_stage_to_abbrev(nir->info.stage),
+  prog->Name);
+   nir_validate_shader(nir);
+
+   return nir;
+}
+
 void GLAPIENTRY
 _mesa_SpecializeShaderARB(GLuint shader,
   const GLchar *pEntryPoint,
diff --git a/src/mesa/main/glspirv.h b/src/mesa/main/glspirv.h
index 0f03b75c111..81626ce75b5 100644
--- a/src/mesa/main/glspirv.h
+++ b/src/mesa/main/glspirv.h
@@ -24,6 +24,7 @@
 #ifndef GLSPIRV_H
 #define GLSPIRV_H
 
+#include "compiler/nir/nir.h"
 #include "mtypes.h"
 
 #ifdef __cplusplus
@@ -80,6 +81,12 @@ void
 _mesa_spirv_link_shaders(struct gl_context *ctx,
  struct gl_shader_program *prog);
 
+nir_shader *
+_mesa_spirv_to_nir(struct gl_context *ctx,
+   const struct gl_shader_program *prog,
+   gl_shader_stage stage,
+   const nir_shader_compiler_options *options);
+
 /**
  * \name API functions
  */
-- 
2.15.1

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


[Mesa-dev] [PATCH v3 00/10] Initial gl_spirv support in Mesa and i965

2017-12-13 Thread Eduardo Lima Mitev
Hi,

This is the 3rd version of the series adding initial support for ARB_gl_spirv.

Previous versions of this series included also support for 
ARB_spirv_extensions, but we have decided to split the two to ease review. So I 
will be sending a second series with only the patches for spirv_extensions.

Notice also that some patches from version 2 were merged in master. These were 
already reviewed favorably and were fairly independent from the rest of the 
series.

There are still some patches in this new series with a Reviewed-by tag that we 
didn't merge yet because we consider they should go in with the rest of the 
series. The patches missing review are 01, 02, 03, 04 and 07.

As usual, a git tree containing this series can be found at 
<https://github.com/Igalia/mesa/tree/arb_gl_spirv-series1-v3> and the larger, 
work-in-progress series at 
<https://github.com/Igalia/mesa/tree/wip/igalia/arb_gl_spirv>.

Thanks for reviewing!

cheers,
Eduardo

Alejandro Piñeiro (2):
  i965: initialize SPIR-V capabilities
  nir/spirv: add gl_spirv_validation method

Eduardo Lima Mitev (6):
  mesa: Add a reference to gl_shader_spirv_data to gl_linked_shader
  mesa/glspirv: Add _mesa_spirv_link_shaders() function
  mesa/program: Link SPIR-V shaders using the SPIR-V code-path
  mesa/glspirv: Add a _mesa_spirv_to_nir() function
  i965: Call spirv_to_nir() instead of glsl_to_nir() for SPIR-V shaders
  i965: Don't call process_glsl_ir() for SPIR-V shaders

Nicolai Hähnle (2):
  mesa: add gl_constants::SpirVCapabilities
  mesa: Implement glSpecializeShaderARB

 src/compiler/spirv/nir_spirv.h  |   5 +
 src/compiler/spirv/spirv_to_nir.c   | 191 +++---
 src/mesa/drivers/dri/i965/brw_context.c |  20 +++
 src/mesa/drivers/dri/i965/brw_link.cpp  |   3 +-
 src/mesa/drivers/dri/i965/brw_program.c |  10 +-
 src/mesa/main/glspirv.c | 236 +++-
 src/mesa/main/glspirv.h |  11 ++
 src/mesa/main/mtypes.h  |  11 ++
 src/mesa/main/shaderobj.c   |   1 +
 src/mesa/program/ir_to_mesa.cpp |   6 +-
 10 files changed, 472 insertions(+), 22 deletions(-)

-- 
2.15.1

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


Re: [Mesa-dev] [PATCH] mesa: remove second include of errors.h in src/mesa/main/glspirv.c

2017-12-13 Thread Eduardo Lima Mitev

On 12/12/2017 05:56 PM, Ian Romanick wrote:
> Weird that this was not noticed before... *shrug*

This was a rebase mistake, sorry about that.

Thanks Kai for catching and fixing it.

Eduardo

> Reviewed-by: Ian Romanick 
>
> On 12/12/2017 07:20 AM, Kai Wasserbäch wrote:
>> Cc: Nicolai Hähnle 
>> Fixes: 5bc03d2508 ("mesa: implement SPIR-V loading in glShaderBinary")
>> Signed-off-by: Kai Wasserbäch 
>> ---
>>  src/mesa/main/glspirv.c | 4 
>>  1 file changed, 4 deletions(-)
>>
>> diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
>> index 7eb8f906c2..81303057d0 100644
>> --- a/src/mesa/main/glspirv.c
>> +++ b/src/mesa/main/glspirv.c
>> @@ -22,11 +22,7 @@
>>   */
>>  
>>  #include "glspirv.h"
>> -
>> -#include "errors.h"
>> -
>>  #include "errors.h"
>> -
>>  #include "util/u_atomic.h"
>>  
>>  void
>>
> ___
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev

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


Re: [Mesa-dev] [PATCH v2 00/25] Initial gl_spirv and spirv_extensions support in Mesa and i965

2017-12-11 Thread Eduardo Lima Mitev
On 12/12/2017 03:01 AM, Ian Romanick wrote:
> Any chance you could push an updated branch to your github? :)

Yes, sure. I was meant to send the v3 series already yesterday.

I just pushed the latest version of this series
to<https://github.com/Igalia/mesa/commits/arb_gl_spirv-series1-v2>.

And the full branch to
<https://github.com/Igalia/mesa/commits/wip/igalia/arb_gl_spirv>.

I'm will send a v3 soon, after I sort out the last review comment.

Eduardo

> On 11/30/2017 09:28 AM, Eduardo Lima Mitev wrote:
>> Hello,
>>
>> This is the second version of the series providing initial support for 
>> ARB_gl_spirv and ARB_spirv_extensions in Mesa and i965.
>>
>> First version of the series can be found at 
>> <https://lists.freedesktop.org/archives/mesa-dev/2017-November/177004.html>.
>>
>> In this series we hope we have addressed all issues detected during the 
>> initial review. Thank you all who participated!
>>
>> Taking the nitpicks and minor fixes apart, most important changes compared 
>> to the first version are:
>>
>> * A dedicated 'spirv' flag was removed from gl_shader struct. Now we use the 
>> nulness of 'spirv_data' member for the same purpose.
>>
>> * The per-program 'spirv' flag was moved out of this series, but will likely 
>> be re-introduced in the next delivery, because it will become necessary.
>>
>> * We enforce one SPIR-V shader per stage, and fail linking if this condition 
>> is not met.
>>
>> * 'SpirVCapabilities' struct of GL context constants is no longer a pointer 
>> but a static struct.
>>
>> As usual, a tree of this series can be found at 
>> <https://github.com/Igalia/mesa/commits/arb_gl_spirv-series1-v2>.
>>
>> A tree of the larger WIP branch from which this series is taken: 
>> <https://github.com/Igalia/mesa/commits/wip/igalia/arb_gl_spirv>.
>>
>> Thanks in advance for the reviews!
>>
>> cheers,
>> Eduardo
>>
>> Alejandro Piñeiro (9):
>>   spirv_extensions: rename nir_spirv_supported_extensions
>>   mesa: move nir_spirv_supported_capabilities definition
>>   i965: initialize SPIR-V capabilities
>>   spirv_extensions: add GL_ARB_spirv_extensions boilerplate
>>   spirv_extensions: add list of extensions and to_string method
>>   spirv_extensions: define spirv_extensions_supported
>>   spirv_extensions: add spirv_supported_extensions on gl_constants
>>   spirv_extensions: i965: initialize SPIR-V extensions
>>   nir/spirv: add gl_spirv_validation method
>>
>> Eduardo Lima Mitev (8):
>>   mesa/glspirv: Add struct gl_shader_spirv_data
>>   mesa/glspirv: Add a _mesa_spirv_link_shaders() placeholder
>>   mesa/program: Link SPIR-V shaders using the SPIR-V code-path
>>   mesa: Add a reference to gl_shader_spirv_data to gl_linked_shader
>>   mesa/glspirv: Create gl_linked_shader objects for a SPIR-V program
>>   mesa/glspirv: Add a _mesa_spirv_to_nir() function
>>   i965: Call spirv_to_nir() instead of glsl_to_nir() for SPIR-V shaders
>>   i965: Don't call process_glsl_ir() for SPIR-V shaders
>>
>> Neil Roberts (1):
>>   mesa: Add boilerplate for the GL 4.6 alias of glSpecializeShaderARB
>>
>> Nicolai Hähnle (7):
>>   mesa: add GL_ARB_gl_spirv boilerplate
>>   mesa/glspirv: Add struct gl_spirv_module
>>   mesa: implement SPIR-V loading in glShaderBinary
>>   mesa/shaderapi: add a getter for GL_SPIR_V_BINARY_ARB
>>   mesa: refuse to compile SPIR-V shaders or link mixed shaders
>>   mesa: add gl_constants::SpirVCapabilities
>>   mesa: Implement glSpecializeShaderARB
>>
>>  src/amd/vulkan/radv_shader.c|   4 +-
>>  src/compiler/Makefile.sources   |   2 +
>>  src/compiler/spirv/nir_spirv.h  |  21 +-
>>  src/compiler/spirv/spirv_extensions.c   |  77 +++
>>  src/compiler/spirv/spirv_extensions.h   |  63 ++
>>  src/compiler/spirv/spirv_to_nir.c   | 160 +-
>>  src/compiler/spirv/vtn_private.h|   2 +-
>>  src/intel/vulkan/anv_pipeline.c |   4 +-
>>  src/mapi/glapi/gen/ARB_gl_spirv.xml |  21 ++
>>  src/mapi/glapi/gen/ARB_spirv_extensions.xml |  13 ++
>>  src/mapi/glapi/gen/GL4x.xml |  11 +
>>  src/mapi/glapi/gen/Makefile.am  |   2 +
>>  src/mapi/glapi/gen/gl_API.xml   |   8 +
>>  src/mapi/glapi/gen/gl_genexec.py|   1 +
>>  src/mapi/glapi/gen/meson.build  |   2 +
>>  src/mesa/Makefile.sources   |   4 +
>>  src/mesa/drivers/dri/i965/brw_context.c |  26 +++
>

Re: [Mesa-dev] [PATCH v2 19/25] mesa/glspirv: Add a _mesa_spirv_link_shaders() placeholder

2017-12-07 Thread Eduardo Lima Mitev
On 12/07/2017 05:51 AM, Timothy Arceri wrote:
> Please squash this with patch 22 tis is just code churn.
>

Ok, this makes sense, though I will have to re-order a bit the patches
to keep each single one building fine.

I the squashed result would keep your R-b from patch 22, right?

thnaks,
Eduardo

> On 01/12/17 04:28, Eduardo Lima Mitev wrote:
>> This will be the equivalent to link_shaders() from
>> src/compiler/glsl/linker.cpp, but for SPIR-V programs.
>> ---
>>   src/mesa/main/glspirv.c | 10 ++
>>   src/mesa/main/glspirv.h |  4 
>>   2 files changed, 14 insertions(+)
>>
>> diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
>> index 18710c0d8fc..e533853f7fa 100644
>> --- a/src/mesa/main/glspirv.c
>> +++ b/src/mesa/main/glspirv.c
>> @@ -104,6 +104,16 @@ _mesa_spirv_shader_binary(struct gl_context *ctx,
>>  }
>>   }
>>   +void
>> +_mesa_spirv_link_shaders(struct gl_context *ctx, struct
>> gl_shader_program *prog)
>> +{
>> +   /* @TODO: This is a placeholder for the equivalent of
>> +    * compiler/glsl/linker.cpp::link_shaders() but for SPIR-V.
>> +    */
>> +   prog->data->LinkStatus = linking_success;
>> +   prog->data->Validated = false;
>> +}
>> +
>>   void GLAPIENTRY
>>   _mesa_SpecializeShaderARB(GLuint shader,
>>     const GLchar *pEntryPoint,
>> diff --git a/src/mesa/main/glspirv.h b/src/mesa/main/glspirv.h
>> index ba281f68bef..0f03b75c111 100644
>> --- a/src/mesa/main/glspirv.h
>> +++ b/src/mesa/main/glspirv.h
>> @@ -76,6 +76,10 @@ _mesa_spirv_shader_binary(struct gl_context *ctx,
>>     unsigned n, struct gl_shader **shaders,
>>     const void* binary, size_t length);
>>   +void
>> +_mesa_spirv_link_shaders(struct gl_context *ctx,
>> + struct gl_shader_program *prog);
>> +
>>   /**
>>    * \name API functions
>>    */
>>
>

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


Re: [Mesa-dev] [PATCH v2 23/25] mesa/glspirv: Add a _mesa_spirv_to_nir() function

2017-12-06 Thread Eduardo Lima Mitev
On 12/06/2017 10:13 AM, Timothy Arceri wrote:
>
>
> On 01/12/17 04:28, Eduardo Lima Mitev wrote:
>> This is basically a wrapper around spirv_to_nir() that includes
>> arguments setup and post-conversion validation.
>>
>> v2: Rebase update (SpirVCapabilities not a pointer anymore)
>> ---
>>   src/mesa/main/glspirv.c | 60
>> +
>>   src/mesa/main/glspirv.h |  7 ++
>>   2 files changed, 67 insertions(+)
>>
>> diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
>> index e5dc8b26ea9..2a20e4b5cc7 100644
>> --- a/src/mesa/main/glspirv.c
>> +++ b/src/mesa/main/glspirv.c
>> @@ -159,6 +159,66 @@ _mesa_spirv_link_shaders(struct gl_context *ctx,
>> struct gl_shader_program *prog)
>>  }
>>   }
>>   +nir_shader *
>> +_mesa_spirv_to_nir(struct gl_context *ctx,
>> +   const struct gl_shader_program *prog,
>> +   gl_shader_stage stage,
>> +   const nir_shader_compiler_options *options)
>> +{
>> +   nir_shader *nir = NULL;
>> +
>> +   struct gl_linked_shader *linked_shader =
>> prog->_LinkedShaders[stage];
>> +   assert (linked_shader);
>> +
>> +   struct gl_shader_spirv_data *spirv_data = linked_shader->spirv_data;
>> +   assert(spirv_data);
>> +
>> +   struct gl_spirv_module *spirv_module = spirv_data->SpirVModule;
>> +   assert (spirv_module != NULL);
>> +
>> +   const char *entry_point_name = spirv_data->SpirVEntryPoint;
>> +   assert(entry_point_name);
>> +
>> +   struct nir_spirv_specialization *spec_entries = NULL;
>> +   spec_entries = calloc(sizeof(*spec_entries),
>> + spirv_data->NumSpecializationConstants);
>
> Can we just make this:
>
>    struct nir_spirv_specialization *spec_entries =
>   calloc(sizeof(*spec_entries),
>  spirv_data->NumSpecializationConstants);
>

Sure, will fix it locally.

>
>> +
>> +   for (unsigned i = 0; i < spirv_data->NumSpecializationConstants;
>> ++i) {
>> +  spec_entries[i].id = spirv_data->SpecializationConstantsIndex[i];
>> +  spec_entries[i].data32 =
>> spirv_data->SpecializationConstantsValue[i];
>> +  spec_entries[i].defined_on_module = false;
>> +   }
>> +
>> +   nir_function *entry_point =
>> +  spirv_to_nir((const uint32_t *) _module->Binary[0],
>> +   spirv_module->Length / 4,
>> +   spec_entries,
>> spirv_data->NumSpecializationConstants,
>> +   stage, entry_point_name,
>> +   >Const.SpirVCapabilities,
>> +   options);
>> +   free(spec_entries);
>> +
>> +   assert (entry_point);
>> +   nir = entry_point->shader;
>> +   assert(nir->info.stage == stage);
>> +
>> +   nir->options = options;
>> +
>> +   nir->info.name =
>> +  ralloc_asprintf(nir, "SPIRV:%s:%d",
>> +  _mesa_shader_stage_to_abbrev(nir->info.stage),
>> +  prog->Name);
>> +   nir_validate_shader(nir);
>> +
>> +   if (false) {
>> +  /* @FIXME: Only for debugging purposes */
>> +  nir_print_shader(nir, stdout);
>> +  fflush(stdout);
>> +   }
>
> I'd rather we not commit this debug code, if you want this for
> development please carry a patch around in your dev branch.
>

Agree. Will remove it locally.


> With those two things addressed:
>
> Reviewed-by: Timothy Arceri <tarc...@itsqueeze.com>
>

Thanks!

>> +
>> +   return nir;
>> +}
>> +
>>   void GLAPIENTRY
>>   _mesa_SpecializeShaderARB(GLuint shader,
>>     const GLchar *pEntryPoint,
>> diff --git a/src/mesa/main/glspirv.h b/src/mesa/main/glspirv.h
>> index 0f03b75c111..81626ce75b5 100644
>> --- a/src/mesa/main/glspirv.h
>> +++ b/src/mesa/main/glspirv.h
>> @@ -24,6 +24,7 @@
>>   #ifndef GLSPIRV_H
>>   #define GLSPIRV_H
>>   +#include "compiler/nir/nir.h"
>>   #include "mtypes.h"
>>     #ifdef __cplusplus
>> @@ -80,6 +81,12 @@ void
>>   _mesa_spirv_link_shaders(struct gl_context *ctx,
>>    struct gl_shader_program *prog);
>>   +nir_shader *
>> +_mesa_spirv_to_nir(struct gl_context *ctx,
>> +   const struct gl_shader_program *prog,
>> +   gl_shader_stage stage,
>> +   const nir_shader_compiler_options *options);
>> +
>>   /**
>>    * \name API functions
>>    */
>>
>

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


Re: [Mesa-dev] [PATCH v3 24/25] i965: Call spirv_to_nir() instead of glsl_to_nir() for SPIR-V shaders

2017-12-05 Thread Eduardo Lima Mitev
On 12/05/2017 06:10 AM, Timothy Arceri wrote:
> Reviewed-by: Timothy Arceri <tarc...@itsqueeze.com>
>

Thanks, Timothy.

Any chance to review the remaining patches in the series?
It would be nice to land this batch soon to focus on the actual linker
stuff.

cheers,
Eduardo

> On 04/12/17 20:21, Eduardo Lima Mitev wrote:
>> This is the main fork of the shader compilation code-path, where a NIR
>> shader is obtained by calling spirv_to_nir() or glsl_to_nir(),
>> depending on its nature..
>>
>> v2: Use 'spirv_data' member from gl_linked_shader to know which method
>>     to call. (Timothy Arceri)
>> ---
>>   src/mesa/drivers/dri/i965/brw_program.c | 10 --
>>   1 file changed, 8 insertions(+), 2 deletions(-)
>>
>> diff --git a/src/mesa/drivers/dri/i965/brw_program.c
>> b/src/mesa/drivers/dri/i965/brw_program.c
>> index 755d4973cc0..4043253a653 100644
>> --- a/src/mesa/drivers/dri/i965/brw_program.c
>> +++ b/src/mesa/drivers/dri/i965/brw_program.c
>> @@ -31,6 +31,7 @@
>>     #include 
>>   #include "main/imports.h"
>> +#include "main/glspirv.h"
>>   #include "program/prog_parameter.h"
>>   #include "program/prog_print.h"
>>   #include "program/prog_to_nir.h"
>> @@ -73,9 +74,14 @@ brw_create_nir(struct brw_context *brw,
>>     ctx->Const.ShaderCompilerOptions[stage].NirOptions;
>>  nir_shader *nir;
>>   -   /* First, lower the GLSL IR or Mesa IR to NIR */
>> +   /* First, lower the GLSL/Mesa IR or SPIR-V to NIR */
>>  if (shader_prog) {
>> -  nir = glsl_to_nir(shader_prog, stage, options);
>> +  if (shader_prog->_LinkedShaders[stage]->spirv_data)
>> + nir = _mesa_spirv_to_nir(ctx, shader_prog, stage, options);
>> +  else
>> + nir = glsl_to_nir(shader_prog, stage, options);
>> +  assert (nir);
>> +
>>     nir_remove_dead_variables(nir, nir_var_shader_in |
>> nir_var_shader_out);
>>     nir_lower_returns(nir);
>>     nir_validate_shader(nir);
>>
>

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


[Mesa-dev] [PATCH v4 22/25] mesa/glspirv: Create gl_linked_shader objects for a SPIR-V program

2017-12-04 Thread Eduardo Lima Mitev
v2: Bail out if we see more that one shader for the same stage, and add
   a corresponding comment. (Timothy Arceri)

v3: Adds also a linker error log to the condition above. (Timothy Arceri)
---
 src/mesa/main/glspirv.c | 64 ++---
 1 file changed, 61 insertions(+), 3 deletions(-)

diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
index f90b4f054a6..ad5b467169e 100644
--- a/src/mesa/main/glspirv.c
+++ b/src/mesa/main/glspirv.c
@@ -29,6 +29,8 @@
 #include "compiler/nir/nir.h"
 #include "compiler/spirv/nir_spirv.h"
 
+#include "program/program.h"
+
 #include "util/u_atomic.h"
 
 void
@@ -104,14 +106,70 @@ _mesa_spirv_shader_binary(struct gl_context *ctx,
}
 }
 
+/**
+ * This is the equivalent to compiler/glsl/linker.cpp::link_shaders()
+ * but for SPIR-V programs.
+ *
+ * This method just creates the gl_linked_shader structs with a reference to
+ * the SPIR-V data collected during previous steps.
+ *
+ * The real linking happens later in the driver-specifc call LinkShader().
+ * This is so backends can implement different linking strategies for
+ * SPIR-V programs.
+ */
 void
 _mesa_spirv_link_shaders(struct gl_context *ctx, struct gl_shader_program 
*prog)
 {
-   /* @TODO: This is a placeholder for the equivalent of
-* compiler/glsl/linker.cpp::link_shaders() but for SPIR-V.
-*/
prog->data->LinkStatus = linking_success;
prog->data->Validated = false;
+
+   for (unsigned i = 0; i < prog->NumShaders; i++) {
+  struct gl_shader *shader = prog->Shaders[i];
+  gl_shader_stage shader_type = shader->Stage;
+
+  /* We only support one shader per stage. The gl_spirv spec doesn't seem
+   * to prevent this, but the way the API is designed, requiring all 
shaders
+   * to be specialized with an entry point, makes supporting this quite
+   * undefined.
+   */
+  if (prog->_LinkedShaders[shader_type]) {
+ ralloc_strcat(>data->InfoLog,
+   "\nError trying to link more than one SPIR-V shader "
+   "per stage.\n");
+ prog->data->LinkStatus = linking_failure;
+ return;
+  }
+
+  assert(shader->spirv_data);
+
+  struct gl_linked_shader *linked = rzalloc(NULL, struct gl_linked_shader);
+  linked->Stage = shader_type;
+
+  /* Create program and attach it to the linked shader */
+  struct gl_program *gl_prog =
+ ctx->Driver.NewProgram(ctx,
+_mesa_shader_stage_to_program(shader_type),
+prog->Name, false);
+  if (!gl_prog) {
+ prog->data->LinkStatus = linking_failure;
+ _mesa_delete_linked_shader(ctx, linked);
+ return;
+  }
+
+  _mesa_reference_shader_program_data(ctx,
+  _prog->sh.data,
+  prog->data);
+
+  /* Don't use _mesa_reference_program() just take ownership */
+  linked->Program = gl_prog;
+
+  /* Reference the SPIR-V data from shader to the linked shader */
+  _mesa_shader_spirv_data_reference(>spirv_data,
+shader->spirv_data);
+
+  prog->_LinkedShaders[shader_type] = linked;
+  prog->data->linked_stages |= 1 << shader_type;
+   }
 }
 
 void GLAPIENTRY
-- 
2.15.0

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


[Mesa-dev] [PATCH v3 24/25] i965: Call spirv_to_nir() instead of glsl_to_nir() for SPIR-V shaders

2017-12-04 Thread Eduardo Lima Mitev
This is the main fork of the shader compilation code-path, where a NIR
shader is obtained by calling spirv_to_nir() or glsl_to_nir(),
depending on its nature..

v2: Use 'spirv_data' member from gl_linked_shader to know which method
   to call. (Timothy Arceri)
---
 src/mesa/drivers/dri/i965/brw_program.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_program.c 
b/src/mesa/drivers/dri/i965/brw_program.c
index 755d4973cc0..4043253a653 100644
--- a/src/mesa/drivers/dri/i965/brw_program.c
+++ b/src/mesa/drivers/dri/i965/brw_program.c
@@ -31,6 +31,7 @@
 
 #include 
 #include "main/imports.h"
+#include "main/glspirv.h"
 #include "program/prog_parameter.h"
 #include "program/prog_print.h"
 #include "program/prog_to_nir.h"
@@ -73,9 +74,14 @@ brw_create_nir(struct brw_context *brw,
   ctx->Const.ShaderCompilerOptions[stage].NirOptions;
nir_shader *nir;
 
-   /* First, lower the GLSL IR or Mesa IR to NIR */
+   /* First, lower the GLSL/Mesa IR or SPIR-V to NIR */
if (shader_prog) {
-  nir = glsl_to_nir(shader_prog, stage, options);
+  if (shader_prog->_LinkedShaders[stage]->spirv_data)
+ nir = _mesa_spirv_to_nir(ctx, shader_prog, stage, options);
+  else
+ nir = glsl_to_nir(shader_prog, stage, options);
+  assert (nir);
+
   nir_remove_dead_variables(nir, nir_var_shader_in | nir_var_shader_out);
   nir_lower_returns(nir);
   nir_validate_shader(nir);
-- 
2.15.0

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


Re: [Mesa-dev] [PATCH v2 24/25] i965: Call spirv_to_nir() instead of glsl_to_nir() for SPIR-V shaders

2017-11-30 Thread Eduardo Lima Mitev
On 12/01/2017 04:44 AM, Timothy Arceri wrote:
>
>
> On 01/12/17 04:28, Eduardo Lima Mitev wrote:
>> This is the main fork of the shader compilation code-path, where a NIR
>> shader is obtained by calling spirv_to_nir() or glsl_to_nir(),
>> depending on its nature..
>>
>> v2: Use 'spirv_data' member from gl_linked_shader to know which method
>>     to call. (Timothy Arceri)
>> ---
>>   src/mesa/drivers/dri/i965/brw_program.c | 14 --
>>   1 file changed, 12 insertions(+), 2 deletions(-)
>>
>> diff --git a/src/mesa/drivers/dri/i965/brw_program.c
>> b/src/mesa/drivers/dri/i965/brw_program.c
>> index 755d4973cc0..596118f2fe5 100644
>> --- a/src/mesa/drivers/dri/i965/brw_program.c
>> +++ b/src/mesa/drivers/dri/i965/brw_program.c
>> @@ -31,6 +31,7 @@
>>     #include 
>>   #include "main/imports.h"
>> +#include "main/glspirv.h"
>>   #include "program/prog_parameter.h"
>>   #include "program/prog_print.h"
>>   #include "program/prog_to_nir.h"
>> @@ -73,9 +74,18 @@ brw_create_nir(struct brw_context *brw,
>>     ctx->Const.ShaderCompilerOptions[stage].NirOptions;
>>  nir_shader *nir;
>>   -   /* First, lower the GLSL IR or Mesa IR to NIR */
>> +   /* First, lower the GLSL/Mesa IR or SPIR-V to NIR */
>>  if (shader_prog) {
>> -  nir = glsl_to_nir(shader_prog, stage, options);
>> +  bool is_spirv_shader =
>> + (shader_prog->_LinkedShaders[stage]->spirv_data != NULL);
>> +
>> +  if (!is_spirv_shader) {
>> + nir = glsl_to_nir(shader_prog, stage, options);
>> +  } else {
>> + nir = _mesa_spirv_to_nir(ctx, shader_prog, stage, options);
>> +  }
>> +  assert (nir);
>
> Rather than messing around with bools, null checks and !'s I'd just
> change this to:
>
>   /* First, lower the GLSL/Mesa IR or SPIR-V to NIR */
>   if (shader_prog->_LinkedShaders[stage]->spirv_data) {
>  nir = _mesa_spirv_to_nir(ctx, shader_prog, stage, options);
>   } else {
>  nir = glsl_to_nir(shader_prog, stage, options);
>   }
>   assert (nir);
>
>

My intention was to make it clearer that we are using a pointer nullness
to decide code-path.
I don't care much so I will use your inlined version above, maybe just
adding a comment.

Thanks,

Eduardo

>> +
>>     nir_remove_dead_variables(nir, nir_var_shader_in |
>> nir_var_shader_out);
>>     nir_lower_returns(nir);
>>     nir_validate_shader(nir);
>>
>

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


Re: [Mesa-dev] [PATCH v2 00/25] Initial gl_spirv and spirv_extensions support in Mesa and i965

2017-11-30 Thread Eduardo Lima Mitev
On 12/01/2017 04:54 AM, Timothy Arceri wrote:
> On 01/12/17 04:28, Eduardo Lima Mitev wrote:
>> Hello,
>>
>> This is the second version of the series providing initial support
>> for ARB_gl_spirv and ARB_spirv_extensions in Mesa and i965.
>>
>> First version of the series can be found at
>> <https://lists.freedesktop.org/archives/mesa-dev/2017-November/177004.html>.
>>
>> In this series we hope we have addressed all issues detected during
>> the initial review. Thank you all who participated!
>>
>> Taking the nitpicks and minor fixes apart, most important changes
>> compared to the first version are:
>>
>> * A dedicated 'spirv' flag was removed from gl_shader struct. Now we
>> use the nulness of 'spirv_data' member for the same purpose.
>>
>> * The per-program 'spirv' flag was moved out of this series, but will
>> likely be re-introduced in the next delivery, because it will become
>> necessary.
>>
>> * We enforce one SPIR-V shader per stage, and fail linking if this
>> condition is not met.
>
> Sorry can you point me to the patch that contains this I couldn't find
> it when skimming over the series. Thanks.
>

Ohh, I'm very sorry. The revised patch got lost during rebase.

I have just sent a v3 of
"[PATCH v2 22/25] mesa/glspirv: Create gl_linked_shader objects for a
SPIR-V program" that includes the check in question.

Thanks for catching this!

Eduardo

>>
>> * 'SpirVCapabilities' struct of GL context constants is no longer a
>> pointer but a static struct.
>>
>> As usual, a tree of this series can be found at
>> <https://github.com/Igalia/mesa/commits/arb_gl_spirv-series1-v2>.
>>
>> A tree of the larger WIP branch from which this series is taken:
>> <https://github.com/Igalia/mesa/commits/wip/igalia/arb_gl_spirv>.
>>
>> Thanks in advance for the reviews!
>>
>> cheers,
>> Eduardo
>>
>> Alejandro Piñeiro (9):
>>    spirv_extensions: rename nir_spirv_supported_extensions
>>    mesa: move nir_spirv_supported_capabilities definition
>>    i965: initialize SPIR-V capabilities
>>    spirv_extensions: add GL_ARB_spirv_extensions boilerplate
>>    spirv_extensions: add list of extensions and to_string method
>>    spirv_extensions: define spirv_extensions_supported
>>    spirv_extensions: add spirv_supported_extensions on gl_constants
>>    spirv_extensions: i965: initialize SPIR-V extensions
>>    nir/spirv: add gl_spirv_validation method
>>
>> Eduardo Lima Mitev (8):
>>    mesa/glspirv: Add struct gl_shader_spirv_data
>>    mesa/glspirv: Add a _mesa_spirv_link_shaders() placeholder
>>    mesa/program: Link SPIR-V shaders using the SPIR-V code-path
>>    mesa: Add a reference to gl_shader_spirv_data to gl_linked_shader
>>    mesa/glspirv: Create gl_linked_shader objects for a SPIR-V program
>>    mesa/glspirv: Add a _mesa_spirv_to_nir() function
>>    i965: Call spirv_to_nir() instead of glsl_to_nir() for SPIR-V shaders
>>    i965: Don't call process_glsl_ir() for SPIR-V shaders
>>
>> Neil Roberts (1):
>>    mesa: Add boilerplate for the GL 4.6 alias of glSpecializeShaderARB
>>
>> Nicolai Hähnle (7):
>>    mesa: add GL_ARB_gl_spirv boilerplate
>>    mesa/glspirv: Add struct gl_spirv_module
>>    mesa: implement SPIR-V loading in glShaderBinary
>>    mesa/shaderapi: add a getter for GL_SPIR_V_BINARY_ARB
>>    mesa: refuse to compile SPIR-V shaders or link mixed shaders
>>    mesa: add gl_constants::SpirVCapabilities
>>    mesa: Implement glSpecializeShaderARB
>>
>>   src/amd/vulkan/radv_shader.c    |   4 +-
>>   src/compiler/Makefile.sources   |   2 +
>>   src/compiler/spirv/nir_spirv.h  |  21 +-
>>   src/compiler/spirv/spirv_extensions.c   |  77 +++
>>   src/compiler/spirv/spirv_extensions.h   |  63 ++
>>   src/compiler/spirv/spirv_to_nir.c   | 160 +-
>>   src/compiler/spirv/vtn_private.h    |   2 +-
>>   src/intel/vulkan/anv_pipeline.c |   4 +-
>>   src/mapi/glapi/gen/ARB_gl_spirv.xml |  21 ++
>>   src/mapi/glapi/gen/ARB_spirv_extensions.xml |  13 ++
>>   src/mapi/glapi/gen/GL4x.xml |  11 +
>>   src/mapi/glapi/gen/Makefile.am  |   2 +
>>   src/mapi/glapi/gen/gl_API.xml   |   8 +
>>   src/mapi/glapi/gen/gl_genexec.py    |   1 +
>>   src/mapi/glapi/gen/meson.build  |   2 +
>>   src/mesa/Makefile.sources   |   4 +
>>   src/mesa/drivers/dri/i965/brw_context.c |  26 +++

[Mesa-dev] [PATCH v3 22/25] mesa/glspirv: Create gl_linked_shader objects for a SPIR-V program

2017-11-30 Thread Eduardo Lima Mitev
v2: Bail out if we see more that one shader for the same stage, and add
   a corresponding comment. (Timothy Arceri)
---
 src/mesa/main/glspirv.c | 61 ++---
 1 file changed, 58 insertions(+), 3 deletions(-)

diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
index e533853f7fa..0934ceccbb3 100644
--- a/src/mesa/main/glspirv.c
+++ b/src/mesa/main/glspirv.c
@@ -29,6 +29,8 @@
 #include "compiler/nir/nir.h"
 #include "compiler/spirv/nir_spirv.h"
 
+#include "program/program.h"
+
 #include "util/u_atomic.h"
 
 void
@@ -104,14 +106,67 @@ _mesa_spirv_shader_binary(struct gl_context *ctx,
}
 }
 
+/**
+ * This is the equivalent to compiler/glsl/linker.cpp::link_shaders()
+ * but for SPIR-V programs.
+ *
+ * This method just creates the gl_linked_shader structs with a reference to
+ * the SPIR-V data collected during previous steps.
+ *
+ * The real linking happens later in the driver-specifc call LinkShader().
+ * This is so backends can implement different linking strategies for
+ * SPIR-V programs.
+ */
 void
 _mesa_spirv_link_shaders(struct gl_context *ctx, struct gl_shader_program 
*prog)
 {
-   /* @TODO: This is a placeholder for the equivalent of
-* compiler/glsl/linker.cpp::link_shaders() but for SPIR-V.
-*/
prog->data->LinkStatus = linking_success;
prog->data->Validated = false;
+
+   for (unsigned i = 0; i < prog->NumShaders; i++) {
+  struct gl_shader *shader = prog->Shaders[i];
+  gl_shader_stage shader_type = shader->Stage;
+
+  /* We only support one shader per stage. The gl_spirv spec doesn't seem
+   * to prevent this, but the way the API is designed, requiring all 
shaders
+   * to be specialized with an entry point, makes supporting this quite
+   * undefined.
+   */
+  if (prog->_LinkedShaders[shader_type]) {
+ prog->data->LinkStatus = linking_failure;
+ return;
+  }
+
+  assert(shader->spirv_data);
+
+  struct gl_linked_shader *linked = rzalloc(NULL, struct gl_linked_shader);
+  linked->Stage = shader_type;
+
+  /* Create program and attach it to the linked shader */
+  struct gl_program *gl_prog =
+ ctx->Driver.NewProgram(ctx,
+_mesa_shader_stage_to_program(shader_type),
+prog->Name, false);
+  if (!gl_prog) {
+ prog->data->LinkStatus = linking_failure;
+ _mesa_delete_linked_shader(ctx, linked);
+ return;
+  }
+
+  _mesa_reference_shader_program_data(ctx,
+  _prog->sh.data,
+  prog->data);
+
+  /* Don't use _mesa_reference_program() just take ownership */
+  linked->Program = gl_prog;
+
+  /* Reference the SPIR-V data from shader to the linked shader */
+  _mesa_shader_spirv_data_reference(>spirv_data,
+shader->spirv_data);
+
+  prog->_LinkedShaders[shader_type] = linked;
+  prog->data->linked_stages |= 1 << shader_type;
+   }
 }
 
 void GLAPIENTRY
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 23/25] mesa/glspirv: Add a _mesa_spirv_to_nir() function

2017-11-30 Thread Eduardo Lima Mitev
This is basically a wrapper around spirv_to_nir() that includes
arguments setup and post-conversion validation.

v2: Rebase update (SpirVCapabilities not a pointer anymore)
---
 src/mesa/main/glspirv.c | 60 +
 src/mesa/main/glspirv.h |  7 ++
 2 files changed, 67 insertions(+)

diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
index e5dc8b26ea9..2a20e4b5cc7 100644
--- a/src/mesa/main/glspirv.c
+++ b/src/mesa/main/glspirv.c
@@ -159,6 +159,66 @@ _mesa_spirv_link_shaders(struct gl_context *ctx, struct 
gl_shader_program *prog)
}
 }
 
+nir_shader *
+_mesa_spirv_to_nir(struct gl_context *ctx,
+   const struct gl_shader_program *prog,
+   gl_shader_stage stage,
+   const nir_shader_compiler_options *options)
+{
+   nir_shader *nir = NULL;
+
+   struct gl_linked_shader *linked_shader = prog->_LinkedShaders[stage];
+   assert (linked_shader);
+
+   struct gl_shader_spirv_data *spirv_data = linked_shader->spirv_data;
+   assert(spirv_data);
+
+   struct gl_spirv_module *spirv_module = spirv_data->SpirVModule;
+   assert (spirv_module != NULL);
+
+   const char *entry_point_name = spirv_data->SpirVEntryPoint;
+   assert(entry_point_name);
+
+   struct nir_spirv_specialization *spec_entries = NULL;
+   spec_entries = calloc(sizeof(*spec_entries),
+ spirv_data->NumSpecializationConstants);
+
+   for (unsigned i = 0; i < spirv_data->NumSpecializationConstants; ++i) {
+  spec_entries[i].id = spirv_data->SpecializationConstantsIndex[i];
+  spec_entries[i].data32 = spirv_data->SpecializationConstantsValue[i];
+  spec_entries[i].defined_on_module = false;
+   }
+
+   nir_function *entry_point =
+  spirv_to_nir((const uint32_t *) _module->Binary[0],
+   spirv_module->Length / 4,
+   spec_entries, spirv_data->NumSpecializationConstants,
+   stage, entry_point_name,
+   >Const.SpirVCapabilities,
+   options);
+   free(spec_entries);
+
+   assert (entry_point);
+   nir = entry_point->shader;
+   assert(nir->info.stage == stage);
+
+   nir->options = options;
+
+   nir->info.name =
+  ralloc_asprintf(nir, "SPIRV:%s:%d",
+  _mesa_shader_stage_to_abbrev(nir->info.stage),
+  prog->Name);
+   nir_validate_shader(nir);
+
+   if (false) {
+  /* @FIXME: Only for debugging purposes */
+  nir_print_shader(nir, stdout);
+  fflush(stdout);
+   }
+
+   return nir;
+}
+
 void GLAPIENTRY
 _mesa_SpecializeShaderARB(GLuint shader,
   const GLchar *pEntryPoint,
diff --git a/src/mesa/main/glspirv.h b/src/mesa/main/glspirv.h
index 0f03b75c111..81626ce75b5 100644
--- a/src/mesa/main/glspirv.h
+++ b/src/mesa/main/glspirv.h
@@ -24,6 +24,7 @@
 #ifndef GLSPIRV_H
 #define GLSPIRV_H
 
+#include "compiler/nir/nir.h"
 #include "mtypes.h"
 
 #ifdef __cplusplus
@@ -80,6 +81,12 @@ void
 _mesa_spirv_link_shaders(struct gl_context *ctx,
  struct gl_shader_program *prog);
 
+nir_shader *
+_mesa_spirv_to_nir(struct gl_context *ctx,
+   const struct gl_shader_program *prog,
+   gl_shader_stage stage,
+   const nir_shader_compiler_options *options);
+
 /**
  * \name API functions
  */
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 25/25] i965: Don't call process_glsl_ir() for SPIR-V shaders

2017-11-30 Thread Eduardo Lima Mitev
v2: Use 'spirv_data' from gl_linked_shader instead, to check if shader
   is SPIR-V. (Timothy Arceri)
---
 src/mesa/drivers/dri/i965/brw_link.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/mesa/drivers/dri/i965/brw_link.cpp 
b/src/mesa/drivers/dri/i965/brw_link.cpp
index d18521e792d..6bf4c413db4 100644
--- a/src/mesa/drivers/dri/i965/brw_link.cpp
+++ b/src/mesa/drivers/dri/i965/brw_link.cpp
@@ -236,7 +236,8 @@ brw_link_shader(struct gl_context *ctx, struct 
gl_shader_program *shProg)
   struct gl_program *prog = shader->Program;
   prog->Parameters = _mesa_new_parameter_list();
 
-  process_glsl_ir(brw, shProg, shader);
+  if (!shader->spirv_data)
+ process_glsl_ir(brw, shProg, shader);
 
   _mesa_copy_linked_program_data(shProg, shader);
 
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 24/25] i965: Call spirv_to_nir() instead of glsl_to_nir() for SPIR-V shaders

2017-11-30 Thread Eduardo Lima Mitev
This is the main fork of the shader compilation code-path, where a NIR
shader is obtained by calling spirv_to_nir() or glsl_to_nir(),
depending on its nature..

v2: Use 'spirv_data' member from gl_linked_shader to know which method
   to call. (Timothy Arceri)
---
 src/mesa/drivers/dri/i965/brw_program.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_program.c 
b/src/mesa/drivers/dri/i965/brw_program.c
index 755d4973cc0..596118f2fe5 100644
--- a/src/mesa/drivers/dri/i965/brw_program.c
+++ b/src/mesa/drivers/dri/i965/brw_program.c
@@ -31,6 +31,7 @@
 
 #include 
 #include "main/imports.h"
+#include "main/glspirv.h"
 #include "program/prog_parameter.h"
 #include "program/prog_print.h"
 #include "program/prog_to_nir.h"
@@ -73,9 +74,18 @@ brw_create_nir(struct brw_context *brw,
   ctx->Const.ShaderCompilerOptions[stage].NirOptions;
nir_shader *nir;
 
-   /* First, lower the GLSL IR or Mesa IR to NIR */
+   /* First, lower the GLSL/Mesa IR or SPIR-V to NIR */
if (shader_prog) {
-  nir = glsl_to_nir(shader_prog, stage, options);
+  bool is_spirv_shader =
+ (shader_prog->_LinkedShaders[stage]->spirv_data != NULL);
+
+  if (!is_spirv_shader) {
+ nir = glsl_to_nir(shader_prog, stage, options);
+  } else {
+ nir = _mesa_spirv_to_nir(ctx, shader_prog, stage, options);
+  }
+  assert (nir);
+
   nir_remove_dead_variables(nir, nir_var_shader_in | nir_var_shader_out);
   nir_lower_returns(nir);
   nir_validate_shader(nir);
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 22/25] mesa/glspirv: Create gl_linked_shader objects for a SPIR-V program

2017-11-30 Thread Eduardo Lima Mitev
---
 src/mesa/main/glspirv.c | 51 ++---
 1 file changed, 48 insertions(+), 3 deletions(-)

diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
index e533853f7fa..e5dc8b26ea9 100644
--- a/src/mesa/main/glspirv.c
+++ b/src/mesa/main/glspirv.c
@@ -29,6 +29,8 @@
 #include "compiler/nir/nir.h"
 #include "compiler/spirv/nir_spirv.h"
 
+#include "program/program.h"
+
 #include "util/u_atomic.h"
 
 void
@@ -104,14 +106,57 @@ _mesa_spirv_shader_binary(struct gl_context *ctx,
}
 }
 
+/**
+ * This is the equivalent to compiler/glsl/linker.cpp::link_shaders()
+ * but for SPIR-V programs.
+ *
+ * This method just creates the gl_linked_shader structs with a reference to
+ * the SPIR-V data collected during previous steps.
+ *
+ * The real linking happens later in the driver-specifc call LinkShader().
+ * This is so backends can implement different linking strategies for
+ * SPIR-V programs.
+ */
 void
 _mesa_spirv_link_shaders(struct gl_context *ctx, struct gl_shader_program 
*prog)
 {
-   /* @TODO: This is a placeholder for the equivalent of
-* compiler/glsl/linker.cpp::link_shaders() but for SPIR-V.
-*/
prog->data->LinkStatus = linking_success;
prog->data->Validated = false;
+
+   for (unsigned i = 0; i < prog->NumShaders; i++) {
+  struct gl_shader *shader = prog->Shaders[i];
+  gl_shader_stage shader_type = shader->Stage;
+
+  assert(shader->spirv_data);
+
+  struct gl_linked_shader *linked = rzalloc(NULL, struct gl_linked_shader);
+  linked->Stage = shader_type;
+
+  /* Create program and attach it to the linked shader */
+  struct gl_program *gl_prog =
+ ctx->Driver.NewProgram(ctx,
+_mesa_shader_stage_to_program(shader_type),
+prog->Name, false);
+  if (!gl_prog) {
+ prog->data->LinkStatus = linking_failure;
+ _mesa_delete_linked_shader(ctx, linked);
+ return;
+  }
+
+  _mesa_reference_shader_program_data(ctx,
+  _prog->sh.data,
+  prog->data);
+
+  /* Don't use _mesa_reference_program() just take ownership */
+  linked->Program = gl_prog;
+
+  /* Reference the SPIR-V data from shader to the linked shader */
+  _mesa_shader_spirv_data_reference(>spirv_data,
+shader->spirv_data);
+
+  prog->_LinkedShaders[shader_type] = linked;
+  prog->data->linked_stages |= 1 << shader_type;
+   }
 }
 
 void GLAPIENTRY
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 19/25] mesa/glspirv: Add a _mesa_spirv_link_shaders() placeholder

2017-11-30 Thread Eduardo Lima Mitev
This will be the equivalent to link_shaders() from
src/compiler/glsl/linker.cpp, but for SPIR-V programs.
---
 src/mesa/main/glspirv.c | 10 ++
 src/mesa/main/glspirv.h |  4 
 2 files changed, 14 insertions(+)

diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
index 18710c0d8fc..e533853f7fa 100644
--- a/src/mesa/main/glspirv.c
+++ b/src/mesa/main/glspirv.c
@@ -104,6 +104,16 @@ _mesa_spirv_shader_binary(struct gl_context *ctx,
}
 }
 
+void
+_mesa_spirv_link_shaders(struct gl_context *ctx, struct gl_shader_program 
*prog)
+{
+   /* @TODO: This is a placeholder for the equivalent of
+* compiler/glsl/linker.cpp::link_shaders() but for SPIR-V.
+*/
+   prog->data->LinkStatus = linking_success;
+   prog->data->Validated = false;
+}
+
 void GLAPIENTRY
 _mesa_SpecializeShaderARB(GLuint shader,
   const GLchar *pEntryPoint,
diff --git a/src/mesa/main/glspirv.h b/src/mesa/main/glspirv.h
index ba281f68bef..0f03b75c111 100644
--- a/src/mesa/main/glspirv.h
+++ b/src/mesa/main/glspirv.h
@@ -76,6 +76,10 @@ _mesa_spirv_shader_binary(struct gl_context *ctx,
   unsigned n, struct gl_shader **shaders,
   const void* binary, size_t length);
 
+void
+_mesa_spirv_link_shaders(struct gl_context *ctx,
+ struct gl_shader_program *prog);
+
 /**
  * \name API functions
  */
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 21/25] mesa: Add a reference to gl_shader_spirv_data to gl_linked_shader

2017-11-30 Thread Eduardo Lima Mitev
This is a reference to the spirv_data object stored in gl_shader, which
stores shader SPIR-V data that is needed during linking too.
---
 src/mesa/main/mtypes.h| 8 
 src/mesa/main/shaderobj.c | 1 +
 2 files changed, 9 insertions(+)

diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index d74bf10daa0..1c8de9542e8 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2542,6 +2542,14 @@ struct gl_linked_shader
struct exec_list *packed_varyings;
struct exec_list *fragdata_arrays;
struct glsl_symbol_table *symbols;
+
+   /**
+* ARB_gl_spirv related data.
+*
+* This is actually a reference to the gl_shader::spirv_data, which
+* stores information that is also needed during linking.
+*/
+   struct gl_shader_spirv_data *spirv_data;
 };
 
 
diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
index 5c1cdd6b27a..834e2a92ec4 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -137,6 +137,7 @@ void
 _mesa_delete_linked_shader(struct gl_context *ctx,
struct gl_linked_shader *sh)
 {
+   _mesa_shader_spirv_data_reference(>spirv_data, NULL);
_mesa_reference_program(ctx, >Program, NULL);
ralloc_free(sh);
 }
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 15/25] spirv_extensions: add spirv_supported_extensions on gl_constants

2017-11-30 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

We can use it to get real values for ARB_spirv_extensions methods.

v2: Rebase update after changes on previous patches.
---
 src/mesa/main/mtypes.h   |  3 +++
 src/mesa/main/spirv_extensions.c | 20 +++-
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index c63a5a67582..d74bf10daa0 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -4031,6 +4031,9 @@ struct gl_constants
 
/** GL_ARB_gl_spirv */
struct nir_spirv_supported_capabilities SpirVCapabilities;
+
+   /** GL_ARB_spirv_extensions */
+   struct spirv_supported_extensions *SpirVExtensions;
 };
 
 
diff --git a/src/mesa/main/spirv_extensions.c b/src/mesa/main/spirv_extensions.c
index 40a89c133aa..2bb29461fd4 100644
--- a/src/mesa/main/spirv_extensions.c
+++ b/src/mesa/main/spirv_extensions.c
@@ -27,16 +27,34 @@
  */
 
 #include "spirv_extensions.h"
+#include "compiler/spirv/spirv_extensions.h"
 
 GLuint
 _mesa_get_spirv_extension_count(struct gl_context *ctx)
 {
-   return 0;
+   if (ctx->Const.SpirVExtensions == NULL)
+  return 0;
+
+   return ctx->Const.SpirVExtensions->count;
 }
 
 const GLubyte *
 _mesa_get_enabled_spirv_extension(struct gl_context *ctx,
   GLuint index)
 {
+   unsigned int n = 0;
+
+   if (ctx->Const.SpirVExtensions == NULL)
+  return (const GLubyte *) 0;
+
+   for (unsigned int i = 0; i < SPV_EXTENSIONS_COUNT; i++) {
+  if (ctx->Const.SpirVExtensions->supported[i]) {
+ if (n == index)
+return (const GLubyte *) spirv_extensions_to_string(i);
+ else
+n++;
+  }
+   }
+
return (const GLubyte *) 0;
 }
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 18/25] mesa: Implement glSpecializeShaderARB

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

v2: * Use gl_spirv_validation instead of spirv_to_nir.
   This method just validates the shader. The conversion to NIR will
   happen later, during linking. (Alejandro Piñeiro)

* Use gl_shader_spirv_data struct to store the SPIR-V data.
   (Eduardo Lima)

* Use the 'spirv_data' member to tell if the gl_shader is
   a SPIR-V shader, instead of a dedicated flag. (Timothy Arceri)
---
 src/mesa/main/glspirv.c | 106 ++--
 1 file changed, 103 insertions(+), 3 deletions(-)

diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
index d2e76bb1927..18710c0d8fc 100644
--- a/src/mesa/main/glspirv.c
+++ b/src/mesa/main/glspirv.c
@@ -24,8 +24,10 @@
 #include "glspirv.h"
 
 #include "errors.h"
+#include "shaderobj.h"
 
-#include "errors.h"
+#include "compiler/nir/nir.h"
+#include "compiler/spirv/nir_spirv.h"
 
 #include "util/u_atomic.h"
 
@@ -110,7 +112,105 @@ _mesa_SpecializeShaderARB(GLuint shader,
   const GLuint *pConstantValue)
 {
GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader *sh;
+   bool has_entry_point;
+   struct nir_spirv_specialization *spec_entries = NULL;
+
+   if (!ctx->Extensions.ARB_gl_spirv) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, "glSpecializeShaderARB");
+  return;
+   }
+
+   sh = _mesa_lookup_shader_err(ctx, shader, "glSpecializeShaderARB");
+   if (!sh)
+  return;
+
+   if (!sh->spirv_data) {
+  _mesa_error(ctx, GL_INVALID_OPERATION,
+  "glSpecializeShaderARB(not SPIR-V)");
+  return;
+   }
+
+   if (sh->CompileStatus) {
+  _mesa_error(ctx, GL_INVALID_OPERATION,
+  "glSpecializeShaderARB(already specialized)");
+  return;
+   }
+
+   struct gl_shader_spirv_data *spirv_data = sh->spirv_data;
+
+   /* From the GL_ARB_gl_spirv spec:
+*
+*"The OpenGL API expects the SPIR-V module to have already been
+* validated, and can return an error if it discovers anything invalid
+* in the module. An invalid SPIR-V module is allowed to result in
+* undefined behavior."
+*
+* However, the following errors still need to be detected (from the same
+* spec):
+*
+*"INVALID_VALUE is generated if  does not name a valid
+* entry point for .
+*
+* INVALID_VALUE is generated if any element of 
+* refers to a specialization constant that does not exist in the
+* shader module contained in ."
+*
+* We cannot flag those errors a-priori because detecting them requires
+* parsing the module. However, flagging them during specialization is okay,
+* since it makes no difference in terms of application-visible state.
+*/
+   spec_entries = calloc(sizeof(*spec_entries), numSpecializationConstants);
+
+   for (unsigned i = 0; i < numSpecializationConstants; ++i) {
+  spec_entries[i].id = pConstantIndex[i];
+  spec_entries[i].data32 = pConstantValue[i];
+  spec_entries[i].defined_on_module = false;
+   }
+
+   has_entry_point =
+  gl_spirv_validation((uint32_t *)_data->SpirVModule->Binary[0],
+  spirv_data->SpirVModule->Length / 4,
+  spec_entries, numSpecializationConstants,
+  sh->Stage, pEntryPoint);
+
+   /* See previous spec comment */
+   if (!has_entry_point) {
+  _mesa_error(ctx, GL_INVALID_VALUE,
+  "glSpecializeShaderARB(\"%s\" is not a valid entry point"
+  " for shader)", pEntryPoint);
+  goto end;
+   }
+
+   for (unsigned i = 0; i < numSpecializationConstants; ++i) {
+  if (spec_entries[i].defined_on_module == false) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glSpecializeShaderARB(constant \"%i\" does not exist "
+ "in shader)", spec_entries[i].id);
+ goto end;
+  }
+   }
+
+   spirv_data->SpirVEntryPoint = ralloc_strdup(spirv_data, pEntryPoint);
+
+   /* Note that we didn't make a real compilation of the module (spirv_to_nir),
+* but just checked some error conditions. Real "compilation" will be done
+* later, upon linking.
+*/
+   sh->CompileStatus = compile_success;
+
+   spirv_data->NumSpecializationConstants = numSpecializationConstants;
+   spirv_data->SpecializationConstantsIndex =
+  rzalloc_array_size(spirv_data, sizeof(GLuint),
+ numSpecializationConstants);
+   spirv_data->SpecializationConstantsValue =
+  rzalloc_array_size(spirv_data, sizeof(GLuint),
+ numSpecializationConstants);
+   for (unsigned i = 0; i < numSpecializationConstants; ++i) {
+  spirv_data->SpecializationConstantsIndex[i] = pConstantIndex[i];
+  spirv_data->SpecializationConstantsValue[i] = pConstantValue[i];
+   }
 
-   /* Just return GL_INVALID_OPERATION error while this is boilerplate */
-   _mesa_error(ctx, GL_INVALID_OPERATION, "SpecializeShaderARB");
+ end:

[Mesa-dev] [PATCH v2 20/25] mesa/program: Link SPIR-V shaders using the SPIR-V code-path

2017-11-30 Thread Eduardo Lima Mitev
---
 src/mesa/program/ir_to_mesa.cpp | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 047f5b38f71..83de0143c65 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -36,6 +36,7 @@
 #include "main/shaderapi.h"
 #include "main/shaderobj.h"
 #include "main/uniforms.h"
+#include "main/glspirv.h"
 #include "compiler/glsl/ast.h"
 #include "compiler/glsl/ir.h"
 #include "compiler/glsl/ir_expression_flattening.h"
@@ -3106,7 +3107,10 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct 
gl_shader_program *prog)
}
 
if (prog->data->LinkStatus) {
-  link_shaders(ctx, prog);
+  if (!spirv)
+ link_shaders(ctx, prog);
+  else
+ _mesa_spirv_link_shaders(ctx, prog);
}
 
if (prog->data->LinkStatus) {
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 16/25] spirv_extensions: i965: initialize SPIR-V extensions

2017-11-30 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

v2: Rebase update after changes on previous patches.
---
 src/mesa/drivers/dri/i965/brw_context.c | 6 ++
 src/mesa/main/context.c | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_context.c 
b/src/mesa/drivers/dri/i965/brw_context.c
index d90b7797a7a..6afc18bcf6e 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -76,6 +76,7 @@
 #include "isl/isl.h"
 
 #include "compiler/spirv/nir_spirv.h"
+#include "compiler/spirv/spirv_extensions.h"
 /***
  * Mesa's Driver Functions
  ***/
@@ -716,6 +717,11 @@ brw_initialize_context_constants(struct brw_context *brw)
/* GL_ARB_gl_spirv */
if (ctx->Version >= 33)
   brw_initialize_spirv_supported_capabilities(brw);
+
+   /* GL_ARB_spirv_extensions */
+   ctx->Const.SpirVExtensions = MALLOC_STRUCT(spirv_supported_extensions);
+   spirv_fill_supported_spirv_extensions(ctx->Const.SpirVExtensions,
+ >Const.SpirVCapabilities);
 }
 
 static void
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 3fa9f69f883..b48481d4372 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -1377,6 +1377,8 @@ _mesa_free_context_data( struct gl_context *ctx )
if (ctx == _mesa_get_current_context()) {
   _mesa_make_current(NULL, NULL, NULL);
}
+
+   free(ctx->Const.SpirVExtensions);
 }
 
 
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 17/25] nir/spirv: add gl_spirv_validation method

2017-11-30 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

ARB_gl_spirv adds the ability to use SPIR-V binaries, and a new
method, glSpecializeShader. From OpenGL 4.6 spec, section 7.2.1
"Shader Specialization", error table:

   INVALID_VALUE is generated if  does not name a valid
   entry point for .

   INVALID_VALUE is generated if any element of 
   refers to a specialization constant that does not exist in the
   shader module contained in .""

But we are not really interested on creating the nir shader at that
point, and adding nir structures on the gl_program, so at that point
we are just interested on the error checking.

So we add a new method focused on just checking those errors. It still
needs to parse the binary, but skips what it is not needed, and
doesn't create the nir shader.

v2:
  * Rebase update
---
 src/compiler/spirv/nir_spirv.h|   6 ++
 src/compiler/spirv/spirv_to_nir.c | 156 +++---
 2 files changed, 152 insertions(+), 10 deletions(-)

diff --git a/src/compiler/spirv/nir_spirv.h b/src/compiler/spirv/nir_spirv.h
index a14b55cdd4b..8b8942fc726 100644
--- a/src/compiler/spirv/nir_spirv.h
+++ b/src/compiler/spirv/nir_spirv.h
@@ -41,8 +41,14 @@ struct nir_spirv_specialization {
   uint32_t data32;
   uint64_t data64;
};
+   bool defined_on_module;
 };
 
+
+bool gl_spirv_validation(const uint32_t *words, size_t word_count,
+ struct nir_spirv_specialization *spec, unsigned 
num_spec,
+ gl_shader_stage stage, const char *entry_point_name);
+
 nir_function *spirv_to_nir(const uint32_t *words, size_t word_count,
struct nir_spirv_specialization *specializations,
unsigned num_specializations,
diff --git a/src/compiler/spirv/spirv_to_nir.c 
b/src/compiler/spirv/spirv_to_nir.c
index 6034228ed36..fea3ad7b09d 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -1031,6 +1031,7 @@ spec_constant_decoration_cb(struct vtn_builder *b, struct 
vtn_value *v,
 const_value->data64 = b->specializations[i].data64;
  else
 const_value->data32 = b->specializations[i].data32;
+ b->specializations[i].defined_on_module = true;
  return;
   }
}
@@ -1065,6 +1066,11 @@ handle_workgroup_size_decoration_cb(struct vtn_builder 
*b,
 const struct vtn_decoration *dec,
 void *data)
 {
+   /* This can happens if we are gl_spirv_validation. We can return safely, as
+* we don't need the workgroup info for such validation. */
+   if (b->shader == NULL)
+  return;
+
assert(member == -1);
if (dec->decoration != SpvDecorationBuiltIn ||
dec->literals[0] != SpvBuiltInWorkgroupSize)
@@ -2848,6 +2854,49 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, 
SpvOp opcode,
return true;
 }
 
+/*
+ * gl_spirv validation. Just need to check for the entry point.
+ */
+static bool
+vtn_validate_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
+  const uint32_t *w, unsigned count)
+{
+   switch (opcode) {
+   /* The following opcodes are not needed for gl_spirv, so we can skip
+* them.
+*/
+   case SpvOpSource:
+   case SpvOpSourceExtension:
+   case SpvOpSourceContinued:
+   case SpvOpExtension:
+   case SpvOpCapability:
+   case SpvOpExtInstImport:
+   case SpvOpMemoryModel:
+   case SpvOpString:
+   case SpvOpName:
+   case SpvOpMemberName:
+   case SpvOpExecutionMode:
+   case SpvOpDecorationGroup:
+   case SpvOpMemberDecorate:
+   case SpvOpGroupDecorate:
+   case SpvOpGroupMemberDecorate:
+  break;
+
+   case SpvOpEntryPoint:
+  vtn_handle_preamble_instruction(b, opcode, w, count);
+  break;
+
+   case SpvOpDecorate:
+  vtn_handle_decoration(b, opcode, w, count);
+  break;
+
+   default:
+  return false; /* End of preamble */
+   }
+
+   return true;
+}
+
 static void
 vtn_handle_execution_mode(struct vtn_builder *b, struct vtn_value *entry_point,
   const struct vtn_decoration *mode, void *data)
@@ -3055,6 +3104,22 @@ vtn_handle_variable_or_type_instruction(struct 
vtn_builder *b, SpvOp opcode,
return true;
 }
 
+static bool
+vtn_handle_constant_or_type_instruction(struct vtn_builder *b, SpvOp opcode,
+const uint32_t *w, unsigned count)
+{
+   switch (opcode) {
+   case SpvOpUndef:
+   case SpvOpVariable:
+  break;
+
+   default:
+  return vtn_handle_variable_or_type_instruction(b, opcode, w, count);
+   }
+
+   return true;
+}
+
 static bool
 vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
 const uint32_t *w, unsigned count)
@@ -3309,15 +3374,10 @@ vtn_handle_body_instruction(struct vtn_builder *b, 
SpvOp opcode,
return true;
 }
 
-nir_function *
-spirv_to_nir(const uint32_t *words, size_t word_count,
-   

[Mesa-dev] [PATCH v2 14/25] spirv_extensions: define spirv_extensions_supported

2017-11-30 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

Add a struct to maintain which SPIR-V extensions are supported, and an
utility method to initialize it based on
nir_spirv_supported_capabilities.

v2:
  * Fixing code style (Ian Romanick)
  * Adding a prefix (spirv) to fill_supported_spirv_extensions (Ian Romanick)
---
 src/compiler/spirv/spirv_extensions.c | 31 +++
 src/compiler/spirv/spirv_extensions.h | 12 
 2 files changed, 43 insertions(+)

diff --git a/src/compiler/spirv/spirv_extensions.c 
b/src/compiler/spirv/spirv_extensions.c
index f50f87b52e1..ae0ceec9a47 100644
--- a/src/compiler/spirv/spirv_extensions.c
+++ b/src/compiler/spirv/spirv_extensions.c
@@ -44,3 +44,34 @@ spirv_extensions_to_string(enum SpvExtension ext)
 
return "unknown";
 }
+
+/**
+ * Sets the supported flags for known SPIR-V extensions based on the
+ * capabilites supported (spirv capabilities based on the spirv to nir
+ * support).
+ *
+ * One could argue that makes more sense in the other way around, as from the
+ * spec pov capabilities are enable for a given extension. But from our pov,
+ * we support or not (depending on the driver) some given capability, and
+ * spirv_to_nir check for capabilities not extensions. Also we usually fill
+ * first the supported capabilities, that are not always related to an
+ * extension.
+ */
+void
+spirv_fill_supported_spirv_extensions(struct spirv_supported_extensions *ext,
+  const struct 
nir_spirv_supported_capabilities *cap)
+{
+   for (unsigned i = 0; i < SPV_EXTENSIONS_COUNT; i++)
+  ext->supported[i] = false;
+
+   ext->count = 0;
+
+   ext->supported[SPV_KHR_shader_draw_parameters] = cap->draw_parameters;
+   ext->supported[SPV_KHR_multiview] = cap->multiview;
+   ext->supported[SPV_KHR_variable_pointers] = cap->variable_pointers;
+
+   for (unsigned i = 0; i < SPV_EXTENSIONS_COUNT; i++) {
+  if (ext->supported[i])
+ ext->count++;
+   }
+}
diff --git a/src/compiler/spirv/spirv_extensions.h 
b/src/compiler/spirv/spirv_extensions.h
index 0568132a517..7c3d9f0f563 100644
--- a/src/compiler/spirv/spirv_extensions.h
+++ b/src/compiler/spirv/spirv_extensions.h
@@ -25,6 +25,7 @@
 #define _SPIRV_EXTENSIONS_H_
 
 #include "compiler/nir/nir.h"
+#include "nir_spirv.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -42,8 +43,19 @@ enum SpvExtension {
SPV_EXTENSIONS_COUNT
 };
 
+struct spirv_supported_extensions {
+   /** Flags the supported extensions. Array to make it easier to iterate. */
+   bool supported[SPV_EXTENSIONS_COUNT];
+
+   /** Number of supported extensions */
+   unsigned int count;
+};
+
 const char *spirv_extensions_to_string(enum SpvExtension ext);
 
+void spirv_fill_supported_spirv_extensions(struct spirv_supported_extensions 
*ext,
+   const struct 
nir_spirv_supported_capabilities *cap);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 12/25] spirv_extensions: add GL_ARB_spirv_extensions boilerplate

2017-11-30 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

v2:
  * Mention extension gap at gl_API.xml (Emil Velikov)
  * Bail with INVALID_ENUM if extension not available on getStringi (Emil 
Velikov)
  * Use EXTRA_EXT macro when defining the extension at
get.c/get_hash_params.py (Emil Velikov)
  * Rename source files (spirvextensions.[ch] -> spirv_extensions.[ch]) (Ian)

Reviewed-by: Ian Romanick 
---
 src/mapi/glapi/gen/ARB_spirv_extensions.xml | 13 
 src/mapi/glapi/gen/Makefile.am  |  1 +
 src/mapi/glapi/gen/gl_API.xml   |  4 +++
 src/mapi/glapi/gen/meson.build  |  1 +
 src/mesa/Makefile.sources   |  2 ++
 src/mesa/main/extensions_table.h|  1 +
 src/mesa/main/get.c |  7 +
 src/mesa/main/get_hash_params.py|  3 ++
 src/mesa/main/getstring.c   | 12 +++
 src/mesa/main/mtypes.h  |  1 +
 src/mesa/main/spirv_extensions.c| 42 +
 src/mesa/main/spirv_extensions.h| 49 +
 src/mesa/meson.build|  2 ++
 13 files changed, 138 insertions(+)
 create mode 100644 src/mapi/glapi/gen/ARB_spirv_extensions.xml
 create mode 100644 src/mesa/main/spirv_extensions.c
 create mode 100644 src/mesa/main/spirv_extensions.h

diff --git a/src/mapi/glapi/gen/ARB_spirv_extensions.xml 
b/src/mapi/glapi/gen/ARB_spirv_extensions.xml
new file mode 100644
index 000..103393104c2
--- /dev/null
+++ b/src/mapi/glapi/gen/ARB_spirv_extensions.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/mapi/glapi/gen/Makefile.am b/src/mapi/glapi/gen/Makefile.am
index 35e37e95a9f..9a7a268adbf 100644
--- a/src/mapi/glapi/gen/Makefile.am
+++ b/src/mapi/glapi/gen/Makefile.am
@@ -167,6 +167,7 @@ API_XML = \
ARB_shader_subroutine.xml \
ARB_shader_storage_buffer_object.xml \
ARB_sparse_buffer.xml \
+   ARB_spirv_extensions.xml \
ARB_sync.xml \
ARB_tessellation_shader.xml \
ARB_texture_barrier.xml \
diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index d3594cfe195..00cf83eca03 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -8404,6 +8404,10 @@
 
 http://www.w3.org/2001/XInclude"/>
 
+
+
+http://www.w3.org/2001/XInclude"/>
+
 
 
 
diff --git a/src/mapi/glapi/gen/meson.build b/src/mapi/glapi/gen/meson.build
index a6a93cc83be..bfc766f7944 100644
--- a/src/mapi/glapi/gen/meson.build
+++ b/src/mapi/glapi/gen/meson.build
@@ -75,6 +75,7 @@ api_xml_files = files(
   'ARB_shader_subroutine.xml',
   'ARB_shader_storage_buffer_object.xml',
   'ARB_sparse_buffer.xml',
+  'ARB_spirv_extensions.xml',
   'ARB_sync.xml',
   'ARB_tessellation_shader.xml',
   'ARB_texture_barrier.xml',
diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources
index e9680bf004c..a897d72f226 100644
--- a/src/mesa/Makefile.sources
+++ b/src/mesa/Makefile.sources
@@ -203,6 +203,8 @@ MAIN_FILES = \
main/shader_query.cpp \
main/shared.c \
main/shared.h \
+   main/spirv_extensions.c \
+   main/spirv_extensions.h \
main/state.c \
main/state.h \
main/stencil.c \
diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h
index ab15ceb9414..06deabd0640 100644
--- a/src/mesa/main/extensions_table.h
+++ b/src/mesa/main/extensions_table.h
@@ -129,6 +129,7 @@ EXT(ARB_shading_language_420pack, 
ARB_shading_language_420pack
 EXT(ARB_shading_language_packing, ARB_shading_language_packing 
  , GLL, GLC,  x ,  x , 2011)
 EXT(ARB_shadow  , ARB_shadow   
  , GLL,  x ,  x ,  x , 2001)
 EXT(ARB_sparse_buffer   , ARB_sparse_buffer
  , GLL, GLC,  x ,  x , 2014)
+EXT(ARB_spirv_extensions, ARB_spirv_extensions 
  ,  x,  GLC,  x ,  x , 2016)
 EXT(ARB_stencil_texturing   , ARB_stencil_texturing
  , GLL, GLC,  x ,  x , 2012)
 EXT(ARB_sync, ARB_sync 
  , GLL, GLC,  x ,  x , 2003)
 EXT(ARB_tessellation_shader , ARB_tessellation_shader  
  ,  x , GLC,  x ,  x , 2009)
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index ea8d932b182..2440f47558d 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -34,6 +34,7 @@
 #include "get.h"
 #include "macros.h"
 #include "mtypes.h"
+#include "spirv_extensions.h"
 #include "state.h"
 #include "texcompress.h"
 #include "texstate.h"
@@ -501,6 +502,7 @@ EXTRA_EXT(OES_primitive_bounding_box);
 EXTRA_EXT(ARB_compute_variable_group_size);
 EXTRA_EXT(KHR_robustness);
 EXTRA_EXT(ARB_sparse_buffer);
+EXTRA_EXT(ARB_spirv_extensions);
 
 static const int
 extra_ARB_color_buffer_float_or_glcore[] = {
@@ -1151,6 +1153,11 @@ 

[Mesa-dev] [PATCH v2 05/25] mesa: implement SPIR-V loading in glShaderBinary

2017-11-30 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)

* Just use the 'spirv_data' member to know whether a gl_shader has
   the SPIR_V_BINARY_ARB state. (Timothy Arceri)

* Remove redundant argument checks. Move extension presence check
   to API entry point where the rest of checks are. Retype 'n' and
   'length'arguments to use the correct and more standard types.
   (Ian Romanick)
---
 src/mesa/main/glspirv.c   | 43 +++
 src/mesa/main/glspirv.h   |  5 +
 src/mesa/main/mtypes.h|  4 
 src/mesa/main/shaderapi.c | 45 ++---
 src/mesa/main/shaderobj.c |  2 ++
 5 files changed, 96 insertions(+), 3 deletions(-)

diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
index 8d1e652e088..d2e76bb1927 100644
--- a/src/mesa/main/glspirv.c
+++ b/src/mesa/main/glspirv.c
@@ -25,6 +25,8 @@
 
 #include "errors.h"
 
+#include "errors.h"
+
 #include "util/u_atomic.h"
 
 void
@@ -59,6 +61,47 @@ _mesa_shader_spirv_data_reference(struct 
gl_shader_spirv_data **dest,
   p_atomic_inc(>RefCount);
 }
 
+void
+_mesa_spirv_shader_binary(struct gl_context *ctx,
+  unsigned n, struct gl_shader **shaders,
+  const void* binary, size_t length)
+{
+   struct gl_spirv_module *module;
+   struct gl_shader_spirv_data *spirv_data;
+
+   assert(length >= 0);
+
+   module = malloc(sizeof(*module) + (size_t)length);
+   if (!module) {
+  _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderBinary");
+  return;
+   }
+
+   p_atomic_set(>RefCount, 0);
+   module->Length = length;
+   memcpy(>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(>spirv_data, spirv_data);
+  _mesa_spirv_module_reference(_data->SpirVModule, module);
+
+  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..ba281f68bef 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,
+  unsigned n, struct gl_shader **shaders,
+  const void* binary, size_t length);
+
 /**
  * \name API functions
  */
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 062eea609c7..50a47e0a65d 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -98,6 +98,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;
@@ -2646,6 +2647,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 72824355838..24058e5ee2e 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"
@@ -1051,6 +1052,16 @@ 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(>spirv_data, NULL);
+
if (sh->CompileStatus == compile_skipped && !sh->FallbackSource) {
   /* If shader was previously compiled back-up the source in case of cache
* fallback.
@@ -2132,9 +2143,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;

[Mesa-dev] [PATCH v2 09/25] mesa: move nir_spirv_supported_capabilities definition

2017-11-30 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

Due gl_spirv we will use it on more places, specifically on
gl_constants, where we would like to use it without a pointer.
---
 src/compiler/spirv/nir_spirv.h | 15 ++-
 src/mesa/main/mtypes.h | 11 +++
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/src/compiler/spirv/nir_spirv.h b/src/compiler/spirv/nir_spirv.h
index 0204e81d091..a14b55cdd4b 100644
--- a/src/compiler/spirv/nir_spirv.h
+++ b/src/compiler/spirv/nir_spirv.h
@@ -28,7 +28,8 @@
 #ifndef _NIR_SPIRV_H_
 #define _NIR_SPIRV_H_
 
-#include "nir/nir.h"
+#include "compiler/nir/nir.h"
+#include "main/mtypes.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -42,18 +43,6 @@ struct nir_spirv_specialization {
};
 };
 
-struct nir_spirv_supported_capabilities {
-   bool float64;
-   bool image_ms_array;
-   bool tessellation;
-   bool draw_parameters;
-   bool image_read_without_format;
-   bool image_write_without_format;
-   bool int64;
-   bool multiview;
-   bool variable_pointers;
-};
-
 nir_function *spirv_to_nir(const uint32_t *words, size_t word_count,
struct nir_spirv_specialization *specializations,
unsigned num_specializations,
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 50a47e0a65d..c8177c9a99a 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -3583,6 +3583,17 @@ struct gl_program_constants
GLuint MaxShaderStorageBlocks;
 };
 
+struct nir_spirv_supported_capabilities {
+   bool float64;
+   bool image_ms_array;
+   bool tessellation;
+   bool draw_parameters;
+   bool image_read_without_format;
+   bool image_write_without_format;
+   bool int64;
+   bool multiview;
+   bool variable_pointers;
+};
 
 /**
  * Constants which may be overridden by device driver during context creation
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 13/25] spirv_extensions: add list of extensions and to_string method

2017-11-30 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

Ideally this should be generated somehow. One option would be gather
all the extension dependencies listed on the core grammar, but there
would be the possibility of not including some of the extensions.

Note that spirv-tools is doing it just slightly better, as it has a
hardcoded list of extensions manually took from the registry, that
they parse to get the enum and the to_string method (see
generate_grammar_tables.py).

v2:
  * Use a macro to improve readability. (Tapani Pälli)
  * Add unreachable on the switch, no default (Eric Engestrom)
  * No typedef enum (Ian Romanick)
  * Sort extensions names (Ian Romanick)
  * Don't add extensions unlikely to be supported by Mesa at any point
(Ian Romanick)
---
 src/compiler/Makefile.sources |  2 ++
 src/compiler/spirv/spirv_extensions.c | 46 +++
 src/compiler/spirv/spirv_extensions.h | 51 +++
 3 files changed, 99 insertions(+)
 create mode 100644 src/compiler/spirv/spirv_extensions.c
 create mode 100644 src/compiler/spirv/spirv_extensions.h

diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources
index 2ab8e163a26..f198456c751 100644
--- a/src/compiler/Makefile.sources
+++ b/src/compiler/Makefile.sources
@@ -293,6 +293,8 @@ SPIRV_FILES = \
spirv/GLSL.std.450.h \
spirv/nir_spirv.h \
spirv/spirv.h \
+   spirv/spirv_extensions.c \
+   spirv/spirv_extensions.h \
spirv/spirv_info.h \
spirv/spirv_to_nir.c \
spirv/vtn_alu.c \
diff --git a/src/compiler/spirv/spirv_extensions.c 
b/src/compiler/spirv/spirv_extensions.c
new file mode 100644
index 000..f50f87b52e1
--- /dev/null
+++ b/src/compiler/spirv/spirv_extensions.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * 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 "spirv.h"
+#include "spirv_extensions.h"
+
+const char *
+spirv_extensions_to_string(enum SpvExtension ext)
+{
+#define STR(x) case x: return #x;
+   switch (ext) {
+   STR(SPV_KHR_16bit_storage);
+   STR(SPV_KHR_device_group);
+   STR(SPV_KHR_multiview);
+   STR(SPV_KHR_shader_ballot);
+   STR(SPV_KHR_shader_draw_parameters);
+   STR(SPV_KHR_storage_buffer_storage_class);
+   STR(SPV_KHR_subgroup_vote);
+   STR(SPV_KHR_variable_pointers);
+   case SPV_EXTENSIONS_COUNT:
+  unreachable("Unknown SPIR-V extension");
+   }
+#undef STR
+
+   return "unknown";
+}
diff --git a/src/compiler/spirv/spirv_extensions.h 
b/src/compiler/spirv/spirv_extensions.h
new file mode 100644
index 000..0568132a517
--- /dev/null
+++ b/src/compiler/spirv/spirv_extensions.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * 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.
+ */
+
+#ifndef _SPIRV_EXTENSIONS_H_
+#define 

[Mesa-dev] [PATCH v2 10/25] mesa: add gl_constants::SpirVCapabilities

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

For drivers to declare which SPIR-V features they support.

v2: Don't use a pointer (Ian Romanick)
---
 src/mesa/main/mtypes.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index c8177c9a99a..7fed85a2ae6 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -4028,6 +4028,9 @@ struct gl_constants
 
/** When drivers are OK with mapped buffers during draw and other calls. */
bool AllowMappedBuffersDuringExecution;
+
+   /** GL_ARB_gl_spirv */
+   struct nir_spirv_supported_capabilities SpirVCapabilities;
 };
 
 
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 04/25] mesa/glspirv: Add struct gl_shader_spirv_data

2017-11-30 Thread Eduardo Lima Mitev
This is a per-shader structure holding the SPIR-V data associated with the
shader (binary module, specialization constants and entry-point).

This is needed because both gl_shader and gl_linked_shader need to share this
data. Instead of copying the data, we pass a reference to it upon program
linking. That's why it is reference-counted.

This struct is created and associated with the shader upon calling
glShaderBinary(), then subsequently filled up by the call to
glSpecializeShaderARB().

v2: Readability improvements (Ian Romanick)

Reviewed-by: Ian Romanick 
---
 src/mesa/main/glspirv.c | 17 +
 src/mesa/main/glspirv.h | 25 +
 2 files changed, 42 insertions(+)

diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
index d4832db549d..8d1e652e088 100644
--- a/src/mesa/main/glspirv.c
+++ b/src/mesa/main/glspirv.c
@@ -42,6 +42,23 @@ _mesa_spirv_module_reference(struct gl_spirv_module **dest,
   p_atomic_inc(>RefCount);
 }
 
+void
+_mesa_shader_spirv_data_reference(struct gl_shader_spirv_data **dest,
+  struct gl_shader_spirv_data *src)
+{
+   struct gl_shader_spirv_data *old = *dest;
+
+   if (old && p_atomic_dec_zero(>RefCount)) {
+  _mesa_spirv_module_reference(&(*dest)->SpirVModule, NULL);
+  ralloc_free(old);
+   }
+
+   *dest = src;
+
+   if (src)
+  p_atomic_inc(>RefCount);
+}
+
 void GLAPIENTRY
 _mesa_SpecializeShaderARB(GLuint shader,
   const GLchar *pEntryPoint,
diff --git a/src/mesa/main/glspirv.h b/src/mesa/main/glspirv.h
index 4e033735cfe..b8a0125ea9f 100644
--- a/src/mesa/main/glspirv.h
+++ b/src/mesa/main/glspirv.h
@@ -42,10 +42,35 @@ struct gl_spirv_module {
char Binary[0];
 };
 
+/**
+ * SPIR-V data needed to compile and link a SPIR-V shader.
+ *
+ * It includes a SPIR-V binary that is potentially shared among different
+ * shaders; and shader-specific specialization constants and entry point.
+ *
+ * It is reference-counted because it is shared between gl_shader and its
+ * corresponding gl_linked_shader.
+ */
+struct gl_shader_spirv_data {
+   GLint RefCount;
+
+   struct gl_spirv_module *SpirVModule;
+
+   GLchar *SpirVEntryPoint;
+
+   GLuint NumSpecializationConstants;
+   GLuint *SpecializationConstantsIndex;
+   GLuint *SpecializationConstantsValue;
+};
+
 void
 _mesa_spirv_module_reference(struct gl_spirv_module **dest,
  struct gl_spirv_module *src);
 
+void
+_mesa_shader_spirv_data_reference(struct gl_shader_spirv_data **dest,
+  struct gl_shader_spirv_data *src);
+
 /**
  * \name API functions
  */
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 06/25] mesa/shaderapi: add a getter for GL_SPIR_V_BINARY_ARB

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

v2: Use the 'spirv_data' member of gl_shader instead of a
   dedicated flag. (Timothy Arceri)
---
 src/mesa/main/shaderapi.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 24058e5ee2e..3ac1419b7ee 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -961,6 +961,9 @@ get_shaderiv(struct gl_context *ctx, GLuint name, GLenum 
pname, GLint *params)
case GL_SHADER_SOURCE_LENGTH:
   *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
   break;
+   case GL_SPIR_V_BINARY_ARB:
+  *params = (shader->spirv_data != NULL);
+  break;
default:
   _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
   return;
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 11/25] i965: initialize SPIR-V capabilities

2017-11-30 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

Needed for ARB_gl_spirv. Right now those are the same that the intel
vulkan driver, but those are not shared. From the ARB_spirv_extensions
spec:

   "3. If a new GL extension is added that includes SPIR-V support via
   a new SPIR-V extension does it's SPIR-V extension also get
   enumerated by the SPIR_V_EXTENSIONS_ARB query?.

   RESOLVED. Yes. It's good to include it for consistency. Any SPIR-V
   functionality supported beyond the SPIR-V version that is required
   for the GL API version should be enumerated."

Reading between lines, there is the possibility of specific GL
extensions enabling specific SPIR-V extensions (so capabilities). That
would mean that it is possible that OpenGL and Vulkan not having the
same capabilities supported, even for the same driver. So for now we
keep them separate. Perhaps in the future it is better to keep them
the same and synced.

v2:
   * Rebase update (SpirVCapabilities not a pointer anymore)
   * Fill spirv capabilities for OpenGL >= 3.3 (Ian Romanick)
---
 src/mesa/drivers/dri/i965/brw_context.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_context.c 
b/src/mesa/drivers/dri/i965/brw_context.c
index b62852d90c8..d90b7797a7a 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -75,6 +75,7 @@
 #include "util/debug.h"
 #include "isl/isl.h"
 
+#include "compiler/spirv/nir_spirv.h"
 /***
  * Mesa's Driver Functions
  ***/
@@ -331,6 +332,21 @@ brw_init_driver_functions(struct brw_context *brw,
   functions->GetSamplePosition = gen6_get_sample_position;
 }
 
+static void
+brw_initialize_spirv_supported_capabilities(struct brw_context *brw)
+{
+   const struct gen_device_info *devinfo = >screen->devinfo;
+   struct gl_context *ctx = >ctx;
+
+   ctx->Const.SpirVCapabilities.float64 = devinfo->gen >= 8;
+   ctx->Const.SpirVCapabilities.int64 = devinfo->gen >= 8;
+   ctx->Const.SpirVCapabilities.tessellation = true;
+   ctx->Const.SpirVCapabilities.draw_parameters = true;
+   ctx->Const.SpirVCapabilities.image_write_without_format = true;
+   ctx->Const.SpirVCapabilities.multiview = true;
+   ctx->Const.SpirVCapabilities.variable_pointers = true;
+}
+
 static void
 brw_initialize_context_constants(struct brw_context *brw)
 {
@@ -696,6 +712,10 @@ brw_initialize_context_constants(struct brw_context *brw)
 
if (!(ctx->Const.ContextFlags & GL_CONTEXT_FLAG_DEBUG_BIT))
   ctx->Const.AllowMappedBuffersDuringExecution = true;
+
+   /* GL_ARB_gl_spirv */
+   if (ctx->Version >= 33)
+  brw_initialize_spirv_supported_capabilities(brw);
 }
 
 static void
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 08/25] spirv_extensions: rename nir_spirv_supported_extensions

2017-11-30 Thread Eduardo Lima Mitev
From: Alejandro Piñeiro 

Renamed to nir_spirv_supported_capabilities.

The original name seemed to suggest that it was directly related to
the SPIR-V extensions supported, but that is not the case. For
example, float64 was supported on SPIR-V 1.0 core, without the need of
any extra extension.

Additionally, this is used at spirv_to_nir to check if a given
capability is supported or not (see spv_check_supported), not if a
given extension is supported or not.

One could argue that it should be renamed to something like
nir_spirv_supported_extra_capabilities (or similar) as not all the
capabilities are flagged there. In any case, that name seemed too long.

This rename was triggered by the need of really maintain the SPIR-V
supported extensions as part of ARB_spirv_extensions implementation,
making that struct name confusing.

Reviewed-by: Ian Romanick 
---
 src/amd/vulkan/radv_shader.c  | 4 ++--
 src/compiler/spirv/nir_spirv.h| 4 ++--
 src/compiler/spirv/spirv_to_nir.c | 6 +++---
 src/compiler/spirv/vtn_private.h  | 2 +-
 src/intel/vulkan/anv_pipeline.c   | 4 ++--
 5 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c
index 32edf2abd22..cea61333ebc 100644
--- a/src/amd/vulkan/radv_shader.c
+++ b/src/amd/vulkan/radv_shader.c
@@ -196,7 +196,7 @@ radv_shader_compile_to_nir(struct radv_device *device,
spec_entries[i].data32 = *(const 
uint32_t *)data;
}
}
-   const struct nir_spirv_supported_extensions supported_ext = {
+   const struct nir_spirv_supported_capabilities supported_cap = {
.draw_parameters = true,
.float64 = true,
.image_read_without_format = true,
@@ -208,7 +208,7 @@ radv_shader_compile_to_nir(struct radv_device *device,
};
entry_point = spirv_to_nir(spirv, module->size / 4,
   spec_entries, num_spec_entries,
-  stage, entrypoint_name, 
_ext, _options);
+  stage, entrypoint_name, 
_cap, _options);
nir = entry_point->shader;
assert(nir->info.stage == stage);
nir_validate_shader(nir);
diff --git a/src/compiler/spirv/nir_spirv.h b/src/compiler/spirv/nir_spirv.h
index 83577fb5d23..0204e81d091 100644
--- a/src/compiler/spirv/nir_spirv.h
+++ b/src/compiler/spirv/nir_spirv.h
@@ -42,7 +42,7 @@ struct nir_spirv_specialization {
};
 };
 
-struct nir_spirv_supported_extensions {
+struct nir_spirv_supported_capabilities {
bool float64;
bool image_ms_array;
bool tessellation;
@@ -58,7 +58,7 @@ nir_function *spirv_to_nir(const uint32_t *words, size_t 
word_count,
struct nir_spirv_specialization *specializations,
unsigned num_specializations,
gl_shader_stage stage, const char *entry_point_name,
-   const struct nir_spirv_supported_extensions *ext,
+   const struct nir_spirv_supported_capabilities *cap,
const nir_shader_compiler_options *options);
 
 #ifdef __cplusplus
diff --git a/src/compiler/spirv/spirv_to_nir.c 
b/src/compiler/spirv/spirv_to_nir.c
index 027efab88d7..6034228ed36 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -2672,7 +2672,7 @@ stage_for_execution_model(SpvExecutionModel model)
 }
 
 #define spv_check_supported(name, cap) do {\
-  if (!(b->ext && b->ext->name))   \
+  if (!(b->cap && b->cap->name))   \
  vtn_warn("Unsupported SPIR-V capability: %s",  \
   spirv_capability_to_string(cap)); \
} while(0)
@@ -3313,7 +3313,7 @@ nir_function *
 spirv_to_nir(const uint32_t *words, size_t word_count,
  struct nir_spirv_specialization *spec, unsigned num_spec,
  gl_shader_stage stage, const char *entry_point_name,
- const struct nir_spirv_supported_extensions *ext,
+ const struct nir_spirv_supported_capabilities *cap,
  const nir_shader_compiler_options *options)
 {
const uint32_t *word_end = words + word_count;
@@ -3336,7 +3336,7 @@ spirv_to_nir(const uint32_t *words, size_t word_count,
exec_list_make_empty(>functions);
b->entry_point_stage = stage;
b->entry_point_name = entry_point_name;
-   b->ext = ext;
+   b->cap = cap;
 
/* Handle all the preamble instructions */
words = vtn_foreach_instruction(b, words, word_end,
diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h
index 6b4645acc8b..0c1ce21dd88 100644
--- a/src/compiler/spirv/vtn_private.h
+++ b/src/compiler/spirv/vtn_private.h
@@ -465,7 

[Mesa-dev] [PATCH v2 07/25] mesa: refuse to compile SPIR-V shaders or link mixed shaders

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

Note that gl_shader::CompileStatus will also indicate whether a shader
has been successfully specialized.

v2: Use the 'spirv_data' member of gl_shader to know if it is a SPIR-V
   shader, instead of a dedicated flag. (Timothy Arceri)
---
 src/mesa/main/shaderapi.c   | 12 
 src/mesa/program/ir_to_mesa.cpp | 17 -
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 3ac1419b7ee..251c876ada8 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -1092,6 +1092,18 @@ _mesa_compile_shader(struct gl_context *ctx, struct 
gl_shader *sh)
if (!sh)
   return;
 
+   /* The GL_ARB_gl_spirv spec says:
+*
+*"Add a new error for the CompileShader command:
+*
+*  An INVALID_OPERATION error is generated if the SPIR_V_BINARY_ARB
+*  state of  is TRUE."
+*/
+   if (sh->spirv_data) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, "glCompileShader(SPIR-V)");
+  return;
+   }
+
if (!sh->Source) {
   /* If the user called glCompileShader without first calling
* glShaderSource, we should fail to compile, but not raise a GL_ERROR.
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index aa8b6d7084b..047f5b38f71 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -3077,6 +3077,7 @@ void
 _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
 {
unsigned int i;
+   GLboolean spirv;
 
_mesa_clear_shader_program_data(ctx, prog);
 
@@ -3086,7 +3087,21 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct 
gl_shader_program *prog)
 
for (i = 0; i < prog->NumShaders; i++) {
   if (!prog->Shaders[i]->CompileStatus) {
-linker_error(prog, "linking with uncompiled shader");
+linker_error(prog, "linking with uncompiled/unspecialized shader");
+  }
+
+  if (!i) {
+ spirv = (prog->Shaders[i]->spirv_data != NULL);
+  } else if (spirv && !prog->Shaders[i]->spirv_data) {
+ /* The GL_ARB_gl_spirv spec adds a new bullet point to the list of
+  * reasons LinkProgram can fail:
+  *
+  *"All the shader objects attached to  do not have the
+  * same value for the SPIR_V_BINARY_ARB state."
+  */
+ linker_error(prog,
+  "not all attached shaders have the same "
+  "SPIR_V_BINARY_ARB state");
   }
}
 
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 01/25] mesa: add GL_ARB_gl_spirv boilerplate

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

v2: * Add meson build bits (Eric Engestrom)

* Return INVALID_OPERATION error on SpecializeShaderARB (Ian Romanick)

Reviewed-by: Emil Velikov 
Reviewed-by: Ian Romanick 
Reviewed-by: Timothy Arceri 
---
 src/mapi/glapi/gen/ARB_gl_spirv.xml | 21 ++
 src/mapi/glapi/gen/Makefile.am  |  1 +
 src/mapi/glapi/gen/gl_API.xml   |  4 +++
 src/mapi/glapi/gen/gl_genexec.py|  1 +
 src/mapi/glapi/gen/meson.build  |  1 +
 src/mesa/Makefile.sources   |  2 ++
 src/mesa/main/extensions_table.h|  1 +
 src/mesa/main/glspirv.c | 39 +
 src/mesa/main/glspirv.h | 51 +
 src/mesa/main/mtypes.h  |  1 +
 src/mesa/main/tests/dispatch_sanity.cpp |  3 ++
 src/mesa/meson.build|  2 ++
 12 files changed, 127 insertions(+)
 create mode 100644 src/mapi/glapi/gen/ARB_gl_spirv.xml
 create mode 100644 src/mesa/main/glspirv.c
 create mode 100644 src/mesa/main/glspirv.h

diff --git a/src/mapi/glapi/gen/ARB_gl_spirv.xml 
b/src/mapi/glapi/gen/ARB_gl_spirv.xml
new file mode 100644
index 000..0dd615480f7
--- /dev/null
+++ b/src/mapi/glapi/gen/ARB_gl_spirv.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/mapi/glapi/gen/Makefile.am b/src/mapi/glapi/gen/Makefile.am
index 87d8517b7ba..35e37e95a9f 100644
--- a/src/mapi/glapi/gen/Makefile.am
+++ b/src/mapi/glapi/gen/Makefile.am
@@ -144,6 +144,7 @@ API_XML = \
ARB_framebuffer_object.xml \
ARB_get_program_binary.xml \
ARB_get_texture_sub_image.xml \
+   ARB_gl_spirv.xml \
ARB_gpu_shader_fp64.xml \
ARB_gpu_shader_int64.xml \
ARB_gpu_shader5.xml \
diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index eb1d9b83b27..d3594cfe195 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -8400,6 +8400,10 @@
 
 http://www.w3.org/2001/XInclude"/>
 
+
+
+http://www.w3.org/2001/XInclude"/>
+
 
 
 
diff --git a/src/mapi/glapi/gen/gl_genexec.py b/src/mapi/glapi/gen/gl_genexec.py
index b7b22328ff8..aaff9f230b3 100644
--- a/src/mapi/glapi/gen/gl_genexec.py
+++ b/src/mapi/glapi/gen/gl_genexec.py
@@ -77,6 +77,7 @@ header = """/**
 #include "main/eval.h"
 #include "main/externalobjects.h"
 #include "main/get.h"
+#include "main/glspirv.h"
 #include "main/feedback.h"
 #include "main/fog.h"
 #include "main/fbobject.h"
diff --git a/src/mapi/glapi/gen/meson.build b/src/mapi/glapi/gen/meson.build
index 599f094e998..a6a93cc83be 100644
--- a/src/mapi/glapi/gen/meson.build
+++ b/src/mapi/glapi/gen/meson.build
@@ -52,6 +52,7 @@ api_xml_files = files(
   'ARB_framebuffer_object.xml',
   'ARB_get_program_binary.xml',
   'ARB_get_texture_sub_image.xml',
+  'ARB_gl_spirv.xml',
   'ARB_gpu_shader_fp64.xml',
   'ARB_gpu_shader_int64.xml',
   'ARB_gpu_shader5.xml',
diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources
index 6da1e3fef9d..e9680bf004c 100644
--- a/src/mesa/Makefile.sources
+++ b/src/mesa/Makefile.sources
@@ -118,6 +118,8 @@ MAIN_FILES = \
main/getstring.c \
main/glformats.c \
main/glformats.h \
+   main/glspirv.c \
+   main/glspirv.h \
main/glthread.c \
main/glthread.h \
main/glheader.h \
diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h
index 5b66e7d30df..ab15ceb9414 100644
--- a/src/mesa/main/extensions_table.h
+++ b/src/mesa/main/extensions_table.h
@@ -72,6 +72,7 @@ EXT(ARB_framebuffer_object  , 
ARB_framebuffer_object
 EXT(ARB_framebuffer_sRGB, EXT_framebuffer_sRGB 
  , GLL, GLC,  x ,  x , 1998)
 EXT(ARB_get_program_binary  , dummy_true   
  , GLL, GLC,  x ,  x , 2010)
 EXT(ARB_get_texture_sub_image   , dummy_true   
  , GLL, GLC,  x ,  x , 2014)
+EXT(ARB_gl_spirv, ARB_gl_spirv 
  ,  x,  GLC,  x ,  x , 2016)
 EXT(ARB_gpu_shader5 , ARB_gpu_shader5  
  ,  x , GLC,  x ,  x , 2010)
 EXT(ARB_gpu_shader_fp64 , ARB_gpu_shader_fp64  
  ,  x , GLC,  x ,  x , 2010)
 EXT(ARB_gpu_shader_int64, ARB_gpu_shader_int64 
  ,  x , GLC,  x ,  x , 2015)
diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
new file mode 100644
index 000..3989f424241
--- /dev/null
+++ b/src/mesa/main/glspirv.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * 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 

[Mesa-dev] [PATCH v2 03/25] mesa/glspirv: Add struct gl_spirv_module

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

v2: * Make the SPIR-V module struct part of a larger gl_shader_spirv_data
struct that will be introduced later, and don't reference it directly
in gl_shader. (Eduardo Lima)
* Readability improvements (Ian Romanick)

Reviewed-by: Ian Romanick 
---
 src/mesa/main/glspirv.c | 17 +
 src/mesa/main/glspirv.h | 16 
 2 files changed, 33 insertions(+)

diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
index 3989f424241..d4832db549d 100644
--- a/src/mesa/main/glspirv.c
+++ b/src/mesa/main/glspirv.c
@@ -25,6 +25,23 @@
 
 #include "errors.h"
 
+#include "util/u_atomic.h"
+
+void
+_mesa_spirv_module_reference(struct gl_spirv_module **dest,
+ struct gl_spirv_module *src)
+{
+   struct gl_spirv_module *old = *dest;
+
+   if (old && p_atomic_dec_zero(>RefCount))
+  free(old);
+
+   *dest = src;
+
+   if (src)
+  p_atomic_inc(>RefCount);
+}
+
 void GLAPIENTRY
 _mesa_SpecializeShaderARB(GLuint shader,
   const GLchar *pEntryPoint,
diff --git a/src/mesa/main/glspirv.h b/src/mesa/main/glspirv.h
index 1de88717faa..4e033735cfe 100644
--- a/src/mesa/main/glspirv.h
+++ b/src/mesa/main/glspirv.h
@@ -30,6 +30,22 @@
 extern "C" {
 #endif
 
+/**
+ * A SPIR-V module contains the raw SPIR-V binary as set by ShaderBinary.
+ *
+ * It is reference-counted, because the same module can be attached to multiple
+ * shader objects simultaneously.
+ */
+struct gl_spirv_module {
+   unsigned RefCount;
+   GLint Length;
+   char Binary[0];
+};
+
+void
+_mesa_spirv_module_reference(struct gl_spirv_module **dest,
+ struct gl_spirv_module *src);
+
 /**
  * \name API functions
  */
-- 
2.15.0

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


[Mesa-dev] [PATCH v2 00/25] Initial gl_spirv and spirv_extensions support in Mesa and i965

2017-11-30 Thread Eduardo Lima Mitev
Hello,

This is the second version of the series providing initial support for 
ARB_gl_spirv and ARB_spirv_extensions in Mesa and i965.

First version of the series can be found at 
<https://lists.freedesktop.org/archives/mesa-dev/2017-November/177004.html>.

In this series we hope we have addressed all issues detected during the initial 
review. Thank you all who participated!

Taking the nitpicks and minor fixes apart, most important changes compared to 
the first version are:

* A dedicated 'spirv' flag was removed from gl_shader struct. Now we use the 
nulness of 'spirv_data' member for the same purpose.

* The per-program 'spirv' flag was moved out of this series, but will likely be 
re-introduced in the next delivery, because it will become necessary.

* We enforce one SPIR-V shader per stage, and fail linking if this condition is 
not met.

* 'SpirVCapabilities' struct of GL context constants is no longer a pointer but 
a static struct.

As usual, a tree of this series can be found at 
<https://github.com/Igalia/mesa/commits/arb_gl_spirv-series1-v2>.

A tree of the larger WIP branch from which this series is taken: 
<https://github.com/Igalia/mesa/commits/wip/igalia/arb_gl_spirv>.

Thanks in advance for the reviews!

cheers,
Eduardo

Alejandro Piñeiro (9):
  spirv_extensions: rename nir_spirv_supported_extensions
  mesa: move nir_spirv_supported_capabilities definition
  i965: initialize SPIR-V capabilities
  spirv_extensions: add GL_ARB_spirv_extensions boilerplate
  spirv_extensions: add list of extensions and to_string method
  spirv_extensions: define spirv_extensions_supported
  spirv_extensions: add spirv_supported_extensions on gl_constants
  spirv_extensions: i965: initialize SPIR-V extensions
  nir/spirv: add gl_spirv_validation method

Eduardo Lima Mitev (8):
  mesa/glspirv: Add struct gl_shader_spirv_data
  mesa/glspirv: Add a _mesa_spirv_link_shaders() placeholder
  mesa/program: Link SPIR-V shaders using the SPIR-V code-path
  mesa: Add a reference to gl_shader_spirv_data to gl_linked_shader
  mesa/glspirv: Create gl_linked_shader objects for a SPIR-V program
  mesa/glspirv: Add a _mesa_spirv_to_nir() function
  i965: Call spirv_to_nir() instead of glsl_to_nir() for SPIR-V shaders
  i965: Don't call process_glsl_ir() for SPIR-V shaders

Neil Roberts (1):
  mesa: Add boilerplate for the GL 4.6 alias of glSpecializeShaderARB

Nicolai Hähnle (7):
  mesa: add GL_ARB_gl_spirv boilerplate
  mesa/glspirv: Add struct gl_spirv_module
  mesa: implement SPIR-V loading in glShaderBinary
  mesa/shaderapi: add a getter for GL_SPIR_V_BINARY_ARB
  mesa: refuse to compile SPIR-V shaders or link mixed shaders
  mesa: add gl_constants::SpirVCapabilities
  mesa: Implement glSpecializeShaderARB

 src/amd/vulkan/radv_shader.c|   4 +-
 src/compiler/Makefile.sources   |   2 +
 src/compiler/spirv/nir_spirv.h  |  21 +-
 src/compiler/spirv/spirv_extensions.c   |  77 +++
 src/compiler/spirv/spirv_extensions.h   |  63 ++
 src/compiler/spirv/spirv_to_nir.c   | 160 +-
 src/compiler/spirv/vtn_private.h|   2 +-
 src/intel/vulkan/anv_pipeline.c |   4 +-
 src/mapi/glapi/gen/ARB_gl_spirv.xml |  21 ++
 src/mapi/glapi/gen/ARB_spirv_extensions.xml |  13 ++
 src/mapi/glapi/gen/GL4x.xml |  11 +
 src/mapi/glapi/gen/Makefile.am  |   2 +
 src/mapi/glapi/gen/gl_API.xml   |   8 +
 src/mapi/glapi/gen/gl_genexec.py|   1 +
 src/mapi/glapi/gen/meson.build  |   2 +
 src/mesa/Makefile.sources   |   4 +
 src/mesa/drivers/dri/i965/brw_context.c |  26 +++
 src/mesa/drivers/dri/i965/brw_link.cpp  |   3 +-
 src/mesa/drivers/dri/i965/brw_program.c |  14 +-
 src/mesa/main/context.c |   2 +
 src/mesa/main/extensions_table.h|   2 +
 src/mesa/main/get.c |   7 +
 src/mesa/main/get_hash_params.py|   3 +
 src/mesa/main/getstring.c   |  12 +
 src/mesa/main/glspirv.c | 331 
 src/mesa/main/glspirv.h | 108 +
 src/mesa/main/mtypes.h  |  31 +++
 src/mesa/main/shaderapi.c   |  60 -
 src/mesa/main/shaderobj.c   |   3 +
 src/mesa/main/spirv_extensions.c|  60 +
 src/mesa/main/spirv_extensions.h|  49 
 src/mesa/main/tests/dispatch_sanity.cpp |   3 +
 src/mesa/meson.build|   4 +
 src/mesa/program/ir_to_mesa.cpp |  23 +-
 34 files changed, 1098 insertions(+), 38 deletions(-)
 create mode 100644 src/compiler/spirv/spirv_extensions.c
 create mode 100644 src/compiler/spirv/spirv_extensions.h
 create mode 100644 src/mapi/glapi/gen/ARB_gl_spirv.xml
 create mode 100644 src/mapi/glapi/gen/ARB_spirv_extensions.xml
 create mode 100644 src/mesa/main/glspirv.c
 create mode 10

[Mesa-dev] [PATCH v2 02/25] mesa: Add boilerplate for the GL 4.6 alias of glSpecializeShaderARB

2017-11-30 Thread Eduardo Lima Mitev
From: Neil Roberts 

---
 src/mapi/glapi/gen/GL4x.xml | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/src/mapi/glapi/gen/GL4x.xml b/src/mapi/glapi/gen/GL4x.xml
index 88dba5cd71a..0a8094166c8 100644
--- a/src/mapi/glapi/gen/GL4x.xml
+++ b/src/mapi/glapi/gen/GL4x.xml
@@ -73,6 +73,17 @@
 
   
   
+
+  
+  
+
+  
+
+
+
+
+
+  
 
 
 
-- 
2.15.0

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


Re: [Mesa-dev] [PATCH 00/24] Initial gl_spirv and spirv_extensions support in Mesa and i965

2017-11-28 Thread Eduardo Lima Mitev
Hi,

This is a heads-up that I'm preparing a v2 of this series incorporating
all the feedback received so far.

I plan to submit it imminently (tomorrow?) and several patches have
diverged quite a bit; so please hold on for a few hours on any review
you might have planned.

Thanks!

Eduardo

On 11/15/2017 02:22 PM, Eduardo Lima Mitev wrote:
> Hello,
>
> This series is the first chunk of our on-going work to support 
> GL_ARB_gl_spirv [1] and GL_ARB_spirv_extensions [2] in Mesa and i965. It adds 
> API entry-points, API error checking, most of driver-agnostic setup and 
> housekeeping, and a few basic i965 bits. It is based off initial work that 
> Nicolai Hähnle did back in July.
>
> In the case of GL_ARB_spirv_extensions, we consider our work on this 
> extension to be completed.
>
> For GL_ARB_gl_spirv, this is the high level explanation of what we do:
>
> * When the user calls glShaderBinary() with a SPIR-V binary, we mark the 
> shader as a SPIR-V shader and save the binary module within it.
>
> * Upon a call to glSpecializeShaderARB(), we perform a pass over the saved 
> binary module to validate that the given specialization constants and entry 
> point are ok. For this, we use a modified version of spirv_to_nir() that 
> doesn't generate any NIR, but simply performs the validation we need. If 
> everything went ok, we then save the specialization constants and entry point 
> within the shader object as well.
>
> * Upon program linking, and before calling driver-specific LinkShader(), we 
> generate gl_linked_shader objects and associate them with the SPIR-V data 
> that has been recorded in gl_shader (namely: the binary module, the 
> specialization constants and the entry point name).
>
> * We also introduce a convenient spirv_to_nir() wrapper for backends that use 
> NIR.
>
> This is all this series does. At this point, driver-specific linkers have all 
> the SPIR-V information they need (attached to the gl_shader and 
> gl_linked_shader objects of a program) to implement whatever linking strategy 
> they choose. For i965, we are planning to go for a (mostly) pure NIR linking 
> approach (see below).
>
>
> This is the series' logical break down:
>
> - Patch 1 introduces the extension in Mesa and adds 'mesa/main/glspirv.c/h' 
> files to hold its implementation.
>
> - Patch 2 adds a flag to gl_shader to tell SPIR-V and GLSL shaders apart.
>
> - Patch 3 adds error checks introduced by the extension.
>
> - Patches 4 to 6 make glShaderBinary() load SPIR-V, associating the SPIR-V 
> binary with the shader for later use.
>
> - Patches 7 to 9 add SPIR-V capabilities to a GL context. This information is 
> an extension requirement. In our case, we already fill it up for i965.
>
> - Patches 10 to 14 implement GL_ARB_spirv_extensions.
>
> - Patches 15 and 16 implement glSpecializeShaderARB().
>
> - Patches 17 to 22 fork the linking code for GLSL or SPIR-V programs, to 
> avoid using the GLSL linker on SPIR-V shaders. The GLSL linker expects 
> GLSL-IR to be present, and that's NULL for SPIR-V shaders.
>
> - Patches 23 and 24 do the same as above but for i965, plus also generate the 
> NIR out of each SPIR-V shader.
>
>
> A tree of this series can be found at 
> <https://github.com/Igalia/mesa/commits/arb_gl_spirv-series1-v1>.
>
> A tree of the larger branch from which this series is taken can be found at 
> <https://github.com/Igalia/mesa/commits/wip/igalia/arb_gl_spirv>. Note that 
> this is still very experimental and will change a lot constantly.
>
>
> What's our plan going forward?
>
> In Mesa we have a single linker that is heavily interwined with GLSL-IR. So, 
> if we want to link SPIR-V shaders, we have basically two approaches:
>
> 1. Convert the SPIR-V to GLSL-IR and reuse the existing linker: Introduces 
> yet another conversion in the shader compilation process, but allows us to 
> reuse a battle-tested linker.
>
> 2. Write a new linker: Obviously a lot of work.
>
> Or use a combination of the two approaches, a mixed (or incremental) solution 
> where we aim at writing a new linker, but for specific cases and/or 
> temporarily we generate some minimal GLSL-IR that would allow us to reuse 
> hard-to-rewrite parts of the existing GLSL linker.
>
> After spending weeks prototyping different solutions, we have more or less 
> settled for a mixed approach: write a pure NIR linker from scratch, that will 
> reuse parts of the GLSL linker, but trying to avoid generating any GLSL-IR to 
> feed the GLSL linker directly (doing that only when really needed).
>
> We have prototyped some bits of this NIR linker already with a promising 
> degree of success. At this point, we are confident that with this mixed 

Re: [Mesa-dev] [PATCH 21/24] mesa/glspirv: Create gl_linked_shader objects for a SPIR-V program

2017-11-28 Thread Eduardo Lima Mitev
On 11/27/2017 03:20 AM, Timothy Arceri wrote:
> On 16/11/17 00:22, Eduardo Lima Mitev wrote:
>> ---
>>   src/mesa/main/glspirv.c | 51
>> ++---
>>   1 file changed, 48 insertions(+), 3 deletions(-)
>>
>> diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
>> index 86f1d221cc9..9332764f152 100644
>> --- a/src/mesa/main/glspirv.c
>> +++ b/src/mesa/main/glspirv.c
>> @@ -29,6 +29,8 @@
>>   #include "compiler/nir/nir.h"
>>   #include "compiler/spirv/nir_spirv.h"
>>   +#include "program/program.h"
>> +
>>   #include "util/u_atomic.h"
>>     void
>> @@ -117,14 +119,57 @@ _mesa_spirv_shader_binary(struct gl_context *ctx,
>>  }
>>   }
>>   +/**
>> + * This is the equivalent to compiler/glsl/linker.cpp::link_shaders()
>> + * but for SPIR-V programs.
>> + *
>> + * This method just creates the gl_linked_shader structs with a
>> reference to
>> + * the SPIR-V data collected during previous steps.
>> + *
>> + * The real linking happens later in the driver-specifc call
>> LinkShader().
>> + * This is so backends can implement different linking strategies for
>> + * SPIR-V programs.
>> + */
>>   void
>>   _mesa_spirv_link_shaders(struct gl_context *ctx, struct
>> gl_shader_program *prog)
>>   {
>> -   /* @TODO: This is a placeholder for the equivalent of
>> -    * compiler/glsl/linker.cpp::link_shaders() but for SPIR-V.
>> -    */
>>  prog->data->LinkStatus = linking_success;
>>  prog->data->Validated = false;
>> +
>> +   for (unsigned i = 0; i < prog->NumShaders; i++) {
>
>
> The GL api allows multiple shaders to be attached to the same stage of
> a program. This code assumes a 1-to-1 mapping of shaders to stages.
>

Yes. I had a comment saying that we only support one shader per stage,
but it got removed at some point.

> I don't see anything in the spec that says its an error to attach more
> than one shader to a single stage, but this looks like a probable and
> might require a spec bug to be filed.
>

Yes, I think the extension spec should forbid it. As the API is designed
right now, all shaders attached to the program must have been
specialized, and specialization requires specifying an entry
pointfunction name. Now, what happens if there are more that one shader
for a single stage? What's the valid entry point? Or should all shaders
of a stage have been specialized with the same entry point? This needs
clarificationIMO.

> With this existing code we will leak gl_linked_shader and never unref
> spirv_data should multiple shaders be attached to the same stage.
>

Right, good catch.I will update the patch to put back the comment saying
that for now we only support one shader per stage, and also bail with a
linker error if we see a second shader for a given stage.

Thanks, Timothy.

Eduardo

>
>> +  struct gl_shader *shader = prog->Shaders[i];
>> +  gl_shader_stage shader_type = shader->Stage;
>> +
>> +  assert(shader->spirv_data);
>> +
>> +  struct gl_linked_shader *linked = rzalloc(NULL, struct
>> gl_linked_shader);
>> +  linked->Stage = shader_type;
>> +
>> +  /* Create program and attach it to the linked shader */
>> +  struct gl_program *gl_prog =
>> + ctx->Driver.NewProgram(ctx,
>> +   
>> _mesa_shader_stage_to_program(shader_type),
>> +    prog->Name, false);
>> +  if (!gl_prog) {
>> + prog->data->LinkStatus = linking_failure;
>> + _mesa_delete_linked_shader(ctx, linked);
>> + return;
>> +  }
>> +
>> +  _mesa_reference_shader_program_data(ctx,
>> +  _prog->sh.data,
>> +  prog->data);
>> +
>> +  /* Don't use _mesa_reference_program() just take ownership */
>> +  linked->Program = gl_prog;
>> +
>> +  /* Reference the SPIR-V data from shader to the linked shader */
>> +  _mesa_shader_spirv_data_reference(>spirv_data,
>> +    shader->spirv_data);
>> +
>> +  prog->_LinkedShaders[shader_type] = linked;
>> +  prog->data->linked_stages |= 1 << shader_type;
>> +   }
>>   }
>>     void GLAPIENTRY
>>
>

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


Re: [Mesa-dev] [PATCH 17/24] mesa/main: Add a 'spirv' flag to gl_shader_program_data

2017-11-21 Thread Eduardo Lima Mitev

On 11/20/2017 01:54 PM, Timothy Arceri wrote:

On 20/11/17 21:56, Eduardo Lima Mitev wrote:

On 11/20/2017 11:31 AM, Timothy Arceri wrote:

On 20/11/17 19:00, Eduardo Lima Mitev wrote:

On 11/16/2017 12:23 AM, Timothy Arceri wrote:

On 16/11/17 00:22, Eduardo Lima Mitev wrote:

This will be used by the linker code to dfferentiate between
programs made out of SPIR-V or GLSL shaders.


So far everywhere this is used it seems you could just do 
something like:


 if (shProg->_LinkedShaders[stage]->spirv_data)
   ... spriv stuff ...
 else
   ... glsl stuff ...


This flag is a per-program variable (as oppose to a per-shader 
one). While it would be possible to know the type of program (spirv 
vs. glsl) indirectly by looking at its linked shaders, I think it 
is clearer and more readable (and more formal) to have a flag in 
the program data for this.


The flag is per-program but as I said above everywhere you use it 
you have access to the shader so it's totally unneeded. Adding bools 
everywhere just ends up with two ways to get to the same solution 
making things less clear and less readable because the code always 
ends up using a bool here and a NULL check there. It's hardly a 
stretch to see that if you have spirv_data than its a spriv shader.




Please check these two patches which are part of the larger, 
in-progress work to support gl_spirv:


https://github.com/Igalia/mesa/commit/968c17dd4258af731bf14e5836e5ededced5d6f5 

https://github.com/Igalia/mesa/commit/0bf39a1d815fdcb0ba281507a6f2d6d88a6dc1a1 



These two explain why we need a a per-program flag to fork code-paths 
between glsl and spirv. In both cases we are not in a per-shader 
context, so we cannot practically use spirv_data from gl_linked_shaders.


Now, if you have a proposal for a different per-program way to do 
what the above two patches intend, I will be happy to consider it.


Why do this for spriv only? Why not us the new nir linker for GLSL 
also? There are many go reasons for doing so.




I agree there are good reasons to eventually use the NIR linker for both 
SPIR-V and GLSL.

However, this should be a long term goal.

Having a NIR linker with the same level of completeness and quality as 
the current GLSL linker requires a lot of effort, that will likely span 
months. We certainly don't want to block supporting ARB_gl_spirv until 
we have a regression-free linker for both SPIR-V and GLSL programs.


Having this temporary fork in the driver linking code-path allows us to 
introduce the NIR linker incrementally, activating it on only for a 
subset of cases (SPIR-V programs).


We have also experimented with activating Ian's GLSL-to-SPIR-V generator 
under an environment variable. This will take normal GLSL shaders and 
turn them into SPIR-V shaders, then route them through our SPIR-V paths. 
This could be an

intermediary step before going full NIR linker.

Timothy, what about if I drop this patch from this series, and 
re-introduced it in the next series when the code-path forks really need 
the flag? Would that be ok for you?


Eduardo



It is my fault if I didn't explain in the commit log that the flag 
would be needed in the 2nd series. Or better, I should have moved 
this patch to the 2nd series where it is actually used.


Eduardo

As the person that spent a bunch of time cleaning up all these 
structs at then end of last year (I believe I landed around 100 
patches to clean up the mess) I'm very much against adding 
unnecessary fields back in here.




This also allows for releasing the memory of the spirv_data 
structure when we don't need it, and still being able to know what 
kind of program we have.


Why do you need this though? The backend shouldn't care where it 
came from once you have compiled it right? You also can't free it 
until gl_shader is freed in which case the API can't query it 
anymore either so as far as I can see it's not needed.




I would personally keep this flag.

Are there more opinions about this?

Thanks for reviewing, Timothy.

Edu




---
  src/mesa/main/mtypes.h | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index d624f2cbd19..db9c2e1deaa 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2902,6 +2902,12 @@ struct gl_shader_program_data
   /* Mask of stages this program was linked against */
 unsigned linked_stages;
+
+   /* Whether the shaders of this program are loaded from SPIR-V 
binaries
+    * (all have the SPIR_V_BINARY_ARB state). This was 
introduced by the

+    * ARB_gl_spirv extension.
+    */
+   bool spirv;
  };
    /**













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


  1   2   3   4   5   6   7   8   9   >