revert
parent
20a30d9192
commit
a0b8b66f2b
|
@ -120,6 +120,7 @@ namespace vks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the index of a queue family that supports the requested queue flags
|
* 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].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
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
|
// This is the frame buffer attachment to where the multisampled image
|
||||||
// will be resolved to and which will be presented to the swapchain
|
// will be resolved to and which will be presented to the swapchain
|
||||||
|
@ -143,7 +143,14 @@ void VulkanExampleBase::prepare()
|
||||||
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
if (settings.headless)
|
||||||
|
{
|
||||||
|
attachments[1].finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
attachments[1].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
attachments[1].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||||
|
}
|
||||||
|
|
||||||
// Multisampled depth attachment we render to
|
// Multisampled depth attachment we render to
|
||||||
attachments[2].format = depthFormat;
|
attachments[2].format = depthFormat;
|
||||||
|
@ -214,31 +221,40 @@ void VulkanExampleBase::prepare()
|
||||||
renderPassCI.pDependencies = dependencies.data();
|
renderPassCI.pDependencies = dependencies.data();
|
||||||
VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassCI, nullptr, &renderPass));
|
VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassCI, nullptr, &renderPass));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
std::array<VkAttachmentDescription, 2> attachments = {};
|
{
|
||||||
|
std::array<VkAttachmentDescription, 2> attachmentDescriptions = {};
|
||||||
// Color attachment
|
// Color attachment
|
||||||
attachments[0].format = swapChain.colorFormat;
|
attachmentDescriptions[0].format = swapChain.colorFormat;
|
||||||
attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
|
attachmentDescriptions[0].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
attachmentDescriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
attachmentDescriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
attachmentDescriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
attachmentDescriptions[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
attachmentDescriptions[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
attachments[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
if (settings.headless)
|
||||||
|
{
|
||||||
|
attachmentDescriptions[0].finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
attachmentDescriptions[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||||
|
}
|
||||||
// Depth attachment
|
// Depth attachment
|
||||||
attachments[1].format = depthFormat;
|
attachmentDescriptions[1].format = depthFormat;
|
||||||
attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
|
attachmentDescriptions[1].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
attachmentDescriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
attachmentDescriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
attachmentDescriptions[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
attachmentDescriptions[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
attachmentDescriptions[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
attachmentDescriptions[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
VkAttachmentReference colorReference = {};
|
VkAttachmentReference colorReference = {};
|
||||||
colorReference.attachment = 0;
|
colorReference.attachment = 0;
|
||||||
colorReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
colorReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
|
||||||
VkAttachmentReference depthReference = {};
|
VkAttachmentReference depthReference = {};
|
||||||
depthReference.attachment = 1;
|
depthReference.attachment = 1;
|
||||||
depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
@ -275,13 +291,16 @@ void VulkanExampleBase::prepare()
|
||||||
|
|
||||||
VkRenderPassCreateInfo renderPassCI{};
|
VkRenderPassCreateInfo renderPassCI{};
|
||||||
renderPassCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
renderPassCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
renderPassCI.attachmentCount = static_cast<uint32_t>(attachments.size());
|
renderPassCI.attachmentCount = static_cast<uint32_t>(attachmentDescriptions.size());
|
||||||
renderPassCI.pAttachments = attachments.data();
|
renderPassCI.pAttachments = attachmentDescriptions.data();
|
||||||
renderPassCI.subpassCount = 1;
|
renderPassCI.subpassCount = 1;
|
||||||
renderPassCI.pSubpasses = &subpassDescription;
|
renderPassCI.pSubpasses = &subpassDescription;
|
||||||
renderPassCI.dependencyCount = static_cast<uint32_t>(dependencies.size());
|
renderPassCI.dependencyCount = static_cast<uint32_t>(dependencies.size());
|
||||||
renderPassCI.pDependencies = dependencies.data();
|
renderPassCI.pDependencies = dependencies.data();
|
||||||
VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassCI, nullptr, &renderPass));
|
VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassCI, nullptr, &renderPass));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -299,189 +318,6 @@ void VulkanExampleBase::prepare()
|
||||||
|
|
||||||
void VulkanExampleBase::fileDropped(std::string filename) { }
|
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()
|
VulkanExampleBase::VulkanExampleBase()
|
||||||
{
|
{
|
||||||
|
@ -539,9 +375,9 @@ VulkanExampleBase::~VulkanExampleBase()
|
||||||
for (uint32_t i = 0; i < frameBuffers.size(); i++) {
|
for (uint32_t i = 0; i < frameBuffers.size(); i++) {
|
||||||
vkDestroyFramebuffer(device, frameBuffers[i], nullptr);
|
vkDestroyFramebuffer(device, frameBuffers[i], nullptr);
|
||||||
}
|
}
|
||||||
vkDestroyImageView(device, depthStencil.view, nullptr);
|
vkDestroyImageView(device, depthAttachment.view, nullptr);
|
||||||
vkDestroyImage(device, depthStencil.image, nullptr);
|
vkDestroyImage(device, depthAttachment.image, nullptr);
|
||||||
vkFreeMemory(device, depthStencil.mem, nullptr);
|
vkFreeMemory(device, depthAttachment.memory, nullptr);
|
||||||
vkDestroyPipelineCache(device, pipelineCache, nullptr);
|
vkDestroyPipelineCache(device, pipelineCache, nullptr);
|
||||||
vkDestroyCommandPool(device, cmdPool, nullptr);
|
vkDestroyCommandPool(device, cmdPool, nullptr);
|
||||||
if (settings.multiSampling) {
|
if (settings.multiSampling) {
|
||||||
|
@ -1822,8 +1658,9 @@ void VulkanExampleBase::setupFrameBuffer()
|
||||||
imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
imageCI.tiling = VK_IMAGE_TILING_OPTIMAL;
|
imageCI.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
imageCI.samples = settings.sampleCount;
|
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;
|
imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
|
||||||
VK_CHECK_RESULT(vkCreateImage(device, &imageCI, nullptr, &multisampleTarget.color.image));
|
VK_CHECK_RESULT(vkCreateImage(device, &imageCI, nullptr, &multisampleTarget.color.image));
|
||||||
|
|
||||||
VkMemoryRequirements memReqs;
|
VkMemoryRequirements memReqs;
|
||||||
|
@ -1891,10 +1728,6 @@ void VulkanExampleBase::setupFrameBuffer()
|
||||||
imageViewCI.subresourceRange.levelCount = 1;
|
imageViewCI.subresourceRange.levelCount = 1;
|
||||||
imageViewCI.subresourceRange.layerCount = 1;
|
imageViewCI.subresourceRange.layerCount = 1;
|
||||||
VK_CHECK_RESULT(vkCreateImageView(device, &imageViewCI, nullptr, &multisampleTarget.depth.view));
|
VK_CHECK_RESULT(vkCreateImageView(device, &imageViewCI, nullptr, &multisampleTarget.depth.view));
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Depth/Stencil attachment is the same for all frame buffers
|
|
||||||
|
|
||||||
VkImageCreateInfo image = {};
|
VkImageCreateInfo image = {};
|
||||||
image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
|
@ -1928,28 +1761,107 @@ void VulkanExampleBase::setupFrameBuffer()
|
||||||
depthStencilView.subresourceRange.baseArrayLayer = 0;
|
depthStencilView.subresourceRange.baseArrayLayer = 0;
|
||||||
depthStencilView.subresourceRange.layerCount = 1;
|
depthStencilView.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
VkMemoryRequirements memReqs;
|
|
||||||
VK_CHECK_RESULT(vkCreateImage(device, &image, nullptr, &depthStencil.image));
|
VK_CHECK_RESULT(vkCreateImage(device, &image, nullptr, &depthAttachment.image));
|
||||||
vkGetImageMemoryRequirements(device, depthStencil.image, &memReqs);
|
vkGetImageMemoryRequirements(device, depthAttachment.image, &memReqs);
|
||||||
mem_alloc.allocationSize = memReqs.size;
|
mem_alloc.allocationSize = memReqs.size;
|
||||||
mem_alloc.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
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(vkAllocateMemory(device, &mem_alloc, nullptr, &depthAttachment.memory));
|
||||||
VK_CHECK_RESULT(vkBindImageMemory(device, depthStencil.image, depthStencil.mem, 0));
|
VK_CHECK_RESULT(vkBindImageMemory(device, depthAttachment.image, depthAttachment.memory, 0));
|
||||||
|
|
||||||
depthStencilView.image = depthStencil.image;
|
depthStencilView.image = depthAttachment.image;
|
||||||
VK_CHECK_RESULT(vkCreateImageView(device, &depthStencilView, nullptr, &depthStencil.view));
|
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;
|
||||||
|
|
||||||
VkImageView attachments[4];
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkImageView attachments[i];
|
||||||
|
|
||||||
if (settings.multiSampling) {
|
if (settings.multiSampling) {
|
||||||
|
|
||||||
attachments[0] = multisampleTarget.color.view;
|
attachments[0] = multisampleTarget.color.view;
|
||||||
attachments[2] = multisampleTarget.depth.view;
|
attachments[2] = multisampleTarget.depth.view;
|
||||||
attachments[3] = depthStencil.view;
|
attachments[3] = depthAttachment.view;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
attachments[1] = depthStencil.view;
|
|
||||||
|
attachments[1] = depthAttachment.view;
|
||||||
|
attachments[0] = colorAttachment.view;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkFramebufferCreateInfo frameBufferCI{};
|
VkFramebufferCreateInfo frameBufferCI{};
|
||||||
|
@ -1962,6 +1874,23 @@ void VulkanExampleBase::setupFrameBuffer()
|
||||||
frameBufferCI.height = height;
|
frameBufferCI.height = height;
|
||||||
frameBufferCI.layers = 1;
|
frameBufferCI.layers = 1;
|
||||||
|
|
||||||
|
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
|
// Create frame buffers for every swap chain image
|
||||||
frameBuffers.resize(swapChain.imageCount);
|
frameBuffers.resize(swapChain.imageCount);
|
||||||
for (uint32_t i = 0; i < frameBuffers.size(); i++) {
|
for (uint32_t i = 0; i < frameBuffers.size(); i++) {
|
||||||
|
@ -1973,6 +1902,8 @@ void VulkanExampleBase::setupFrameBuffer()
|
||||||
}
|
}
|
||||||
VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCI, nullptr, &frameBuffers[i]));
|
VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCI, nullptr, &frameBuffers[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanExampleBase::windowResize()
|
void VulkanExampleBase::windowResize()
|
||||||
|
@ -1994,9 +1925,9 @@ void VulkanExampleBase::windowResize()
|
||||||
vkDestroyImage(device, multisampleTarget.depth.image, nullptr);
|
vkDestroyImage(device, multisampleTarget.depth.image, nullptr);
|
||||||
vkFreeMemory(device, multisampleTarget.depth.memory, nullptr);
|
vkFreeMemory(device, multisampleTarget.depth.memory, nullptr);
|
||||||
}
|
}
|
||||||
vkDestroyImageView(device, depthStencil.view, nullptr);
|
vkDestroyImageView(device, depthAttachment.view, nullptr);
|
||||||
vkDestroyImage(device, depthStencil.image, nullptr);
|
vkDestroyImage(device, depthAttachment.image, nullptr);
|
||||||
vkFreeMemory(device, depthStencil.mem, nullptr);
|
vkFreeMemory(device, depthAttachment.memory, nullptr);
|
||||||
for (uint32_t i = 0; i < frameBuffers.size(); i++) {
|
for (uint32_t i = 0; i < frameBuffers.size(); i++) {
|
||||||
vkDestroyFramebuffer(device, frameBuffers[i], nullptr);
|
vkDestroyFramebuffer(device, frameBuffers[i], nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,16 +58,7 @@
|
||||||
|
|
||||||
class VulkanExampleBase
|
class VulkanExampleBase
|
||||||
{
|
{
|
||||||
private:
|
public:
|
||||||
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;
|
|
||||||
struct MultisampleTarget {
|
struct MultisampleTarget {
|
||||||
struct {
|
struct {
|
||||||
VkImage image;
|
VkImage image;
|
||||||
|
@ -80,6 +71,17 @@ private:
|
||||||
VkDeviceMemory memory;
|
VkDeviceMemory memory;
|
||||||
} depth;
|
} depth;
|
||||||
} multisampleTarget;
|
} 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:
|
protected:
|
||||||
VkInstance instance;
|
VkInstance instance;
|
||||||
VkPhysicalDevice physicalDevice;
|
VkPhysicalDevice physicalDevice;
|
||||||
|
@ -90,6 +92,7 @@ protected:
|
||||||
vks::VulkanDevice *vulkanDevice;
|
vks::VulkanDevice *vulkanDevice;
|
||||||
VkQueue queue;
|
VkQueue queue;
|
||||||
VkFormat depthFormat;
|
VkFormat depthFormat;
|
||||||
|
VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
VkCommandPool cmdPool;
|
VkCommandPool cmdPool;
|
||||||
VkRenderPass renderPass;
|
VkRenderPass renderPass;
|
||||||
std::vector<VkFramebuffer>frameBuffers;
|
std::vector<VkFramebuffer>frameBuffers;
|
||||||
|
@ -106,25 +109,31 @@ public:
|
||||||
bool prepared = false;
|
bool prepared = false;
|
||||||
uint32_t width = 1280;
|
uint32_t width = 1280;
|
||||||
uint32_t height = 720;
|
uint32_t height = 720;
|
||||||
float frameTimer = 1.0f;
|
|
||||||
Camera camera;
|
Camera camera;
|
||||||
glm::vec2 mousePos;
|
glm::vec2 mousePos;
|
||||||
bool paused = false;
|
bool paused = false;
|
||||||
uint32_t lastFPS = 0;
|
|
||||||
|
|
||||||
struct Settings {
|
struct Settings {
|
||||||
bool validation = true;
|
bool validation = true;
|
||||||
bool fullscreen = false;
|
bool fullscreen = false;
|
||||||
bool vsync = false;
|
bool vsync = false;
|
||||||
bool multiSampling = true;
|
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;
|
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT;
|
||||||
} settings;
|
} settings;
|
||||||
|
|
||||||
struct DepthStencil {
|
struct FrameBufferAttachment {
|
||||||
VkImage image;
|
VkImage image;
|
||||||
VkDeviceMemory mem;
|
VkDeviceMemory memory;
|
||||||
VkImageView view;
|
VkImageView view;
|
||||||
} depthStencil;
|
};
|
||||||
|
|
||||||
|
FrameBufferAttachment colorAttachment, depthAttachment;
|
||||||
|
VkFramebuffer framebuffer;
|
||||||
|
|
||||||
struct GamePadState {
|
struct GamePadState {
|
||||||
glm::vec2 axisLeft = glm::vec2(0.0f);
|
glm::vec2 axisLeft = glm::vec2(0.0f);
|
||||||
|
|
|
@ -189,6 +189,9 @@ PlumageRender::PlumageRender()
|
||||||
VK_CHECK_RESULT(vkEndCommandBuffer(currentCB));
|
VK_CHECK_RESULT(vkEndCommandBuffer(currentCB));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -530,6 +533,7 @@ PlumageRender::PlumageRender()
|
||||||
rasterizationStateCI.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
rasterizationStateCI.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||||
rasterizationStateCI.lineWidth = 1.0f;
|
rasterizationStateCI.lineWidth = 1.0f;
|
||||||
|
|
||||||
|
|
||||||
VkPipelineColorBlendAttachmentState blendAttachmentState{};
|
VkPipelineColorBlendAttachmentState blendAttachmentState{};
|
||||||
blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||||
blendAttachmentState.blendEnable = VK_FALSE;
|
blendAttachmentState.blendEnable = VK_FALSE;
|
||||||
|
@ -558,6 +562,10 @@ PlumageRender::PlumageRender()
|
||||||
if (settings.multiSampling) {
|
if (settings.multiSampling) {
|
||||||
multisampleStateCI.rasterizationSamples = settings.sampleCount;
|
multisampleStateCI.rasterizationSamples = settings.sampleCount;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
multisampleStateCI.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<VkDynamicState> dynamicStateEnables = {
|
std::vector<VkDynamicState> dynamicStateEnables = {
|
||||||
VK_DYNAMIC_STATE_VIEWPORT,
|
VK_DYNAMIC_STATE_VIEWPORT,
|
||||||
|
@ -619,9 +627,7 @@ PlumageRender::PlumageRender()
|
||||||
pipelineCI.stageCount = static_cast<uint32_t>(shaderStages.size());
|
pipelineCI.stageCount = static_cast<uint32_t>(shaderStages.size());
|
||||||
pipelineCI.pStages = shaderStages.data();
|
pipelineCI.pStages = shaderStages.data();
|
||||||
|
|
||||||
if (settings.multiSampling) {
|
|
||||||
multisampleStateCI.rasterizationSamples = settings.sampleCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skybox pipeline (background cube)
|
// Skybox pipeline (background cube)
|
||||||
shaderStages = {
|
shaderStages = {
|
||||||
|
@ -1578,29 +1584,23 @@ PlumageRender::PlumageRender()
|
||||||
prepared = true;
|
prepared = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlumageRender::submitWork(VkCommandBuffer cmdBuffer, VkQueue queue)
|
void PlumageRender::submitWork(VkCommandBuffer cmdBuffer, VkQueue queue, VkFence fence)
|
||||||
{
|
{
|
||||||
VkSubmitInfo submitInfo = vks::initializers::submitInfo();
|
VkSubmitInfo submitInfo = vks::initializers::submitInfo();
|
||||||
submitInfo.commandBufferCount = 1;
|
submitInfo.commandBufferCount = 1;
|
||||||
submitInfo.pCommandBuffers = &cmdBuffer;
|
submitInfo.pCommandBuffers = &cmdBuffer;
|
||||||
VkFenceCreateInfo fenceInfo = vks::initializers::fenceCreateInfo();
|
VK_CHECK_RESULT(vkResetFences(device, 1, &fence));
|
||||||
VkFence fence;
|
|
||||||
VK_CHECK_RESULT(vkCreateFence(device, &fenceInfo, nullptr, &fence));
|
|
||||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, fence));
|
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, fence));
|
||||||
VK_CHECK_RESULT(vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX));
|
VK_CHECK_RESULT(vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX));
|
||||||
vkDestroyFence(device, fence, nullptr);
|
//vkDestroyFence(device, fence, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo :根据physicalDeviceIndex确定子文件夹路径,frameIndex确定fileName
|
// todo :根据physicalDeviceIndex确定子文件夹路径,frameIndex确定fileName
|
||||||
void PlumageRender::writeImageToFile(std::string filePath)
|
void PlumageRender::writeImageToFile(std::string filePath)
|
||||||
{
|
{
|
||||||
|
|
||||||
bool surpportBlit = true;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char* imageData;
|
char* imageData;
|
||||||
// create dst image to copy
|
// create dst image to copy
|
||||||
|
|
||||||
VkImageCreateInfo imageCreateInfo(vks::initializers::imageCreateInfo());
|
VkImageCreateInfo imageCreateInfo(vks::initializers::imageCreateInfo());
|
||||||
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||||
imageCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
|
imageCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
@ -1610,7 +1610,14 @@ PlumageRender::PlumageRender()
|
||||||
imageCreateInfo.arrayLayers = 1;
|
imageCreateInfo.arrayLayers = 1;
|
||||||
imageCreateInfo.mipLevels = 1;
|
imageCreateInfo.mipLevels = 1;
|
||||||
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
if (settings.multiSampling)
|
||||||
|
{
|
||||||
|
imageCreateInfo.samples = settings.sampleCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
}
|
||||||
imageCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;
|
imageCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;
|
||||||
imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||||
|
|
||||||
|
@ -1623,20 +1630,28 @@ PlumageRender::PlumageRender()
|
||||||
VkDeviceMemory dstImageMemory;
|
VkDeviceMemory dstImageMemory;
|
||||||
vkGetImageMemoryRequirements(device, dstImage, &memRequirements);
|
vkGetImageMemoryRequirements(device, dstImage, &memRequirements);
|
||||||
memAllocInfo.allocationSize = memRequirements.size;
|
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
|
// allocate and bind memory
|
||||||
VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &dstImageMemory));
|
VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &dstImageMemory));
|
||||||
VK_CHECK_RESULT(vkBindImageMemory(device, dstImage, dstImageMemory, 0));
|
VK_CHECK_RESULT(vkBindImageMemory(device, dstImage, dstImageMemory, 0));
|
||||||
|
|
||||||
// blit image and copy to host visualable memory
|
// blit image and copy to host visualable memory
|
||||||
VkCommandBufferAllocateInfo cmdBufferAllocInfo;
|
VkCommandBufferAllocateInfo cmdBufferAllocInfo = vks::initializers::commandBufferAllocateInfo(cmdPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY,1);
|
||||||
VkCommandBuffer copyCmd;
|
VkCommandBuffer copyCmd;
|
||||||
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufferAllocInfo, ©Cmd));
|
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufferAllocInfo, ©Cmd));
|
||||||
VkCommandBufferBeginInfo cmdBufferBeginInfo = vks::initializers::commandBufferBeginInfo();
|
VkCommandBufferBeginInfo cmdBufferBeginInfo = vks::initializers::commandBufferBeginInfo();
|
||||||
VK_CHECK_RESULT(vkBeginCommandBuffer(copyCmd, &cmdBufferBeginInfo));
|
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{};
|
VkImageCopy imageCopyRegion{};
|
||||||
imageCopyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
imageCopyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
@ -1647,14 +1662,50 @@ PlumageRender::PlumageRender()
|
||||||
imageCopyRegion.extent.height = height;
|
imageCopyRegion.extent.height = height;
|
||||||
imageCopyRegion.extent.depth = 1;
|
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
|
// 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));
|
VK_CHECK_RESULT(vkEndCommandBuffer(copyCmd));
|
||||||
|
|
||||||
submitWork(copyCmd, queue);
|
submitWork(copyCmd, queue,waitFences[frameIndex]);
|
||||||
|
|
||||||
|
vkDeviceWaitIdle(device);
|
||||||
|
|
||||||
// Get layout of the image
|
// Get layout of the image
|
||||||
VkImageSubresource subResource{};
|
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);
|
std::string deviceFilePath = filePath.outputPath + "/device" + std::to_string(selectedPhysicalDeviceIndex);
|
||||||
|
@ -1713,33 +1764,34 @@ PlumageRender::PlumageRender()
|
||||||
{
|
{
|
||||||
_mkdir(deviceFilePath.c_str());
|
_mkdir(deviceFilePath.c_str());
|
||||||
}
|
}
|
||||||
|
std::string fileName = "/" + std::to_string(currentFrame) + "result.pmm";
|
||||||
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 outputPath = deviceFilePath + fileName;
|
||||||
//std::cout << outputPath << std::endl;
|
//std::cout << outputPath << std::endl;
|
||||||
writeImageToFile(outputPath);
|
writeImageToFile(outputPath);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlumageRender::renderFrame()
|
||||||
|
{
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t PlumageRender::getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlumageRender::render()
|
void PlumageRender::render()
|
||||||
{
|
{
|
||||||
|
@ -1750,12 +1802,9 @@ PlumageRender::PlumageRender()
|
||||||
updateUIOverlay();
|
updateUIOverlay();
|
||||||
//加入写到文件的函数
|
//加入写到文件的函数
|
||||||
//swapChainImage = swapChain.images[frameIndex];
|
//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);
|
VkResult acquire = swapChain.acquireNextImage(presentCompleteSemaphores[frameIndex], ¤tBuffer);
|
||||||
if ((acquire == VK_ERROR_OUT_OF_DATE_KHR) || (acquire == VK_SUBOPTIMAL_KHR)) {
|
if ((acquire == VK_ERROR_OUT_OF_DATE_KHR) || (acquire == VK_SUBOPTIMAL_KHR)) {
|
||||||
|
@ -1764,7 +1813,6 @@ PlumageRender::PlumageRender()
|
||||||
else {
|
else {
|
||||||
VK_CHECK_RESULT(acquire);
|
VK_CHECK_RESULT(acquire);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update UBOs
|
// Update UBOs
|
||||||
|
@ -1784,7 +1832,9 @@ PlumageRender::PlumageRender()
|
||||||
submitInfo.signalSemaphoreCount = 1;
|
submitInfo.signalSemaphoreCount = 1;
|
||||||
submitInfo.pCommandBuffers = &commandBuffers[currentBuffer];
|
submitInfo.pCommandBuffers = &commandBuffers[currentBuffer];
|
||||||
submitInfo.commandBufferCount = 1;
|
submitInfo.commandBufferCount = 1;
|
||||||
|
VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[frameIndex]));
|
||||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, 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]);
|
VkResult present = swapChain.queuePresent(queue, currentBuffer, renderCompleteSemaphores[frameIndex]);
|
||||||
|
@ -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)
|
void PlumageRender::fileDropped(std::string filename)
|
||||||
{
|
{
|
||||||
vkDeviceWaitIdle(device);
|
vkDeviceWaitIdle(device);
|
||||||
|
|
|
@ -216,19 +216,6 @@ public:
|
||||||
VkDescriptorSet tonemappingDescriptorSet = VK_NULL_HANDLE;
|
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 {
|
struct DescriptorSetLayouts {
|
||||||
VkDescriptorSetLayout scene;
|
VkDescriptorSetLayout scene;
|
||||||
VkDescriptorSetLayout material;
|
VkDescriptorSetLayout material;
|
||||||
|
@ -261,6 +248,7 @@ public:
|
||||||
} lightSource;
|
} lightSource;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//cube map generation
|
//cube map generation
|
||||||
|
|
||||||
struct OffScreen
|
struct OffScreen
|
||||||
|
@ -287,6 +275,13 @@ public:
|
||||||
|
|
||||||
UI* gui;
|
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();
|
||||||
~PlumageRender()
|
~PlumageRender()
|
||||||
|
@ -345,12 +340,14 @@ public:
|
||||||
void updateShaderData();
|
void updateShaderData();
|
||||||
void windowResized();
|
void windowResized();
|
||||||
void prepare();
|
void prepare();
|
||||||
void submitWork(VkCommandBuffer cmdBuffer, VkQueue queue);
|
void submitWork(VkCommandBuffer cmdBuffer, VkQueue queue, VkFence fence);
|
||||||
void writeImageToFile(std::string filePath);
|
void writeImageToFile(std::string filePath);
|
||||||
void outputImageSequence();
|
void outputImageSequence(uint32_t currentFrame);
|
||||||
|
void renderFrame();
|
||||||
void outputScreenShot();
|
void outputScreenShot();
|
||||||
uint32_t getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties);
|
uint32_t getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties);
|
||||||
virtual void render();
|
virtual void render();
|
||||||
|
void renderLoop();
|
||||||
virtual void updateUIOverlay();
|
virtual void updateUIOverlay();
|
||||||
virtual void fileDropped(std::string filename);
|
virtual void fileDropped(std::string filename);
|
||||||
};
|
};
|
Loading…
Reference in New Issue