This commit is contained in:
Attila Uygun 2021-01-06 22:21:12 +01:00
parent bb4c6032fb
commit 3a5572c8d0
6 changed files with 62 additions and 62 deletions

View File

@ -335,7 +335,8 @@ bool RendererOpenGL::StartRenderThread() {
void RendererOpenGL::TerminateRenderThread() {
#ifdef THREADED_RENDERING
DCHECK(!terminate_render_thread_);
if (terminate_render_thread_)
return;
// Notify worker thread and wait for it to terminate.
{

View File

@ -15,11 +15,7 @@ bool RendererOpenGL::Initialize(ANativeWindow* window) {
}
void RendererOpenGL::Shutdown() {
if (terminate_render_thread_)
return;
LOG << "Shutting down renderer.";
TerminateRenderThread();
}

View File

@ -1,10 +1,8 @@
#include "renderer_vulkan.h"
#include <algorithm>
#include <atomic>
#include <cstring>
#include <sstream>
#include <unordered_set>
#include "../../../base/log.h"
#include "../../../base/vecmath.h"
@ -786,20 +784,27 @@ bool RendererVulkan::InitializeInternal() {
// Use a background thread for filling up staging buffers and recording setup
// commands.
quit_.store(false, std::memory_order_relaxed);
setup_thread_ =
std::thread(&RendererVulkan::SetupThreadMain, this, frame_count);
if (context_lost_cb_) {
LOG << "Context lost.";
context_lost_cb_();
}
return true;
}
void RendererVulkan::Shutdown() {
LOG << "Shutting down renderer.";
vkDeviceWaitIdle(device_);
InvalidateAllResources();
quit_.store(true, std::memory_order_relaxed);
semaphore_.Release();
setup_thread_.join();
vkDeviceWaitIdle(device_);
for (int i = 0; i < frames_.size(); ++i) {
FreePendingResources(i);
vkDestroyCommandPool(device_, frames_[i].setup_command_pool, nullptr);
@ -812,6 +817,14 @@ void RendererVulkan::Shutdown() {
vkDestroySampler(device_, sampler_, nullptr);
device_ = VK_NULL_HANDLE;
frames_drawn_ = 0;
frames_.clear();
current_frame_ = 0;
staging_buffers_.clear();
current_staging_buffer_ = 0;
staging_buffer_used_ = false;
context_.DestroyWindow();
context_.Shutdown();
@ -995,8 +1008,8 @@ bool RendererVulkan::AllocateStagingBuffer(uint32_t amount,
staging_buffers_[current_staging_buffer_].frame_used =
frames_drawn_;
} else {
// Worst case scenario, all the staging buffers belong to this frame
// and this frame is not even done. Flush everything.
// All the staging buffers belong to this frame and we can't create
// more. Flush setup buffer to make room.
FlushSetupBuffer();
// Clear the whole staging buffer.
@ -1205,12 +1218,12 @@ void RendererVulkan::UpdateBuffer(VkBuffer buffer,
size_t submit_from = 0;
while (to_submit > 0) {
uint32_t block_write_offset;
uint32_t block_write_amount;
uint32_t write_offset;
uint32_t write_amount;
if (!AllocateStagingBuffer(
std::min((uint32_t)to_submit, staging_buffer_size_), 32,
block_write_offset, block_write_amount))
write_offset, write_amount))
return;
Buffer<VkBuffer> staging_buffer =
staging_buffers_[current_staging_buffer_].buffer;
@ -1218,20 +1231,20 @@ void RendererVulkan::UpdateBuffer(VkBuffer buffer,
// Copy to staging buffer.
void* data_ptr =
staging_buffers_[current_staging_buffer_].alloc_info.pMappedData;
memcpy(((uint8_t*)data_ptr) + block_write_offset, (char*)data + submit_from,
block_write_amount);
memcpy(((uint8_t*)data_ptr) + write_offset, (char*)data + submit_from,
write_amount);
// Insert a command to copy to GPU buffer.
VkBufferCopy region;
region.srcOffset = block_write_offset;
region.srcOffset = write_offset;
region.dstOffset = submit_from + offset;
region.size = block_write_amount;
region.size = write_amount;
vkCmdCopyBuffer(frames_[current_frame_].setup_command_buffer,
std::get<0>(staging_buffer), buffer, 1, &region);
to_submit -= block_write_amount;
submit_from += block_write_amount;
to_submit -= write_amount;
submit_from += write_amount;
}
}
@ -1405,10 +1418,10 @@ void RendererVulkan::UpdateImage(VkImage image,
DCHECK(staging_buffer_size_ >= segment);
while (to_submit > 0) {
uint32_t block_write_offset;
uint32_t block_write_amount;
uint32_t write_offset;
uint32_t write_amount;
if (!AllocateStagingBuffer(std::min((uint32_t)to_submit, max_size), segment,
block_write_offset, block_write_amount))
write_offset, write_amount))
return;
Buffer<VkBuffer> staging_buffer =
staging_buffers_[current_staging_buffer_].buffer;
@ -1416,14 +1429,14 @@ void RendererVulkan::UpdateImage(VkImage image,
// Copy to staging buffer.
void* data_ptr =
staging_buffers_[current_staging_buffer_].alloc_info.pMappedData;
memcpy(((uint8_t*)data_ptr) + block_write_offset, (char*)data + submit_from,
block_write_amount);
memcpy(((uint8_t*)data_ptr) + write_offset, (char*)data + submit_from,
write_amount);
uint32_t region_height = (block_write_amount / segment) * block_height;
uint32_t region_height = (write_amount / segment) * block_height;
// Insert a command to copy to GPU buffer.
VkBufferImageCopy buffer_image_copy;
buffer_image_copy.bufferOffset = block_write_offset;
buffer_image_copy.bufferOffset = write_offset;
buffer_image_copy.bufferRowLength = 0;
buffer_image_copy.bufferImageHeight = 0;
buffer_image_copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -1442,8 +1455,8 @@ void RendererVulkan::UpdateImage(VkImage image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
&buffer_image_copy);
to_submit -= block_write_amount;
submit_from += block_write_amount;
to_submit -= write_amount;
submit_from += write_amount;
region_offset_y += region_height;
}
}
@ -1826,12 +1839,6 @@ bool RendererVulkan::IsFormatSupported(VkFormat format) {
return properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
}
void RendererVulkan::ContextLost() {
LOG << "Context lost.";
InvalidateAllResources();
context_lost_cb_();
}
std::unique_ptr<RenderResource> RendererVulkan::CreateResource(
RenderResourceFactoryBase& factory) {
static unsigned last_id = 0;

View File

@ -184,13 +184,6 @@ class RendererVulkan : public Renderer {
base::Semaphore semaphore_;
std::atomic<bool> quit_{false};
#if defined(__ANDROID__)
ANativeWindow* window_;
#elif defined(__linux__)
Display* display_ = NULL;
Window window_ = 0;
#endif
bool InitializeInternal();
void BeginFrame();
@ -269,8 +262,6 @@ class RendererVulkan : public Renderer {
bool IsFormatSupported(VkFormat format);
void ContextLost();
void InvalidateAllResources();
};

View File

@ -7,11 +7,8 @@ namespace eng {
bool RendererVulkan::Initialize(Display* display, Window window) {
LOG << "Initializing renderer.";
display_ = display;
window_ = window;
XWindowAttributes xwa;
XGetWindowAttributes(display_, window_, &xwa);
XGetWindowAttributes(display, window, &xwa);
screen_width_ = xwa.width;
screen_height_ = xwa.height;

View File

@ -61,6 +61,12 @@ void VulkanContext::Shutdown() {
vkDestroyDevice(device_, nullptr);
device_ = VK_NULL_HANDLE;
}
buffers_prepared_ = false;
queues_initialized_ = false;
separate_present_queue_ = false;
swapchain_image_count_ = 0;
command_buffers_.clear();
window_ = {};
}
VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::DebugMessengerCallback(
@ -392,23 +398,25 @@ bool VulkanContext::CreatePhysicalDevice() {
uint32_t gpu_count;
VkResult err = vkCreateInstance(&inst_info, nullptr, &instance_);
if (err == VK_ERROR_INCOMPATIBLE_DRIVER) {
DLOG << "Cannot find a compatible Vulkan installable client driver (ICD).";
return false;
}
if (err == VK_ERROR_EXTENSION_NOT_PRESENT) {
DLOG << "Cannot find a specified extension library. Make sure your layers "
"path is set appropriately. ";
return false;
}
if (err) {
DLOG << "vkCreateInstance failed. Error: " << err;
return false;
if (instance_ == VK_NULL_HANDLE) {
VkResult err = vkCreateInstance(&inst_info, nullptr, &instance_);
if (err == VK_ERROR_INCOMPATIBLE_DRIVER) {
DLOG << "Cannot find a compatible Vulkan installable client driver (ICD).";
return false;
}
if (err == VK_ERROR_EXTENSION_NOT_PRESENT) {
DLOG << "Cannot find a specified extension library. Make sure your layers "
"path is set appropriately. ";
return false;
}
if (err) {
DLOG << "vkCreateInstance failed. Error: " << err;
return false;
}
}
// Make initial call to query gpu_count.
err = vkEnumeratePhysicalDevices(instance_, &gpu_count, nullptr);
VkResult err = vkEnumeratePhysicalDevices(instance_, &gpu_count, nullptr);
if (err) {
DLOG << "vkEnumeratePhysicalDevices failed. Error: " << err;
return false;
@ -919,7 +927,7 @@ bool VulkanContext::UpdateSwapChain(Window* window) {
// between VSync signals, which is 16.6ms at a rate of 60 fps. The rendered
// image is presented to the swapchain, and the previously presented one is
// made available to the application again. If the GPU cannot process frames
// fast enough, VSync will be missed and the application wait have to wait for
// fast enough, VSync will be missed and the application will have to wait for
// another whole VSync cycle, which caps framerate at 30 fps. This may be ok,
// but triple buffering can deliver higher framerate.
uint32_t desired_num_of_swapchain_images = 3;