mirror of
https://github.com/barkeser2002/flower.git
synced 2026-09-25 18:56:16 +03:00
665 lines
22 KiB
C++
665 lines
22 KiB
C++
#include "rhi.h"
|
|
#include <asset/asset_system.h>
|
|
#include "gpu_asset.h"
|
|
#include <asset/asset_staticmesh.h>
|
|
#include <asset/asset_texture.h>
|
|
|
|
namespace engine
|
|
{
|
|
static AutoCVarBool cVarRHIDebugMarkerEnable(
|
|
"r.RHI.DebugMarkerEnable",
|
|
"Enable debug marker or not.",
|
|
"RHI",
|
|
true,
|
|
CVarFlags::ReadOnly
|
|
);
|
|
|
|
static AutoCVarCmd cVarUpdatePasses("cmd.updatePasses", "Update passes shader and pipeline info.");
|
|
|
|
void VulkanContext::registerCheck(Engine* engine)
|
|
{
|
|
ASSERT(engine->isRuntimeModuleEmpty(), "When vulkan context enable, you must set it as the first module when register.")
|
|
}
|
|
|
|
bool VulkanContext::init()
|
|
{
|
|
m_state = EContextState::init;
|
|
|
|
// Then try init vulkan context.
|
|
try
|
|
{
|
|
// Windows app, assign windows handle.
|
|
if (m_engine->isWindowApp())
|
|
{
|
|
m_window = m_engine->getFramework()->getWindow();
|
|
}
|
|
|
|
// Create vulkan instance.
|
|
initInstance();
|
|
|
|
// Select gpu.
|
|
selectGPU();
|
|
|
|
// Query gpu infos.
|
|
queryGPUInfo();
|
|
|
|
// Query depth format support state.
|
|
quertDepthFormatSupportState();
|
|
|
|
// Create surface for window.
|
|
if(m_engine->isWindowApp())
|
|
{
|
|
RHICheck(glfwCreateWindowSurface(m_instance, m_window, nullptr, &m_surface));
|
|
}
|
|
|
|
// Create logic device for vulkan.
|
|
initDeviceAndQueue();
|
|
|
|
initVMA();
|
|
|
|
// Init command pools.
|
|
initCommandPools();
|
|
ASSERT(m_copyPools.size() > 0 && m_computePools.size() > 0 && m_graphicsPools.size() > 0,
|
|
"Your graphics card is too old and even no support async vulkan queue. exiting...");
|
|
|
|
// Init descriptor allocator and layout cache.
|
|
m_descriptorAllocator.init(this);
|
|
m_descriptorLayoutCache.init(this);
|
|
|
|
// Init bindless resources.
|
|
m_bindlessSampler.init("Bindless Sampler", this);
|
|
m_bindlessTexture.init("Bindless Texture", this);
|
|
m_bindlessStorageBuffer.init("Bindless SSBO", this);
|
|
|
|
// Init shader cache.
|
|
m_shaderCache.init(this);
|
|
|
|
// Init sampler cache, must after bindless sampler.
|
|
m_samplerCache.init(this);
|
|
|
|
// 64 MB static uploader, 32 MB dynamic uploader.
|
|
m_uploader = std::make_unique<AsyncUploaderManager>(this, 64, 32);
|
|
|
|
// 1024 MB + 512 MB LRU cache.
|
|
m_lru = std::make_unique<LRUAssetCache>(1024, 512);
|
|
|
|
uint32_t frameNum = 1;
|
|
if (m_engine->isWindowApp())
|
|
{
|
|
// Swapchain init.
|
|
m_swapchain.init(this);
|
|
|
|
initPresentContext();
|
|
|
|
frameNum = m_swapchain.getBackbufferCount();
|
|
|
|
|
|
}
|
|
m_gpuResourcePending.resize(frameNum);
|
|
|
|
m_dynamicUniformBuffer = std::make_unique<DynamicUniformBuffer>(this, frameNum, 16, 8); // 16 MB init dynamic uniform buffer size, 8 MB increment when overflow.
|
|
|
|
m_rtPool = std::make_unique<RenderTexturePool>(this);
|
|
m_bufferParameters = std::make_unique<BufferParameterPool>();
|
|
m_passCollector = std::make_unique<PassCollector>(this);
|
|
|
|
initEngineAssets();
|
|
|
|
}
|
|
catch (...)
|
|
{
|
|
LOG_ERROR("Vulkan context init failed!");
|
|
return false;
|
|
}
|
|
|
|
|
|
// Switch state.
|
|
m_state = EContextState::ticking;
|
|
return true;
|
|
}
|
|
|
|
bool VulkanContext::tick(const RuntimeModuleTickData& tickData)
|
|
{
|
|
m_dynamicUniformBuffer->onFrameStart();
|
|
|
|
// Update passes if need.
|
|
CVarCmdHandle(cVarUpdatePasses, [&]() { m_passCollector->updateAllPasses(); });
|
|
|
|
// Update pool state.
|
|
m_rtPool->tick();
|
|
m_bufferParameters->tick();
|
|
|
|
m_gpuResourcePending[m_presentContext.currentFrame].clear();
|
|
return true;
|
|
}
|
|
|
|
void VulkanContext::release()
|
|
{
|
|
vkDeviceWaitIdle(m_device);
|
|
|
|
// Set bit to know current context state.
|
|
m_state = EContextState::release;
|
|
|
|
// Release engine asset.
|
|
m_engineAssets.clear();
|
|
|
|
m_dynamicUniformBuffer = nullptr;
|
|
|
|
// Clear pass.
|
|
m_passCollector = nullptr;
|
|
|
|
// Clear rt pool.
|
|
m_rtPool = nullptr;
|
|
m_bufferParameters = nullptr;
|
|
|
|
// Clear lru cache.
|
|
m_lru->clear();
|
|
|
|
m_uploader->release();
|
|
|
|
if (m_engine->isWindowApp())
|
|
{
|
|
destroyPresentContext();
|
|
m_swapchain.release();
|
|
}
|
|
|
|
// Release bindless resource.
|
|
m_bindlessSampler.release();
|
|
m_bindlessTexture.release();
|
|
m_bindlessStorageBuffer.release();
|
|
|
|
// Release descriptor allocator and layout cache.
|
|
m_descriptorAllocator.release();
|
|
m_descriptorLayoutCache.release();
|
|
|
|
// Sampler cache release.
|
|
m_samplerCache.release();
|
|
|
|
// Shader cache release.
|
|
m_shaderCache.release();
|
|
|
|
destroyCommandPools();
|
|
|
|
destroyVMA();
|
|
|
|
destroyDevice();
|
|
|
|
if(m_surface != VK_NULL_HANDLE)
|
|
{
|
|
// release surface.
|
|
vkDestroySurfaceKHR(m_instance, m_surface, nullptr);
|
|
m_surface = VK_NULL_HANDLE;
|
|
}
|
|
|
|
destroyInstance();
|
|
}
|
|
|
|
void VulkanContext::initVMA()
|
|
{
|
|
VmaAllocatorCreateInfo allocatorInfo = {};
|
|
allocatorInfo.physicalDevice = m_gpu;
|
|
allocatorInfo.device = m_device;
|
|
allocatorInfo.instance = m_instance;
|
|
|
|
if (m_graphicsSupportStates.bSupportRaytrace)
|
|
{
|
|
allocatorInfo.flags |= VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT;
|
|
}
|
|
|
|
vmaCreateAllocator(&allocatorInfo, &m_vma);
|
|
}
|
|
|
|
void VulkanContext::destroyVMA()
|
|
{
|
|
if (m_vma != VK_NULL_HANDLE)
|
|
{
|
|
vmaDestroyAllocator(m_vma);
|
|
}
|
|
}
|
|
|
|
void VulkanContext::initCommandPools()
|
|
{
|
|
VkCommandPoolCreateInfo poolInfo{};
|
|
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
|
poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
|
|
|
// Graphics command pools.
|
|
ASSERT(m_queues.graphcisQueues.size() > 2, "Your device too old and even don't support more than one graphics queue. Closing...");
|
|
poolInfo.queueFamilyIndex = m_queues.graphicsFamily;
|
|
|
|
m_majorGraphicsPool.queue = m_queues.graphcisQueues[0];
|
|
m_secondMajorGraphicsPool.queue = m_queues.graphcisQueues[1];
|
|
|
|
RHICheck(vkCreateCommandPool(m_device, &poolInfo, nullptr, &m_majorGraphicsPool.pool));
|
|
RHICheck(vkCreateCommandPool(m_device, &poolInfo, nullptr, &m_secondMajorGraphicsPool.pool));
|
|
|
|
// Other normal queue command pools init.
|
|
if (m_queues.graphcisQueues.size() > 2)
|
|
{
|
|
m_graphicsPools.resize(m_queues.graphcisQueues.size() - 2);
|
|
uint32_t index = 2;
|
|
for (auto& pool : m_graphicsPools)
|
|
{
|
|
pool.queue = m_queues.graphcisQueues[index];
|
|
RHICheck(vkCreateCommandPool(m_device, &poolInfo, nullptr, &pool.pool));
|
|
|
|
index++;
|
|
}
|
|
}
|
|
|
|
// Compute command pools.
|
|
ASSERT(m_queues.computeQueues.size() > 1, "Your device too old and even don't support more than one compute queue.");
|
|
poolInfo.queueFamilyIndex = m_queues.computeFamily;
|
|
m_majorComputePool.queue = m_queues.computeQueues[0];
|
|
RHICheck(vkCreateCommandPool(m_device, &poolInfo, nullptr, &m_majorComputePool.pool));
|
|
if (m_queues.computeQueues.size() > 1)
|
|
{
|
|
m_computePools.resize(m_queues.computeQueues.size() - 1);
|
|
uint32_t index = 1;
|
|
for (auto& pool : m_computePools)
|
|
{
|
|
pool.queue = m_queues.computeQueues[index];
|
|
RHICheck(vkCreateCommandPool(m_device, &poolInfo, nullptr, &pool.pool));
|
|
index++;
|
|
}
|
|
}
|
|
|
|
// Copy command pools.
|
|
poolInfo.queueFamilyIndex = m_queues.copyFamily;
|
|
if (m_queues.copyQueues.size() > 0)
|
|
{
|
|
m_copyPools.resize(m_queues.copyQueues.size());
|
|
uint32_t index = 0;
|
|
for (auto& pool : m_copyPools)
|
|
{
|
|
pool.queue = m_queues.copyQueues[index];
|
|
RHICheck(vkCreateCommandPool(m_device, &poolInfo, nullptr, &pool.pool));
|
|
index++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void VulkanContext::destroyCommandPools()
|
|
{
|
|
// 1.0 priority queue.
|
|
vkDestroyCommandPool(m_device, m_majorGraphicsPool.pool, nullptr);
|
|
|
|
// 0.8 priority queue.
|
|
vkDestroyCommandPool(m_device, m_majorComputePool.pool, nullptr);
|
|
vkDestroyCommandPool(m_device, m_secondMajorGraphicsPool.pool, nullptr);
|
|
|
|
// 0.5 priority queues.
|
|
for (auto& pool : m_graphicsPools)
|
|
{
|
|
vkDestroyCommandPool(m_device, pool.pool, nullptr);
|
|
}
|
|
for (auto& pool : m_computePools)
|
|
{
|
|
vkDestroyCommandPool(m_device, pool.pool, nullptr);
|
|
}
|
|
for (auto& pool : m_copyPools)
|
|
{
|
|
vkDestroyCommandPool(m_device, pool.pool, nullptr);
|
|
}
|
|
}
|
|
|
|
void VulkanContext::setResourceName(VkObjectType objectType, uint64_t handle, const char* name) const
|
|
{
|
|
if (!cVarRHIDebugMarkerEnable.get())
|
|
{
|
|
return;
|
|
}
|
|
|
|
static PFN_vkSetDebugUtilsObjectNameEXT setDebugUtilsObjectName = (PFN_vkSetDebugUtilsObjectNameEXT)vkGetDeviceProcAddr(m_device, "vkSetDebugUtilsObjectNameEXT");
|
|
static std::mutex gMutexForSetResource;
|
|
|
|
if (setDebugUtilsObjectName && handle && name)
|
|
{
|
|
std::unique_lock<std::mutex> lock(gMutexForSetResource);
|
|
|
|
VkDebugUtilsObjectNameInfoEXT nameInfo = {};
|
|
nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
|
|
nameInfo.objectType = objectType;
|
|
nameInfo.objectHandle = handle;
|
|
nameInfo.pObjectName = name;
|
|
|
|
setDebugUtilsObjectName(m_device, &nameInfo);
|
|
}
|
|
}
|
|
|
|
void VulkanContext::setPerfMarkerBegin(VkCommandBuffer cmdBuf, const char* name, const math::vec4& color) const
|
|
{
|
|
if (!cVarRHIDebugMarkerEnable.get())
|
|
{
|
|
return;
|
|
}
|
|
|
|
static PFN_vkCmdBeginDebugUtilsLabelEXT cmdBeginDebugUtilsLabel = (PFN_vkCmdBeginDebugUtilsLabelEXT)vkGetDeviceProcAddr(m_device, "vkCmdBeginDebugUtilsLabelEXT");
|
|
if (cmdBeginDebugUtilsLabel)
|
|
{
|
|
VkDebugUtilsLabelEXT label = {};
|
|
label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
|
|
label.pLabelName = name;
|
|
label.color[0] = color.r;
|
|
label.color[1] = color.g;
|
|
label.color[2] = color.b;
|
|
label.color[3] = color.a;
|
|
cmdBeginDebugUtilsLabel(cmdBuf, &label);
|
|
}
|
|
}
|
|
|
|
VkPipelineLayout VulkanContext::createPipelineLayout(const VkPipelineLayoutCreateInfo& info)
|
|
{
|
|
VkPipelineLayout layout;
|
|
RHICheck(vkCreatePipelineLayout(m_device, &info, nullptr, &layout));
|
|
return layout;
|
|
}
|
|
|
|
void VulkanContext::setPerfMarkerEnd(VkCommandBuffer cmdBuf) const
|
|
{
|
|
if (!cVarRHIDebugMarkerEnable.get())
|
|
{
|
|
return;
|
|
}
|
|
|
|
static PFN_vkCmdEndDebugUtilsLabelEXT cmdEndDebugUtilsLabel = (PFN_vkCmdEndDebugUtilsLabelEXT)vkGetDeviceProcAddr(m_device, "vkCmdEndDebugUtilsLabelEXT");
|
|
|
|
if (cmdEndDebugUtilsLabel)
|
|
{
|
|
cmdEndDebugUtilsLabel(cmdBuf);
|
|
}
|
|
}
|
|
|
|
VkCommandBuffer VulkanContext::createMajorGraphicsCommandBuffer()
|
|
{
|
|
VkCommandBufferAllocateInfo info{};
|
|
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
|
info.commandBufferCount = 1;
|
|
info.commandPool = getMajorGraphicsCommandPool();
|
|
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
|
|
|
VkCommandBuffer newBuffer;
|
|
RHICheck(vkAllocateCommandBuffers(m_device, &info, &newBuffer));
|
|
|
|
return newBuffer;
|
|
}
|
|
|
|
void VulkanContext::freeMajorGraphicsCommandBuffer(VkCommandBuffer cmd)
|
|
{
|
|
vkFreeCommandBuffers(m_device, getMajorGraphicsCommandPool(), 1, &cmd);
|
|
}
|
|
|
|
void VulkanContext::executeImmediately(VkCommandPool commandPool, VkQueue queue, std::function<void(VkCommandBuffer cb)>&& func) const
|
|
{
|
|
VkCommandBufferAllocateInfo allocInfo{};
|
|
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
|
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
|
allocInfo.commandPool = commandPool;
|
|
allocInfo.commandBufferCount = 1;
|
|
|
|
VkCommandBuffer commandBuffer;
|
|
vkAllocateCommandBuffers(m_device, &allocInfo, &commandBuffer);
|
|
|
|
VkCommandBufferBeginInfo beginInfo{};
|
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
|
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
|
vkBeginCommandBuffer(commandBuffer, &beginInfo);
|
|
func(commandBuffer);
|
|
|
|
vkEndCommandBuffer(commandBuffer);
|
|
VkSubmitInfo submitInfo{};
|
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
|
submitInfo.commandBufferCount = 1;
|
|
submitInfo.pCommandBuffers = &commandBuffer;
|
|
vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE);
|
|
vkQueueWaitIdle(queue);
|
|
vkFreeCommandBuffers(m_device, commandPool, 1, &commandBuffer);
|
|
}
|
|
|
|
void VulkanContext::executeImmediatelyMajorGraphics(std::function<void(VkCommandBuffer cb)>&& func) const
|
|
{
|
|
executeImmediately(getMajorGraphicsCommandPool(), getMajorGraphicsQueue(), std::move(func));
|
|
}
|
|
|
|
DescriptorFactory VulkanContext::descriptorFactoryBegin()
|
|
{
|
|
return DescriptorFactory::begin(&m_descriptorLayoutCache, &m_descriptorAllocator);
|
|
}
|
|
|
|
UUID VulkanContext::getBuiltEngineAssetUUID(EBuiltinEngineAsset type)
|
|
{
|
|
#define CASE_STR(X) case EBuiltinEngineAsset::X: return "EBuiltinEngineAsset::"#X;
|
|
|
|
switch (type)
|
|
{
|
|
CASE_STR(Texture_White)
|
|
CASE_STR(Texture_Grey)
|
|
CASE_STR(Texture_Black)
|
|
CASE_STR(Texture_Translucent)
|
|
CASE_STR(Texture_Normal)
|
|
CASE_STR(Texture_Specular)
|
|
CASE_STR(Texture_CloudWeather)
|
|
CASE_STR(Texture_CurlNoise)
|
|
CASE_STR(Texture_Noise)
|
|
CASE_STR(Texture_Sky3d)
|
|
CASE_STR(Texture_SkinLut)
|
|
CASE_STR(Texture_SkinLutShadow)
|
|
CASE_STR(StaticMesh_Box)
|
|
CASE_STR(StaticMesh_Sphere)
|
|
}
|
|
|
|
// Non-implement check.
|
|
CHECK_ENTRY();
|
|
return {};
|
|
#undef CASE_STR
|
|
}
|
|
|
|
void VulkanContext::insertEngineAsset(const UUID& uuid, std::shared_ptr<LRUAssetInterface> asset)
|
|
{
|
|
ASSERT(!m_engineAssets.contains(uuid), "Engine asset insert repeat with same uuid!");
|
|
m_engineAssets[uuid] = asset;
|
|
}
|
|
|
|
void VulkanContext::insertLRUAsset(const UUID& uuid, std::shared_ptr<LRUAssetInterface> asset)
|
|
{
|
|
m_lru->insert(uuid, asset);
|
|
}
|
|
|
|
void VulkanContext::initEngineAssets()
|
|
{
|
|
m_uploader->addTask(RawAssetTextureLoadTask::buildEngineFlatTexture(
|
|
this,
|
|
"EngineWhite",
|
|
getBuiltEngineAssetUUID(EBuiltinEngineAsset::Texture_White),
|
|
{ 255, 255, 255, 255 }
|
|
));
|
|
|
|
m_uploader->addTask(RawAssetTextureLoadTask::buildEngineFlatTexture(
|
|
this,
|
|
"EngineGray",
|
|
getBuiltEngineAssetUUID(EBuiltinEngineAsset::Texture_Grey),
|
|
{ 128, 128, 128, 255 }
|
|
));
|
|
|
|
m_uploader->addTask(RawAssetTextureLoadTask::buildEngineFlatTexture(
|
|
this,
|
|
"EngineBlack",
|
|
getBuiltEngineAssetUUID(EBuiltinEngineAsset::Texture_Black),
|
|
{ 0,0,0,255 }
|
|
));
|
|
|
|
m_uploader->addTask(RawAssetTextureLoadTask::buildEngineFlatTexture(
|
|
this,
|
|
"EngineTranslucent",
|
|
getBuiltEngineAssetUUID(EBuiltinEngineAsset::Texture_Translucent),
|
|
{ 0,0,0,0 }
|
|
));
|
|
|
|
m_uploader->addTask(RawAssetTextureLoadTask::buildEngineFlatTexture(
|
|
this,
|
|
"EngineNormal",
|
|
getBuiltEngineAssetUUID(EBuiltinEngineAsset::Texture_Normal),
|
|
{ 125,130,255,0 }
|
|
));
|
|
|
|
m_uploader->addTask(RawAssetTextureLoadTask::buildEngineFlatTexture(
|
|
this,
|
|
"EngineSpecular",
|
|
getBuiltEngineAssetUUID(EBuiltinEngineAsset::Texture_Specular),
|
|
{ 255, 255, 0, 0 }
|
|
));
|
|
|
|
m_uploader->addTask(RawAssetTextureLoadTask::buildTexture(
|
|
true,
|
|
this,
|
|
"./image/T_WeatherTexture.tga",
|
|
getBuiltEngineAssetUUID(EBuiltinEngineAsset::Texture_CloudWeather),
|
|
VK_FORMAT_R8G8B8A8_UNORM,
|
|
false
|
|
));
|
|
|
|
m_uploader->addTask(RawAssetTextureLoadTask::buildTexture(
|
|
true,
|
|
this,
|
|
"./image/T_CurlNoise.png",
|
|
getBuiltEngineAssetUUID(EBuiltinEngineAsset::Texture_CurlNoise),
|
|
VK_FORMAT_R8G8B8A8_UNORM,
|
|
false
|
|
));
|
|
m_uploader->addTask(RawAssetTextureLoadTask::buildTexture(
|
|
true,
|
|
this,
|
|
"./image/T_Noise.png",
|
|
getBuiltEngineAssetUUID(EBuiltinEngineAsset::Texture_Noise),
|
|
VK_FORMAT_R8G8B8A8_UNORM,
|
|
false
|
|
));
|
|
|
|
m_uploader->addTask(RawAssetTextureLoadTask::buildTexture(
|
|
true,
|
|
this,
|
|
"./image/skinLut.png",
|
|
getBuiltEngineAssetUUID(EBuiltinEngineAsset::Texture_SkinLut),
|
|
VK_FORMAT_R8G8B8A8_UNORM,
|
|
false
|
|
));
|
|
|
|
m_uploader->addTask(RawAssetTextureLoadTask::buildTexture(
|
|
true,
|
|
this,
|
|
"./image/shadowLUT.bmp",
|
|
getBuiltEngineAssetUUID(EBuiltinEngineAsset::Texture_SkinLutShadow),
|
|
VK_FORMAT_R8G8B8A8_UNORM,
|
|
false
|
|
));
|
|
|
|
m_uploader->addTask(RawAssetTextureLoadTask::buildEngine3dTexture(
|
|
this,
|
|
"./image/T_Sky.texture3d",
|
|
getBuiltEngineAssetUUID(EBuiltinEngineAsset::Texture_Sky3d),
|
|
VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
{ 256, 128, 33 }
|
|
));
|
|
|
|
m_uploader->addTask(AssetRawStaticMeshLoadTask::buildFromPath(
|
|
this,
|
|
"./staticmesh/box.obj",
|
|
getBuiltEngineAssetUUID(EBuiltinEngineAsset::StaticMesh_Box),
|
|
m_engineMeshBounds[getBuiltEngineAssetUUID(EBuiltinEngineAsset::StaticMesh_Box)]
|
|
));
|
|
|
|
m_uploader->addTask(AssetRawStaticMeshLoadTask::buildFromPath(
|
|
this,
|
|
"./staticmesh/sphere.obj",
|
|
getBuiltEngineAssetUUID(EBuiltinEngineAsset::StaticMesh_Sphere),
|
|
m_engineMeshBounds[getBuiltEngineAssetUUID(EBuiltinEngineAsset::StaticMesh_Sphere)]
|
|
));
|
|
|
|
m_uploader->flushTask();
|
|
|
|
if (getGraphicsCardState().bSupportRaytrace)
|
|
{
|
|
for (size_t i = ((size_t)EBuiltinEngineAsset::StaticMesh_Min + 1);
|
|
i < size_t(EBuiltinEngineAsset::StaticMesh_Max); i++)
|
|
{
|
|
auto mesh = std::static_pointer_cast<GPUStaticMeshAsset>(getEngineAsset((EBuiltinEngineAsset)i));
|
|
mesh->getOrBuilddBLAS();
|
|
}
|
|
}
|
|
}
|
|
|
|
std::shared_ptr<LRUAssetInterface> engine::VulkanContext::getEngineAsset(EBuiltinEngineAsset asset) const
|
|
{
|
|
return m_engineAssets.at(getBuiltEngineAssetUUID(asset));
|
|
}
|
|
|
|
std::shared_ptr<LRUAssetInterface> VulkanContext::getEngineAsset(const UUID& uuid) const
|
|
{
|
|
return m_engineAssets.at(uuid);
|
|
}
|
|
|
|
std::shared_ptr<GPUStaticMeshAsset> VulkanContext::getOrCreateStaticMeshAsset(const UUID& uuid)
|
|
{
|
|
if (m_engineAssets.contains(uuid))
|
|
{
|
|
return std::dynamic_pointer_cast<GPUStaticMeshAsset>(m_engineAssets.at(uuid));
|
|
}
|
|
|
|
if (!m_lru->contain(uuid))
|
|
{
|
|
auto asset = std::dynamic_pointer_cast<AssetStaticMesh>(getAssetSystem()->getAsset(uuid));
|
|
auto newTask = AssetStaticMeshLoadFromCacheTask::build(getContext(), asset);
|
|
m_uploader->addTask(newTask);
|
|
}
|
|
|
|
return std::dynamic_pointer_cast<GPUStaticMeshAsset>(m_lru->tryGet(uuid));
|
|
}
|
|
|
|
std::shared_ptr<GPUImageAsset> VulkanContext::getOrCreateTextureAsset(const UUID& uuid)
|
|
{
|
|
if (m_engineAssets.contains(uuid))
|
|
{
|
|
return std::dynamic_pointer_cast<GPUImageAsset>(m_engineAssets.at(uuid));
|
|
}
|
|
|
|
if (!m_lru->contain(uuid))
|
|
{
|
|
auto asset = std::dynamic_pointer_cast<AssetTexture>(getAssetSystem()->getAsset(uuid));
|
|
auto newTask = AssetTextureCacheLoadTask::build(getContext(), asset);
|
|
m_uploader->addTask(newTask);
|
|
}
|
|
|
|
return std::dynamic_pointer_cast<GPUImageAsset>(m_lru->tryGet(uuid));
|
|
}
|
|
|
|
void VulkanContext::waitDeviceIdle() const
|
|
{
|
|
m_uploader->flushTask();
|
|
vkDeviceWaitIdle(m_device);
|
|
}
|
|
|
|
VulkanContext* getContext()
|
|
{
|
|
static VulkanContext* context = Framework::get()->getEngine().getRuntimeModule<VulkanContext>();
|
|
return context;
|
|
}
|
|
|
|
void VulkanContext::pushDescriptorSet(
|
|
VkCommandBuffer commandBuffer,
|
|
VkPipelineBindPoint pipelineBindPoint,
|
|
VkPipelineLayout layout,
|
|
uint32_t set,
|
|
uint32_t descriptorWriteCount,
|
|
const VkWriteDescriptorSet* pDescriptorWrites)
|
|
{
|
|
static auto pushDescriptorSetKHR = (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(m_device, "vkCmdPushDescriptorSetKHR");
|
|
|
|
|
|
pushDescriptorSetKHR(commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount, pDescriptorWrites);
|
|
}
|
|
|
|
void VulkanContext::pushGpuResourceAsPendingKill(std::shared_ptr<GpuResource> asset)
|
|
{
|
|
m_gpuResourcePending[m_presentContext.currentFrame].push_back(asset);
|
|
}
|
|
} |