Beispiel #1
0
/** Please see header for specification */
void Anvil::Instance::destroy()
{
    if (m_debug_callback_data != VK_NULL_HANDLE)
    {
        lock();
        {
            m_ext_debug_report_entrypoints.vkDestroyDebugReportCallbackEXT(m_instance,
                                                                           m_debug_callback_data,
                                                                           nullptr /* pAllocator */);
        }
        unlock();

        m_debug_callback_data = VK_NULL_HANDLE;
    }

    m_physical_devices.clear();

    #ifdef _DEBUG
    {
        /* Make sure no physical devices are still registered with Object Tracker at this point */
        auto object_manager_ptr = Anvil::ObjectTracker::get();

        anvil_assert(object_manager_ptr->get_object_at_index(Anvil::OBJECT_TYPE_PHYSICAL_DEVICE,
                                                             0) == nullptr);
    }
    #endif
}
/* Please see header for specification */
bool Anvil::GLSLShaderToSPIRVGenerator::bake_spirv_blob() const
{
    bool           glsl_filename_is_temporary = false;
    std::string    glsl_filename_with_path;
    bool           result                     = false;

    ANVIL_REDUNDANT_VARIABLE(glsl_filename_is_temporary);

    if (m_glsl_source_code_dirty)
    {
        bake_glsl_source_code();

        anvil_assert(!m_glsl_source_code_dirty);
    }

    if (m_mode == MODE_LOAD_SOURCE_FROM_FILE)
    {
        glsl_filename_is_temporary = false;
        glsl_filename_with_path    = m_data;
    }

    /* Form a temporary file name we will use to write the modified GLSL shader to. */
    #ifndef ANVIL_LINK_WITH_GLSLANG
    {
        switch (m_shader_stage)
        {
            case ShaderStage::COMPUTE:                 glsl_filename_with_path = "temp.comp"; break;
            case ShaderStage::FRAGMENT:                glsl_filename_with_path = "temp.frag"; break;
            case ShaderStage::GEOMETRY:                glsl_filename_with_path = "temp.geom"; break;
            case ShaderStage::TESSELLATION_CONTROL:    glsl_filename_with_path = "temp.tesc"; break;
            case ShaderStage::TESSELLATION_EVALUATION: glsl_filename_with_path = "temp.tese"; break;
            case ShaderStage::VERTEX:                  glsl_filename_with_path = "temp.vert"; break;

            default:
            {
                anvil_assert_fail();

                goto end;
            }
        }

        /* Write down the file to a temporary location */
        Anvil::IO::write_text_file(glsl_filename_with_path,
                                   m_glsl_source_code);

        glsl_filename_is_temporary = true;
    }
    #endif


    #ifdef ANVIL_LINK_WITH_GLSLANG
    {
        /* Shader modules are cached throughout Instance's lifetime in Anvil. It might just happen that
         * the shader we're about to convert to SPIR-V representation has already been converted in the past.
         *
         * Given that the conversion process can be time-consuming, let's try to see if any of the living
         * shader module instances already use exactly the same source code.
         */
        uint32_t n_current_shader_module = 0;
        auto     object_tracker_ptr      = Anvil::ObjectTracker::get();

        do
        {
            auto                       shader_module_raw_ptr = object_tracker_ptr->get_object_at_index     (Anvil::ObjectType::SHADER_MODULE,
                                                                                                            n_current_shader_module);
            const Anvil::ShaderModule* shader_module_ptr     = reinterpret_cast<const Anvil::ShaderModule*>(shader_module_raw_ptr);

            if (shader_module_raw_ptr == nullptr)
            {
                /* Out of shader module instances. */
                break;
            }

            if (shader_module_ptr->get_glsl_source_code() == m_glsl_source_code)
            {
                const auto reference_spirv_blob               = shader_module_ptr->get_spirv_blob();
                const auto reference_spirv_blob_size_in_bytes = reference_spirv_blob.size() * sizeof(reference_spirv_blob.at(0) );

                anvil_assert(reference_spirv_blob_size_in_bytes != 0);

                m_spirv_blob.resize(reference_spirv_blob_size_in_bytes);

                memcpy(&m_spirv_blob.at        (0),
                       &reference_spirv_blob.at(0),
                       reference_spirv_blob_size_in_bytes);

                result = true;
                break;
            }

            /* Move to the next shader module instance */
            ++n_current_shader_module;
        }
        while (n_current_shader_module != 0); /* work around "conditional expression is constant" warnings issued by some compilers */

        if (m_spirv_blob.size() == 0)
        {
            /* Need to bake a brand new SPIR-V blob */
            result = bake_spirv_blob_by_calling_glslang(m_glsl_source_code.c_str() );
        }
    }

    #else
    {
        /* We need to point glslangvalidator at a location where it can stash the SPIR-V blob. */
        result = bake_spirv_blob_by_spawning_glslang_process(glsl_filename_with_path,
                                                             "temp.spv");
    }

end:
    #endif



    return result;
}