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 <jordan.l.justen@intel.com>
This commit is contained in:
Erik Faye-Lund 2019-07-22 13:24:14 +02:00
parent a046957a79
commit 1f3d2b9f80
2 changed files with 43 additions and 3 deletions

View 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);

View 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: