revert
parent
20a30d9192
commit
a0b8b66f2b
|
@ -120,6 +120,7 @@ namespace vks
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the index of a queue family that supports the requested queue flags
|
||||
*
|
||||
|
|
|
@ -132,7 +132,7 @@ void VulkanExampleBase::prepare()
|
|||
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
attachments[0].finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
|
||||
// This is the frame buffer attachment to where the multisampled image
|
||||
// will be resolved to and which will be presented to the swapchain
|
||||
|
@ -143,8 +143,15 @@ void VulkanExampleBase::prepare()
|
|||
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
attachments[1].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
|
||||
if (settings.headless)
|
||||
{
|
||||
attachments[1].finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
attachments[1].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
}
|
||||
|
||||
// Multisampled depth attachment we render to
|
||||
attachments[2].format = depthFormat;
|
||||
attachments[2].samples = settings.sampleCount;
|
||||
|
@ -214,30 +221,39 @@ void VulkanExampleBase::prepare()
|
|||
renderPassCI.pDependencies = dependencies.data();
|
||||
VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassCI, nullptr, &renderPass));
|
||||
}
|
||||
else {
|
||||
std::array<VkAttachmentDescription, 2> attachments = {};
|
||||
else
|
||||
{
|
||||
std::array<VkAttachmentDescription, 2> attachmentDescriptions = {};
|
||||
// Color attachment
|
||||
attachments[0].format = swapChain.colorFormat;
|
||||
attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
attachments[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
attachmentDescriptions[0].format = swapChain.colorFormat;
|
||||
attachmentDescriptions[0].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
attachmentDescriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
attachmentDescriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachmentDescriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
attachmentDescriptions[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
attachmentDescriptions[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
if (settings.headless)
|
||||
{
|
||||
attachmentDescriptions[0].finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
attachmentDescriptions[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
}
|
||||
// Depth attachment
|
||||
attachments[1].format = depthFormat;
|
||||
attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
attachmentDescriptions[1].format = depthFormat;
|
||||
attachmentDescriptions[1].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
attachmentDescriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
attachmentDescriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachmentDescriptions[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
attachmentDescriptions[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
attachmentDescriptions[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
attachmentDescriptions[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
|
||||
VkAttachmentReference colorReference = {};
|
||||
colorReference.attachment = 0;
|
||||
colorReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
|
||||
VkAttachmentReference depthReference = {};
|
||||
depthReference.attachment = 1;
|
||||
|
@ -275,13 +291,16 @@ void VulkanExampleBase::prepare()
|
|||
|
||||
VkRenderPassCreateInfo renderPassCI{};
|
||||
renderPassCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
renderPassCI.attachmentCount = static_cast<uint32_t>(attachments.size());
|
||||
renderPassCI.pAttachments = attachments.data();
|
||||
renderPassCI.attachmentCount = static_cast<uint32_t>(attachmentDescriptions.size());
|
||||
renderPassCI.pAttachments = attachmentDescriptions.data();
|
||||
renderPassCI.subpassCount = 1;
|
||||
renderPassCI.pSubpasses = &subpassDescription;
|
||||
renderPassCI.dependencyCount = static_cast<uint32_t>(dependencies.size());
|
||||
renderPassCI.pDependencies = dependencies.data();
|
||||
VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassCI, nullptr, &renderPass));
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -299,189 +318,6 @@ void VulkanExampleBase::prepare()
|
|||
|
||||
void VulkanExampleBase::fileDropped(std::string filename) { }
|
||||
|
||||
void VulkanExampleBase::renderFrame()
|
||||
{
|
||||
auto tStart = std::chrono::high_resolution_clock::now();
|
||||
|
||||
render();
|
||||
frameCounter++;
|
||||
auto tEnd = std::chrono::high_resolution_clock::now();
|
||||
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
||||
frameTimer = (float)tDiff / 1000.0f;
|
||||
camera.update(frameTimer);
|
||||
fpsTimer += (float)tDiff;
|
||||
if (fpsTimer > 1000.0f) {
|
||||
lastFPS = static_cast<uint32_t>((float)frameCounter * (1000.0f / fpsTimer));
|
||||
fpsTimer = 0.0f;
|
||||
frameCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanExampleBase::renderLoop()
|
||||
{
|
||||
destWidth = width;
|
||||
destHeight = height;
|
||||
#if defined(_WIN32)
|
||||
MSG msg;
|
||||
bool quitMessageReceived = false;
|
||||
while (!quitMessageReceived) {
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
if (msg.message == WM_QUIT) {
|
||||
quitMessageReceived = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!IsIconic(window)) {
|
||||
renderFrame();
|
||||
}
|
||||
}
|
||||
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||
while (1)
|
||||
{
|
||||
int ident;
|
||||
int events;
|
||||
struct android_poll_source* source;
|
||||
bool destroy = false;
|
||||
|
||||
focused = true;
|
||||
|
||||
while ((ident = ALooper_pollAll(focused ? 0 : -1, NULL, &events, (void**)&source)) >= 0)
|
||||
{
|
||||
if (source != NULL)
|
||||
{
|
||||
source->process(androidApp, source);
|
||||
}
|
||||
if (androidApp->destroyRequested != 0)
|
||||
{
|
||||
LOGD("Android app destroy requested");
|
||||
destroy = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// App destruction requested
|
||||
// Exit loop, example will be destroyed in application main
|
||||
if (destroy)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Render frame
|
||||
if (prepared)
|
||||
{
|
||||
auto tStart = std::chrono::high_resolution_clock::now();
|
||||
render();
|
||||
frameCounter++;
|
||||
auto tEnd = std::chrono::high_resolution_clock::now();
|
||||
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
||||
frameTimer = tDiff / 1000.0f;
|
||||
camera.update(frameTimer);
|
||||
fpsTimer += (float)tDiff;
|
||||
if (fpsTimer > 1000.0f)
|
||||
{
|
||||
lastFPS = (float)frameCounter * (1000.0f / fpsTimer);
|
||||
fpsTimer = 0.0f;
|
||||
frameCounter = 0;
|
||||
}
|
||||
|
||||
// Check gamepad state
|
||||
const float deadZone = 0.0015f;
|
||||
// todo : check if gamepad is present
|
||||
// todo : time based and relative axis positions
|
||||
if (camera.type != Camera::CameraType::firstperson)
|
||||
{
|
||||
// Rotate
|
||||
if (std::abs(gamePadState.axisLeft.x) > deadZone) {
|
||||
camera.rotate(glm::vec3(0.0f, gamePadState.axisLeft.x * 0.5f, 0.0f));
|
||||
}
|
||||
if (std::abs(gamePadState.axisLeft.y) > deadZone) {
|
||||
camera.rotate(glm::vec3(gamePadState.axisLeft.y * 0.5f, 0.0f, 0.0f));
|
||||
}
|
||||
} else {
|
||||
camera.updatePad(gamePadState.axisLeft, gamePadState.axisRight, frameTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined(_DIRECT2DISPLAY)
|
||||
while (!quit)
|
||||
{
|
||||
auto tStart = std::chrono::high_resolution_clock::now();
|
||||
render();
|
||||
frameCounter++;
|
||||
auto tEnd = std::chrono::high_resolution_clock::now();
|
||||
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
||||
frameTimer = tDiff / 1000.0f;
|
||||
camera.update(frameTimer);
|
||||
fpsTimer += (float)tDiff;
|
||||
if (fpsTimer > 1000.0f)
|
||||
{
|
||||
lastFPS = (float)frameCounter * (1000.0f / fpsTimer);
|
||||
fpsTimer = 0.0f;
|
||||
frameCounter = 0;
|
||||
}
|
||||
}
|
||||
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
while (!quit)
|
||||
{
|
||||
auto tStart = std::chrono::high_resolution_clock::now();
|
||||
|
||||
while (wl_display_prepare_read(display) != 0)
|
||||
wl_display_dispatch_pending(display);
|
||||
wl_display_flush(display);
|
||||
wl_display_read_events(display);
|
||||
wl_display_dispatch_pending(display);
|
||||
|
||||
render();
|
||||
frameCounter++;
|
||||
auto tEnd = std::chrono::high_resolution_clock::now();
|
||||
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
||||
frameTimer = tDiff / 1000.0f;
|
||||
camera.update(frameTimer);
|
||||
fpsTimer += (float)tDiff;
|
||||
if (fpsTimer > 1000.0f)
|
||||
{
|
||||
wl_shell_surface_set_title(shell_surface, title.c_str());
|
||||
lastFPS = (float)frameCounter * (1000.0f / fpsTimer);
|
||||
fpsTimer = 0.0f;
|
||||
frameCounter = 0;
|
||||
}
|
||||
}
|
||||
#elif defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
xcb_flush(connection);
|
||||
while (!quit)
|
||||
{
|
||||
auto tStart = std::chrono::high_resolution_clock::now();
|
||||
xcb_generic_event_t *event;
|
||||
while ((event = xcb_poll_for_event(connection)))
|
||||
{
|
||||
handleEvent(event);
|
||||
free(event);
|
||||
}
|
||||
render();
|
||||
frameCounter++;
|
||||
auto tEnd = std::chrono::high_resolution_clock::now();
|
||||
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
||||
frameTimer = tDiff / 1000.0f;
|
||||
camera.update(frameTimer);
|
||||
fpsTimer += (float)tDiff;
|
||||
if (fpsTimer > 1000.0f)
|
||||
{
|
||||
xcb_change_property(connection, XCB_PROP_MODE_REPLACE,
|
||||
window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8,
|
||||
title.size(), title.c_str());
|
||||
lastFPS = (float)frameCounter * (1000.0f / fpsTimer);
|
||||
fpsTimer = 0.0f;
|
||||
frameCounter = 0;
|
||||
}
|
||||
}
|
||||
#elif defined(VK_USE_PLATFORM_MACOS_MVK)
|
||||
[NSApp run];
|
||||
#endif
|
||||
// Flush device to make sure all resources can be freed
|
||||
vkDeviceWaitIdle(device);
|
||||
}
|
||||
|
||||
VulkanExampleBase::VulkanExampleBase()
|
||||
{
|
||||
|
@ -539,9 +375,9 @@ VulkanExampleBase::~VulkanExampleBase()
|
|||
for (uint32_t i = 0; i < frameBuffers.size(); i++) {
|
||||
vkDestroyFramebuffer(device, frameBuffers[i], nullptr);
|
||||
}
|
||||
vkDestroyImageView(device, depthStencil.view, nullptr);
|
||||
vkDestroyImage(device, depthStencil.image, nullptr);
|
||||
vkFreeMemory(device, depthStencil.mem, nullptr);
|
||||
vkDestroyImageView(device, depthAttachment.view, nullptr);
|
||||
vkDestroyImage(device, depthAttachment.image, nullptr);
|
||||
vkFreeMemory(device, depthAttachment.memory, nullptr);
|
||||
vkDestroyPipelineCache(device, pipelineCache, nullptr);
|
||||
vkDestroyCommandPool(device, cmdPool, nullptr);
|
||||
if (settings.multiSampling) {
|
||||
|
@ -1822,8 +1658,9 @@ void VulkanExampleBase::setupFrameBuffer()
|
|||
imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
imageCI.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
imageCI.samples = settings.sampleCount;
|
||||
imageCI.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
imageCI.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
VK_CHECK_RESULT(vkCreateImage(device, &imageCI, nullptr, &multisampleTarget.color.image));
|
||||
|
||||
VkMemoryRequirements memReqs;
|
||||
|
@ -1891,65 +1728,140 @@ void VulkanExampleBase::setupFrameBuffer()
|
|||
imageViewCI.subresourceRange.levelCount = 1;
|
||||
imageViewCI.subresourceRange.layerCount = 1;
|
||||
VK_CHECK_RESULT(vkCreateImageView(device, &imageViewCI, nullptr, &multisampleTarget.depth.view));
|
||||
|
||||
VkImageCreateInfo image = {};
|
||||
image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
image.pNext = NULL;
|
||||
image.imageType = VK_IMAGE_TYPE_2D;
|
||||
image.format = depthFormat;
|
||||
image.extent = { width, height, 1 };
|
||||
image.mipLevels = 1;
|
||||
image.arrayLayers = 1;
|
||||
image.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
image.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
image.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
image.flags = 0;
|
||||
|
||||
VkMemoryAllocateInfo mem_alloc = {};
|
||||
mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
mem_alloc.pNext = NULL;
|
||||
mem_alloc.allocationSize = 0;
|
||||
mem_alloc.memoryTypeIndex = 0;
|
||||
|
||||
VkImageViewCreateInfo depthStencilView = {};
|
||||
depthStencilView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
depthStencilView.pNext = NULL;
|
||||
depthStencilView.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
depthStencilView.format = depthFormat;
|
||||
depthStencilView.flags = 0;
|
||||
depthStencilView.subresourceRange = {};
|
||||
depthStencilView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
depthStencilView.subresourceRange.baseMipLevel = 0;
|
||||
depthStencilView.subresourceRange.levelCount = 1;
|
||||
depthStencilView.subresourceRange.baseArrayLayer = 0;
|
||||
depthStencilView.subresourceRange.layerCount = 1;
|
||||
|
||||
|
||||
VK_CHECK_RESULT(vkCreateImage(device, &image, nullptr, &depthAttachment.image));
|
||||
vkGetImageMemoryRequirements(device, depthAttachment.image, &memReqs);
|
||||
mem_alloc.allocationSize = memReqs.size;
|
||||
mem_alloc.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
VK_CHECK_RESULT(vkAllocateMemory(device, &mem_alloc, nullptr, &depthAttachment.memory));
|
||||
VK_CHECK_RESULT(vkBindImageMemory(device, depthAttachment.image, depthAttachment.memory, 0));
|
||||
|
||||
depthStencilView.image = depthAttachment.image;
|
||||
VK_CHECK_RESULT(vkCreateImageView(device, &depthStencilView, nullptr, &depthAttachment.view));
|
||||
}
|
||||
else // color attachment when MSAA is no enabled
|
||||
{
|
||||
VkFormat colorFormat = VK_FORMAT_B8G8R8A8_SRGB;
|
||||
VkFormat depthFormat;
|
||||
vks::tools::getSupportedDepthFormat(physicalDevice, &depthFormat);
|
||||
|
||||
// Color attachment
|
||||
VkImageCreateInfo image = vks::initializers::imageCreateInfo();
|
||||
image.imageType = VK_IMAGE_TYPE_2D;
|
||||
image.format = colorFormat;
|
||||
image.extent.width = width;
|
||||
image.extent.height = height;
|
||||
image.extent.depth = 1;
|
||||
image.mipLevels = 1;
|
||||
image.arrayLayers = 1;
|
||||
image.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
image.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
image.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
|
||||
VkMemoryAllocateInfo memAlloc = vks::initializers::memoryAllocateInfo();
|
||||
VkMemoryRequirements memReqs;
|
||||
|
||||
VK_CHECK_RESULT(vkCreateImage(device, &image, nullptr, &colorAttachment.image));
|
||||
vkGetImageMemoryRequirements(device, colorAttachment.image, &memReqs);
|
||||
memAlloc.allocationSize = memReqs.size;
|
||||
memAlloc.memoryTypeIndex = vulkanDevice -> getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, &colorAttachment.memory));
|
||||
VK_CHECK_RESULT(vkBindImageMemory(device, colorAttachment.image, colorAttachment.memory, 0));
|
||||
|
||||
VkImageViewCreateInfo colorImageView = vks::initializers::imageViewCreateInfo();
|
||||
colorImageView.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
colorImageView.format = colorFormat;
|
||||
colorImageView.subresourceRange = {};
|
||||
colorImageView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
colorImageView.subresourceRange.baseMipLevel = 0;
|
||||
colorImageView.subresourceRange.levelCount = 1;
|
||||
colorImageView.subresourceRange.baseArrayLayer = 0;
|
||||
colorImageView.subresourceRange.layerCount = 1;
|
||||
colorImageView.image = colorAttachment.image;
|
||||
VK_CHECK_RESULT(vkCreateImageView(device, &colorImageView, nullptr, &colorAttachment.view));
|
||||
|
||||
// Depth stencil attachment
|
||||
image.format = depthFormat;
|
||||
image.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
|
||||
VK_CHECK_RESULT(vkCreateImage(device, &image, nullptr, &depthAttachment.image));
|
||||
vkGetImageMemoryRequirements(device, depthAttachment.image, &memReqs);
|
||||
memAlloc.allocationSize = memReqs.size;
|
||||
memAlloc.memoryTypeIndex = vulkanDevice -> getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, &depthAttachment.memory));
|
||||
VK_CHECK_RESULT(vkBindImageMemory(device, depthAttachment.image, depthAttachment.memory, 0));
|
||||
|
||||
VkImageViewCreateInfo depthStencilView = vks::initializers::imageViewCreateInfo();
|
||||
depthStencilView.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
depthStencilView.format = depthFormat;
|
||||
depthStencilView.flags = 0;
|
||||
depthStencilView.subresourceRange = {};
|
||||
depthStencilView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
if (depthFormat >= VK_FORMAT_D16_UNORM_S8_UINT)
|
||||
depthStencilView.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
depthStencilView.subresourceRange.baseMipLevel = 0;
|
||||
depthStencilView.subresourceRange.levelCount = 1;
|
||||
depthStencilView.subresourceRange.baseArrayLayer = 0;
|
||||
depthStencilView.subresourceRange.layerCount = 1;
|
||||
depthStencilView.image = depthAttachment.image;
|
||||
VK_CHECK_RESULT(vkCreateImageView(device, &depthStencilView, nullptr, &depthAttachment.view));
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
if (settings.multiSampling)
|
||||
{
|
||||
i = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 2;
|
||||
}
|
||||
|
||||
// Depth/Stencil attachment is the same for all frame buffers
|
||||
|
||||
VkImageCreateInfo image = {};
|
||||
image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
image.pNext = NULL;
|
||||
image.imageType = VK_IMAGE_TYPE_2D;
|
||||
image.format = depthFormat;
|
||||
image.extent = { width, height, 1 };
|
||||
image.mipLevels = 1;
|
||||
image.arrayLayers = 1;
|
||||
image.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
image.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
image.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
image.flags = 0;
|
||||
|
||||
VkMemoryAllocateInfo mem_alloc = {};
|
||||
mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
mem_alloc.pNext = NULL;
|
||||
mem_alloc.allocationSize = 0;
|
||||
mem_alloc.memoryTypeIndex = 0;
|
||||
|
||||
VkImageViewCreateInfo depthStencilView = {};
|
||||
depthStencilView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
depthStencilView.pNext = NULL;
|
||||
depthStencilView.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
depthStencilView.format = depthFormat;
|
||||
depthStencilView.flags = 0;
|
||||
depthStencilView.subresourceRange = {};
|
||||
depthStencilView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
depthStencilView.subresourceRange.baseMipLevel = 0;
|
||||
depthStencilView.subresourceRange.levelCount = 1;
|
||||
depthStencilView.subresourceRange.baseArrayLayer = 0;
|
||||
depthStencilView.subresourceRange.layerCount = 1;
|
||||
|
||||
VkMemoryRequirements memReqs;
|
||||
VK_CHECK_RESULT(vkCreateImage(device, &image, nullptr, &depthStencil.image));
|
||||
vkGetImageMemoryRequirements(device, depthStencil.image, &memReqs);
|
||||
mem_alloc.allocationSize = memReqs.size;
|
||||
mem_alloc.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
VK_CHECK_RESULT(vkAllocateMemory(device, &mem_alloc, nullptr, &depthStencil.mem));
|
||||
VK_CHECK_RESULT(vkBindImageMemory(device, depthStencil.image, depthStencil.mem, 0));
|
||||
|
||||
depthStencilView.image = depthStencil.image;
|
||||
VK_CHECK_RESULT(vkCreateImageView(device, &depthStencilView, nullptr, &depthStencil.view));
|
||||
|
||||
//
|
||||
|
||||
VkImageView attachments[4];
|
||||
VkImageView attachments[i];
|
||||
|
||||
if (settings.multiSampling) {
|
||||
|
||||
attachments[0] = multisampleTarget.color.view;
|
||||
attachments[2] = multisampleTarget.depth.view;
|
||||
attachments[3] = depthStencil.view;
|
||||
attachments[3] = depthAttachment.view;
|
||||
}
|
||||
else {
|
||||
attachments[1] = depthStencil.view;
|
||||
|
||||
attachments[1] = depthAttachment.view;
|
||||
attachments[0] = colorAttachment.view;
|
||||
}
|
||||
|
||||
VkFramebufferCreateInfo frameBufferCI{};
|
||||
|
@ -1962,16 +1874,35 @@ void VulkanExampleBase::setupFrameBuffer()
|
|||
frameBufferCI.height = height;
|
||||
frameBufferCI.layers = 1;
|
||||
|
||||
// Create frame buffers for every swap chain image
|
||||
frameBuffers.resize(swapChain.imageCount);
|
||||
for (uint32_t i = 0; i < frameBuffers.size(); i++) {
|
||||
if (settings.multiSampling) {
|
||||
attachments[1] = swapChain.buffers[i].view;
|
||||
if (settings.headless && ! settings.multiSampling)
|
||||
{
|
||||
VkImageView attachments[2];
|
||||
attachments[0] = colorAttachment.view;
|
||||
attachments[1] = depthAttachment.view;
|
||||
|
||||
VkFramebufferCreateInfo framebufferCreateInfo = vks::initializers::framebufferCreateInfo();
|
||||
framebufferCreateInfo.renderPass = renderPass;
|
||||
framebufferCreateInfo.attachmentCount = 2;
|
||||
framebufferCreateInfo.pAttachments = attachments;
|
||||
framebufferCreateInfo.width = width;
|
||||
framebufferCreateInfo.height = height;
|
||||
framebufferCreateInfo.layers = 1;
|
||||
VK_CHECK_RESULT(vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &framebuffer));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create frame buffers for every swap chain image
|
||||
frameBuffers.resize(swapChain.imageCount);
|
||||
for (uint32_t i = 0; i < frameBuffers.size(); i++) {
|
||||
if (settings.multiSampling) {
|
||||
attachments[1] = swapChain.buffers[i].view;
|
||||
}
|
||||
else {
|
||||
attachments[0] = swapChain.buffers[i].view;
|
||||
}
|
||||
VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCI, nullptr, &frameBuffers[i]));
|
||||
}
|
||||
else {
|
||||
attachments[0] = swapChain.buffers[i].view;
|
||||
}
|
||||
VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCI, nullptr, &frameBuffers[i]));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1994,9 +1925,9 @@ void VulkanExampleBase::windowResize()
|
|||
vkDestroyImage(device, multisampleTarget.depth.image, nullptr);
|
||||
vkFreeMemory(device, multisampleTarget.depth.memory, nullptr);
|
||||
}
|
||||
vkDestroyImageView(device, depthStencil.view, nullptr);
|
||||
vkDestroyImage(device, depthStencil.image, nullptr);
|
||||
vkFreeMemory(device, depthStencil.mem, nullptr);
|
||||
vkDestroyImageView(device, depthAttachment.view, nullptr);
|
||||
vkDestroyImage(device, depthAttachment.image, nullptr);
|
||||
vkFreeMemory(device, depthAttachment.memory, nullptr);
|
||||
for (uint32_t i = 0; i < frameBuffers.size(); i++) {
|
||||
vkDestroyFramebuffer(device, frameBuffers[i], nullptr);
|
||||
}
|
||||
|
|
|
@ -58,16 +58,7 @@
|
|||
|
||||
class VulkanExampleBase
|
||||
{
|
||||
private:
|
||||
float fpsTimer = 0.0f;
|
||||
uint32_t frameCounter = 0;
|
||||
uint32_t destWidth;
|
||||
uint32_t destHeight;
|
||||
bool resizing = false;
|
||||
void handleMouseMove(int32_t x, int32_t y);
|
||||
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallback;
|
||||
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallback;
|
||||
VkDebugReportCallbackEXT debugReportCallback;
|
||||
public:
|
||||
struct MultisampleTarget {
|
||||
struct {
|
||||
VkImage image;
|
||||
|
@ -80,6 +71,17 @@ private:
|
|||
VkDeviceMemory memory;
|
||||
} depth;
|
||||
} multisampleTarget;
|
||||
|
||||
private:
|
||||
|
||||
uint32_t destWidth;
|
||||
uint32_t destHeight;
|
||||
bool resizing = false;
|
||||
void handleMouseMove(int32_t x, int32_t y);
|
||||
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallback;
|
||||
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallback;
|
||||
VkDebugReportCallbackEXT debugReportCallback;
|
||||
|
||||
protected:
|
||||
VkInstance instance;
|
||||
VkPhysicalDevice physicalDevice;
|
||||
|
@ -90,6 +92,7 @@ protected:
|
|||
vks::VulkanDevice *vulkanDevice;
|
||||
VkQueue queue;
|
||||
VkFormat depthFormat;
|
||||
VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
VkCommandPool cmdPool;
|
||||
VkRenderPass renderPass;
|
||||
std::vector<VkFramebuffer>frameBuffers;
|
||||
|
@ -106,25 +109,31 @@ public:
|
|||
bool prepared = false;
|
||||
uint32_t width = 1280;
|
||||
uint32_t height = 720;
|
||||
float frameTimer = 1.0f;
|
||||
Camera camera;
|
||||
glm::vec2 mousePos;
|
||||
bool paused = false;
|
||||
uint32_t lastFPS = 0;
|
||||
|
||||
struct Settings {
|
||||
bool validation = true;
|
||||
bool fullscreen = false;
|
||||
bool vsync = false;
|
||||
bool multiSampling = true;
|
||||
bool rotateModel = false;
|
||||
bool enableSaveToImageSequeue = false;
|
||||
uint32_t outputFrameCount = 50;
|
||||
bool takeScreenShot = false;
|
||||
bool headless = true;
|
||||
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT;
|
||||
} settings;
|
||||
|
||||
struct DepthStencil {
|
||||
|
||||
struct FrameBufferAttachment {
|
||||
VkImage image;
|
||||
VkDeviceMemory mem;
|
||||
VkDeviceMemory memory;
|
||||
VkImageView view;
|
||||
} depthStencil;
|
||||
};
|
||||
|
||||
FrameBufferAttachment colorAttachment, depthAttachment;
|
||||
VkFramebuffer framebuffer;
|
||||
|
||||
struct GamePadState {
|
||||
glm::vec2 axisLeft = glm::vec2(0.0f);
|
||||
|
|
|
@ -189,6 +189,9 @@ PlumageRender::PlumageRender()
|
|||
VK_CHECK_RESULT(vkEndCommandBuffer(currentCB));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -529,6 +532,7 @@ PlumageRender::PlumageRender()
|
|||
rasterizationStateCI.cullMode = VK_CULL_MODE_BACK_BIT;
|
||||
rasterizationStateCI.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
rasterizationStateCI.lineWidth = 1.0f;
|
||||
|
||||
|
||||
VkPipelineColorBlendAttachmentState blendAttachmentState{};
|
||||
blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
|
@ -558,6 +562,10 @@ PlumageRender::PlumageRender()
|
|||
if (settings.multiSampling) {
|
||||
multisampleStateCI.rasterizationSamples = settings.sampleCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
multisampleStateCI.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
}
|
||||
|
||||
std::vector<VkDynamicState> dynamicStateEnables = {
|
||||
VK_DYNAMIC_STATE_VIEWPORT,
|
||||
|
@ -619,9 +627,7 @@ PlumageRender::PlumageRender()
|
|||
pipelineCI.stageCount = static_cast<uint32_t>(shaderStages.size());
|
||||
pipelineCI.pStages = shaderStages.data();
|
||||
|
||||
if (settings.multiSampling) {
|
||||
multisampleStateCI.rasterizationSamples = settings.sampleCount;
|
||||
}
|
||||
|
||||
|
||||
// Skybox pipeline (background cube)
|
||||
shaderStages = {
|
||||
|
@ -1578,29 +1584,23 @@ PlumageRender::PlumageRender()
|
|||
prepared = true;
|
||||
}
|
||||
|
||||
void PlumageRender::submitWork(VkCommandBuffer cmdBuffer, VkQueue queue)
|
||||
void PlumageRender::submitWork(VkCommandBuffer cmdBuffer, VkQueue queue, VkFence fence)
|
||||
{
|
||||
VkSubmitInfo submitInfo = vks::initializers::submitInfo();
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &cmdBuffer;
|
||||
VkFenceCreateInfo fenceInfo = vks::initializers::fenceCreateInfo();
|
||||
VkFence fence;
|
||||
VK_CHECK_RESULT(vkCreateFence(device, &fenceInfo, nullptr, &fence));
|
||||
VK_CHECK_RESULT(vkResetFences(device, 1, &fence));
|
||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, fence));
|
||||
VK_CHECK_RESULT(vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX));
|
||||
vkDestroyFence(device, fence, nullptr);
|
||||
//vkDestroyFence(device, fence, nullptr);
|
||||
}
|
||||
|
||||
// todo :根据physicalDeviceIndex确定子文件夹路径,frameIndex确定fileName
|
||||
void PlumageRender::writeImageToFile(std::string filePath)
|
||||
{
|
||||
|
||||
bool surpportBlit = true;
|
||||
|
||||
|
||||
|
||||
char* imageData;
|
||||
// create dst image to copy
|
||||
|
||||
VkImageCreateInfo imageCreateInfo(vks::initializers::imageCreateInfo());
|
||||
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||
imageCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
|
@ -1610,7 +1610,14 @@ PlumageRender::PlumageRender()
|
|||
imageCreateInfo.arrayLayers = 1;
|
||||
imageCreateInfo.mipLevels = 1;
|
||||
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
if (settings.multiSampling)
|
||||
{
|
||||
imageCreateInfo.samples = settings.sampleCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
}
|
||||
imageCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;
|
||||
imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
|
@ -1623,20 +1630,28 @@ PlumageRender::PlumageRender()
|
|||
VkDeviceMemory dstImageMemory;
|
||||
vkGetImageMemoryRequirements(device, dstImage, &memRequirements);
|
||||
memAllocInfo.allocationSize = memRequirements.size;
|
||||
memAllocInfo.memoryTypeIndex = getMemoryTypeIndex(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
memAllocInfo.memoryTypeIndex = vulkanDevice -> getMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
|
||||
// allocate and bind memory
|
||||
VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &dstImageMemory));
|
||||
VK_CHECK_RESULT(vkBindImageMemory(device, dstImage, dstImageMemory, 0));
|
||||
|
||||
// blit image and copy to host visualable memory
|
||||
VkCommandBufferAllocateInfo cmdBufferAllocInfo;
|
||||
VkCommandBufferAllocateInfo cmdBufferAllocInfo = vks::initializers::commandBufferAllocateInfo(cmdPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY,1);
|
||||
VkCommandBuffer copyCmd;
|
||||
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufferAllocInfo, ©Cmd));
|
||||
VkCommandBufferBeginInfo cmdBufferBeginInfo = vks::initializers::commandBufferBeginInfo();
|
||||
VK_CHECK_RESULT(vkBeginCommandBuffer(copyCmd, &cmdBufferBeginInfo));
|
||||
|
||||
vks::tools::insertImageMemoryBarrier(copyCmd, dstImage, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VkImageSubresourceRange{ VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,1 });
|
||||
|
||||
vks::tools::insertImageMemoryBarrier(copyCmd,
|
||||
dstImage,
|
||||
0,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VkImageSubresourceRange{ VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,1 });
|
||||
|
||||
VkImageCopy imageCopyRegion{};
|
||||
imageCopyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
@ -1647,14 +1662,50 @@ PlumageRender::PlumageRender()
|
|||
imageCopyRegion.extent.height = height;
|
||||
imageCopyRegion.extent.depth = 1;
|
||||
|
||||
vkCmdCopyImage(copyCmd, offscreen.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageCopyRegion);
|
||||
VkImage srcImage;
|
||||
|
||||
if (settings.multiSampling)
|
||||
{
|
||||
srcImage = multisampleTarget.color.image;
|
||||
}
|
||||
else
|
||||
{
|
||||
srcImage = colorAttachment.image;
|
||||
}
|
||||
|
||||
vks::tools::insertImageMemoryBarrier(copyCmd,
|
||||
srcImage,
|
||||
0,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VkImageSubresourceRange{ VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,1 });
|
||||
|
||||
vkCmdCopyImage(copyCmd,
|
||||
srcImage,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
dstImage,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, &imageCopyRegion);
|
||||
|
||||
// transition dst image to general layout for map memory
|
||||
vks::tools::insertImageMemoryBarrier(copyCmd, dstImage, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,VkImageSubresourceRange{VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,1});
|
||||
vks::tools::insertImageMemoryBarrier(copyCmd,
|
||||
dstImage,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_ACCESS_MEMORY_READ_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VkImageSubresourceRange{VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,1});
|
||||
|
||||
VK_CHECK_RESULT(vkEndCommandBuffer(copyCmd));
|
||||
|
||||
submitWork(copyCmd, queue);
|
||||
submitWork(copyCmd, queue,waitFences[frameIndex]);
|
||||
|
||||
vkDeviceWaitIdle(device);
|
||||
|
||||
// Get layout of the image
|
||||
VkImageSubresource subResource{};
|
||||
|
@ -1705,7 +1756,7 @@ PlumageRender::PlumageRender()
|
|||
|
||||
}
|
||||
|
||||
void PlumageRender::outputImageSequence()
|
||||
void PlumageRender::outputImageSequence(uint32_t currentFrame)
|
||||
{
|
||||
|
||||
std::string deviceFilePath = filePath.outputPath + "/device" + std::to_string(selectedPhysicalDeviceIndex);
|
||||
|
@ -1713,33 +1764,34 @@ PlumageRender::PlumageRender()
|
|||
{
|
||||
_mkdir(deviceFilePath.c_str());
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < settings.outputFrameCount; i++)
|
||||
{
|
||||
std::string fileName = "/" + std::to_string(i) + "result.pmm";
|
||||
std::string outputPath = deviceFilePath + fileName;
|
||||
std::string fileName = "/" + std::to_string(currentFrame) + "result.pmm";
|
||||
std::string outputPath = deviceFilePath + fileName;
|
||||
//std::cout << outputPath << std::endl;
|
||||
writeImageToFile(outputPath);
|
||||
}
|
||||
writeImageToFile(outputPath);
|
||||
|
||||
}
|
||||
|
||||
uint32_t PlumageRender::getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties)
|
||||
void PlumageRender::renderFrame()
|
||||
{
|
||||
VkPhysicalDeviceMemoryProperties deviceMemoryProperties;
|
||||
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &deviceMemoryProperties);
|
||||
for (uint32_t i = 0; i < deviceMemoryProperties.memoryTypeCount; i++)
|
||||
{
|
||||
if ((typeBits & 1) == 1)
|
||||
{
|
||||
if ((deviceMemoryProperties.memoryTypes[i].propertyFlags & properties) == properties)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
typeBits >>= 1;
|
||||
auto tStart = std::chrono::high_resolution_clock::now();
|
||||
|
||||
render();
|
||||
frameCounter++;
|
||||
//VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[frameIndex], VK_TRUE, UINT64_MAX));
|
||||
outputImageSequence(frameCounter);
|
||||
//VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[frameIndex]));
|
||||
auto tEnd = std::chrono::high_resolution_clock::now();
|
||||
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
||||
frameTimer = (float)tDiff / 1000.0f;
|
||||
camera.update(frameTimer);
|
||||
fpsTimer += (float)tDiff;
|
||||
if (fpsTimer > 1000.0f) {
|
||||
lastFPS = static_cast<uint32_t>((float)frameCounter * (1000.0f / fpsTimer));
|
||||
fpsTimer = 0.0f;
|
||||
frameCounter = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PlumageRender::render()
|
||||
{
|
||||
|
@ -1750,12 +1802,9 @@ PlumageRender::PlumageRender()
|
|||
updateUIOverlay();
|
||||
//加入写到文件的函数
|
||||
//swapChainImage = swapChain.images[frameIndex];
|
||||
//outputImageSequeue(swapChainImage,filePath.imageSequenceFilePath);
|
||||
|
||||
|
||||
|
||||
VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[frameIndex], VK_TRUE, UINT64_MAX));
|
||||
VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[frameIndex]));
|
||||
//VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[frameIndex], VK_TRUE, UINT64_MAX));
|
||||
//VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[frameIndex]));
|
||||
|
||||
VkResult acquire = swapChain.acquireNextImage(presentCompleteSemaphores[frameIndex], ¤tBuffer);
|
||||
if ((acquire == VK_ERROR_OUT_OF_DATE_KHR) || (acquire == VK_SUBOPTIMAL_KHR)) {
|
||||
|
@ -1764,7 +1813,6 @@ PlumageRender::PlumageRender()
|
|||
else {
|
||||
VK_CHECK_RESULT(acquire);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Update UBOs
|
||||
|
@ -1784,8 +1832,10 @@ PlumageRender::PlumageRender()
|
|||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pCommandBuffers = &commandBuffers[currentBuffer];
|
||||
submitInfo.commandBufferCount = 1;
|
||||
VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[frameIndex]));
|
||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, waitFences[frameIndex]));
|
||||
|
||||
VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[frameIndex], VK_TRUE, MAXINT64));
|
||||
|
||||
//显示队列
|
||||
VkResult present = swapChain.queuePresent(queue, currentBuffer, renderCompleteSemaphores[frameIndex]);
|
||||
if (!((present == VK_SUCCESS) || (present == VK_SUBOPTIMAL_KHR))) {
|
||||
|
@ -1826,6 +1876,174 @@ PlumageRender::PlumageRender()
|
|||
|
||||
}
|
||||
|
||||
void PlumageRender::renderLoop()
|
||||
{
|
||||
destWidth = width;
|
||||
destHeight = height;
|
||||
|
||||
#if defined(_WIN32)
|
||||
MSG msg;
|
||||
bool quitMessageReceived = false;
|
||||
while (!quitMessageReceived) {
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
if (msg.message == WM_QUIT) {
|
||||
quitMessageReceived = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!IsIconic(window)) {
|
||||
renderFrame();
|
||||
}
|
||||
}
|
||||
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||
while (1)
|
||||
{
|
||||
int ident;
|
||||
int events;
|
||||
struct android_poll_source* source;
|
||||
bool destroy = false;
|
||||
|
||||
focused = true;
|
||||
|
||||
while ((ident = ALooper_pollAll(focused ? 0 : -1, NULL, &events, (void**)&source)) >= 0)
|
||||
{
|
||||
if (source != NULL)
|
||||
{
|
||||
source->process(androidApp, source);
|
||||
}
|
||||
if (androidApp->destroyRequested != 0)
|
||||
{
|
||||
LOGD("Android app destroy requested");
|
||||
destroy = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// App destruction requested
|
||||
// Exit loop, example will be destroyed in application main
|
||||
if (destroy)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Render frame
|
||||
if (prepared)
|
||||
{
|
||||
auto tStart = std::chrono::high_resolution_clock::now();
|
||||
render();
|
||||
frameCounter++;
|
||||
auto tEnd = std::chrono::high_resolution_clock::now();
|
||||
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
||||
frameTimer = tDiff / 1000.0f;
|
||||
camera.update(frameTimer);
|
||||
fpsTimer += (float)tDiff;
|
||||
if (fpsTimer > 1000.0f)
|
||||
{
|
||||
lastFPS = (float)frameCounter * (1000.0f / fpsTimer);
|
||||
fpsTimer = 0.0f;
|
||||
frameCounter = 0;
|
||||
}
|
||||
|
||||
// Check gamepad state
|
||||
const float deadZone = 0.0015f;
|
||||
// todo : check if gamepad is present
|
||||
// todo : time based and relative axis positions
|
||||
if (camera.type != Camera::CameraType::firstperson)
|
||||
{
|
||||
// Rotate
|
||||
if (std::abs(gamePadState.axisLeft.x) > deadZone) {
|
||||
camera.rotate(glm::vec3(0.0f, gamePadState.axisLeft.x * 0.5f, 0.0f));
|
||||
}
|
||||
if (std::abs(gamePadState.axisLeft.y) > deadZone) {
|
||||
camera.rotate(glm::vec3(gamePadState.axisLeft.y * 0.5f, 0.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
else {
|
||||
camera.updatePad(gamePadState.axisLeft, gamePadState.axisRight, frameTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined(_DIRECT2DISPLAY)
|
||||
while (!quit)
|
||||
{
|
||||
auto tStart = std::chrono::high_resolution_clock::now();
|
||||
render();
|
||||
frameCounter++;
|
||||
auto tEnd = std::chrono::high_resolution_clock::now();
|
||||
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
||||
frameTimer = tDiff / 1000.0f;
|
||||
camera.update(frameTimer);
|
||||
fpsTimer += (float)tDiff;
|
||||
if (fpsTimer > 1000.0f)
|
||||
{
|
||||
lastFPS = (float)frameCounter * (1000.0f / fpsTimer);
|
||||
fpsTimer = 0.0f;
|
||||
frameCounter = 0;
|
||||
}
|
||||
}
|
||||
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
while (!quit)
|
||||
{
|
||||
auto tStart = std::chrono::high_resolution_clock::now();
|
||||
|
||||
while (wl_display_prepare_read(display) != 0)
|
||||
wl_display_dispatch_pending(display);
|
||||
wl_display_flush(display);
|
||||
wl_display_read_events(display);
|
||||
wl_display_dispatch_pending(display);
|
||||
|
||||
render();
|
||||
frameCounter++;
|
||||
auto tEnd = std::chrono::high_resolution_clock::now();
|
||||
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
||||
frameTimer = tDiff / 1000.0f;
|
||||
camera.update(frameTimer);
|
||||
fpsTimer += (float)tDiff;
|
||||
if (fpsTimer > 1000.0f)
|
||||
{
|
||||
wl_shell_surface_set_title(shell_surface, title.c_str());
|
||||
lastFPS = (float)frameCounter * (1000.0f / fpsTimer);
|
||||
fpsTimer = 0.0f;
|
||||
frameCounter = 0;
|
||||
}
|
||||
}
|
||||
#elif defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
xcb_flush(connection);
|
||||
while (!quit)
|
||||
{
|
||||
auto tStart = std::chrono::high_resolution_clock::now();
|
||||
xcb_generic_event_t* event;
|
||||
while ((event = xcb_poll_for_event(connection)))
|
||||
{
|
||||
handleEvent(event);
|
||||
free(event);
|
||||
}
|
||||
render();
|
||||
frameCounter++;
|
||||
auto tEnd = std::chrono::high_resolution_clock::now();
|
||||
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
||||
frameTimer = tDiff / 1000.0f;
|
||||
camera.update(frameTimer);
|
||||
fpsTimer += (float)tDiff;
|
||||
if (fpsTimer > 1000.0f)
|
||||
{
|
||||
xcb_change_property(connection, XCB_PROP_MODE_REPLACE,
|
||||
window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8,
|
||||
title.size(), title.c_str());
|
||||
lastFPS = (float)frameCounter * (1000.0f / fpsTimer);
|
||||
fpsTimer = 0.0f;
|
||||
frameCounter = 0;
|
||||
}
|
||||
}
|
||||
#elif defined(VK_USE_PLATFORM_MACOS_MVK)
|
||||
[NSApp run];
|
||||
#endif
|
||||
// Flush device to make sure all resources can be freed
|
||||
vkDeviceWaitIdle(device);
|
||||
}
|
||||
|
||||
void PlumageRender::fileDropped(std::string filename)
|
||||
{
|
||||
vkDeviceWaitIdle(device);
|
||||
|
|
|
@ -216,19 +216,6 @@ public:
|
|||
VkDescriptorSet tonemappingDescriptorSet = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
struct Settings {
|
||||
bool validation = true;
|
||||
bool fullscreen = false;
|
||||
bool vsync = false;
|
||||
bool multiSampling = true;
|
||||
bool rotateModel = true;
|
||||
bool enableSaveToImageSequeue = false;
|
||||
uint32_t outputFrameCount = 50;
|
||||
bool takeScreenShot = false;
|
||||
|
||||
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT;
|
||||
} settings;
|
||||
|
||||
struct DescriptorSetLayouts {
|
||||
VkDescriptorSetLayout scene;
|
||||
VkDescriptorSetLayout material;
|
||||
|
@ -260,6 +247,7 @@ public:
|
|||
glm::vec3 rotation = glm::vec3(75.0f, 40.0f, 0.0f);
|
||||
} lightSource;
|
||||
|
||||
|
||||
|
||||
//cube map generation
|
||||
|
||||
|
@ -286,7 +274,14 @@ public:
|
|||
} prefilterPushBlock;
|
||||
|
||||
UI* gui;
|
||||
|
||||
|
||||
float frameTimer = 1.0f;
|
||||
uint32_t lastFPS = 0;
|
||||
float fpsTimer = 0.0f;
|
||||
uint32_t frameCounter = 0;
|
||||
|
||||
uint32_t destWidth;
|
||||
uint32_t destHeight;
|
||||
|
||||
PlumageRender();
|
||||
~PlumageRender()
|
||||
|
@ -345,12 +340,14 @@ public:
|
|||
void updateShaderData();
|
||||
void windowResized();
|
||||
void prepare();
|
||||
void submitWork(VkCommandBuffer cmdBuffer, VkQueue queue);
|
||||
void submitWork(VkCommandBuffer cmdBuffer, VkQueue queue, VkFence fence);
|
||||
void writeImageToFile(std::string filePath);
|
||||
void outputImageSequence();
|
||||
void outputImageSequence(uint32_t currentFrame);
|
||||
void renderFrame();
|
||||
void outputScreenShot();
|
||||
uint32_t getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties);
|
||||
virtual void render();
|
||||
void renderLoop();
|
||||
virtual void updateUIOverlay();
|
||||
virtual void fileDropped(std::string filename);
|
||||
};
|
Loading…
Reference in New Issue