X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fspirv%2Fspirv_to_nir.c;h=fe0a4efceb13b651a6bb7c674fe61f671f6d59e2;hb=59fb59ad54d368683d5cc3b149f021452bddc05f;hp=763dbf4e681955150b384817265633fcc1ecb187;hpb=b117f59710e62f4afa5781c554f8113e2b0df9cc;p=mesa.git diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 763dbf4e681..fe0a4efceb1 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -185,6 +185,13 @@ vtn_ssa_value(struct vtn_builder *b, uint32_t value_id) case vtn_value_type_ssa: return val->ssa; + case vtn_value_type_pointer: + assert(val->pointer->ptr_type && val->pointer->ptr_type->type); + struct vtn_ssa_value *ssa = + vtn_create_ssa_value(b, val->pointer->ptr_type->type); + ssa->def = vtn_pointer_to_ssa(b, val->pointer); + return ssa; + default: unreachable("Invalid type for an SSA value"); } @@ -255,7 +262,7 @@ vtn_handle_extension(struct vtn_builder *b, SpvOp opcode, if (strcmp((const char *)&w[2], "GLSL.std.450") == 0) { val->ext_handler = vtn_handle_glsl450_instruction; } else { - assert(!"Unsupported extension"); + unreachable("Unsupported extension"); } break; } @@ -599,12 +606,17 @@ type_decoration_cb(struct vtn_builder *b, switch (dec->decoration) { case SpvDecorationArrayStride: + assert(type->base_type == vtn_base_type_matrix || + type->base_type == vtn_base_type_array || + type->base_type == vtn_base_type_pointer); type->stride = dec->literals[0]; break; case SpvDecorationBlock: + assert(type->base_type == vtn_base_type_struct); type->block = true; break; case SpvDecorationBufferBlock: + assert(type->base_type == vtn_base_type_struct); type->buffer_block = true; break; case SpvDecorationGLSLShared: @@ -709,10 +721,10 @@ translate_image_format(SpvImageFormat format) case SpvImageFormatRg32ui: return 0x823C; /* GL_RG32UI */ case SpvImageFormatRg16ui: return 0x823A; /* GL_RG16UI */ case SpvImageFormatRg8ui: return 0x8238; /* GL_RG8UI */ - case SpvImageFormatR16ui: return 0x823A; /* GL_RG16UI */ + case SpvImageFormatR16ui: return 0x8234; /* GL_R16UI */ case SpvImageFormatR8ui: return 0x8232; /* GL_R8UI */ default: - assert(!"Invalid image format"); + unreachable("Invalid image format"); return 0; } } @@ -856,9 +868,16 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode, vtn_value(b, w[3], vtn_value_type_type)->type; val->type->base_type = vtn_base_type_pointer; - val->type->type = NULL; val->type->storage_class = storage_class; val->type->deref = deref_type; + + if (storage_class == SpvStorageClassUniform || + storage_class == SpvStorageClassStorageBuffer) { + /* These can actually be stored to nir_variables and used as SSA + * values so they need a real glsl_type. + */ + val->type->type = glsl_vector_type(GLSL_TYPE_UINT, 2); + } break; } @@ -900,7 +919,7 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode, else if (dim == GLSL_SAMPLER_DIM_SUBPASS) dim = GLSL_SAMPLER_DIM_SUBPASS_MS; else - assert(!"Unsupported multisampled image type"); + unreachable("Unsupported multisampled image type"); } val->type->image_format = translate_image_format(format); @@ -915,7 +934,7 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode, val->type->type = glsl_image_type(dim, is_array, glsl_get_base_type(sampled_type)); } else { - assert(!"We need to know if the image will be sampled"); + unreachable("We need to know if the image will be sampled"); } break; } @@ -1359,7 +1378,7 @@ vtn_handle_constant(struct vtn_builder *b, SpvOp opcode, break; case SpvOpConstantSampler: - assert(!"OpConstantSampler requires Kernel Capability"); + unreachable("OpConstantSampler requires Kernel Capability"); break; default: @@ -1374,6 +1393,7 @@ static void vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode, const uint32_t *w, unsigned count) { + struct vtn_type *res_type = vtn_value(b, w[1], vtn_value_type_type)->type; struct nir_function *callee = vtn_value(b, w[3], vtn_value_type_function)->func->impl->function; @@ -1381,7 +1401,8 @@ vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode, for (unsigned i = 0; i < call->num_params; i++) { unsigned arg_id = w[4 + i]; struct vtn_value *arg = vtn_untyped_value(b, arg_id); - if (arg->value_type == vtn_value_type_pointer) { + if (arg->value_type == vtn_value_type_pointer && + arg->pointer->ptr_type->type == NULL) { nir_deref_var *d = vtn_pointer_to_deref(b, arg->pointer); call->params[i] = nir_deref_var_clone(d, call); } else { @@ -1397,6 +1418,7 @@ vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode, } nir_variable *out_tmp = NULL; + assert(res_type->type == callee->return_type); if (!glsl_type_is_void(callee->return_type)) { out_tmp = nir_local_variable_create(b->impl, callee->return_type, "out_tmp"); @@ -1408,8 +1430,7 @@ vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode, if (glsl_type_is_void(callee->return_type)) { vtn_push_value(b, w[2], vtn_value_type_undef); } else { - struct vtn_value *retval = vtn_push_value(b, w[2], vtn_value_type_ssa); - retval->ssa = vtn_local_load(b, call->return_deref); + vtn_push_ssa(b, w[2], res_type, vtn_local_load(b, call->return_deref)); } } @@ -2013,6 +2034,7 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode, case SpvOpAtomicIDecrement: case SpvOpAtomicExchange: case SpvOpAtomicIAdd: + case SpvOpAtomicISub: case SpvOpAtomicSMin: case SpvOpAtomicUMin: case SpvOpAtomicSMax: @@ -2605,7 +2627,7 @@ gl_primitive_from_spv_execution_mode(SpvExecutionMode mode) case SpvExecutionModeOutputTriangleStrip: return 5; /* GL_TRIANGLE_STRIP */ default: - assert(!"Invalid primitive type"); + unreachable("Invalid primitive type"); return 4; } } @@ -2625,7 +2647,7 @@ vertices_in_from_spv_execution_mode(SpvExecutionMode mode) case SpvExecutionModeInputTrianglesAdjacency: return 6; default: - assert(!"Invalid GS input mode"); + unreachable("Invalid GS input mode"); return 0; } } @@ -2685,6 +2707,7 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode, case SpvCapabilitySampled1D: case SpvCapabilityImage1D: case SpvCapabilitySampledCubeArray: + case SpvCapabilityImageCubeArray: case SpvCapabilitySampledBuffer: case SpvCapabilityImageBuffer: case SpvCapabilityImageQuery: @@ -2708,7 +2731,6 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode, case SpvCapabilityAtomicStorage: case SpvCapabilityInt16: case SpvCapabilityStorageImageMultisample: - case SpvCapabilityImageCubeArray: case SpvCapabilityInt8: case SpvCapabilitySparseResidency: case SpvCapabilityMinLod: @@ -2763,6 +2785,11 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode, spv_check_supported(multiview, cap); break; + case SpvCapabilityVariablePointersStorageBuffer: + case SpvCapabilityVariablePointers: + spv_check_supported(variable_pointers, cap); + break; + default: unreachable("Unhandled capability"); } @@ -2836,34 +2863,34 @@ vtn_handle_execution_mode(struct vtn_builder *b, struct vtn_value *entry_point, break; case SpvExecutionModeEarlyFragmentTests: - assert(b->shader->stage == MESA_SHADER_FRAGMENT); + assert(b->shader->info.stage == MESA_SHADER_FRAGMENT); b->shader->info.fs.early_fragment_tests = true; break; case SpvExecutionModeInvocations: - assert(b->shader->stage == MESA_SHADER_GEOMETRY); + assert(b->shader->info.stage == MESA_SHADER_GEOMETRY); b->shader->info.gs.invocations = MAX2(1, mode->literals[0]); break; case SpvExecutionModeDepthReplacing: - assert(b->shader->stage == MESA_SHADER_FRAGMENT); + assert(b->shader->info.stage == MESA_SHADER_FRAGMENT); b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_ANY; break; case SpvExecutionModeDepthGreater: - assert(b->shader->stage == MESA_SHADER_FRAGMENT); + assert(b->shader->info.stage == MESA_SHADER_FRAGMENT); b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_GREATER; break; case SpvExecutionModeDepthLess: - assert(b->shader->stage == MESA_SHADER_FRAGMENT); + assert(b->shader->info.stage == MESA_SHADER_FRAGMENT); b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_LESS; break; case SpvExecutionModeDepthUnchanged: - assert(b->shader->stage == MESA_SHADER_FRAGMENT); + assert(b->shader->info.stage == MESA_SHADER_FRAGMENT); b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_UNCHANGED; break; case SpvExecutionModeLocalSize: - assert(b->shader->stage == MESA_SHADER_COMPUTE); + assert(b->shader->info.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]; @@ -2872,11 +2899,11 @@ vtn_handle_execution_mode(struct vtn_builder *b, struct vtn_value *entry_point, break; /* Nothing to do with this */ case SpvExecutionModeOutputVertices: - if (b->shader->stage == MESA_SHADER_TESS_CTRL || - b->shader->stage == MESA_SHADER_TESS_EVAL) { + if (b->shader->info.stage == MESA_SHADER_TESS_CTRL || + b->shader->info.stage == MESA_SHADER_TESS_EVAL) { b->shader->info.tess.tcs_vertices_out = mode->literals[0]; } else { - assert(b->shader->stage == MESA_SHADER_GEOMETRY); + assert(b->shader->info.stage == MESA_SHADER_GEOMETRY); b->shader->info.gs.vertices_out = mode->literals[0]; } break; @@ -2888,12 +2915,12 @@ vtn_handle_execution_mode(struct vtn_builder *b, struct vtn_value *entry_point, case SpvExecutionModeInputTrianglesAdjacency: case SpvExecutionModeQuads: case SpvExecutionModeIsolines: - if (b->shader->stage == MESA_SHADER_TESS_CTRL || - b->shader->stage == MESA_SHADER_TESS_EVAL) { + if (b->shader->info.stage == MESA_SHADER_TESS_CTRL || + b->shader->info.stage == MESA_SHADER_TESS_EVAL) { b->shader->info.tess.primitive_mode = gl_primitive_from_spv_execution_mode(mode->exec_mode); } else { - assert(b->shader->stage == MESA_SHADER_GEOMETRY); + assert(b->shader->info.stage == MESA_SHADER_GEOMETRY); b->shader->info.gs.vertices_in = vertices_in_from_spv_execution_mode(mode->exec_mode); } @@ -2902,44 +2929,39 @@ vtn_handle_execution_mode(struct vtn_builder *b, struct vtn_value *entry_point, case SpvExecutionModeOutputPoints: case SpvExecutionModeOutputLineStrip: case SpvExecutionModeOutputTriangleStrip: - assert(b->shader->stage == MESA_SHADER_GEOMETRY); + assert(b->shader->info.stage == MESA_SHADER_GEOMETRY); 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); + assert(b->shader->info.stage == MESA_SHADER_TESS_CTRL || + b->shader->info.stage == MESA_SHADER_TESS_EVAL); 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); + assert(b->shader->info.stage == MESA_SHADER_TESS_CTRL || + b->shader->info.stage == MESA_SHADER_TESS_EVAL); 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); + assert(b->shader->info.stage == MESA_SHADER_TESS_CTRL || + b->shader->info.stage == MESA_SHADER_TESS_EVAL); b->shader->info.tess.spacing = TESS_SPACING_FRACTIONAL_ODD; break; case SpvExecutionModeVertexOrderCw: - assert(b->shader->stage == MESA_SHADER_TESS_CTRL || - b->shader->stage == MESA_SHADER_TESS_EVAL); - /* Vulkan's notion of CCW seems to match the hardware backends, - * but be the opposite of OpenGL. Currently NIR follows GL semantics, - * so we set it backwards here. - */ - b->shader->info.tess.ccw = true; + assert(b->shader->info.stage == MESA_SHADER_TESS_CTRL || + b->shader->info.stage == MESA_SHADER_TESS_EVAL); + b->shader->info.tess.ccw = false; 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; + assert(b->shader->info.stage == MESA_SHADER_TESS_CTRL || + b->shader->info.stage == MESA_SHADER_TESS_EVAL); + b->shader->info.tess.ccw = true; break; case SpvExecutionModePointMode: - assert(b->shader->stage == MESA_SHADER_TESS_CTRL || - b->shader->stage == MESA_SHADER_TESS_EVAL); + assert(b->shader->info.stage == MESA_SHADER_TESS_CTRL || + b->shader->info.stage == MESA_SHADER_TESS_EVAL); b->shader->info.tess.point_mode = true; break; @@ -2948,7 +2970,7 @@ vtn_handle_execution_mode(struct vtn_builder *b, struct vtn_value *entry_point, break; case SpvExecutionModeXfb: - assert(!"Unhandled execution mode"); + unreachable("Unhandled execution mode"); break; case SpvExecutionModeVecTypeHint: @@ -2982,7 +3004,7 @@ vtn_handle_variable_or_type_instruction(struct vtn_builder *b, SpvOp opcode, case SpvOpMemberDecorate: case SpvOpGroupDecorate: case SpvOpGroupMemberDecorate: - assert(!"Invalid opcode types and variables section"); + unreachable("Invalid opcode types and variables section"); break; case SpvOpTypeVoid: @@ -3063,6 +3085,7 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode, case SpvOpCopyMemory: case SpvOpCopyMemorySized: case SpvOpAccessChain: + case SpvOpPtrAccessChain: case SpvOpInBoundsAccessChain: case SpvOpArrayLength: vtn_handle_variables(b, opcode, w, count); @@ -3146,6 +3169,19 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode, break; } + case SpvOpSelect: { + /* Handle OpSelect up-front here because it needs to be able to handle + * pointers and not just regular vectors and scalars. + */ + struct vtn_type *res_type = vtn_value(b, w[1], vtn_value_type_type)->type; + struct vtn_ssa_value *ssa = vtn_create_ssa_value(b, res_type->type); + ssa->def = nir_bcsel(&b->nb, vtn_ssa_value(b, w[3])->def, + vtn_ssa_value(b, w[4])->def, + vtn_ssa_value(b, w[5])->def); + vtn_push_ssa(b, w[2], res_type, ssa); + break; + } + case SpvOpSNegate: case SpvOpFNegate: case SpvOpNot: @@ -3203,7 +3239,6 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode, case SpvOpBitwiseOr: case SpvOpBitwiseXor: case SpvOpBitwiseAnd: - case SpvOpSelect: case SpvOpIEqual: case SpvOpFOrdEqual: case SpvOpFUnordEqual: