From 1f3d2b9f801dc6cd5c58bba5c6b9d0bbe5e302d2 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Mon, 22 Jul 2019 13:24:14 +0200 Subject: [PATCH] zink/spirv: implement load_front_face 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 --- .../drivers/zink/nir_to_spirv/nir_to_spirv.c | 43 +++++++++++++++++-- src/gallium/drivers/zink/zink_screen.c | 3 ++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c index 3e4612fe1a9..8e34b629a07 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c @@ -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); diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index f1b4d89f1fa..f1a19a10431 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -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: