Better allocator and logging
This commit is contained in:
parent
87fc0c3f10
commit
d5f1bba4d8
|
@ -5,6 +5,8 @@ option(PROFILING "Build with profiling" 0)
|
||||||
option(FIXED_WINDOW "Lock window size: Force floating on i3" 0)
|
option(FIXED_WINDOW "Lock window size: Force floating on i3" 0)
|
||||||
set(SIMD_LEVEL "avx2" CACHE STRING "SIMD processor acceleration (sse2, sse4.1, avx2, avx512f)")
|
set(SIMD_LEVEL "avx2" CACHE STRING "SIMD processor acceleration (sse2, sse4.1, avx2, avx512f)")
|
||||||
option(USE_FMA "Use fma" 1)
|
option(USE_FMA "Use fma" 1)
|
||||||
|
option(LOG_DEBUG "Show debug logs" 0)
|
||||||
|
option(LOG_TRACE "Show trace logs" 0)
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
set(CMAKE_BUILD_TYPE Release)
|
set(CMAKE_BUILD_TYPE Release)
|
||||||
|
@ -23,7 +25,7 @@ add_subdirectory("include/glm")
|
||||||
add_subdirectory("include/enet")
|
add_subdirectory("include/enet")
|
||||||
add_subdirectory("include/zstd")
|
add_subdirectory("include/zstd")
|
||||||
|
|
||||||
add_compile_definitions(FIXED_WINDOW=${FIXED_WINDOW} HN_USE_FILESYSTEM=1)
|
add_compile_definitions(FIXED_WINDOW=${FIXED_WINDOW} LOG_DEBUG=${LOG_DEBUG} LOG_TRACE=${LOG_TRACE} HN_USE_FILESYSTEM=1)
|
||||||
if(PROFILING)
|
if(PROFILING)
|
||||||
add_compile_definitions(TRACY_ENABLE=1)
|
add_compile_definitions(TRACY_ENABLE=1)
|
||||||
endif(PROFILING)
|
endif(PROFILING)
|
||||||
|
|
|
@ -7,12 +7,12 @@ namespace render {
|
||||||
|
|
||||||
bool Load(Window& window, bool preferVulkan, const renderOptions& options) {
|
bool Load(Window& window, bool preferVulkan, const renderOptions& options) {
|
||||||
if(!preferVulkan) {
|
if(!preferVulkan) {
|
||||||
LOG_D("Trying OpenGL");
|
LOG_T("Trying OpenGL");
|
||||||
if(gl::Renderer::Load(window, options))
|
if(gl::Renderer::Load(window, options))
|
||||||
return true;
|
return true;
|
||||||
window.destroy();
|
window.destroy();
|
||||||
}
|
}
|
||||||
LOG_D("Trying Vulkan");
|
LOG_T("Trying Vulkan");
|
||||||
if(vk::Renderer::Load(window, options))
|
if(vk::Renderer::Load(window, options))
|
||||||
return true;
|
return true;
|
||||||
window.destroy();
|
window.destroy();
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
using namespace render::vk;
|
using namespace render::vk;
|
||||||
|
|
||||||
|
constexpr auto HOST_EASILY_WRITABLE = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
||||||
|
constexpr VkDeviceSize MIN_ALLOC_SIZE = 1 << 28;
|
||||||
const auto NO_DELETER = Allocator::MemoryDeleter(nullptr);
|
const auto NO_DELETER = Allocator::MemoryDeleter(nullptr);
|
||||||
Allocator::memory_ptr Allocator::GetNull() { return Allocator::memory_ptr(nullptr, NO_DELETER); }
|
Allocator::memory_ptr Allocator::GetNull() { return Allocator::memory_ptr(nullptr, NO_DELETER); }
|
||||||
|
|
||||||
|
@ -54,11 +56,11 @@ void Allocator::setTracyZone(const char* name) {
|
||||||
(void)name;
|
(void)name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Allocator::memory_ptr Allocator::createBuffer(VkDeviceSize size, VkMemoryPropertyFlags properties, VkBufferUsageFlags usage, buffer_info& out) {
|
Allocator::memory_ptr Allocator::createBuffer(const buffer_requirement& requirement, VkMemoryPropertyFlags properties, buffer_info& out) {
|
||||||
VkBufferCreateInfo bufferInfo{};
|
VkBufferCreateInfo bufferInfo{};
|
||||||
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
bufferInfo.size = size;
|
bufferInfo.size = requirement.size;
|
||||||
bufferInfo.usage = usage;
|
bufferInfo.usage = requirement.usage;
|
||||||
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
|
||||||
if (vkCreateBuffer(device, &bufferInfo, ALLOC, &out.buffer) != VK_SUCCESS) {
|
if (vkCreateBuffer(device, &bufferInfo, ALLOC, &out.buffer) != VK_SUCCESS) {
|
||||||
|
@ -70,12 +72,28 @@ Allocator::memory_ptr Allocator::createBuffer(VkDeviceSize size, VkMemoryPropert
|
||||||
VkMemoryRequirements memRequirements;
|
VkMemoryRequirements memRequirements;
|
||||||
vkGetBufferMemoryRequirements(device, out.buffer, &memRequirements);
|
vkGetBufferMemoryRequirements(device, out.buffer, &memRequirements);
|
||||||
|
|
||||||
if (auto memory = allocate(memRequirements, properties)) {
|
auto memory = allocate(memRequirements, properties);
|
||||||
if(vkBindBufferMemory(device, out.buffer, memory->ref, memory->offset) == VK_SUCCESS)
|
if (!memory || vkBindBufferMemory(device, out.buffer, memory->ref, memory->offset) != VK_SUCCESS) {
|
||||||
return memory;
|
LOG_E("Failed to allocate buffer memory");
|
||||||
|
return GetNull();
|
||||||
}
|
}
|
||||||
LOG_E("Failed to allocate buffer memory");
|
|
||||||
return GetNull();
|
if (requirement.size != 0 && requirement.data != nullptr) {
|
||||||
|
if (memory->ptr != nullptr) {
|
||||||
|
memory->write(requirement.data, requirement.data_size, requirement.data_offset);
|
||||||
|
} else {
|
||||||
|
Allocator::buffer_info stagingBuffer;
|
||||||
|
if(auto stagingMemory = createBuffer({requirement.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT}, HOST_EASILY_WRITABLE, stagingBuffer)) {
|
||||||
|
stagingMemory->write(requirement.data, requirement.data_size, requirement.data_offset);
|
||||||
|
copyBuffer(stagingBuffer, out, requirement.size);
|
||||||
|
vkDestroyBuffer(device, stagingBuffer.buffer, ALLOC); //TODO: move to buffer destructor
|
||||||
|
} else {
|
||||||
|
FATAL("Cannot allocate staging memory");
|
||||||
|
return GetNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return memory;
|
||||||
}
|
}
|
||||||
Allocator::memory_ptr Allocator::createBuffers(const std::vector<buffer_requirement>& requirements, VkMemoryPropertyFlags properties, std::vector<buffer_info>& out) {
|
Allocator::memory_ptr Allocator::createBuffers(const std::vector<buffer_requirement>& requirements, VkMemoryPropertyFlags properties, std::vector<buffer_info>& out) {
|
||||||
assert(!requirements.empty());
|
assert(!requirements.empty());
|
||||||
|
@ -118,31 +136,93 @@ Allocator::memory_ptr Allocator::createBuffers(const std::vector<buffer_requirem
|
||||||
out.pop_back();
|
out.pop_back();
|
||||||
|
|
||||||
// Bind memory
|
// Bind memory
|
||||||
if (auto memory = allocate(memRequirements, properties)) {
|
auto memory = allocate(memRequirements, properties);
|
||||||
for (size_t i = 0; i < requirements.size(); i++) {
|
if (!memory) {
|
||||||
if (vkBindBufferMemory(device, out[i].buffer, memory->ref, memory->offset + out[i].offset) != VK_SUCCESS) {
|
LOG_E("Failed to allocate buffers");
|
||||||
LOG_E("Failed to bind buffer");
|
return GetNull();
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < requirements.size(); i++) {
|
||||||
|
if (vkBindBufferMemory(device, out[i].buffer, memory->ref, memory->offset + out[i].offset) != VK_SUCCESS) {
|
||||||
|
LOG_E("Failed to bind buffer");
|
||||||
|
return GetNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VkDeviceSize stagingSize = 0;
|
||||||
|
for (auto& requirement: requirements)
|
||||||
|
if (requirement.data != nullptr)
|
||||||
|
stagingSize = std::max(stagingSize, requirement.size);
|
||||||
|
|
||||||
|
// Copy datas
|
||||||
|
if (stagingSize != 0) {
|
||||||
|
if (memory->ptr != nullptr) {
|
||||||
|
for (size_t i = 0; i < requirements.size(); i++) {
|
||||||
|
if (requirements[i].data != nullptr && requirements[i].size != 0) {
|
||||||
|
assert(requirements[i].data_size + requirements[i].data_offset <= requirements[i].size);
|
||||||
|
memory->write(requirements[i].data, requirements[i].data_size, out[i].offset + requirements[i].data_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Allocator::buffer_info stagingBuffer;
|
||||||
|
if(auto stagingMemory = createBuffer({stagingSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT}, HOST_EASILY_WRITABLE, stagingBuffer)) {
|
||||||
|
for (size_t i = 0; i < requirements.size(); i++) {
|
||||||
|
if (requirements[i].data != nullptr && requirements[i].size != 0) {
|
||||||
|
assert(requirements[i].data_size + requirements[i].data_offset <= requirements[i].size);
|
||||||
|
stagingMemory->write(requirements[i].data, requirements[i].data_size, requirements[i].data_offset);
|
||||||
|
copyBuffer(stagingBuffer, out[i], requirements[i].size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vkDestroyBuffer(device, stagingBuffer.buffer, ALLOC); //TODO: move to buffer destructor
|
||||||
|
} else {
|
||||||
|
FATAL("Cannot allocate staging memory");
|
||||||
return GetNull();
|
return GetNull();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return memory;
|
|
||||||
}
|
}
|
||||||
LOG_E("Failed to allocate buffers");
|
|
||||||
return GetNull();
|
return memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
Allocator::memory_ptr Allocator::allocate(VkMemoryRequirements requirements, VkMemoryPropertyFlags properties) {
|
Allocator::memory_ptr Allocator::allocate(VkMemoryRequirements requirements, VkMemoryPropertyFlags properties) {
|
||||||
//TODO: search for existing allocation
|
// Search in existing allocations
|
||||||
//TODO: allocate more ???
|
for (auto& alloc: allocations) {
|
||||||
|
if ((requirements.memoryTypeBits & (1 << alloc->memoryType)) && (this->properties.memoryTypes[alloc->memoryType].propertyFlags & properties) == properties && alloc->size > requirements.size) {
|
||||||
|
VkDeviceSize start = 0;
|
||||||
|
auto aligned = [&](VkDeviceSize offset) {
|
||||||
|
if (offset % requirements.alignment == 0)
|
||||||
|
return offset;
|
||||||
|
return offset + requirements.alignment - (offset % requirements.alignment);
|
||||||
|
};
|
||||||
|
auto it = alloc->areas.cbegin();
|
||||||
|
auto done = [&] {
|
||||||
|
alloc->areas.insert(it, {requirements.size, start});
|
||||||
|
return memory_ptr(new memory_area{alloc->memory, requirements.size, start, alloc->ptr != nullptr ? alloc->ptr + start : nullptr}, alloc->deleter);
|
||||||
|
};
|
||||||
|
while (it != alloc->areas.cend()) {
|
||||||
|
if (it->offset - start > requirements.size) {
|
||||||
|
return done();
|
||||||
|
}
|
||||||
|
start = aligned(it->offset + it->size);
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
if (alloc->size - start > requirements.size) {
|
||||||
|
return done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_T("Need to allocate more");
|
||||||
|
|
||||||
VkMemoryAllocateInfo allocInfo{};
|
VkMemoryAllocateInfo allocInfo{};
|
||||||
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
allocInfo.allocationSize = requirements.size;
|
allocInfo.allocationSize = std::max(MIN_ALLOC_SIZE, requirements.size);
|
||||||
if (const auto memIdx = findMemory(requirements.memoryTypeBits, properties, requirements.size)) {
|
if (const auto memIdx = findMemory(requirements.memoryTypeBits, properties, allocInfo.allocationSize)) {
|
||||||
//TODO: check budget
|
allocInfo.memoryTypeIndex = memIdx.value();
|
||||||
|
} else if (const auto memIdx = findMemory(requirements.memoryTypeBits, properties, requirements.size)) {
|
||||||
|
LOG_W("Memory heavily limited cannot allocate full page");
|
||||||
|
allocInfo.allocationSize = requirements.size;
|
||||||
allocInfo.memoryTypeIndex = memIdx.value();
|
allocInfo.memoryTypeIndex = memIdx.value();
|
||||||
} else {
|
} else {
|
||||||
LOG_E("No suitable memory heap");
|
LOG_E("No suitable memory heap under budget");
|
||||||
return GetNull();
|
return GetNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,12 +233,12 @@ Allocator::memory_ptr Allocator::allocate(VkMemoryRequirements requirements, VkM
|
||||||
}
|
}
|
||||||
|
|
||||||
void *ptr = nullptr;
|
void *ptr = nullptr;
|
||||||
if (properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
|
if ((this->properties.memoryTypes[allocInfo.memoryTypeIndex].propertyFlags & HOST_EASILY_WRITABLE) == HOST_EASILY_WRITABLE) {
|
||||||
vkMapMemory(device, memory, 0, VK_WHOLE_SIZE, 0, &ptr);
|
vkMapMemory(device, memory, 0, VK_WHOLE_SIZE, 0, &ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto allocation = allocations.emplace_back(new Allocation(device, memory, allocInfo.allocationSize, allocInfo.memoryTypeIndex, ptr)).get();
|
auto allocation = allocations.emplace_back(new Allocation(device, memory, allocInfo.allocationSize, allocInfo.memoryTypeIndex, ptr)).get();
|
||||||
allocation->areas.push_back({allocInfo.allocationSize, 0});
|
allocation->areas.push_back({requirements.size, 0});
|
||||||
|
|
||||||
return memory_ptr(new memory_area{memory, requirements.size, 0, ptr}, allocation->deleter);
|
return memory_ptr(new memory_area{memory, requirements.size, 0, ptr}, allocation->deleter);
|
||||||
}
|
}
|
||||||
|
@ -191,10 +271,10 @@ void Allocator::copyBuffer(buffer_info src, buffer_info dst, VkDeviceSize size)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<uint32_t> Allocator::findMemory(uint32_t typeFilter, VkMemoryPropertyFlags requirement, VkDeviceSize size) const {
|
std::optional<uint32_t> Allocator::findMemory(uint32_t typeFilter, VkMemoryPropertyFlags requirement, VkDeviceSize size) const {
|
||||||
#if DEBUG
|
#if LOG_TRACE
|
||||||
LOG_D("available memory:");
|
LOG_T("Available memory:");
|
||||||
for (uint32_t i = 0; i < properties.memoryTypeCount; i++) {
|
for (uint32_t i = 0; i < properties.memoryTypeCount; i++) {
|
||||||
LOG_D('\t' << i << ": " << ((properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) ? "local " : "")
|
LOG_T('\t' << i << ": " << ((properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) ? "local " : "")
|
||||||
<< ((properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) ? "visible " : "")
|
<< ((properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) ? "visible " : "")
|
||||||
<< ((properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) ? "coherent " : "")
|
<< ((properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) ? "coherent " : "")
|
||||||
<< ((properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) ? "cached " : "")
|
<< ((properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) ? "cached " : "")
|
||||||
|
@ -232,6 +312,7 @@ void Allocator::MemoryDeleter::operator()(memory_area* area) {
|
||||||
if(it->offset == area->offset) {
|
if(it->offset == area->offset) {
|
||||||
assert(it->size == area->size);
|
assert(it->size == area->size);
|
||||||
owner->areas.erase(it);
|
owner->areas.erase(it);
|
||||||
|
//MAYBE: remove if empty
|
||||||
delete area;
|
delete area;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,14 +45,15 @@ public:
|
||||||
VkBuffer buffer = nullptr;
|
VkBuffer buffer = nullptr;
|
||||||
VkDeviceSize offset = 0;
|
VkDeviceSize offset = 0;
|
||||||
};
|
};
|
||||||
memory_ptr createBuffer(VkDeviceSize, VkMemoryPropertyFlags, VkBufferUsageFlags, buffer_info&);
|
|
||||||
struct buffer_requirement {
|
struct buffer_requirement {
|
||||||
VkDeviceSize size;
|
VkDeviceSize size;
|
||||||
VkBufferUsageFlags usage;
|
VkBufferUsageFlags usage;
|
||||||
|
const void *data = nullptr;
|
||||||
|
VkDeviceSize data_size = 0;
|
||||||
|
VkDeviceSize data_offset = 0;
|
||||||
};
|
};
|
||||||
|
memory_ptr createBuffer(const buffer_requirement&, VkMemoryPropertyFlags, buffer_info&);
|
||||||
memory_ptr createBuffers(const std::vector<buffer_requirement> &, VkMemoryPropertyFlags, std::vector<buffer_info> &);
|
memory_ptr createBuffers(const std::vector<buffer_requirement> &, VkMemoryPropertyFlags, std::vector<buffer_info> &);
|
||||||
//TODO: create Buffer{MemoryArea + VkBuffer}
|
|
||||||
//TODO: create readonly buffer with data
|
|
||||||
|
|
||||||
void copyBuffer(buffer_info srcBuffer, buffer_info dstBuffer, VkDeviceSize size);
|
void copyBuffer(buffer_info srcBuffer, buffer_info dstBuffer, VkDeviceSize size);
|
||||||
|
|
||||||
|
@ -71,7 +72,7 @@ private:
|
||||||
const VkDeviceMemory memory;
|
const VkDeviceMemory memory;
|
||||||
const VkDeviceSize size;
|
const VkDeviceSize size;
|
||||||
const uint32_t memoryType;
|
const uint32_t memoryType;
|
||||||
const void *ptr = nullptr;
|
void *const ptr = nullptr;
|
||||||
const MemoryDeleter deleter;
|
const MemoryDeleter deleter;
|
||||||
|
|
||||||
struct area { VkDeviceSize size; VkDeviceSize offset; };
|
struct area { VkDeviceSize size; VkDeviceSize offset; };
|
||||||
|
|
|
@ -24,27 +24,14 @@ device(device), indexedBufferMemory(Allocator::GetNull()), uniformBuffersMemory(
|
||||||
{ // Vertex buffers (const)
|
{ // Vertex buffers (const)
|
||||||
size_t vertexSize = sizeof(buffer::vk::vertices[0]) * buffer::vk::vertices.size();
|
size_t vertexSize = sizeof(buffer::vk::vertices[0]) * buffer::vk::vertices.size();
|
||||||
size_t indexSize = sizeof(buffer::vk::indices[0]) * buffer::vk::indices.size();
|
size_t indexSize = sizeof(buffer::vk::indices[0]) * buffer::vk::indices.size();
|
||||||
size_t stagingSize = std::max(vertexSize, indexSize);
|
if(std::vector<Allocator::buffer_info> out; indexedBufferMemory = alloc.createBuffers({
|
||||||
Allocator::buffer_info stagingBuffer;
|
{indexSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, buffer::vk::indices.data(), indexSize, 0},
|
||||||
if(auto stagingMemory = alloc.createBuffer(stagingSize, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, stagingBuffer)) {
|
{vertexSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, buffer::vk::vertices.data(), vertexSize, 0}
|
||||||
if(std::vector<Allocator::buffer_info> out; indexedBufferMemory = alloc.createBuffers({
|
}, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, out)) {
|
||||||
{indexSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT},
|
indexBuffer = out[0];
|
||||||
{vertexSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT}
|
vertexBuffer = out[1];
|
||||||
}, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, out)) {
|
|
||||||
indexBuffer = out[0];
|
|
||||||
vertexBuffer = out[1];
|
|
||||||
} else {
|
|
||||||
FATAL("Cannot allocate buffer memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
stagingMemory->write(buffer::vk::vertices.data(), vertexSize);
|
|
||||||
alloc.copyBuffer(stagingBuffer, vertexBuffer, vertexSize);
|
|
||||||
stagingMemory->write(buffer::vk::indices.data(), indexSize);
|
|
||||||
alloc.copyBuffer(stagingBuffer, indexBuffer, indexSize);
|
|
||||||
|
|
||||||
vkDestroyBuffer(device, stagingBuffer.buffer, ALLOC); //TODO: move to buffer
|
|
||||||
} else {
|
} else {
|
||||||
FATAL("Cannot allocate staging memory");
|
FATAL("Cannot create vertex buffer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,8 +42,8 @@ QueueFamilyIndices QueueFamilyIndices::Query(VkPhysicalDevice device, VkSurfaceK
|
||||||
queueIndices.presentFamily = i;
|
queueIndices.presentFamily = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if LOG_TRACE
|
||||||
LOG_D("Queue " << i << ' ' << (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT ? "graphics " : "")
|
LOG_T("Queue " << i << ' ' << (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT ? "graphics " : "")
|
||||||
<< (queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT ? "compute " : "")
|
<< (queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT ? "compute " : "")
|
||||||
<< (presentSupport ? "present " : "")
|
<< (presentSupport ? "present " : "")
|
||||||
<< (queueFamily.queueFlags & VK_QUEUE_TRANSFER_BIT ? "transfer " : "")
|
<< (queueFamily.queueFlags & VK_QUEUE_TRANSFER_BIT ? "transfer " : "")
|
||||||
|
|
|
@ -135,10 +135,10 @@ bool Renderer::Load(Window& window, const renderOptions& opt) {
|
||||||
std::vector<VkExtensionProperties> availableExtensions(availableExtensionCount);
|
std::vector<VkExtensionProperties> availableExtensions(availableExtensionCount);
|
||||||
vkEnumerateInstanceExtensionProperties(nullptr, &availableExtensionCount, availableExtensions.data());
|
vkEnumerateInstanceExtensionProperties(nullptr, &availableExtensionCount, availableExtensions.data());
|
||||||
|
|
||||||
#if DEBUG
|
#if LOG_TRACE
|
||||||
LOG_D("Available extensions:");
|
LOG_T("Available extensions:");
|
||||||
for (const auto &extension : availableExtensions) {
|
for (const auto &extension : availableExtensions) {
|
||||||
LOG_D('\t' << extension.extensionName << " : " << extension.specVersion);
|
LOG_T('\t' << extension.extensionName << " : " << extension.specVersion);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -163,10 +163,10 @@ bool Renderer::Load(Window& window, const renderOptions& opt) {
|
||||||
std::vector<VkLayerProperties> availableLayers(availableLayerCount);
|
std::vector<VkLayerProperties> availableLayers(availableLayerCount);
|
||||||
vkEnumerateInstanceLayerProperties(&availableLayerCount, availableLayers.data());
|
vkEnumerateInstanceLayerProperties(&availableLayerCount, availableLayers.data());
|
||||||
|
|
||||||
#if DEBUG
|
#if LOG_TRACE
|
||||||
LOG_D("Available layers:");
|
LOG_T("Available layers:");
|
||||||
for (const auto &layer : availableLayers) {
|
for (const auto &layer : availableLayers) {
|
||||||
LOG_D('\t' << layer.layerName << " : " << layer.specVersion);
|
LOG_T('\t' << layer.layerName << " : " << layer.specVersion);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ void DistantUniverse::pullNetwork(voxel_pos pos) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
dict.emplace(packet->data + sizeof(server_packet_type), packet->dataLength - sizeof(server_packet_type));
|
dict.emplace(packet->data + sizeof(server_packet_type), packet->dataLength - sizeof(server_packet_type));
|
||||||
LOG_D("Compression dictionnary loaded");
|
LOG_T("Compression dictionnary loaded");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ public:
|
||||||
for(int i = 0; i < count && enet_host_service(host, &event, delay) > 0; i++) {
|
for(int i = 0; i < count && enet_host_service(host, &event, delay) > 0; i++) {
|
||||||
switch(event.type) {
|
switch(event.type) {
|
||||||
case ENET_EVENT_TYPE_CONNECT:
|
case ENET_EVENT_TYPE_CONNECT:
|
||||||
LOG_D("Client reconnected");
|
LOG_T("Client reconnected");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ENET_EVENT_TYPE_DISCONNECT:
|
case ENET_EVENT_TYPE_DISCONNECT:
|
||||||
|
@ -60,30 +60,30 @@ public:
|
||||||
|
|
||||||
case ENET_EVENT_TYPE_RECEIVE: {
|
case ENET_EVENT_TYPE_RECEIVE: {
|
||||||
if(event.packet->dataLength < sizeof(server_packet_type)) {
|
if(event.packet->dataLength < sizeof(server_packet_type)) {
|
||||||
LOG_D("Empty packet from server");
|
LOG_T("Empty packet from server");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const server_packet_type type = static_cast<server_packet_type>(*event.packet->data);
|
const server_packet_type type = static_cast<server_packet_type>(*event.packet->data);
|
||||||
if(type < server_packet_type::BROADCASTED) {
|
if(type < server_packet_type::BROADCASTED) {
|
||||||
if(event.packet->dataLength < sizeof(server_packet_type) + sizeof(salt)) {
|
if(event.packet->dataLength < sizeof(server_packet_type) + sizeof(salt)) {
|
||||||
LOG_D("Wrong salted packet size");
|
LOG_T("Wrong salted packet size");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(memcmp(&salt, event.packet->data + sizeof(server_packet_type), sizeof(salt)) != 0) {
|
if(memcmp(&salt, event.packet->data + sizeof(server_packet_type), sizeof(salt)) != 0) {
|
||||||
LOG_D("Wrong server salt");
|
LOG_T("Wrong server salt");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(type == server_packet_type::CHALLENGE) {
|
if(type == server_packet_type::CHALLENGE) {
|
||||||
if(event.packet->dataLength != sizeof(server_packet_type) + 2 * sizeof(salt)) {
|
if(event.packet->dataLength != sizeof(server_packet_type) + 2 * sizeof(salt)) {
|
||||||
LOG_D("Wrong challenge packet size");
|
LOG_T("Wrong challenge packet size");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
salt_t l;
|
salt_t l;
|
||||||
PacketReader(event.packet).read(l);
|
PacketReader(event.packet).read(l);
|
||||||
salt ^= l;
|
salt ^= l;
|
||||||
LOG_D("Handshake done");
|
LOG_T("Handshake done");
|
||||||
ready = true;
|
ready = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,20 @@
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
#define _OUT(expr) {std::ostringstream oss; oss << expr << std::endl; std::cout << oss.str();}
|
#define _OUT(expr) {std::ostringstream oss; oss << expr << std::endl; std::cout << oss.str();}
|
||||||
#define LOG(expr) _OUT("[" << logger::now() << "] " << expr)
|
#define LOG(expr) _OUT("[" << BOLD << logger::now() << END_COLOR << "] " << BOLD << expr << END_COLOR)
|
||||||
#define LOG_E(expr) _OUT("[" << RED << logger::now() << END_COLOR << "] " << expr)
|
#define LOG_E(expr) _OUT("[" << RED << logger::now() << END_COLOR << "] " << expr)
|
||||||
#define LOG_W(expr) _OUT("[" << YELLOW << logger::now() << END_COLOR << "] " << expr)
|
#define LOG_W(expr) _OUT("[" << YELLOW << logger::now() << END_COLOR << "] " << expr)
|
||||||
#define LOG_I(expr) _OUT("[" << GREEN << logger::now() << END_COLOR << "] " << expr)
|
#define LOG_I(expr) _OUT("[" << GREEN << logger::now() << END_COLOR << "] " << expr)
|
||||||
#define LOG_D(expr) _OUT("[" << GREY << logger::now() << END_COLOR << "] " << expr)
|
#if LOG_DEBUG
|
||||||
|
#define LOG_D(expr) _OUT("[" << END_COLOR << logger::now() << END_COLOR << "] " << expr)
|
||||||
|
#else
|
||||||
|
#define LOG_D(expr)
|
||||||
|
#endif
|
||||||
|
#if LOG_TRACE
|
||||||
|
#define LOG_T(expr) _OUT("[" << GREY << logger::now() << END_COLOR << "] " << expr)
|
||||||
|
#else
|
||||||
|
#define LOG_T(expr)
|
||||||
|
#endif
|
||||||
#define FATAL(expr) LOG_E(expr); exit(EXIT_FAILURE)
|
#define FATAL(expr) LOG_E(expr); exit(EXIT_FAILURE)
|
||||||
|
|
||||||
namespace logger {
|
namespace logger {
|
||||||
|
|
|
@ -43,7 +43,7 @@ Universe::Universe(const Universe::options &options): host(options.connection, o
|
||||||
}
|
}
|
||||||
assert(tmp.size() == size && "Corrupted areas index");
|
assert(tmp.size() == size && "Corrupted areas index");
|
||||||
far_areas = data::generational::vector<Area::params>(tmp);
|
far_areas = data::generational::vector<Area::params>(tmp);
|
||||||
LOG_D(far_areas.size() << " areas loaded");
|
LOG_T(far_areas.size() << " areas loaded");
|
||||||
} else {
|
} else {
|
||||||
LOG_E("No index file!!! Probably a new world...");
|
LOG_E("No index file!!! Probably a new world...");
|
||||||
//TODO: generate universe
|
//TODO: generate universe
|
||||||
|
@ -333,7 +333,7 @@ void Universe::pullNetwork() {
|
||||||
host.pull(
|
host.pull(
|
||||||
[&](peer_t *peer, salt_t salt) {
|
[&](peer_t *peer, salt_t salt) {
|
||||||
ZoneScopedN("Connect");
|
ZoneScopedN("Connect");
|
||||||
LOG_D("Client connect from " << peer->address);
|
LOG_I("Client connect from " << peer->address);
|
||||||
net_client* client = new net_client(salt, entities.at(PLAYER_ENTITY_ID).instances.emplace(Entity::Instance{ }));
|
net_client* client = new net_client(salt, entities.at(PLAYER_ENTITY_ID).instances.emplace(Entity::Instance{ }));
|
||||||
peer->data = client;
|
peer->data = client;
|
||||||
|
|
||||||
|
@ -347,14 +347,14 @@ void Universe::pullNetwork() {
|
||||||
},
|
},
|
||||||
[](peer_t *peer, disconnect_reason reason) {
|
[](peer_t *peer, disconnect_reason reason) {
|
||||||
ZoneScopedN("Disconnect");
|
ZoneScopedN("Disconnect");
|
||||||
LOG_D("Client disconnect from " << peer->address << " with " << (enet_uint32)reason);
|
LOG_I("Client disconnect from " << peer->address << " with " << (enet_uint32)reason);
|
||||||
if (const auto data = Server::GetPeerData<net_client>(peer); data != nullptr)
|
if (const auto data = Server::GetPeerData<net_client>(peer); data != nullptr)
|
||||||
delete data;
|
delete data;
|
||||||
},
|
},
|
||||||
[&](peer_t *peer, packet_t* packet, channel_type) {
|
[&](peer_t *peer, packet_t* packet, channel_type) {
|
||||||
ZoneScopedN("Data");
|
ZoneScopedN("Data");
|
||||||
if(packet->dataLength < sizeof(client_packet_type) + sizeof(salt_t)) {
|
if(packet->dataLength < sizeof(client_packet_type) + sizeof(salt_t)) {
|
||||||
LOG_D("Empty packet from " << peer->address);
|
LOG_T("Empty packet from " << peer->address);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (memcmp(peer->data, packet->data + sizeof(client_packet_type), sizeof(salt_t)) != 0) {
|
if (memcmp(peer->data, packet->data + sizeof(client_packet_type), sizeof(salt_t)) != 0) {
|
||||||
|
@ -368,7 +368,7 @@ void Universe::pullNetwork() {
|
||||||
case client_packet_type::MOVE: {
|
case client_packet_type::MOVE: {
|
||||||
if(voxel_pos pos; !PacketReader(packet).read(pos) ||
|
if(voxel_pos pos; !PacketReader(packet).read(pos) ||
|
||||||
!movePlayer(Server::GetPeerData<net_client>(peer)->instanceId, pos)) {
|
!movePlayer(Server::GetPeerData<net_client>(peer)->instanceId, pos)) {
|
||||||
LOG_D("Bad move");
|
LOG_T("Bad move");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -377,7 +377,7 @@ void Universe::pullNetwork() {
|
||||||
//TODO: handle inventory
|
//TODO: handle inventory
|
||||||
setCube(fill->pos, fill->val, fill->radius);
|
setCube(fill->pos, fill->val, fill->radius);
|
||||||
} else {
|
} else {
|
||||||
LOG_D("Bad fill");
|
LOG_T("Bad fill");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -396,16 +396,16 @@ void Universe::pullNetwork() {
|
||||||
host.send(peer, serializeChunk({std::make_pair(id, cpos), std::dynamic_pointer_cast<Chunk>(chunk->second)}), net::channel_type::RELIABLE);
|
host.send(peer, serializeChunk({std::make_pair(id, cpos), std::dynamic_pointer_cast<Chunk>(chunk->second)}), net::channel_type::RELIABLE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_D("Request out of range chunk");
|
LOG_T("Request out of range chunk");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_D("Bad chunk request");
|
LOG_T("Bad chunk request");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
LOG_D("Bad packet from " << peer->address);
|
LOG_T("Bad packet from " << peer->address);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue