zink/spirv: implement load_front_face
authorErik Faye-Lund <erik.faye-lund@collabora.com>
Mon, 22 Jul 2019 11:24:14 +0000 (13:24 +0200)
committerErik Faye-Lund <erik.faye-lund@collabora.com>
Mon, 28 Oct 2019 08:51:48 +0000 (08:51 +0000)
We're now adding interface-types during code-emitting, so we need to
defer emitting the entry-point. No biggie, spirv_builder is prepares for
this.

Acked-by: Jordan Justen <jordan.l.justen@intel.com>
src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
src/gallium/drivers/zink/zink_screen.c

index 3e4612fe1a99a7eb1e599901c926071ed0dffd56..8e34b629a079ce38fd83e97c53d138da0eac140c 100644 (file)
@@ -56,6 +56,8 @@ struct ntv_context {
    size_t num_blocks;
    bool block_started;
    SpvId loop_break, loop_cont;
+
+   SpvId front_face_var;
 };
 
 static SpvId
@@ -174,6 +176,9 @@ static SpvId
 get_glsl_basetype(struct ntv_context *ctx, enum glsl_base_type type)
 {
    switch (type) {
+   case GLSL_TYPE_BOOL:
+      return spirv_builder_type_bool(&ctx->builder);
+
    case GLSL_TYPE_FLOAT:
       return spirv_builder_type_float(&ctx->builder, 32);
 
@@ -1146,6 +1151,33 @@ emit_store_deref(struct ntv_context *ctx, nir_intrinsic_instr *intr)
    spirv_builder_emit_store(&ctx->builder, ptr, result);
 }
 
+static void
+emit_load_front_face(struct ntv_context *ctx, nir_intrinsic_instr *intr)
+{
+   SpvId var_type = get_glsl_type(ctx, glsl_bool_type());
+   if (!ctx->front_face_var) {
+      SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
+                                                      SpvStorageClassInput,
+                                                      var_type);
+      ctx->front_face_var = spirv_builder_emit_var(&ctx->builder,
+                                                   pointer_type,
+                                                   SpvStorageClassInput);
+      spirv_builder_emit_name(&ctx->builder, ctx->front_face_var,
+                              "gl_FrontFacing");
+      spirv_builder_emit_builtin(&ctx->builder, ctx->front_face_var,
+                                 SpvBuiltInFrontFacing);
+
+      assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
+      ctx->entry_ifaces[ctx->num_entry_ifaces++] = ctx->front_face_var;
+   }
+
+   SpvId result = spirv_builder_emit_load(&ctx->builder, var_type,
+                                          ctx->front_face_var);
+   assert(1 == nir_dest_num_components(intr->dest));
+   result = bvec_to_uvec(ctx, result, 1);
+   store_dest_uint(ctx, &intr->dest, result);
+}
+
 static void
 emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
 {
@@ -1166,6 +1198,10 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
       emit_store_deref(ctx, intr);
       break;
 
+   case nir_intrinsic_load_front_face:
+      emit_load_front_face(ctx, intr);
+      break;
+
    default:
       fprintf(stderr, "emit_intrinsic: not implemented (%s)\n",
               nir_intrinsic_infos[intr->intrinsic].name);
@@ -1638,9 +1674,6 @@ nir_to_spirv(struct nir_shader *s)
    nir_foreach_variable(var, &s->uniforms)
       emit_uniform(&ctx, var);
 
-   spirv_builder_emit_entry_point(&ctx.builder, exec_model, entry_point,
-                                  "main", ctx.entry_ifaces,
-                                  ctx.num_entry_ifaces);
    if (s->info.stage == MESA_SHADER_FRAGMENT) {
       spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
                                    SpvExecutionModeOriginUpperLeft);
@@ -1698,6 +1731,10 @@ nir_to_spirv(struct nir_shader *s)
    spirv_builder_return(&ctx.builder); // doesn't belong here, but whatevz
    spirv_builder_function_end(&ctx.builder);
 
+   spirv_builder_emit_entry_point(&ctx.builder, exec_model, entry_point,
+                                  "main", ctx.entry_ifaces,
+                                  ctx.num_entry_ifaces);
+
    size_t num_words = spirv_builder_get_num_words(&ctx.builder);
 
    ret = CALLOC_STRUCT(spirv_shader);
index f1b4d89f1faffdf75a5f8667de4b845a274885dd..f1a19a10431e7f5bbef87784073d0c9a1d12965c 100644 (file)
@@ -289,6 +289,9 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_NIR_COMPACT_ARRAYS:
       return 1;
 
+   case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
+      return 1;
+
    case PIPE_CAP_FLATSHADE:
    case PIPE_CAP_ALPHA_TEST:
    case PIPE_CAP_CLIP_PLANES: