#include "nir.h"
#include "pipe/p_state.h"
#include "util/u_memory.h"
+#include "util/hash_table.h"
struct ntv_context {
struct spirv_builder builder;
SpvId GLSL_std_450;
gl_shader_stage stage;
- SpvId inputs[PIPE_MAX_SHADER_INPUTS][4];
- SpvId input_types[PIPE_MAX_SHADER_INPUTS][4];
- SpvId outputs[PIPE_MAX_SHADER_OUTPUTS][4];
- SpvId output_types[PIPE_MAX_SHADER_OUTPUTS][4];
int var_location;
SpvId ubos[128];
SpvId *defs;
size_t num_defs;
- SpvId *vars;
- size_t num_vars;
+ SpvId *regs;
+ size_t num_regs;
+
+ struct hash_table *vars; /* nir_variable -> SpvId */
const SpvId *block_ids;
size_t num_blocks;
get_glsl_basetype(ctx, glsl_get_base_type(type)),
glsl_get_vector_elements(type));
+ if (glsl_type_is_array(type)) {
+ SpvId ret = spirv_builder_type_array(&ctx->builder,
+ get_glsl_type(ctx, glsl_get_array_element(type)),
+ spirv_builder_const_uint(&ctx->builder, 32, glsl_get_length(type)));
+ uint32_t stride = glsl_get_explicit_stride(type);
+ if (stride)
+ spirv_builder_emit_array_stride(&ctx->builder, ret, stride);
+ return ret;
+ }
+
+
unreachable("we shouldn't get here, I think...");
}
static void
emit_input(struct ntv_context *ctx, struct nir_variable *var)
{
- SpvId vec_type = get_glsl_type(ctx, var->type);
+ SpvId var_type = get_glsl_type(ctx, var->type);
SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
SpvStorageClassInput,
- vec_type);
+ var_type);
SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
SpvStorageClassInput);
break;
default:
- unreachable("unknown varying slot");
+ debug_printf("unknown varying slot: %s\n", gl_varying_slot_name(var->data.location));
+ unreachable("unexpected varying slot");
}
}
} else {
if (var->data.interpolation == INTERP_MODE_FLAT)
spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationFlat);
- assert(var->data.driver_location < PIPE_MAX_SHADER_INPUTS);
- assert(var->data.location_frac < 4);
- assert(ctx->inputs[var->data.driver_location][var->data.location_frac] == 0);
- ctx->inputs[var->data.driver_location][var->data.location_frac] = var_id;
- ctx->input_types[var->data.driver_location][var->data.location_frac] = vec_type;
+ _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
static void
emit_output(struct ntv_context *ctx, struct nir_variable *var)
{
- SpvId vec_type = get_glsl_type(ctx, var->type);
+ SpvId var_type = get_glsl_type(ctx, var->type);
SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
SpvStorageClassOutput,
- vec_type);
+ var_type);
SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
SpvStorageClassOutput);
if (var->name)
spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInPointSize);
break;
+ case VARYING_SLOT_CLIP_DIST0:
+ assert(glsl_type_is_array(var->type));
+ spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInClipDistance);
+ break;
+
default:
- unreachable("unknown varying slot");
+ debug_printf("unknown varying slot: %s\n", gl_varying_slot_name(var->data.location));
+ unreachable("unexpected varying slot");
}
}
} else if (ctx->stage == MESA_SHADER_FRAGMENT) {
- switch (var->data.location) {
- case FRAG_RESULT_DEPTH:
- spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInFragDepth);
- break;
-
- default:
+ if (var->data.location >= FRAG_RESULT_DATA0)
spirv_builder_emit_location(&ctx->builder, var_id,
- var->data.driver_location);
+ var->data.location - FRAG_RESULT_DATA0);
+ else {
+ switch (var->data.location) {
+ case FRAG_RESULT_COLOR:
+ spirv_builder_emit_location(&ctx->builder, var_id, 0);
+ break;
+
+ case FRAG_RESULT_DEPTH:
+ spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInFragDepth);
+ break;
+
+ default:
+ spirv_builder_emit_location(&ctx->builder, var_id,
+ var->data.driver_location);
+ }
}
}
spirv_builder_emit_component(&ctx->builder, var_id,
var->data.location_frac);
- assert(var->data.driver_location < PIPE_MAX_SHADER_INPUTS);
- assert(var->data.location_frac < 4);
- assert(ctx->outputs[var->data.driver_location][var->data.location_frac] == 0);
- ctx->outputs[var->data.driver_location][var->data.location_frac] = var_id;
- ctx->output_types[var->data.driver_location][var->data.location_frac] = vec_type;
+ _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
static void
emit_uniform(struct ntv_context *ctx, struct nir_variable *var)
{
- if (glsl_type_is_sampler(var->type))
- emit_sampler(ctx, var);
- else if (var->interface_type)
+ if (var->data.mode == nir_var_mem_ubo)
emit_ubo(ctx, var);
+ else {
+ assert(var->data.mode == nir_var_uniform);
+ if (glsl_type_is_sampler(var->type))
+ emit_sampler(ctx, var);
+ }
}
static SpvId
static SpvId
get_var_from_reg(struct ntv_context *ctx, nir_register *reg)
{
- assert(reg->index < ctx->num_vars);
- assert(ctx->vars[reg->index] != 0);
- return ctx->vars[reg->index];
+ assert(reg->index < ctx->num_regs);
+ assert(ctx->regs[reg->index] != 0);
+ return ctx->regs[reg->index];
}
static SpvId
return def;
int bit_size = nir_src_bit_size(alu->src[src].src);
+ assert(bit_size == 32);
SpvId uint_type = spirv_builder_type_uint(&ctx->builder, bit_size);
if (used_channels == 1) {
result = emit_unop(ctx, spirv_op, dest_type, src[0]); \
break;
+ UNOP(nir_op_ineg, SpvOpSNegate)
+ UNOP(nir_op_fneg, SpvOpFNegate)
+ UNOP(nir_op_fddx, SpvOpDPdx)
+ UNOP(nir_op_fddy, SpvOpDPdy)
+ UNOP(nir_op_f2i32, SpvOpConvertFToS)
+ UNOP(nir_op_f2u32, SpvOpConvertFToU)
+ UNOP(nir_op_i2f32, SpvOpConvertSToF)
+ UNOP(nir_op_u2f32, SpvOpConvertUToF)
+#undef UNOP
+
#define BUILTIN_UNOP(nir_op, spirv_op) \
case nir_op: \
assert(nir_op_infos[alu->op].num_inputs == 1); \
result = emit_builtin_unop(ctx, spirv_op, dest_type, src[0]); \
break;
- UNOP(nir_op_fneg, SpvOpFNegate)
- UNOP(nir_op_fddx, SpvOpDPdx)
- UNOP(nir_op_fddy, SpvOpDPdy)
-
BUILTIN_UNOP(nir_op_fabs, GLSLstd450FAbs)
BUILTIN_UNOP(nir_op_fsqrt, GLSLstd450Sqrt)
BUILTIN_UNOP(nir_op_frsq, GLSLstd450InverseSqrt)
BUILTIN_UNOP(nir_op_fsign, GLSLstd450FSign)
BUILTIN_UNOP(nir_op_fsin, GLSLstd450Sin)
BUILTIN_UNOP(nir_op_fcos, GLSLstd450Cos)
+#undef BUILTIN_UNOP
case nir_op_frcp: {
assert(nir_op_infos[alu->op].num_inputs == 1);
}
break;
-#undef UNOP
-#undef BUILTIN_UNOP
+ case nir_op_f2b1: {
+ assert(nir_op_infos[alu->op].num_inputs == 1);
+ float values[NIR_MAX_VEC_COMPONENTS] = { 0 };
+ SpvId zero = get_fvec_constant(ctx, nir_src_bit_size(alu->src[0].src),
+ num_components, values);
+ result = emit_binop(ctx, SpvOpFOrdNotEqual, dest_type, src[0], zero);
+ } break;
+
#define BINOP(nir_op, spirv_op) \
case nir_op: \
result = emit_binop(ctx, spirv_op, dest_type, src[0], src[1]); \
break;
-#define BUILTIN_BINOP(nir_op, spirv_op) \
- case nir_op: \
- assert(nir_op_infos[alu->op].num_inputs == 2); \
- result = emit_builtin_binop(ctx, spirv_op, dest_type, src[0], src[1]); \
- break;
-
BINOP(nir_op_iadd, SpvOpIAdd)
BINOP(nir_op_isub, SpvOpISub)
BINOP(nir_op_imul, SpvOpIMul)
+ BINOP(nir_op_idiv, SpvOpSDiv)
+ BINOP(nir_op_udiv, SpvOpUDiv)
BINOP(nir_op_fadd, SpvOpFAdd)
BINOP(nir_op_fsub, SpvOpFSub)
BINOP(nir_op_fmul, SpvOpFMul)
+ BINOP(nir_op_fdiv, SpvOpFDiv)
BINOP(nir_op_fmod, SpvOpFMod)
- BINOP(nir_op_flt, SpvOpFUnordLessThan)
- BINOP(nir_op_fge, SpvOpFUnordGreaterThanEqual)
+ BINOP(nir_op_ilt, SpvOpSLessThan)
+ BINOP(nir_op_ige, SpvOpSGreaterThanEqual)
+ BINOP(nir_op_ieq, SpvOpIEqual)
+ BINOP(nir_op_ine, SpvOpINotEqual)
+ BINOP(nir_op_flt, SpvOpFOrdLessThan)
+ BINOP(nir_op_fge, SpvOpFOrdGreaterThanEqual)
+ BINOP(nir_op_feq, SpvOpFOrdEqual)
+ BINOP(nir_op_fne, SpvOpFOrdNotEqual)
+ BINOP(nir_op_ishl, SpvOpShiftLeftLogical)
+ BINOP(nir_op_ishr, SpvOpShiftRightArithmetic)
+ BINOP(nir_op_ushr, SpvOpShiftRightLogical)
+#undef BINOP
+
+#define BUILTIN_BINOP(nir_op, spirv_op) \
+ case nir_op: \
+ assert(nir_op_infos[alu->op].num_inputs == 2); \
+ result = emit_builtin_binop(ctx, spirv_op, dest_type, src[0], src[1]); \
+ break;
BUILTIN_BINOP(nir_op_fmin, GLSLstd450FMin)
BUILTIN_BINOP(nir_op_fmax, GLSLstd450FMax)
-
-#undef BINOP
#undef BUILTIN_BINOP
case nir_op_fdot2:
}
break;
+ case nir_op_bcsel:
+ assert(nir_op_infos[alu->op].num_inputs == 3);
+ result = emit_triop(ctx, SpvOpSelect, dest_type, src[0], src[1], src[2]);
+ break;
+
case nir_op_vec2:
case nir_op_vec3:
case nir_op_vec4: {
store_ssa_def_uint(ctx, &load_const->def, constant);
}
-static void
-emit_load_input(struct ntv_context *ctx, nir_intrinsic_instr *intr)
-{
- nir_const_value *const_offset = nir_src_as_const_value(intr->src[0]);
- if (const_offset) {
- int driver_location = (int)nir_intrinsic_base(intr) + const_offset->u32;
- assert(driver_location < PIPE_MAX_SHADER_INPUTS);
- int location_frac = nir_intrinsic_component(intr);
- assert(location_frac < 4);
-
- SpvId ptr = ctx->inputs[driver_location][location_frac];
- SpvId type = ctx->input_types[driver_location][location_frac];
- assert(ptr && type);
-
- SpvId result = spirv_builder_emit_load(&ctx->builder, type, ptr);
-
- unsigned num_components = nir_dest_num_components(intr->dest);
- unsigned bit_size = nir_dest_bit_size(intr->dest);
- result = bitcast_to_uvec(ctx, result, bit_size, num_components);
-
- store_dest_uint(ctx, &intr->dest, result);
- } else
- unreachable("input-addressing not yet supported");
-}
-
static void
emit_load_ubo(struct ntv_context *ctx, nir_intrinsic_instr *intr)
{
unreachable("uniform-addressing not yet supported");
}
-static void
-emit_store_output(struct ntv_context *ctx, nir_intrinsic_instr *intr)
-{
- nir_const_value *const_offset = nir_src_as_const_value(intr->src[1]);
- if (const_offset) {
- int driver_location = (int)nir_intrinsic_base(intr) + const_offset->u32;
- assert(driver_location < PIPE_MAX_SHADER_OUTPUTS);
- int location_frac = nir_intrinsic_component(intr);
- assert(location_frac < 4);
-
- SpvId ptr = ctx->outputs[driver_location][location_frac];
- assert(ptr > 0);
-
- SpvId src = get_src_uint(ctx, &intr->src[0]);
- SpvId spirv_type = ctx->output_types[driver_location][location_frac];
- SpvId result = emit_unop(ctx, SpvOpBitcast, spirv_type, src);
- spirv_builder_emit_store(&ctx->builder, ptr, result);
- } else
- unreachable("output-addressing not yet supported");
-}
-
static void
emit_discard(struct ntv_context *ctx, nir_intrinsic_instr *intr)
{
spirv_builder_label(&ctx->builder, spirv_builder_new_id(&ctx->builder));
}
+static void
+emit_load_deref(struct ntv_context *ctx, nir_intrinsic_instr *intr)
+{
+ /* uint is a bit of a lie here; it's really just a pointer */
+ SpvId ptr = get_src_uint(ctx, intr->src);
+
+ nir_variable *var = nir_intrinsic_get_var(intr, 0);
+ SpvId result = spirv_builder_emit_load(&ctx->builder,
+ get_glsl_type(ctx, var->type),
+ ptr);
+ unsigned num_components = nir_dest_num_components(intr->dest);
+ unsigned bit_size = nir_dest_bit_size(intr->dest);
+ result = bitcast_to_uvec(ctx, result, bit_size, num_components);
+ store_dest_uint(ctx, &intr->dest, result);
+}
+
+static void
+emit_store_deref(struct ntv_context *ctx, nir_intrinsic_instr *intr)
+{
+ /* uint is a bit of a lie here; it's really just a pointer */
+ SpvId ptr = get_src_uint(ctx, &intr->src[0]);
+ SpvId src = get_src_uint(ctx, &intr->src[1]);
+
+ nir_variable *var = nir_intrinsic_get_var(intr, 0);
+ SpvId result = emit_unop(ctx, SpvOpBitcast,
+ get_glsl_type(ctx, glsl_without_array(var->type)),
+ src);
+ spirv_builder_emit_store(&ctx->builder, ptr, result);
+}
+
static void
emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
{
switch (intr->intrinsic) {
- case nir_intrinsic_load_input:
- emit_load_input(ctx, intr);
- break;
-
case nir_intrinsic_load_ubo:
emit_load_ubo(ctx, intr);
break;
- case nir_intrinsic_store_output:
- emit_store_output(ctx, intr);
- break;
-
case nir_intrinsic_discard:
emit_discard(ctx, intr);
break;
+ case nir_intrinsic_load_deref:
+ emit_load_deref(ctx, intr);
+ break;
+
+ case nir_intrinsic_store_deref:
+ emit_store_deref(ctx, intr);
+ break;
+
default:
fprintf(stderr, "emit_intrinsic: not implemented (%s)\n",
nir_intrinsic_infos[intr->intrinsic].name);
static void
emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
{
- assert(tex->op == nir_texop_tex);
+ assert(tex->op == nir_texop_tex ||
+ tex->op == nir_texop_txb ||
+ tex->op == nir_texop_txl);
assert(nir_alu_type_get_base_type(tex->dest_type) == nir_type_float);
assert(tex->texture_index == tex->sampler_index);
- bool has_proj = false, has_lod = false;
- SpvId coord = 0, proj, lod;
+ SpvId coord = 0, proj = 0, bias = 0, lod = 0, dref = 0;
unsigned coord_components;
for (unsigned i = 0; i < tex->num_srcs; i++) {
switch (tex->src[i].src_type) {
break;
case nir_tex_src_projector:
- has_proj = true;
- proj = get_src_float(ctx, &tex->src[i].src);
assert(nir_src_num_components(tex->src[i].src) == 1);
+ proj = get_src_float(ctx, &tex->src[i].src);
+ assert(proj != 0);
+ break;
+
+ case nir_tex_src_bias:
+ assert(tex->op == nir_texop_txb);
+ bias = get_src_float(ctx, &tex->src[i].src);
+ assert(bias != 0);
break;
case nir_tex_src_lod:
- has_lod = true;
+ assert(nir_src_num_components(tex->src[i].src) == 1);
lod = get_src_float(ctx, &tex->src[i].src);
+ assert(lod != 0);
+ break;
+
+ case nir_tex_src_comparator:
assert(nir_src_num_components(tex->src[i].src) == 1);
+ dref = get_src_float(ctx, &tex->src[i].src);
+ assert(dref != 0);
break;
default:
}
}
- if (!has_lod && ctx->stage != MESA_SHADER_FRAGMENT) {
- has_lod = true;
+ if (lod == 0 && ctx->stage != MESA_SHADER_FRAGMENT) {
lod = spirv_builder_const_float(&ctx->builder, 32, 0);
+ assert(lod != 0);
}
bool is_ms;
SpvId dest_type = get_dest_type(ctx, &tex->dest, tex->dest_type);
- SpvId result;
- if (has_proj) {
+ if (proj) {
SpvId constituents[coord_components + 1];
- SpvId float_type = spirv_builder_type_float(&ctx->builder, 32);
- for (uint32_t i = 0; i < coord_components; ++i)
- constituents[i] = spirv_builder_emit_composite_extract(&ctx->builder,
- float_type,
- coord,
- &i, 1);
+ if (coord_components == 1)
+ constituents[0] = coord;
+ else {
+ assert(coord_components > 1);
+ SpvId float_type = spirv_builder_type_float(&ctx->builder, 32);
+ for (uint32_t i = 0; i < coord_components; ++i)
+ constituents[i] = spirv_builder_emit_composite_extract(&ctx->builder,
+ float_type,
+ coord,
+ &i, 1);
+ }
constituents[coord_components++] = proj;
SpvId vec_type = get_fvec_type(ctx, 32, coord_components);
- SpvId merged = spirv_builder_emit_composite_construct(&ctx->builder,
+ coord = spirv_builder_emit_composite_construct(&ctx->builder,
vec_type,
constituents,
coord_components);
-
- if (has_lod)
- result = spirv_builder_emit_image_sample_proj_explicit_lod(&ctx->builder,
- dest_type,
- load,
- merged,
- lod);
- else
- result = spirv_builder_emit_image_sample_proj_implicit_lod(&ctx->builder,
- dest_type,
- load,
- merged);
- } else {
- if (has_lod)
- result = spirv_builder_emit_image_sample_explicit_lod(&ctx->builder,
- dest_type,
- load,
- coord, lod);
- else
- result = spirv_builder_emit_image_sample_implicit_lod(&ctx->builder,
- dest_type,
- load,
- coord);
}
+
+ SpvId actual_dest_type = dest_type;
+ if (dref)
+ actual_dest_type = float_type;
+
+ SpvId result = spirv_builder_emit_image_sample(&ctx->builder,
+ actual_dest_type, load,
+ coord,
+ proj != 0,
+ lod, bias, dref);
spirv_builder_emit_decoration(&ctx->builder, result,
SpvDecorationRelaxedPrecision);
+ if (dref) {
+ SpvId components[4] = { result, result, result, result };
+ result = spirv_builder_emit_composite_construct(&ctx->builder,
+ dest_type,
+ components,
+ 4);
+ }
+
store_dest(ctx, &tex->dest, result, tex->dest_type);
}
}
}
+static void
+emit_deref_var(struct ntv_context *ctx, nir_deref_instr *deref)
+{
+ assert(deref->deref_type == nir_deref_type_var);
+
+ struct hash_entry *he = _mesa_hash_table_search(ctx->vars, deref->var);
+ assert(he);
+ SpvId result = (SpvId)(intptr_t)he->data;
+ /* uint is a bit of a lie here, it's really just an opaque type */
+ store_dest_uint(ctx, &deref->dest, result);
+}
+
+static void
+emit_deref_array(struct ntv_context *ctx, nir_deref_instr *deref)
+{
+ assert(deref->deref_type == nir_deref_type_array);
+ nir_variable *var = nir_deref_instr_get_variable(deref);
+
+ SpvStorageClass storage_class;
+ switch (var->data.mode) {
+ case nir_var_shader_in:
+ storage_class = SpvStorageClassInput;
+ break;
+
+ case nir_var_shader_out:
+ storage_class = SpvStorageClassOutput;
+ break;
+
+ default:
+ unreachable("Unsupported nir_variable_mode\n");
+ }
+
+ SpvId index = get_src_uint(ctx, &deref->arr.index);
+
+ SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
+ storage_class,
+ get_glsl_type(ctx, deref->type));
+
+ SpvId result = spirv_builder_emit_access_chain(&ctx->builder,
+ ptr_type,
+ get_src_uint(ctx, &deref->parent),
+ &index, 1);
+ /* uint is a bit of a lie here, it's really just an opaque type */
+ store_dest_uint(ctx, &deref->dest, result);
+}
+
+static void
+emit_deref(struct ntv_context *ctx, nir_deref_instr *deref)
+{
+ switch (deref->deref_type) {
+ case nir_deref_type_var:
+ emit_deref_var(ctx, deref);
+ break;
+
+ case nir_deref_type_array:
+ emit_deref_array(ctx, deref);
+ break;
+
+ default:
+ unreachable("unexpected deref_type");
+ }
+}
+
static void
emit_block(struct ntv_context *ctx, struct nir_block *block)
{
unreachable("nir_instr_type_parallel_copy not supported");
break;
case nir_instr_type_deref:
- unreachable("nir_instr_type_deref not supported");
+ emit_deref(ctx, nir_instr_as_deref(instr));
break;
}
}
unreachable("invalid stage");
}
+ // TODO: only enable when needed
+ if (s->info.stage == MESA_SHADER_FRAGMENT)
+ spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySampled1D);
+
ctx.stage = s->info.stage;
ctx.GLSL_std_450 = spirv_builder_import(&ctx.builder, "GLSL.std.450");
spirv_builder_emit_source(&ctx.builder, SpvSourceLanguageGLSL, 450);
SpvId entry_point = spirv_builder_new_id(&ctx.builder);
spirv_builder_emit_name(&ctx.builder, entry_point, "main");
+ ctx.vars = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
+ _mesa_key_pointer_equal);
+
nir_foreach_variable(var, &s->inputs)
emit_input(&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)
+ if (s->info.stage == MESA_SHADER_FRAGMENT) {
spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
SpvExecutionModeOriginUpperLeft);
+ if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
+ spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
+ SpvExecutionModeDepthReplacing);
+ }
spirv_builder_function(&ctx.builder, entry_point, type_void,
ctx.num_defs = entry->ssa_alloc;
nir_index_local_regs(entry);
- ctx.vars = malloc(sizeof(SpvId) * entry->reg_alloc);
- if (!ctx.vars)
+ ctx.regs = malloc(sizeof(SpvId) * entry->reg_alloc);
+ if (!ctx.regs)
goto fail;
- ctx.num_vars = entry->reg_alloc;
+ ctx.num_regs = entry->reg_alloc;
SpvId *block_ids = (SpvId *)malloc(sizeof(SpvId) * entry->num_blocks);
if (!block_ids)
SpvId var = spirv_builder_emit_var(&ctx.builder, pointer_type,
SpvStorageClassFunction);
- ctx.vars[reg->index] = var;
+ ctx.regs[reg->index] = var;
}
emit_cf_list(&ctx, &entry->body);
if (ret)
spirv_shader_delete(ret);
+ if (ctx.vars)
+ _mesa_hash_table_destroy(ctx.vars, NULL);
+
return NULL;
}