/** 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; }