Shaders assets and loading fix
- a = { ... } definitions replaced with a { ... }
- GetOverlappedResult replaced with waiting for event in Windows async file loading
- FileHandles and AssetHandles stored in heap for container element adresses consistence
- Shader assets examples
This commit is contained in:
parent
9a258f7443
commit
7ad2ec4dc8
@ -11,12 +11,12 @@ struct WorldBenchmark : testing::Test
|
|||||||
{
|
{
|
||||||
for (int16_t i = 0; i < 1000; i++)
|
for (int16_t i = 0; i < 1000; i++)
|
||||||
{
|
{
|
||||||
ee_economy::Container resources = {.capacity = 100.0};
|
ee_economy::Container resources {.capacity = 100.0};
|
||||||
resources.add(ee_economy::RESOURCE_TYPE::COAL, 100.0);
|
resources.add(ee_economy::RESOURCE_TYPE::COAL, 100.0);
|
||||||
entt::entity state = world.registerState(i, resources);
|
entt::entity state = world.registerState(i, resources);
|
||||||
|
|
||||||
ee_economy::EnterpriseDefaults miner = {
|
ee_economy::EnterpriseDefaults miner {
|
||||||
.container = {.capacity = 100.0},
|
.container {.capacity = 100.0},
|
||||||
.resourceTarget = ee_economy::RESOURCE_TYPE::GOLD,
|
.resourceTarget = ee_economy::RESOURCE_TYPE::GOLD,
|
||||||
.baseEfficiency = 1.0
|
.baseEfficiency = 1.0
|
||||||
};
|
};
|
||||||
|
|||||||
@ -7,7 +7,7 @@ TEST(WorldTest, RegisterState)
|
|||||||
{
|
{
|
||||||
ee_ecs::World world;
|
ee_ecs::World world;
|
||||||
|
|
||||||
ee_economy::Container res = {.capacity = 100.0};
|
ee_economy::Container res {.capacity = 100.0};
|
||||||
res.add(ee_economy::RESOURCE_TYPE::COAL, 98.0);
|
res.add(ee_economy::RESOURCE_TYPE::COAL, 98.0);
|
||||||
entt::entity state = world.registerState(10, res);
|
entt::entity state = world.registerState(10, res);
|
||||||
|
|
||||||
@ -37,8 +37,8 @@ TEST(WorldTest, SpawnMiner)
|
|||||||
world.getRegistry().emplace<ee_economy::State>(state, (int16_t)0);
|
world.getRegistry().emplace<ee_economy::State>(state, (int16_t)0);
|
||||||
world.getRegistry().emplace<ee_economy::Container>(state, 100.0);
|
world.getRegistry().emplace<ee_economy::Container>(state, 100.0);
|
||||||
|
|
||||||
ee_economy::EnterpriseDefaults defaults = {
|
ee_economy::EnterpriseDefaults defaults {
|
||||||
.container = {.capacity = 100.0 },
|
.container {.capacity = 100.0 },
|
||||||
.resourceTarget = ee_economy::RESOURCE_TYPE::COAL,
|
.resourceTarget = ee_economy::RESOURCE_TYPE::COAL,
|
||||||
.baseEfficiency = 1.0,
|
.baseEfficiency = 1.0,
|
||||||
};
|
};
|
||||||
@ -62,8 +62,8 @@ TEST(WorldTest, SpawnDeliverer)
|
|||||||
world.getRegistry().emplace<ee_economy::State>(state, (int16_t)0);
|
world.getRegistry().emplace<ee_economy::State>(state, (int16_t)0);
|
||||||
world.getRegistry().emplace<ee_economy::Container>(state, 100.0);
|
world.getRegistry().emplace<ee_economy::Container>(state, 100.0);
|
||||||
|
|
||||||
ee_economy::EnterpriseDefaults defaults = {
|
ee_economy::EnterpriseDefaults defaults {
|
||||||
.container = {.capacity = 100.0 },
|
.container {.capacity = 100.0 },
|
||||||
.resourceTarget = ee_economy::RESOURCE_TYPE::COAL,
|
.resourceTarget = ee_economy::RESOURCE_TYPE::COAL,
|
||||||
.baseEfficiency = 1.0,
|
.baseEfficiency = 1.0,
|
||||||
};
|
};
|
||||||
|
|||||||
BIN
assets/shaders/helloworld.frag.spv
Normal file
BIN
assets/shaders/helloworld.frag.spv
Normal file
Binary file not shown.
BIN
assets/shaders/helloworld.vert.spv
Normal file
BIN
assets/shaders/helloworld.vert.spv
Normal file
Binary file not shown.
@ -12,4 +12,5 @@ struct AssetBinary : AssetData
|
|||||||
|
|
||||||
AssetBinary(uint8_t* &source, size_t sourceSize);
|
AssetBinary(uint8_t* &source, size_t sourceSize);
|
||||||
~AssetBinary();
|
~AssetBinary();
|
||||||
};
|
};
|
||||||
|
typedef AssetBinary AssetShader;
|
||||||
@ -27,6 +27,7 @@ public:
|
|||||||
BINARY,
|
BINARY,
|
||||||
|
|
||||||
SHADER,
|
SHADER,
|
||||||
|
MATERIAL,
|
||||||
IMAGE
|
IMAGE
|
||||||
} type = BINARY;
|
} type = BINARY;
|
||||||
|
|
||||||
@ -82,6 +83,8 @@ public:
|
|||||||
void Request(const AssetStreamCommand &command);
|
void Request(const AssetStreamCommand &command);
|
||||||
void Request(const AssetStreamCommand::Type &type);
|
void Request(const AssetStreamCommand::Type &type);
|
||||||
|
|
||||||
|
void LoadShaders();
|
||||||
|
|
||||||
void LoadAsync(AssetInfo::Type type, const std::filesystem::path &path);
|
void LoadAsync(AssetInfo::Type type, const std::filesystem::path &path);
|
||||||
AssetHandle& Find(const std::filesystem::path &path);
|
AssetHandle& Find(const std::filesystem::path &path);
|
||||||
void Redirect(AssetHandle &handle, void *resource);
|
void Redirect(AssetHandle &handle, void *resource);
|
||||||
@ -96,7 +99,7 @@ private:
|
|||||||
IFileSystem *diskSystem;
|
IFileSystem *diskSystem;
|
||||||
|
|
||||||
std::vector<AssetInfo> activeAssets;
|
std::vector<AssetInfo> activeAssets;
|
||||||
std::unordered_map<std::filesystem::path, AssetHandle> assetsMapping;
|
std::unordered_map<std::filesystem::path, AssetHandle*> assetsMapping;
|
||||||
std::vector<size_t> freeAssetSlots;
|
std::vector<size_t> freeAssetSlots;
|
||||||
std::vector<AssetLoadingEntry> loadingEntries;
|
std::vector<AssetLoadingEntry> loadingEntries;
|
||||||
|
|
||||||
@ -111,7 +114,7 @@ private:
|
|||||||
template <Asset T> T& AssetManager::Get(const AssetHandle &handle)
|
template <Asset T> T& AssetManager::Get(const AssetHandle &handle)
|
||||||
{
|
{
|
||||||
std::atomic<void*> result;
|
std::atomic<void*> result;
|
||||||
AssetStreamCommand command = {
|
AssetStreamCommand command {
|
||||||
.type = AssetStreamCommand::GET,
|
.type = AssetStreamCommand::GET,
|
||||||
.target = handle,
|
.target = handle,
|
||||||
.out = &result
|
.out = &result
|
||||||
|
|||||||
@ -46,11 +46,13 @@ public:
|
|||||||
virtual FileHandle& Open(const std::filesystem::path &path, const uint32_t flags) = 0;
|
virtual FileHandle& Open(const std::filesystem::path &path, const uint32_t flags) = 0;
|
||||||
virtual void ReadAsync(FileHandle &file, const uint32_t bufferSize, const uint32_t flags) = 0;
|
virtual void ReadAsync(FileHandle &file, const uint32_t bufferSize, const uint32_t flags) = 0;
|
||||||
virtual bool PollReady(FileHandle &file) = 0;
|
virtual bool PollReady(FileHandle &file) = 0;
|
||||||
virtual void Close(const FileHandle &file) = 0;
|
virtual void Close(FileHandle &file) = 0;
|
||||||
|
|
||||||
|
~IFileSystem();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<FileHandle> activeFiles;
|
std::vector<FileHandle*> activeFiles;
|
||||||
std::vector<FileHandle> failedFiles;
|
std::vector<FileHandle*> failedFiles;
|
||||||
std::vector<size_t> freeFileSlots;
|
std::vector<size_t> freeFileSlots;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,7 +62,7 @@ public:
|
|||||||
FileHandle& Open(const std::filesystem::path &path, const uint32_t flags) override;
|
FileHandle& Open(const std::filesystem::path &path, const uint32_t flags) override;
|
||||||
void ReadAsync(FileHandle &file, const uint32_t bufferSize, uint32_t flags) override;
|
void ReadAsync(FileHandle &file, const uint32_t bufferSize, uint32_t flags) override;
|
||||||
bool PollReady(FileHandle &file) override;
|
bool PollReady(FileHandle &file) override;
|
||||||
void Close(const FileHandle &file) override;
|
void Close(FileHandle &file) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include "AssetManager.hpp"
|
#include "AssetManager.hpp"
|
||||||
#include "allocator.hpp"
|
#include "allocator.hpp"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
AssetInfo::AssetInfo(void *resource)
|
AssetInfo::AssetInfo(void *resource)
|
||||||
{
|
{
|
||||||
@ -81,7 +82,7 @@ void AssetManager::Request(const AssetStreamCommand::Type &type)
|
|||||||
|
|
||||||
void AssetManager::LoadAsync(AssetInfo::Type type, const std::filesystem::path &path)
|
void AssetManager::LoadAsync(AssetInfo::Type type, const std::filesystem::path &path)
|
||||||
{
|
{
|
||||||
AssetStreamCommand command = {
|
AssetStreamCommand command {
|
||||||
.type = AssetStreamCommand::LOAD,
|
.type = AssetStreamCommand::LOAD,
|
||||||
.targetPath = path,
|
.targetPath = path,
|
||||||
.targetType = type
|
.targetType = type
|
||||||
@ -92,7 +93,7 @@ void AssetManager::LoadAsync(AssetInfo::Type type, const std::filesystem::path &
|
|||||||
AssetHandle& AssetManager::Find(const std::filesystem::path &path)
|
AssetHandle& AssetManager::Find(const std::filesystem::path &path)
|
||||||
{
|
{
|
||||||
std::atomic<void*> result;
|
std::atomic<void*> result;
|
||||||
AssetStreamCommand command = {
|
AssetStreamCommand command {
|
||||||
.type = AssetStreamCommand::FIND,
|
.type = AssetStreamCommand::FIND,
|
||||||
.targetPath = path,
|
.targetPath = path,
|
||||||
.out = &result
|
.out = &result
|
||||||
@ -104,7 +105,7 @@ AssetHandle& AssetManager::Find(const std::filesystem::path &path)
|
|||||||
|
|
||||||
void AssetManager::Start()
|
void AssetManager::Start()
|
||||||
{
|
{
|
||||||
if (isRunning) throw std::exception("Asset Streaming can be started only once");
|
if (isRunning) throw std::logic_error("Asset Streaming can be started only once");
|
||||||
|
|
||||||
isRunning.store(true);
|
isRunning.store(true);
|
||||||
streamingThread = std::jthread([this](std::stop_token stop) {
|
streamingThread = std::jthread([this](std::stop_token stop) {
|
||||||
@ -156,7 +157,7 @@ void AssetManager::Loop()
|
|||||||
//TODO: functions for each type
|
//TODO: functions for each type
|
||||||
switch (asset.type)
|
switch (asset.type)
|
||||||
{
|
{
|
||||||
case AssetInfo::SHADER:
|
case AssetInfo::MATERIAL:
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -166,6 +167,7 @@ void AssetManager::Loop()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case AssetInfo::SHADER:
|
||||||
case AssetInfo::BINARY:
|
case AssetInfo::BINARY:
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
@ -176,8 +178,13 @@ void AssetManager::Loop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
asset.isReady.store(true);
|
entry.fileOwner->Close(*entry.file);
|
||||||
|
#ifndef NDEBUG
|
||||||
|
auto path = entry.file->debugPath.c_str();
|
||||||
|
LOG(INFO, "Asset loaded: [%s]", path);
|
||||||
|
#endif
|
||||||
entry.file = nullptr;
|
entry.file = nullptr;
|
||||||
|
asset.isReady.store(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +199,7 @@ void AssetManager::ProcessCommand(AssetStreamCommand &command)
|
|||||||
{
|
{
|
||||||
case AssetStreamCommand::LOAD:
|
case AssetStreamCommand::LOAD:
|
||||||
{
|
{
|
||||||
LOG(INFO, "LOAD command");
|
LOG(INFO, "LOAD command: [%s]", command.targetPath.c_str());
|
||||||
|
|
||||||
/* TODO: process path to select FS */
|
/* TODO: process path to select FS */
|
||||||
/* TODO: select between async load and sync job task */
|
/* TODO: select between async load and sync job task */
|
||||||
@ -202,7 +209,7 @@ void AssetManager::ProcessCommand(AssetStreamCommand &command)
|
|||||||
|
|
||||||
diskSystem->ReadAsync(file, static_cast<uint32_t>(file.size), FILE_READ_SEQUENTIAL);
|
diskSystem->ReadAsync(file, static_cast<uint32_t>(file.size), FILE_READ_SEQUENTIAL);
|
||||||
|
|
||||||
AssetHandle handle;
|
AssetHandle* handle = Allocate<AssetHandle>();
|
||||||
AssetInfo asset(nullptr);
|
AssetInfo asset(nullptr);
|
||||||
asset.type = command.targetType;
|
asset.type = command.targetType;
|
||||||
|
|
||||||
@ -218,11 +225,11 @@ void AssetManager::ProcessCommand(AssetStreamCommand &command)
|
|||||||
activeAssets.push_back(std::move(asset));
|
activeAssets.push_back(std::move(asset));
|
||||||
assetPos = activeAssets.size() - 1;
|
assetPos = activeAssets.size() - 1;
|
||||||
}
|
}
|
||||||
handle.id = assetPos;
|
handle->id = assetPos;
|
||||||
assetsMapping[command.targetPath] = handle;
|
assetsMapping[command.targetPath] = handle;
|
||||||
|
|
||||||
AssetLoadingEntry loadingEntry = {
|
AssetLoadingEntry loadingEntry {
|
||||||
.handle = handle,
|
.handle = *handle,
|
||||||
.file = &file,
|
.file = &file,
|
||||||
.fileOwner = diskSystem
|
.fileOwner = diskSystem
|
||||||
};
|
};
|
||||||
@ -234,12 +241,12 @@ void AssetManager::ProcessCommand(AssetStreamCommand &command)
|
|||||||
|
|
||||||
case AssetStreamCommand::FIND:
|
case AssetStreamCommand::FIND:
|
||||||
{
|
{
|
||||||
std::unordered_map<std::filesystem::path, AssetHandle>::iterator mapping = assetsMapping.find(command.targetPath);
|
std::unordered_map<std::filesystem::path, AssetHandle*>::iterator mapping = assetsMapping.find(command.targetPath);
|
||||||
|
|
||||||
if (mapping == assetsMapping.end())
|
if (mapping == assetsMapping.end())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
command.out->store(&mapping->second);
|
command.out->store(mapping->second);
|
||||||
|
|
||||||
command.type = AssetStreamCommand::COMPLETED;
|
command.type = AssetStreamCommand::COMPLETED;
|
||||||
break;
|
break;
|
||||||
@ -280,6 +287,20 @@ void AssetManager::Release()
|
|||||||
}
|
}
|
||||||
activeAssets.clear();
|
activeAssets.clear();
|
||||||
|
|
||||||
|
for (auto &mapping : assetsMapping)
|
||||||
|
Deallocate(mapping.second);
|
||||||
|
assetsMapping.clear();
|
||||||
|
|
||||||
LOG(INFO, "Asset Streaming is released");
|
LOG(INFO, "Asset Streaming is released");
|
||||||
isRunning.store(false);
|
isRunning.store(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetManager::LoadShaders()
|
||||||
|
{
|
||||||
|
std::filesystem::path shadersRoot = "assets/shaders";
|
||||||
|
for (const std::filesystem::directory_entry &entry : std::filesystem::directory_iterator(shadersRoot))
|
||||||
|
{
|
||||||
|
if (entry.is_directory()) continue;
|
||||||
|
LoadAsync(AssetInfo::SHADER, entry.path());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,15 +1,24 @@
|
|||||||
#include "FileSystem.hpp"
|
#include "FileSystem.hpp"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "allocator.hpp"
|
#include "allocator.hpp"
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
IFileSystem::~IFileSystem()
|
||||||
|
{
|
||||||
|
for (FileHandle* handle : activeFiles)
|
||||||
|
Deallocate(handle);
|
||||||
|
for (FileHandle* handle : failedFiles)
|
||||||
|
Deallocate(handle);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
FileHandle& NativeFileSystem::Open(const std::filesystem::path &path, const uint32_t flags)
|
FileHandle& NativeFileSystem::Open(const std::filesystem::path &path, const uint32_t flags)
|
||||||
{
|
{
|
||||||
FileHandle result;
|
FileHandle* result = Allocate<FileHandle>();
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
result.debugPath = path;
|
result->debugPath = path;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DWORD createFileMode = 0;
|
DWORD createFileMode = 0;
|
||||||
@ -33,78 +42,126 @@ FileHandle& NativeFileSystem::Open(const std::filesystem::path &path, const uint
|
|||||||
{
|
{
|
||||||
LOG(ERROR, "Failed to open file %s. Error: %d", path.c_str(), GetLastError());
|
LOG(ERROR, "Failed to open file %s. Error: %d", path.c_str(), GetLastError());
|
||||||
failedFiles.push_back(result);
|
failedFiles.push_back(result);
|
||||||
return failedFiles[result.id];
|
return *result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.win32Handle = file;
|
result->win32Handle = file;
|
||||||
result.size = GetFileSize(file, NULL);
|
result->size = GetFileSize(file, NULL);
|
||||||
if (result.size == INVALID_FILE_SIZE)
|
if (result->size == INVALID_FILE_SIZE)
|
||||||
LOG(ERROR, "Failed to get size of file %s. Error: %d", path.c_str(), GetLastError());
|
LOG(ERROR, "Failed to get size of file %s. Error: %d", path.c_str(), GetLastError());
|
||||||
|
|
||||||
if (freeFileSlots.size() > 0)
|
if (freeFileSlots.size() > 0)
|
||||||
{
|
{
|
||||||
activeFiles[freeFileSlots.back()] = result;
|
size_t pos = freeFileSlots.back();
|
||||||
result.id = freeFileSlots.back();
|
result->id = pos;
|
||||||
|
activeFiles[pos] = result;
|
||||||
freeFileSlots.pop_back();
|
freeFileSlots.pop_back();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
result->id = activeFiles.size();
|
||||||
activeFiles.push_back(result);
|
activeFiles.push_back(result);
|
||||||
result.id = activeFiles.size() - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return activeFiles[result.id];
|
return *result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeFileSystem::ReadAsync(FileHandle &file, const uint32_t bufferSize, const uint32_t flags)
|
void NativeFileSystem::ReadAsync(FileHandle &file, const uint32_t bufferSize, const uint32_t flags)
|
||||||
{
|
{
|
||||||
file.overlapped = {};
|
file.overlapped = {
|
||||||
|
.hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr)
|
||||||
|
};
|
||||||
file.buffer = AllocateArray<uint8_t>(bufferSize);
|
file.buffer = AllocateArray<uint8_t>(bufferSize);
|
||||||
|
|
||||||
ReadFile(
|
BOOL isSync = ReadFile(
|
||||||
file.win32Handle,
|
file.win32Handle,
|
||||||
file.buffer,
|
file.buffer,
|
||||||
bufferSize,
|
bufferSize,
|
||||||
NULL,
|
NULL,
|
||||||
&file.overlapped
|
&file.overlapped
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (isSync || GetLastError() != ERROR_IO_PENDING)
|
||||||
|
LOG(ERROR, "File reading is synchronious while asynchronious is awaited");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeFileSystem::PollReady(FileHandle &file)
|
bool NativeFileSystem::PollReady(FileHandle &file)
|
||||||
{
|
{
|
||||||
DWORD transferredSize = 0L;
|
// DWORD transferredSize = 0L;
|
||||||
BOOL status = GetOverlappedResult(
|
// BOOL status = GetOverlappedResult(
|
||||||
file.win32Handle,
|
// file.win32Handle,
|
||||||
&file.overlapped,
|
// &file.overlapped,
|
||||||
&transferredSize,
|
// &transferredSize,
|
||||||
FALSE
|
// FALSE
|
||||||
);
|
// );
|
||||||
if (!status && GetLastError() != ERROR_IO_INCOMPLETE)
|
|
||||||
{
|
// DWORD error = GetLastError();
|
||||||
LOG(ERROR, "Error in file status. Code: %d", GetLastError());
|
// if (!status && error != ERROR_IO_INCOMPLETE)
|
||||||
return false;
|
// {
|
||||||
}
|
// LOG(CRITICAL, "Error in reading file status. Code: %d", error);
|
||||||
|
// throw std::runtime_error("Error in reading file status");
|
||||||
|
// }
|
||||||
|
|
||||||
if (file.size == transferredSize)
|
// if (file.size == transferredSize)
|
||||||
{
|
// {
|
||||||
file.data = file.buffer;
|
// file.data = file.buffer;
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
/* TODO: reserve size for data, shift and move */
|
// /* TODO: reserve size for data, shift and move */
|
||||||
}
|
// }
|
||||||
file.buffer = nullptr;
|
// file.buffer = nullptr;
|
||||||
|
|
||||||
return status;
|
DWORD status = WaitForSingleObject(file.overlapped.hEvent, 0);
|
||||||
|
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case WAIT_OBJECT_0:
|
||||||
|
{
|
||||||
|
if (file.size == file.bufferSize)
|
||||||
|
{
|
||||||
|
file.data = file.buffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* TODO: reserve size for data, shift and move */
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WAIT_ABANDONED:
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
LOG(CRITICAL, "Failed to get file status. Error: %d", GetLastError());
|
||||||
|
throw std::runtime_error("Failed to get file status");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeFileSystem::Close(const FileHandle &file)
|
void NativeFileSystem::Close(FileHandle &file)
|
||||||
{
|
{
|
||||||
DeallocateArray(file.buffer);
|
if (file.buffer != nullptr)
|
||||||
DeallocateArray(file.data);
|
{
|
||||||
|
DeallocateArray(file.buffer);
|
||||||
|
file.buffer = nullptr;
|
||||||
|
}
|
||||||
|
if (file.data != nullptr)
|
||||||
|
{
|
||||||
|
DeallocateArray(file.data);
|
||||||
|
file.data = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
CloseHandle(file.win32Handle);
|
if (file.win32Handle != INVALID_HANDLE_VALUE)
|
||||||
activeFiles[file.id].win32Handle = INVALID_HANDLE_VALUE;
|
{
|
||||||
|
CloseHandle(file.win32Handle);
|
||||||
|
file.win32Handle = INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
freeFileSlots.push_back(file.id);
|
freeFileSlots.push_back(file.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,8 +6,8 @@
|
|||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include <allocator.hpp>
|
#include <allocator.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <exception>
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
Renderer::Renderer(SDL_Window *window) : isRunning(false)
|
Renderer::Renderer(SDL_Window *window) : isRunning(false)
|
||||||
{
|
{
|
||||||
@ -228,7 +228,7 @@ void Renderer::SetupDevice()
|
|||||||
if (deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
if (deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
||||||
priority += GPU_DISCRETE_PRIORITY;
|
priority += GPU_DISCRETE_PRIORITY;
|
||||||
|
|
||||||
for (VkSurfaceFormatKHR format : surfaceInfoBuffer.availableFormats)
|
for (const VkSurfaceFormatKHR &format : surfaceInfoBuffer.availableFormats)
|
||||||
{
|
{
|
||||||
surfaceInfoBuffer.format = format;
|
surfaceInfoBuffer.format = format;
|
||||||
if (format.format == VK_FORMAT_B8G8R8_SRGB && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
|
if (format.format == VK_FORMAT_B8G8R8_SRGB && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
|
||||||
@ -239,7 +239,7 @@ void Renderer::SetupDevice()
|
|||||||
}
|
}
|
||||||
|
|
||||||
surfaceInfoBuffer.presentMode = VK_PRESENT_MODE_FIFO_KHR;
|
surfaceInfoBuffer.presentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||||
for (VkPresentModeKHR presentMode : surfaceInfoBuffer.availablePresentModes)
|
for (const VkPresentModeKHR &presentMode : surfaceInfoBuffer.availablePresentModes)
|
||||||
{
|
{
|
||||||
if (presentMode == VK_PRESENT_MODE_FIFO_RELAXED_KHR)
|
if (presentMode == VK_PRESENT_MODE_FIFO_RELAXED_KHR)
|
||||||
{
|
{
|
||||||
@ -265,7 +265,7 @@ void Renderer::SetupDevice()
|
|||||||
|
|
||||||
// Define queues
|
// Define queues
|
||||||
std::vector<VkDeviceQueueCreateInfo> queuesCreateConfigs;
|
std::vector<VkDeviceQueueCreateInfo> queuesCreateConfigs;
|
||||||
std::set<uint32_t> uniqueQueueFamilies = {
|
std::set<uint32_t> uniqueQueueFamilies {
|
||||||
queueFamilies.graphics,
|
queueFamilies.graphics,
|
||||||
queueFamilies.present
|
queueFamilies.present
|
||||||
};
|
};
|
||||||
@ -284,11 +284,11 @@ void Renderer::SetupDevice()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create logical device
|
// Create logical device
|
||||||
std::vector<const char*> deviceExtensions = {
|
std::vector<const char*> deviceExtensions {
|
||||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||||
};
|
};
|
||||||
|
|
||||||
VkDeviceCreateInfo deviceInfo = {
|
VkDeviceCreateInfo deviceInfo {
|
||||||
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.queueCreateInfoCount = static_cast<uint32_t>(queuesCreateConfigs.size()),
|
.queueCreateInfoCount = static_cast<uint32_t>(queuesCreateConfigs.size()),
|
||||||
@ -355,7 +355,7 @@ void Renderer::SetupSwapchain()
|
|||||||
|
|
||||||
if (queueFamilies.graphics != queueFamilies.present)
|
if (queueFamilies.graphics != queueFamilies.present)
|
||||||
{
|
{
|
||||||
uint32_t queueFamiliesShare[] = {queueFamilies.graphics, queueFamilies.present};
|
uint32_t queueFamiliesShare[] {queueFamilies.graphics, queueFamilies.present};
|
||||||
swapchainCreateConfig.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
swapchainCreateConfig.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||||
swapchainCreateConfig.queueFamilyIndexCount = 2;
|
swapchainCreateConfig.queueFamilyIndexCount = 2;
|
||||||
swapchainCreateConfig.pQueueFamilyIndices = queueFamiliesShare;
|
swapchainCreateConfig.pQueueFamilyIndices = queueFamiliesShare;
|
||||||
@ -386,13 +386,13 @@ void Renderer::SetupSwapchain()
|
|||||||
.image = frames[i],
|
.image = frames[i],
|
||||||
.viewType = VK_IMAGE_VIEW_TYPE_2D,
|
.viewType = VK_IMAGE_VIEW_TYPE_2D,
|
||||||
.format = surfaceInfo.format.format,
|
.format = surfaceInfo.format.format,
|
||||||
.components = {
|
.components {
|
||||||
.r = VK_COMPONENT_SWIZZLE_IDENTITY,
|
.r = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
.g = VK_COMPONENT_SWIZZLE_IDENTITY,
|
.g = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
.b = VK_COMPONENT_SWIZZLE_IDENTITY,
|
.b = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
.a = VK_COMPONENT_SWIZZLE_IDENTITY
|
.a = VK_COMPONENT_SWIZZLE_IDENTITY
|
||||||
},
|
},
|
||||||
.subresourceRange = {
|
.subresourceRange {
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
.baseMipLevel = 0,
|
.baseMipLevel = 0,
|
||||||
.levelCount = 1,
|
.levelCount = 1,
|
||||||
@ -413,7 +413,7 @@ void Renderer::Start()
|
|||||||
if (isRunning)
|
if (isRunning)
|
||||||
{
|
{
|
||||||
LOG(CRITICAL, "Renderer can be started only once");
|
LOG(CRITICAL, "Renderer can be started only once");
|
||||||
throw std::exception("Renderer can be started only once");
|
throw std::logic_error("Renderer can be started only once");
|
||||||
}
|
}
|
||||||
|
|
||||||
isRunning.store(true);
|
isRunning.store(true);
|
||||||
@ -493,7 +493,7 @@ void Renderer::Request(const RenderCommand::Type &type)
|
|||||||
|
|
||||||
void Renderer::Release()
|
void Renderer::Release()
|
||||||
{
|
{
|
||||||
for (VkImageView frameView : frameViews)
|
for (VkImageView &frameView : frameViews)
|
||||||
{
|
{
|
||||||
vkDestroyImageView(device, frameView, nullptr);
|
vkDestroyImageView(device, frameView, nullptr);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,6 +43,7 @@ int SDL_main(int argc, char **argv)
|
|||||||
// Setup assets
|
// Setup assets
|
||||||
AssetManager assetManager;
|
AssetManager assetManager;
|
||||||
assetManager.Start();
|
assetManager.Start();
|
||||||
|
assetManager.LoadShaders();
|
||||||
|
|
||||||
// Setup Renderer
|
// Setup Renderer
|
||||||
Renderer renderer(window);
|
Renderer renderer(window);
|
||||||
|
|||||||
8
shaders/helloworld/helloworld.frag
Normal file
8
shaders/helloworld/helloworld.frag
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#version 330
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
outColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
12
shaders/helloworld/helloworld.vert
Normal file
12
shaders/helloworld/helloworld.vert
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
vec2 positions[3] = vec2[](
|
||||||
|
vec2(-1.0, 1.0),
|
||||||
|
vec2(0.0, -1.0),
|
||||||
|
vec2(1.0, 1.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user