[Mesa-dev] [PATCH 5/8] tgsi: add support for image operations to tgsi_exec. (v2.1)

2016-03-30 Thread Dave Airlie
From: Dave Airlie 

This adds support for load/store/atomic operations on images
along with image tracking support.

v2: add RESQ support. (Ilia)
v2.1: constify interface (Brian)

Signed-off-by: Dave Airlie 
---
 src/gallium/auxiliary/draw/draw_gs.c  |   2 +-
 src/gallium/auxiliary/draw/draw_vs_exec.c |   2 +-
 src/gallium/auxiliary/tgsi/tgsi_exec.c| 266 +-
 src/gallium/auxiliary/tgsi/tgsi_exec.h|  44 -
 src/gallium/drivers/softpipe/sp_fs_exec.c |   4 +-
 5 files changed, 312 insertions(+), 6 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_gs.c 
b/src/gallium/auxiliary/draw/draw_gs.c
index fcef31b..2f18df8 100644
--- a/src/gallium/auxiliary/draw/draw_gs.c
+++ b/src/gallium/auxiliary/draw/draw_gs.c
@@ -681,7 +681,7 @@ void draw_geometry_shader_prepare(struct 
draw_geometry_shader *shader,
if (!use_llvm && shader && shader->machine->Tokens != shader->state.tokens) 
{
   tgsi_exec_machine_bind_shader(shader->machine,
 shader->state.tokens,
-draw->gs.tgsi.sampler);
+draw->gs.tgsi.sampler, NULL);
}
 }
 
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c 
b/src/gallium/auxiliary/draw/draw_vs_exec.c
index 3fd8ef3..c1266e7 100644
--- a/src/gallium/auxiliary/draw/draw_vs_exec.c
+++ b/src/gallium/auxiliary/draw/draw_vs_exec.c
@@ -70,7 +70,7 @@ vs_exec_prepare( struct draw_vertex_shader *shader,
if (evs->machine->Tokens != shader->state.tokens) {
   tgsi_exec_machine_bind_shader(evs->machine,
 shader->state.tokens,
-draw->vs.tgsi.sampler);
+draw->vs.tgsi.sampler, NULL);
}
 }
 
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c 
b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index fa1c916..21e2631 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -853,7 +853,8 @@ void
 tgsi_exec_machine_bind_shader(
struct tgsi_exec_machine *mach,
const struct tgsi_token *tokens,
-   struct tgsi_sampler *sampler)
+   struct tgsi_sampler *sampler,
+   struct tgsi_image *image)
 {
uint k;
struct tgsi_parse_context parse;
@@ -871,6 +872,7 @@ tgsi_exec_machine_bind_shader(
 
mach->Tokens = tokens;
mach->Sampler = sampler;
+   mach->Image = image;
 
if (!tokens) {
   /* unbind and free all */
@@ -3706,6 +3708,240 @@ exec_dfracexp(struct tgsi_exec_machine *mach,
}
 }
 
+static int
+get_image_coord_dim(int tgsi_tex, int *sample)
+{
+   int dim;
+   switch (tgsi_tex) {
+   case TGSI_TEXTURE_BUFFER:
+   case TGSI_TEXTURE_1D:
+  dim = 1;
+  break;
+   case TGSI_TEXTURE_2D:
+   case TGSI_TEXTURE_RECT:
+   case TGSI_TEXTURE_1D_ARRAY:
+   case TGSI_TEXTURE_2D_MSAA:
+  dim = 2;
+  break;
+   case TGSI_TEXTURE_3D:
+   case TGSI_TEXTURE_CUBE:
+   case TGSI_TEXTURE_2D_ARRAY:
+   case TGSI_TEXTURE_2D_ARRAY_MSAA:
+   case TGSI_TEXTURE_CUBE_ARRAY:
+  dim = 3;
+  break;
+   default:
+  assert(!"unknown texture target");
+  dim = 0;
+  break;
+   }
+
+   if (sample) {
+  switch (tgsi_tex) {
+  case TGSI_TEXTURE_2D_MSAA:
+ *sample = 3;
+ break;
+  case TGSI_TEXTURE_2D_ARRAY_MSAA:
+ *sample = 4;
+ break;
+  default:
+ *sample = 0;
+ break;
+  }
+   }
+   return dim;
+}
+
+static void
+exec_load(struct tgsi_exec_machine *mach,
+  const struct tgsi_full_instruction *inst)
+{
+   union tgsi_exec_channel r[4], sample_r;
+   uint unit;
+   int sample;
+   int i, j;
+   int dim;
+   uint chan;
+   float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
+   struct tgsi_image_params params;
+   int kilmask = mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0];
+
+   unit = fetch_sampler_unit(mach, inst, 0);
+   dim = get_image_coord_dim(inst->Memory.Texture, );
+   assert(dim <= 3);
+
+   params.execmask = mach->ExecMask & mach->NonHelperMask & ~kilmask;
+   params.unit = unit;
+   params.tgsi_tex_instr = inst->Memory.Texture;
+   params.format = inst->Memory.Format;
+
+   for (i = 0; i < dim; i++) {
+  IFETCH([i], 1, TGSI_CHAN_X + i);
+   }
+
+   if (sample)
+  IFETCH(_r, 1, TGSI_CHAN_X + sample);
+
+   mach->Image->load(mach->Image, ,
+ r[0].i, r[1].i, r[2].i, sample_r.i,
+ rgba);
+   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
+  r[0].f[j] = rgba[0][j];
+  r[1].f[j] = rgba[1][j];
+  r[2].f[j] = rgba[2][j];
+  r[3].f[j] = rgba[3][j];
+   }
+   for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+  if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, [chan], >Dst[0], inst, chan, 
TGSI_EXEC_DATA_FLOAT);
+  }
+   }
+}
+
+static void
+exec_store(struct tgsi_exec_machine *mach,
+   const struct tgsi_full_instruction *inst)
+{
+   union tgsi_exec_channel 

Re: [Mesa-dev] [PATCH 5/8] tgsi: add support for image operations to tgsi_exec.

2016-03-22 Thread Dave Airlie
>> +   int dim;
>> +   switch (tgsi_tex) {
>> +   case TGSI_TEXTURE_BUFFER:
>> +   case TGSI_TEXTURE_1D:
>> +  dim = 1;
>> +  break;
>> +   case TGSI_TEXTURE_2D:
>> +   case TGSI_TEXTURE_RECT:
>> +   case TGSI_TEXTURE_1D_ARRAY:
>> +   case TGSI_TEXTURE_2D_MSAA:
>> +  dim = 2;
>> +  break;
>> +   case TGSI_TEXTURE_3D:
>> +   case TGSI_TEXTURE_CUBE:
>> +   case TGSI_TEXTURE_2D_ARRAY:
>> +   case TGSI_TEXTURE_2D_ARRAY_MSAA:
>> +   case TGSI_TEXTURE_CUBE_ARRAY:
>> +  dim = 3;
>> +  break;
>> +   default:
>> +  assert(!"unknown texture target");
>> +  dim = 0;
>> +  break;
>> +   }
>> +
>> +   if (sample) {
>> +  switch (tgsi_tex) {
>> +  case TGSI_TEXTURE_2D_MSAA:
>> + *sample = 3;
>> + break;
>> +  case TGSI_TEXTURE_2D_ARRAY_MSAA:
>> + *sample = 4;
>> + break;
>> +  default:
>> + *sample = 0;
>> + break;
>> +  }
>> +   }
>> +   return dim;
>> +}
>
>
> That function seems to do two independent things.  Can this be two
> functions?
>
Probably, I was just following local style

tgsi_util_get_texture_coord_dim

was what I copied.

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


Re: [Mesa-dev] [PATCH 5/8] tgsi: add support for image operations to tgsi_exec.

2016-03-22 Thread Brian Paul

On 03/21/2016 04:02 PM, Dave Airlie wrote:

From: Dave Airlie 

This adds support for load/store/atomic operations on images
along with image tracking support.

Signed-off-by: Dave Airlie 
---
  src/gallium/auxiliary/draw/draw_gs.c  |   2 +-
  src/gallium/auxiliary/draw/draw_vs_exec.c |   2 +-
  src/gallium/auxiliary/tgsi/tgsi_exec.c| 229 +-
  src/gallium/auxiliary/tgsi/tgsi_exec.h|  40 +-
  src/gallium/drivers/softpipe/sp_fs_exec.c |   4 +-
  5 files changed, 271 insertions(+), 6 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_gs.c 
b/src/gallium/auxiliary/draw/draw_gs.c
index 6b33341..c4ced9f 100644
--- a/src/gallium/auxiliary/draw/draw_gs.c
+++ b/src/gallium/auxiliary/draw/draw_gs.c
@@ -687,7 +687,7 @@ void draw_geometry_shader_prepare(struct 
draw_geometry_shader *shader,
 if (!use_llvm && shader && shader->machine->Tokens != 
shader->state.tokens) {
tgsi_exec_machine_bind_shader(shader->machine,
  shader->state.tokens,
-draw->gs.tgsi.sampler);
+draw->gs.tgsi.sampler, NULL);
 }
  }

diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c 
b/src/gallium/auxiliary/draw/draw_vs_exec.c
index abd64f5..8c759d4 100644
--- a/src/gallium/auxiliary/draw/draw_vs_exec.c
+++ b/src/gallium/auxiliary/draw/draw_vs_exec.c
@@ -70,7 +70,7 @@ vs_exec_prepare( struct draw_vertex_shader *shader,
 if (evs->machine->Tokens != shader->state.tokens) {
tgsi_exec_machine_bind_shader(evs->machine,
  shader->state.tokens,
-draw->vs.tgsi.sampler);
+draw->vs.tgsi.sampler, NULL);
 }
  }

diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c 
b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index fa1c916..fe82a95 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -853,7 +853,8 @@ void
  tgsi_exec_machine_bind_shader(
 struct tgsi_exec_machine *mach,
 const struct tgsi_token *tokens,
-   struct tgsi_sampler *sampler)
+   struct tgsi_sampler *sampler,
+   struct tgsi_image *image)
  {
 uint k;
 struct tgsi_parse_context parse;
@@ -871,6 +872,7 @@ tgsi_exec_machine_bind_shader(

 mach->Tokens = tokens;
 mach->Sampler = sampler;
+   mach->Image = image;

 if (!tokens) {
/* unbind and free all */
@@ -3706,6 +3708,206 @@ exec_dfracexp(struct tgsi_exec_machine *mach,
 }
  }

+static int
+get_image_coord_dim(int tgsi_tex, int *sample)
+{
+   int dim;
+   switch (tgsi_tex) {
+   case TGSI_TEXTURE_BUFFER:
+   case TGSI_TEXTURE_1D:
+  dim = 1;
+  break;
+   case TGSI_TEXTURE_2D:
+   case TGSI_TEXTURE_RECT:
+   case TGSI_TEXTURE_1D_ARRAY:
+   case TGSI_TEXTURE_2D_MSAA:
+  dim = 2;
+  break;
+   case TGSI_TEXTURE_3D:
+   case TGSI_TEXTURE_CUBE:
+   case TGSI_TEXTURE_2D_ARRAY:
+   case TGSI_TEXTURE_2D_ARRAY_MSAA:
+   case TGSI_TEXTURE_CUBE_ARRAY:
+  dim = 3;
+  break;
+   default:
+  assert(!"unknown texture target");
+  dim = 0;
+  break;
+   }
+
+   if (sample) {
+  switch (tgsi_tex) {
+  case TGSI_TEXTURE_2D_MSAA:
+ *sample = 3;
+ break;
+  case TGSI_TEXTURE_2D_ARRAY_MSAA:
+ *sample = 4;
+ break;
+  default:
+ *sample = 0;
+ break;
+  }
+   }
+   return dim;
+}


That function seems to do two independent things.  Can this be two 
functions?





+
+static void
+exec_load(struct tgsi_exec_machine *mach,
+  const struct tgsi_full_instruction *inst)
+{
+   union tgsi_exec_channel r[4], sample_r;
+   uint unit;
+   int sample;
+   int i, j;
+   int dim;
+   uint chan;
+   float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
+   struct tgsi_image_params params;
+   int kilmask = mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0];
+
+   unit = fetch_sampler_unit(mach, inst, 0);
+   dim = get_image_coord_dim(inst->Memory.Texture, );
+   assert(dim <= 3);
+
+   params.execmask = mach->ExecMask & mach->NonHelperMask & ~kilmask;
+   params.unit = unit;
+   params.tgsi_tex_instr = inst->Memory.Texture;
+   params.format = inst->Memory.Format;
+
+   for (i = 0; i < dim; i++) {
+  IFETCH([i], 1, TGSI_CHAN_X + i);
+   }
+
+   if (sample)
+  IFETCH(_r, 1, TGSI_CHAN_X + sample);
+
+   mach->Image->load(mach->Image, ,
+ r[0].i, r[1].i, r[2].i, sample_r.i,
+ rgba);
+   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
+  r[0].f[j] = rgba[0][j];
+  r[1].f[j] = rgba[1][j];
+  r[2].f[j] = rgba[2][j];
+  r[3].f[j] = rgba[3][j];
+   }
+   for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+  if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, [chan], >Dst[0], inst, chan, 
TGSI_EXEC_DATA_FLOAT);
+  }
+   }
+}
+
+static void
+exec_store(struct tgsi_exec_machine 

[Mesa-dev] [PATCH 5/8] tgsi: add support for image operations to tgsi_exec.

2016-03-21 Thread Dave Airlie
From: Dave Airlie 

This adds support for load/store/atomic operations on images
along with image tracking support.

Signed-off-by: Dave Airlie 
---
 src/gallium/auxiliary/draw/draw_gs.c  |   2 +-
 src/gallium/auxiliary/draw/draw_vs_exec.c |   2 +-
 src/gallium/auxiliary/tgsi/tgsi_exec.c| 229 +-
 src/gallium/auxiliary/tgsi/tgsi_exec.h|  40 +-
 src/gallium/drivers/softpipe/sp_fs_exec.c |   4 +-
 5 files changed, 271 insertions(+), 6 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_gs.c 
b/src/gallium/auxiliary/draw/draw_gs.c
index 6b33341..c4ced9f 100644
--- a/src/gallium/auxiliary/draw/draw_gs.c
+++ b/src/gallium/auxiliary/draw/draw_gs.c
@@ -687,7 +687,7 @@ void draw_geometry_shader_prepare(struct 
draw_geometry_shader *shader,
if (!use_llvm && shader && shader->machine->Tokens != shader->state.tokens) 
{
   tgsi_exec_machine_bind_shader(shader->machine,
 shader->state.tokens,
-draw->gs.tgsi.sampler);
+draw->gs.tgsi.sampler, NULL);
}
 }
 
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c 
b/src/gallium/auxiliary/draw/draw_vs_exec.c
index abd64f5..8c759d4 100644
--- a/src/gallium/auxiliary/draw/draw_vs_exec.c
+++ b/src/gallium/auxiliary/draw/draw_vs_exec.c
@@ -70,7 +70,7 @@ vs_exec_prepare( struct draw_vertex_shader *shader,
if (evs->machine->Tokens != shader->state.tokens) {
   tgsi_exec_machine_bind_shader(evs->machine,
 shader->state.tokens,
-draw->vs.tgsi.sampler);
+draw->vs.tgsi.sampler, NULL);
}
 }
 
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c 
b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index fa1c916..fe82a95 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -853,7 +853,8 @@ void
 tgsi_exec_machine_bind_shader(
struct tgsi_exec_machine *mach,
const struct tgsi_token *tokens,
-   struct tgsi_sampler *sampler)
+   struct tgsi_sampler *sampler,
+   struct tgsi_image *image)
 {
uint k;
struct tgsi_parse_context parse;
@@ -871,6 +872,7 @@ tgsi_exec_machine_bind_shader(
 
mach->Tokens = tokens;
mach->Sampler = sampler;
+   mach->Image = image;
 
if (!tokens) {
   /* unbind and free all */
@@ -3706,6 +3708,206 @@ exec_dfracexp(struct tgsi_exec_machine *mach,
}
 }
 
+static int
+get_image_coord_dim(int tgsi_tex, int *sample)
+{
+   int dim;
+   switch (tgsi_tex) {
+   case TGSI_TEXTURE_BUFFER:
+   case TGSI_TEXTURE_1D:
+  dim = 1;
+  break;
+   case TGSI_TEXTURE_2D:
+   case TGSI_TEXTURE_RECT:
+   case TGSI_TEXTURE_1D_ARRAY:
+   case TGSI_TEXTURE_2D_MSAA:
+  dim = 2;
+  break;
+   case TGSI_TEXTURE_3D:
+   case TGSI_TEXTURE_CUBE:
+   case TGSI_TEXTURE_2D_ARRAY:
+   case TGSI_TEXTURE_2D_ARRAY_MSAA:
+   case TGSI_TEXTURE_CUBE_ARRAY:
+  dim = 3;
+  break;
+   default:
+  assert(!"unknown texture target");
+  dim = 0;
+  break;
+   }
+
+   if (sample) {
+  switch (tgsi_tex) {
+  case TGSI_TEXTURE_2D_MSAA:
+ *sample = 3;
+ break;
+  case TGSI_TEXTURE_2D_ARRAY_MSAA:
+ *sample = 4;
+ break;
+  default:
+ *sample = 0;
+ break;
+  }
+   }
+   return dim;
+}
+
+static void
+exec_load(struct tgsi_exec_machine *mach,
+  const struct tgsi_full_instruction *inst)
+{
+   union tgsi_exec_channel r[4], sample_r;
+   uint unit;
+   int sample;
+   int i, j;
+   int dim;
+   uint chan;
+   float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
+   struct tgsi_image_params params;
+   int kilmask = mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0];
+
+   unit = fetch_sampler_unit(mach, inst, 0);
+   dim = get_image_coord_dim(inst->Memory.Texture, );
+   assert(dim <= 3);
+
+   params.execmask = mach->ExecMask & mach->NonHelperMask & ~kilmask;
+   params.unit = unit;
+   params.tgsi_tex_instr = inst->Memory.Texture;
+   params.format = inst->Memory.Format;
+
+   for (i = 0; i < dim; i++) {
+  IFETCH([i], 1, TGSI_CHAN_X + i);
+   }
+
+   if (sample)
+  IFETCH(_r, 1, TGSI_CHAN_X + sample);
+
+   mach->Image->load(mach->Image, ,
+ r[0].i, r[1].i, r[2].i, sample_r.i,
+ rgba);
+   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
+  r[0].f[j] = rgba[0][j];
+  r[1].f[j] = rgba[1][j];
+  r[2].f[j] = rgba[2][j];
+  r[3].f[j] = rgba[3][j];
+   }
+   for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+  if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, [chan], >Dst[0], inst, chan, 
TGSI_EXEC_DATA_FLOAT);
+  }
+   }
+}
+
+static void
+exec_store(struct tgsi_exec_machine *mach,
+   const struct tgsi_full_instruction *inst)
+{
+   union tgsi_exec_channel r[3], sample_r;
+   union tgsi_exec_channel value[4];
+