switch (glsl_get_base_type(type)) {
case GLSL_TYPE_INT:
case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT64:
+ case GLSL_TYPE_UINT64:
case GLSL_TYPE_BOOL:
case GLSL_TYPE_FLOAT:
case GLSL_TYPE_DOUBLE: {
switch (glsl_get_base_type(src->type)) {
case GLSL_TYPE_INT:
case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT64:
+ case GLSL_TYPE_UINT64:
case GLSL_TYPE_BOOL:
case GLSL_TYPE_FLOAT:
case GLSL_TYPE_DOUBLE:
vtn_warn("Decoration only allowed for CL-style kernels: %s",
spirv_decoration_to_string(dec->decoration));
break;
+
+ default:
+ unreachable("Unhandled decoration");
}
}
case SpvDecorationOffset:
case SpvDecorationXfbBuffer:
case SpvDecorationXfbStride:
- vtn_warn("Decoraiton only allowed for struct members: %s",
+ vtn_warn("Decoration only allowed for struct members: %s",
spirv_decoration_to_string(dec->decoration));
break;
case SpvDecorationLinkageAttributes:
case SpvDecorationNoContraction:
case SpvDecorationInputAttachmentIndex:
- vtn_warn("Decoraiton not allowed on types: %s",
+ vtn_warn("Decoration not allowed on types: %s",
spirv_decoration_to_string(dec->decoration));
break;
case SpvDecorationFPRoundingMode:
case SpvDecorationFPFastMathMode:
case SpvDecorationAlignment:
- vtn_warn("Decoraiton only allowed for CL-style kernels: %s",
+ vtn_warn("Decoration only allowed for CL-style kernels: %s",
spirv_decoration_to_string(dec->decoration));
break;
+
+ default:
+ unreachable("Unhandled decoration");
}
}
val->type->type = glsl_bool_type();
break;
case SpvOpTypeInt: {
+ int bit_size = w[2];
const bool signedness = w[3];
- val->type->type = (signedness ? glsl_int_type() : glsl_uint_type());
+ if (bit_size == 64)
+ val->type->type = (signedness ? glsl_int64_t_type() : glsl_uint64_t_type());
+ else
+ val->type->type = (signedness ? glsl_int_type() : glsl_uint_type());
break;
}
case SpvOpTypeFloat: {
val->type->type = glsl_sampler_type(dim, is_shadow, is_array,
glsl_get_base_type(sampled_type));
} else if (sampled == 2) {
- assert((dim == GLSL_SAMPLER_DIM_SUBPASS ||
- dim == GLSL_SAMPLER_DIM_SUBPASS_MS) || format);
assert(!is_shadow);
val->type->type = glsl_image_type(dim, is_array,
glsl_get_base_type(sampled_type));
switch (glsl_get_base_type(type)) {
case GLSL_TYPE_INT:
case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT64:
+ case GLSL_TYPE_UINT64:
case GLSL_TYPE_BOOL:
case GLSL_TYPE_FLOAT:
case GLSL_TYPE_DOUBLE:
assert(val->const_type == glsl_vector_type(GLSL_TYPE_UINT, 3));
- b->shader->info->cs.local_size[0] = val->constant->values[0].u32[0];
- b->shader->info->cs.local_size[1] = val->constant->values[0].u32[1];
- b->shader->info->cs.local_size[2] = val->constant->values[0].u32[2];
+ b->shader->info.cs.local_size[0] = val->constant->values[0].u32[0];
+ b->shader->info.cs.local_size[1] = val->constant->values[0].u32[1];
+ b->shader->info.cs.local_size[2] = val->constant->values[0].u32[2];
}
static void
switch (glsl_get_base_type(val->const_type)) {
case GLSL_TYPE_UINT:
case GLSL_TYPE_INT:
+ case GLSL_TYPE_UINT64:
+ case GLSL_TYPE_INT64:
case GLSL_TYPE_FLOAT:
case GLSL_TYPE_BOOL:
case GLSL_TYPE_DOUBLE: {
SpvOp opcode = get_specialization(b, val, w[3]);
switch (opcode) {
case SpvOpVectorShuffle: {
- struct vtn_value *v0 = vtn_value(b, w[4], vtn_value_type_constant);
- struct vtn_value *v1 = vtn_value(b, w[5], vtn_value_type_constant);
- unsigned len0 = glsl_get_vector_elements(v0->const_type);
- unsigned len1 = glsl_get_vector_elements(v1->const_type);
+ struct vtn_value *v0 = &b->values[w[4]];
+ struct vtn_value *v1 = &b->values[w[5]];
+
+ assert(v0->value_type == vtn_value_type_constant ||
+ v0->value_type == vtn_value_type_undef);
+ assert(v1->value_type == vtn_value_type_constant ||
+ v1->value_type == vtn_value_type_undef);
+
+ unsigned len0 = v0->value_type == vtn_value_type_constant ?
+ glsl_get_vector_elements(v0->const_type) :
+ glsl_get_vector_elements(v0->type->type);
+ unsigned len1 = v1->value_type == vtn_value_type_constant ?
+ glsl_get_vector_elements(v1->const_type) :
+ glsl_get_vector_elements(v1->type->type);
assert(len0 + len1 < 16);
unsigned bit_size = glsl_get_bit_size(val->const_type);
- assert(bit_size == glsl_get_bit_size(v0->const_type) &&
- bit_size == glsl_get_bit_size(v1->const_type));
+ unsigned bit_size0 = v0->value_type == vtn_value_type_constant ?
+ glsl_get_bit_size(v0->const_type) :
+ glsl_get_bit_size(v0->type->type);
+ unsigned bit_size1 = v1->value_type == vtn_value_type_constant ?
+ glsl_get_bit_size(v1->const_type) :
+ glsl_get_bit_size(v1->type->type);
+
+ assert(bit_size == bit_size0 && bit_size == bit_size1);
+ (void)bit_size0; (void)bit_size1;
if (bit_size == 64) {
uint64_t u64[8];
- for (unsigned i = 0; i < len0; i++)
- u64[i] = v0->constant->values[0].u64[i];
- for (unsigned i = 0; i < len1; i++)
- u64[len0 + i] = v1->constant->values[0].u64[i];
+ if (v0->value_type == vtn_value_type_constant) {
+ for (unsigned i = 0; i < len0; i++)
+ u64[i] = v0->constant->values[0].u64[i];
+ }
+ if (v1->value_type == vtn_value_type_constant) {
+ for (unsigned i = 0; i < len1; i++)
+ u64[len0 + i] = v1->constant->values[0].u64[i];
+ }
for (unsigned i = 0, j = 0; i < count - 6; i++, j++) {
uint32_t comp = w[i + 6];
}
} else {
uint32_t u32[8];
- for (unsigned i = 0; i < len0; i++)
- u32[i] = v0->constant->values[0].u32[i];
-
- for (unsigned i = 0; i < len1; i++)
- u32[len0 + i] = v1->constant->values[0].u32[i];
+ if (v0->value_type == vtn_value_type_constant) {
+ for (unsigned i = 0; i < len0; i++)
+ u32[i] = v0->constant->values[0].u32[i];
+ }
+ if (v1->value_type == vtn_value_type_constant) {
+ for (unsigned i = 0; i < len1; i++)
+ u32[len0 + i] = v1->constant->values[0].u32[i];
+ }
for (unsigned i = 0, j = 0; i < count - 6; i++, j++) {
uint32_t comp = w[i + 6];
switch (glsl_get_base_type(type)) {
case GLSL_TYPE_UINT:
case GLSL_TYPE_INT:
+ case GLSL_TYPE_UINT64:
+ case GLSL_TYPE_INT64:
case GLSL_TYPE_FLOAT:
case GLSL_TYPE_DOUBLE:
case GLSL_TYPE_BOOL:
switch (glsl_get_base_type(type)) {
case GLSL_TYPE_INT:
case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT64:
+ case GLSL_TYPE_UINT64:
case GLSL_TYPE_BOOL:
case GLSL_TYPE_FLOAT:
case GLSL_TYPE_DOUBLE:
coord_components++;
coord = vtn_ssa_value(b, w[idx++])->def;
- p->src = nir_src_for_ssa(coord);
+ p->src = nir_src_for_ssa(nir_channels(&b->nb, coord,
+ (1 << coord_components) - 1));
p->src_type = nir_tex_src_coord;
p++;
break;
if (opcode != SpvOpImageWrite) {
struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
struct vtn_type *type = vtn_value(b, w[1], vtn_value_type_type)->type;
- nir_ssa_dest_init(&intrin->instr, &intrin->dest, 4, 32, NULL);
+
+ unsigned dest_components =
+ nir_intrinsic_infos[intrin->intrinsic].dest_components;
+ if (intrin->intrinsic == nir_intrinsic_image_size) {
+ dest_components = intrin->num_components =
+ glsl_get_vector_elements(type->type);
+ }
+
+ nir_ssa_dest_init(&intrin->instr, &intrin->dest,
+ dest_components, 32, NULL);
nir_builder_instr_insert(&b->nb, &intrin->instr);
- /* The image intrinsics always return 4 channels but we may not want
- * that many. Emit a mov to trim it down.
- */
- unsigned swiz[4] = {0, 1, 2, 3};
val->ssa = vtn_create_ssa_value(b, type->type);
- val->ssa->def = nir_swizzle(&b->nb, &intrin->dest.ssa, swiz,
- glsl_get_vector_elements(type->type), false);
+ val->ssa->def = &intrin->dest.ssa;
} else {
nir_builder_instr_insert(&b->nb, &intrin->instr);
}
nir_alu_instr *vec = create_vec(b->shader, num_components,
srcs[0]->bit_size);
+ /* From the SPIR-V 1.1 spec for OpCompositeConstruct:
+ *
+ * "When constructing a vector, there must be at least two Constituent
+ * operands."
+ */
+ assert(num_srcs >= 2);
+
unsigned dest_idx = 0;
for (unsigned i = 0; i < num_srcs; i++) {
nir_ssa_def *src = srcs[i];
+ assert(dest_idx + src->num_components <= num_components);
for (unsigned j = 0; j < src->num_components; j++) {
vec->src[dest_idx].src = nir_src_for_ssa(src);
vec->src[dest_idx].swizzle[0] = j;
}
}
+ /* From the SPIR-V 1.1 spec for OpCompositeConstruct:
+ *
+ * "When constructing a vector, the total number of components in all
+ * the operands must equal the number of components in Result Type."
+ */
+ assert(dest_idx == num_components);
+
nir_builder_instr_insert(&b->nb, &vec->instr);
return &vec->dest.dest.ssa;
case SpvCapabilityVector16:
case SpvCapabilityFloat16Buffer:
case SpvCapabilityFloat16:
- case SpvCapabilityInt64:
case SpvCapabilityInt64Atomics:
case SpvCapabilityAtomicStorage:
case SpvCapabilityInt16:
case SpvCapabilitySparseResidency:
case SpvCapabilityMinLod:
case SpvCapabilityTransformFeedback:
- case SpvCapabilityStorageImageReadWithoutFormat:
- case SpvCapabilityStorageImageWriteWithoutFormat:
vtn_warn("Unsupported SPIR-V capability: %s",
spirv_capability_to_string(cap));
break;
case SpvCapabilityFloat64:
spv_check_supported(float64, cap);
break;
+ case SpvCapabilityInt64:
+ spv_check_supported(int64, cap);
+ break;
case SpvCapabilityAddresses:
case SpvCapabilityKernel:
case SpvCapabilityTessellationPointSize:
spv_check_supported(tessellation, cap);
break;
+
+ case SpvCapabilityDrawParameters:
+ spv_check_supported(draw_parameters, cap);
+ break;
+
+ case SpvCapabilityStorageImageReadWithoutFormat:
+ spv_check_supported(image_read_without_format, cap);
+ break;
+
+ case SpvCapabilityStorageImageWriteWithoutFormat:
+ spv_check_supported(image_write_without_format, cap);
+ break;
+
+ case SpvCapabilityMultiView:
+ spv_check_supported(multiview, cap);
+ break;
+
+ default:
+ unreachable("Unhandled capability");
}
break;
}
case SpvExecutionModeEarlyFragmentTests:
assert(b->shader->stage == MESA_SHADER_FRAGMENT);
- b->shader->info->fs.early_fragment_tests = true;
+ b->shader->info.fs.early_fragment_tests = true;
break;
case SpvExecutionModeInvocations:
assert(b->shader->stage == MESA_SHADER_GEOMETRY);
- b->shader->info->gs.invocations = MAX2(1, mode->literals[0]);
+ b->shader->info.gs.invocations = MAX2(1, mode->literals[0]);
break;
case SpvExecutionModeDepthReplacing:
assert(b->shader->stage == MESA_SHADER_FRAGMENT);
- b->shader->info->fs.depth_layout = FRAG_DEPTH_LAYOUT_ANY;
+ b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_ANY;
break;
case SpvExecutionModeDepthGreater:
assert(b->shader->stage == MESA_SHADER_FRAGMENT);
- b->shader->info->fs.depth_layout = FRAG_DEPTH_LAYOUT_GREATER;
+ b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_GREATER;
break;
case SpvExecutionModeDepthLess:
assert(b->shader->stage == MESA_SHADER_FRAGMENT);
- b->shader->info->fs.depth_layout = FRAG_DEPTH_LAYOUT_LESS;
+ b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_LESS;
break;
case SpvExecutionModeDepthUnchanged:
assert(b->shader->stage == MESA_SHADER_FRAGMENT);
- b->shader->info->fs.depth_layout = FRAG_DEPTH_LAYOUT_UNCHANGED;
+ b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_UNCHANGED;
break;
case SpvExecutionModeLocalSize:
assert(b->shader->stage == MESA_SHADER_COMPUTE);
- b->shader->info->cs.local_size[0] = mode->literals[0];
- b->shader->info->cs.local_size[1] = mode->literals[1];
- b->shader->info->cs.local_size[2] = mode->literals[2];
+ b->shader->info.cs.local_size[0] = mode->literals[0];
+ b->shader->info.cs.local_size[1] = mode->literals[1];
+ b->shader->info.cs.local_size[2] = mode->literals[2];
break;
case SpvExecutionModeLocalSizeHint:
break; /* Nothing to do with this */
case SpvExecutionModeOutputVertices:
if (b->shader->stage == MESA_SHADER_TESS_CTRL ||
b->shader->stage == MESA_SHADER_TESS_EVAL) {
- b->shader->info->tess.tcs_vertices_out = mode->literals[0];
+ b->shader->info.tess.tcs_vertices_out = mode->literals[0];
} else {
assert(b->shader->stage == MESA_SHADER_GEOMETRY);
- b->shader->info->gs.vertices_out = mode->literals[0];
+ b->shader->info.gs.vertices_out = mode->literals[0];
}
break;
case SpvExecutionModeIsolines:
if (b->shader->stage == MESA_SHADER_TESS_CTRL ||
b->shader->stage == MESA_SHADER_TESS_EVAL) {
- b->shader->info->tess.primitive_mode =
+ b->shader->info.tess.primitive_mode =
gl_primitive_from_spv_execution_mode(mode->exec_mode);
} else {
assert(b->shader->stage == MESA_SHADER_GEOMETRY);
- b->shader->info->gs.vertices_in =
+ b->shader->info.gs.vertices_in =
vertices_in_from_spv_execution_mode(mode->exec_mode);
}
break;
case SpvExecutionModeOutputLineStrip:
case SpvExecutionModeOutputTriangleStrip:
assert(b->shader->stage == MESA_SHADER_GEOMETRY);
- b->shader->info->gs.output_primitive =
+ b->shader->info.gs.output_primitive =
gl_primitive_from_spv_execution_mode(mode->exec_mode);
break;
case SpvExecutionModeSpacingEqual:
assert(b->shader->stage == MESA_SHADER_TESS_CTRL ||
b->shader->stage == MESA_SHADER_TESS_EVAL);
- b->shader->info->tess.spacing = TESS_SPACING_EQUAL;
+ b->shader->info.tess.spacing = TESS_SPACING_EQUAL;
break;
case SpvExecutionModeSpacingFractionalEven:
assert(b->shader->stage == MESA_SHADER_TESS_CTRL ||
b->shader->stage == MESA_SHADER_TESS_EVAL);
- b->shader->info->tess.spacing = TESS_SPACING_FRACTIONAL_EVEN;
+ b->shader->info.tess.spacing = TESS_SPACING_FRACTIONAL_EVEN;
break;
case SpvExecutionModeSpacingFractionalOdd:
assert(b->shader->stage == MESA_SHADER_TESS_CTRL ||
b->shader->stage == MESA_SHADER_TESS_EVAL);
- b->shader->info->tess.spacing = TESS_SPACING_FRACTIONAL_ODD;
+ b->shader->info.tess.spacing = TESS_SPACING_FRACTIONAL_ODD;
break;
case SpvExecutionModeVertexOrderCw:
assert(b->shader->stage == MESA_SHADER_TESS_CTRL ||
* but be the opposite of OpenGL. Currently NIR follows GL semantics,
* so we set it backwards here.
*/
- b->shader->info->tess.ccw = true;
+ b->shader->info.tess.ccw = true;
break;
case SpvExecutionModeVertexOrderCcw:
assert(b->shader->stage == MESA_SHADER_TESS_CTRL ||
b->shader->stage == MESA_SHADER_TESS_EVAL);
/* Backwards; see above */
- b->shader->info->tess.ccw = false;
+ b->shader->info.tess.ccw = false;
break;
case SpvExecutionModePointMode:
assert(b->shader->stage == MESA_SHADER_TESS_CTRL ||
b->shader->stage == MESA_SHADER_TESS_EVAL);
- b->shader->info->tess.point_mode = true;
+ b->shader->info.tess.point_mode = true;
break;
case SpvExecutionModePixelCenterInteger:
case SpvExecutionModeVecTypeHint:
case SpvExecutionModeContractionOff:
break; /* OpenCL */
+
+ default:
+ unreachable("Unhandled execution mode");
}
}
vtn_handle_constant(b, opcode, w, count);
break;
+ case SpvOpUndef:
case SpvOpVariable:
vtn_handle_variables(b, opcode, w, count);
break;
b->shader = nir_shader_create(NULL, stage, options, NULL);
/* Set shader info defaults */
- b->shader->info->gs.invocations = 1;
+ b->shader->info.gs.invocations = 1;
/* Parse execution modes */
vtn_foreach_execution_mode(b, b->entry_point,