Skip to content
Snippets Groups Projects
spirv.c 401 KiB
Newer Older
    if (!is_in_default_phase(compiler))
        spirv_compiler_leave_shader_phase(compiler);
    else
        vkd3d_spirv_build_op_function_end(builder);
    if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL)
        spirv_compiler_emit_hull_shader_main(compiler);
    if (compiler->shader_type == VKD3D_SHADER_TYPE_DOMAIN)
    {
        if (info && (ds_info = vkd3d_find_struct(compile_info->next, SPIRV_DOMAIN_SHADER_TARGET_INFO)))
            spirv_compiler_emit_tessellator_output_primitive(compiler, ds_info->output_primitive);
            spirv_compiler_emit_tessellator_partitioning(compiler, ds_info->partitioning);
        else if (spirv_compiler_is_opengl_target(compiler))
            ERR("vkd3d_shader_spirv_domain_shader_target_info is required for "
                    "OpenGL tessellation evaluation shader.\n");
        }
    }

    if (compiler->epilogue_function_id)
    {
        vkd3d_spirv_build_op_name(builder, compiler->epilogue_function_id, "epilogue");
        spirv_compiler_emit_shader_epilogue_function(compiler);
        vkd3d_spirv_stream_clear(&builder->debug_stream);

    if (!vkd3d_spirv_compile_module(builder, spirv, spirv_compiler_get_entry_point_name(compiler)))
    if (TRACE_ON() || parser->config_flags & VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION)
        enum vkd3d_shader_spirv_environment environment = spirv_compiler_get_target_environment(compiler);
        struct vkd3d_string_buffer buffer;

        if (TRACE_ON())
            vkd3d_spirv_dump(spirv, environment);

        vkd3d_string_buffer_init(&buffer);
        if (!vkd3d_spirv_validate(&buffer, spirv, environment))
        {
            FIXME("Failed to validate SPIR-V binary.\n");
            vkd3d_shader_trace_text(buffer.buffer, buffer.content_size);

            if (compiler->config_flags & VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION)
            {
                spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_SHADER,
                        "Execution generated an invalid shader, failing compilation:\n%s",
                        buffer.buffer);
            }
        }
        vkd3d_string_buffer_cleanup(&buffer);
    if (compiler->failed)
        return VKD3D_ERROR_INVALID_SHADER;

    if (compile_info->target_type == VKD3D_SHADER_TARGET_SPIRV_TEXT)
    {
        struct vkd3d_shader_code text;
        enum vkd3d_shader_spirv_environment environment = spirv_compiler_get_target_environment(compiler);
        if (vkd3d_spirv_binary_to_text(spirv, environment, compiler->formatting, &text) != VKD3D_OK)
int spirv_compile(struct vkd3d_shader_parser *parser,
        const struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info,
        const struct vkd3d_shader_compile_info *compile_info,
        struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context)
{
    struct spirv_compiler *spirv_compiler;
    int ret;

    if (!(spirv_compiler = spirv_compiler_create(&parser->shader_version, &parser->shader_desc,
            compile_info, scan_descriptor_info, message_context, &parser->location, parser->config_flags)))
    {
        ERR("Failed to create SPIR-V compiler.\n");
        return VKD3D_ERROR;
    }

    ret = spirv_compiler_generate_spirv(spirv_compiler, compile_info, parser, out);

    spirv_compiler_destroy(spirv_compiler);
    return ret;
}