Compare commits

...

6 Commits

Author SHA1 Message Date
Anish Bhobe 22cbc41af1 Added Pipeline Caching. 2024-07-27 15:19:39 +02:00
Anish Bhobe f9517db592 Bug Fixes in Image init and Texture GRM.
Image flags now init to 0 (Image invalid by default).
GPU Resource manager correctly adds Texture Descriptor Write Ownership.
2024-07-27 13:00:18 +02:00
Anish Bhobe 1e58446940 Added Assets. 2024-07-27 12:58:38 +02:00
Anish Bhobe a6423bf1a4 Resolve Macro clash. 2024-07-26 00:34:27 +02:00
Anish Bhobe 6f29f580bd Memcpy related fixes. 2024-07-25 22:07:43 +02:00
Anish Bhobe 88d74de291 Added light intensity and camera controls. 2024-07-25 21:48:02 +02:00
29 changed files with 418 additions and 39 deletions

View File

@ -20,7 +20,7 @@ set(HEADER_FILES
physical_device.h physical_device.h
device.h device.h
swapchain.h swapchain.h
"pipeline.h" pipeline.h
queue_allocation.h queue_allocation.h
buffer.h) buffer.h)

View File

@ -19,6 +19,13 @@ constexpr eastl::array DEVICE_EXTENSIONS = {
Device::Device(const Context *context, PhysicalDevice *physicalDevice, Features *enabledFeatures, Device::Device(const Context *context, PhysicalDevice *physicalDevice, Features *enabledFeatures,
const eastl::vector<QueueAllocation> &queueAllocations, NameString &&name) const eastl::vector<QueueAllocation> &queueAllocations, NameString &&name)
: Device(context, physicalDevice, enabledFeatures, queueAllocations, {}, std::move(name))
{
}
Device::Device(const Context *context, PhysicalDevice *physicalDevice, Features *enabledFeatures,
const eastl::vector<QueueAllocation> &queueAllocations, eastl::span<u8> &&pipelineCacheData,
NameString &&name)
: m_Name(std::move(name)) : m_Name(std::move(name))
, m_PhysicalDevice(physicalDevice->m_PhysicalDevice) , m_PhysicalDevice(physicalDevice->m_PhysicalDevice)
{ {
@ -86,11 +93,22 @@ Device::Device(const Context *context, PhysicalDevice *physicalDevice, Features
THEN_ABORT(result) THEN_ABORT(result)
ELSE_VERBOSE("Memory Allocator Created"); ELSE_VERBOSE("Memory Allocator Created");
DEBUG("Created '{}' Successfully", m_Name); vk::PipelineCacheCreateInfo pipelineCacheCreateInfo = {
.initialDataSize = pipelineCacheData.size_bytes(),
.pInitialData = pipelineCacheData.data(),
};
result = m_Device.createPipelineCache(&pipelineCacheCreateInfo, nullptr, &m_PipelineCache);
ERROR_IF(Failed(result), "Pipeline Cache creation failed. Cause: {}", result)
DO(m_Device.destroy(nullptr))
THEN_ABORT(result)
ELSE_VERBOSE("Pipeline Cache created.");
DEBUG("Created Device '{}' Successfully", m_Name);
} }
Device::~Device() Device::~Device()
{ {
m_Device.destroy(m_PipelineCache, nullptr);
if (m_Allocator) if (m_Allocator)
{ {
vmaDestroyAllocator(m_Allocator); vmaDestroyAllocator(m_Allocator);
@ -110,6 +128,19 @@ Device::GetQueue(const u32 familyIndex, const u32 queueIndex) const
return queue; return queue;
} }
eastl::vector<u8>
Device::DumpPipelineCache() const
{
usize pipelineCacheSize = 0;
vk::Result result = m_Device.getPipelineCacheData(m_PipelineCache, &pipelineCacheSize, nullptr);
ERROR_IF(Failed(result), "Pipeline Cache data fetch failed. Cause: {}", result);
eastl::vector<u8> pipelineCacheData(pipelineCacheSize);
result = m_Device.getPipelineCacheData(m_PipelineCache, &pipelineCacheSize, pipelineCacheData.data());
ERROR_IF(Failed(result), "Pipeline Cache data fetch failed. Cause: {}", result);
return pipelineCacheData;
}
Device::Device(Device &&other) noexcept Device::Device(Device &&other) noexcept
: m_Name(std::move(other.m_Name)) : m_Name(std::move(other.m_Name))
, m_PhysicalDevice(Take(other.m_PhysicalDevice)) , m_PhysicalDevice(Take(other.m_PhysicalDevice))

View File

@ -8,6 +8,7 @@
#include "global.h" #include "global.h"
#include <EASTL/vector.h> #include <EASTL/vector.h>
#include <EASTL/span.h>
struct QueueAllocation; struct QueueAllocation;
struct Context; struct Context;
@ -27,14 +28,19 @@ struct Device final
vk::PhysicalDevice m_PhysicalDevice = nullptr; vk::PhysicalDevice m_PhysicalDevice = nullptr;
vk::Device m_Device = nullptr; vk::Device m_Device = nullptr;
VmaAllocator m_Allocator = nullptr; VmaAllocator m_Allocator = nullptr;
vk::PipelineCache m_PipelineCache = nullptr;
template <typename T> template <typename T>
requires vk::isVulkanHandleType<T>::value void SetName(const T &object, cstr name) const; requires vk::isVulkanHandleType<T>::value void SetName(const T &object, cstr name) const;
[[nodiscard]] vk::Queue GetQueue(u32 familyIndex, u32 queueIndex) const; [[nodiscard]] vk::Queue GetQueue(u32 familyIndex, u32 queueIndex) const;
[[nodiscard]] eastl::vector<u8> DumpPipelineCache() const;
// Ctor/Dtor // Ctor/Dtor
Device(const Context *context, PhysicalDevice *physicalDevice, Features *enabledFeatures, Device(const Context *context, PhysicalDevice *physicalDevice, Features *enabledFeatures,
const eastl::vector<QueueAllocation> &queueAllocations, NameString &&name); const eastl::vector<QueueAllocation> &queueAllocations, NameString &&name);
Device(const Context *context, PhysicalDevice *physicalDevice, Features *enabledFeatures,
const eastl::vector<QueueAllocation> &queueAllocations, eastl::span<u8> &&pipelineCacheData, NameString &&name);
~Device(); ~Device();
// Move // Move

View File

@ -41,7 +41,7 @@ struct Image
vk::Extent3D m_Extent; vk::Extent3D m_Extent;
// Image.m_MipLevels_ is used for bookkeeping // Image.m_MipLevels_ is used for bookkeeping
// If the image is Invalid, the remaining data in Image is used intrusively by `GpuResourceManager`. // If the image is Invalid, the remaining data in Image is used intrusively by `GpuResourceManager`.
u32 m_MipLevels_; u32 m_MipLevels_ = 0;
[[nodiscard]] bool IsValid() const; [[nodiscard]] bool IsValid() const;
[[nodiscard]] bool IsOwned() const; [[nodiscard]] bool IsOwned() const;

View File

@ -36,7 +36,7 @@ TextureManager::Commit(Texture *texture)
// Ensure it is copyable. // Ensure it is copyable.
static_assert(std::is_trivially_copyable_v<Texture>); static_assert(std::is_trivially_copyable_v<Texture>);
memcpy(allocatedTexture, texture, sizeof *texture); *allocatedTexture = *texture;
// Take ownership of the buffer. // Take ownership of the buffer.
texture->m_MipLevels_ &= ~Texture::OWNED_BIT; texture->m_MipLevels_ &= ~Texture::OWNED_BIT;
@ -51,7 +51,7 @@ TextureManager::Commit(Texture *texture)
// Ensure it is copyable. // Ensure it is copyable.
static_assert(std::is_trivially_copyable_v<Texture>); static_assert(std::is_trivially_copyable_v<Texture>);
memcpy(allocatedTexture, texture, sizeof *texture); *allocatedTexture = *texture;
texture->m_MipLevels_ &= ~Texture::OWNED_BIT; texture->m_MipLevels_ &= ~Texture::OWNED_BIT;
@ -115,7 +115,7 @@ BufferManager::Commit(StorageBuffer *buffer)
// Ensure it is copyable. // Ensure it is copyable.
static_assert(std::is_trivially_copyable_v<StorageBuffer>); static_assert(std::is_trivially_copyable_v<StorageBuffer>);
memcpy(allocatedBuffer, buffer, sizeof *buffer); *allocatedBuffer = *buffer;
// Take ownership of the buffer. // Take ownership of the buffer.
buffer->m_Size_ &= ~StorageBuffer::OWNED_BIT; buffer->m_Size_ &= ~StorageBuffer::OWNED_BIT;
@ -130,7 +130,7 @@ BufferManager::Commit(StorageBuffer *buffer)
// Ensure it is copyable. // Ensure it is copyable.
static_assert(std::is_trivially_copyable_v<StorageBuffer>); static_assert(std::is_trivially_copyable_v<StorageBuffer>);
memcpy(allocatedBuffer, buffer, sizeof *buffer); *allocatedBuffer = *buffer;
buffer->m_Size_ &= ~StorageBuffer::OWNED_BIT; buffer->m_Size_ &= ~StorageBuffer::OWNED_BIT;
@ -294,7 +294,7 @@ GpuResourceManager::Commit(Texture *texture)
.pImageInfo = &m_WriteInfos.back().uImageInfo, .pImageInfo = &m_WriteInfos.back().uImageInfo,
}); });
m_WriteOwner.emplace_back(HandleType::eBuffer, handle.m_Index); m_WriteOwner.emplace_back(HandleType::eTexture, handle.m_Index);
#if !defined(NDEBUG) #if !defined(NDEBUG)
++m_CommitedTextureCount; ++m_CommitedTextureCount;
@ -428,6 +428,7 @@ GpuResourceManager::~GpuResourceManager()
#endif #endif
m_BufferManager.Destroy(m_Device); m_BufferManager.Destroy(m_Device);
m_TextureManager.Destroy(m_Device);
m_Device->m_Device.destroy(m_ImmutableSampler, nullptr); m_Device->m_Device.destroy(m_ImmutableSampler, nullptr);
m_Device->m_Device.destroy(m_DescriptorPool, nullptr); m_Device->m_Device.destroy(m_DescriptorPool, nullptr);
m_Device->m_Device.destroy(m_SetLayout, nullptr); m_Device->m_Device.destroy(m_SetLayout, nullptr);

View File

@ -84,7 +84,54 @@ ReadFile(cstr fileName)
outputVec.resize(nextSize); outputVec.resize(nextSize);
memcpy(outputVec.data() + totalRead, buffer.data(), readCount * sizeof *buffer.data()); memcpy(outputVec.data() + totalRead, buffer.data(), readCount * sizeof *buffer.data());
totalRead = nextSize; totalRead = nextSize;
} while (readCount == 1024); } while (readCount == buffer.size());
return outputVec; return outputVec;
} }
eastl::vector<u8>
ReadFileBytes(cstr fileName, bool errorOnFail)
{
FILE *filePtr = fopen(fileName, "rb");
if (!filePtr)
{
ERROR_IF(errorOnFail, "Invalid open (r) of {}. Cause: {}", fileName, errno);
return {};
}
eastl::vector<u8> outputVec;
eastl::array<u8, 4096> buffer{};
usize totalRead = 0;
usize readCount;
do
{
readCount = fread(buffer.data(), sizeof(u8), buffer.size(), filePtr);
const auto nextSize = totalRead + readCount;
outputVec.resize(nextSize);
memcpy(outputVec.data() + totalRead, buffer.data(), readCount * sizeof *buffer.data());
totalRead = nextSize;
} while (readCount == buffer.size());
(void)fclose(filePtr);
return outputVec;
}
bool
WriteFileBytes(cstr fileName, eastl::span<u8> data)
{
FILE *filePtr = fopen(fileName, "wb");
if (!filePtr)
{
ERROR("Invalid open (w) of {}. Cause: {}", fileName, errno);
return false;
}
const usize written = fwrite(data.data(), sizeof(u8), data.size(), filePtr);
(void)fclose(filePtr);
return written == data.size();
}

View File

@ -8,6 +8,8 @@
#include "global.h" #include "global.h"
#include "queue_allocation.h" #include "queue_allocation.h"
#include "EASTL/span.h"
#include <EASTL/vector.h> #include <EASTL/vector.h>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
@ -17,6 +19,8 @@ class PhysicalDevices;
PhysicalDevice FindSuitableDevice(const PhysicalDevices &physicalDevices); PhysicalDevice FindSuitableDevice(const PhysicalDevices &physicalDevices);
QueueAllocation FindAppropriateQueueAllocation(const PhysicalDevice *physicalDevice); QueueAllocation FindAppropriateQueueAllocation(const PhysicalDevice *physicalDevice);
eastl::vector<u32> ReadFile(cstr fileName); eastl::vector<u32> ReadFile(cstr fileName);
eastl::vector<u8> ReadFileBytes(cstr fileName, bool errorOnFail = true);
bool WriteFileBytes(cstr fileName, eastl::span<u8> data);
#define AbortIfFailed(RESULT) \ #define AbortIfFailed(RESULT) \
do \ do \

View File

@ -0,0 +1,2 @@
*.hdr filter=lfs diff=lfs merge=lfs -text
*.exr filter=lfs diff=lfs merge=lfs -text

BIN
samples/03_model_render/image/dresden_station_night_4k.exr (Stored with Git LFS) Normal file

Binary file not shown.

BIN
samples/03_model_render/image/dresden_station_night_4k.hdr (Stored with Git LFS) Normal file

Binary file not shown.

BIN
samples/03_model_render/image/overcast_soil_4k.exr (Stored with Git LFS) Normal file

Binary file not shown.

BIN
samples/03_model_render/image/overcast_soil_4k.hdr (Stored with Git LFS) Normal file

Binary file not shown.

BIN
samples/03_model_render/image/photo_studio_loft_hall_4k.exr (Stored with Git LFS) Normal file

Binary file not shown.

BIN
samples/03_model_render/image/photo_studio_loft_hall_4k.hdr (Stored with Git LFS) Normal file

Binary file not shown.

BIN
samples/03_model_render/image/preller_drive_4k.exr (Stored with Git LFS) Normal file

Binary file not shown.

BIN
samples/03_model_render/image/preller_drive_4k.hdr (Stored with Git LFS) Normal file

Binary file not shown.

BIN
samples/03_model_render/image/shanghai_bund_4k.exr (Stored with Git LFS) Normal file

Binary file not shown.

BIN
samples/03_model_render/image/shanghai_bund_4k.hdr (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -115,7 +115,7 @@ LightManager::operator=(LightManager &&other) noexcept
} }
LightHandle LightHandle
LightManager::AddDirectional(const vec3 &direction, const vec3 &color) LightManager::AddDirectional(const vec3 &direction, const vec3 &color, f32 intensity)
{ {
const vec3 normDirection = normalize(direction); const vec3 normDirection = normalize(direction);
if (m_DirectionalLightCount < m_MetaInfo.m_DirectionalLightMaxCount) if (m_DirectionalLightCount < m_MetaInfo.m_DirectionalLightMaxCount)
@ -130,6 +130,7 @@ LightManager::AddDirectional(const vec3 &direction, const vec3 &color)
light.m_Color_ = (ToColor32(color) & Light::COLOR_MASK) | Light::TYPE_DIRECTIONAL | gen; light.m_Color_ = (ToColor32(color) & Light::COLOR_MASK) | Light::TYPE_DIRECTIONAL | gen;
light.m_Range = 1.0f; light.m_Range = 1.0f;
light.um_Direction = normDirection; light.um_Direction = normDirection;
light.m_Intensity = intensity;
m_GpuBufferCapacity_ |= UPDATE_REQUIRED_BIT; m_GpuBufferCapacity_ |= UPDATE_REQUIRED_BIT;
@ -153,10 +154,14 @@ LightManager::AddDirectional(const vec3 &direction, const vec3 &color)
if (m_MetaInfo.m_PointLightMaxCount > 0) // Edge Case: nullptr at size 0 if (m_MetaInfo.m_PointLightMaxCount > 0) // Edge Case: nullptr at size 0
{ {
Light *oldPointStart = m_Lights.data() + oldPointLightOffset; Light *oldPointStart = m_Lights.data() + oldPointLightOffset;
Light *newPointStart = oldPointStart + 2; Light *oldPointEnd = oldPointStart + pointLightMaxCount;
Light *newPointEnd = oldPointEnd + 2;
static_assert(std::is_trivially_copyable_v<Light>); static_assert(std::is_trivially_copyable_v<Light>);
memcpy(newPointStart, oldPointStart, pointLightMaxCount * sizeof *newPointStart);
// Overlaps since 0 -> 2, 1 -> 3, 2 -> 4 (old 2 is lost)
// Backward copy fixes this.
std::copy_backward(oldPointStart, oldPointEnd, newPointEnd);
} }
m_MetaInfo.m_PointLightOffset += 2; m_MetaInfo.m_PointLightOffset += 2;
@ -166,6 +171,7 @@ LightManager::AddDirectional(const vec3 &direction, const vec3 &color)
m_Lights[m_DirectionalLightCount].m_Color_ = (ToColor32(color) & Light::COLOR_MASK) | Light::TYPE_DIRECTIONAL | gen; m_Lights[m_DirectionalLightCount].m_Color_ = (ToColor32(color) & Light::COLOR_MASK) | Light::TYPE_DIRECTIONAL | gen;
m_Lights[m_DirectionalLightCount].m_Range = 1.0f; m_Lights[m_DirectionalLightCount].m_Range = 1.0f;
m_Lights[m_DirectionalLightCount].um_Direction = normDirection; m_Lights[m_DirectionalLightCount].um_Direction = normDirection;
m_Lights[m_DirectionalLightCount].m_Intensity = intensity;
const u16 index = m_DirectionalLightCount; const u16 index = m_DirectionalLightCount;
++m_DirectionalLightCount; ++m_DirectionalLightCount;
@ -175,7 +181,7 @@ LightManager::AddDirectional(const vec3 &direction, const vec3 &color)
} }
LightHandle LightHandle
LightManager::AddPoint(const vec3 &position, const vec3 &color, const f32 radius) LightManager::AddPoint(const vec3 &position, const vec3 &color, const f32 radius, f32 intensity)
{ {
assert(m_PointLightCount <= m_MetaInfo.m_PointLightMaxCount); assert(m_PointLightCount <= m_MetaInfo.m_PointLightMaxCount);
assert(radius >= 0.0f); assert(radius >= 0.0f);
@ -191,6 +197,7 @@ LightManager::AddPoint(const vec3 &position, const vec3 &color, const f32 radius
light->m_Color_ = (ToColor32(color) & Light::COLOR_MASK) | Light::TYPE_POINT | gen; light->m_Color_ = (ToColor32(color) & Light::COLOR_MASK) | Light::TYPE_POINT | gen;
light->m_Range = radius; light->m_Range = radius;
light->um_Position = position; light->um_Position = position;
light->m_Intensity = intensity;
m_GpuBufferCapacity_ |= UPDATE_REQUIRED_BIT; m_GpuBufferCapacity_ |= UPDATE_REQUIRED_BIT;
@ -211,6 +218,7 @@ LightManager::AddPoint(const vec3 &position, const vec3 &color, const f32 radius
light->m_Color_ = (ToColor32(color) & Light::COLOR_MASK) | Light::TYPE_POINT | gen; light->m_Color_ = (ToColor32(color) & Light::COLOR_MASK) | Light::TYPE_POINT | gen;
light->m_Range = radius; light->m_Range = radius;
light->um_Position = position; light->um_Position = position;
light->m_Intensity = intensity;
++m_PointLightCount; ++m_PointLightCount;
++m_MetaInfo.m_PointLightMaxCount; ++m_MetaInfo.m_PointLightMaxCount;

View File

@ -68,8 +68,8 @@ struct LightManager
constexpr static u16 UPDATE_REQUIRED_BIT = 1; constexpr static u16 UPDATE_REQUIRED_BIT = 1;
constexpr static u16 CAPACITY_MASK = ~(UPDATE_REQUIRED_BIT); constexpr static u16 CAPACITY_MASK = ~(UPDATE_REQUIRED_BIT);
LightHandle AddDirectional(const vec3 &direction, const vec3 &color); LightHandle AddDirectional(const vec3 &direction, const vec3 &color, f32 intensity);
LightHandle AddPoint(const vec3 &position, const vec3 &color, f32 radius); LightHandle AddPoint(const vec3 &position, const vec3 &color, f32 radius, f32 intensity);
void Update(); void Update();
void RemoveLight(LightHandle handle); void RemoveLight(LightHandle handle);

BIN
samples/03_model_render/model/MarbleBust/marble_bust_01.bin (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,161 @@
{
"asset": {
"generator": "Khronos glTF Blender I/O v1.6.16",
"version": "2.0"
},
"scene": 0,
"scenes": [
{
"name": "Scene",
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0,
"name": "marble_bust_01",
"translation": [
0,
0.028335653245449066,
0
]
}
],
"materials": [
{
"doubleSided": true,
"name": "marble_bust_01",
"normalTexture": {
"index": 0
},
"pbrMetallicRoughness": {
"baseColorTexture": {
"index": 1
},
"metallicFactor": 0,
"metallicRoughnessTexture": {
"index": 2
}
}
}
],
"meshes": [
{
"name": "marble_bust_01",
"primitives": [
{
"attributes": {
"POSITION": 0,
"NORMAL": 1,
"TEXCOORD_0": 2
},
"indices": 3,
"material": 0
}
]
}
],
"textures": [
{
"sampler": 0,
"source": 0
},
{
"sampler": 0,
"source": 1
},
{
"sampler": 0,
"source": 2
}
],
"images": [
{
"mimeType": "image/jpeg",
"name": "marble_bust_01_nor_gl",
"uri": "textures/marble_bust_01_nor_gl_4k.jpg"
},
{
"mimeType": "image/jpeg",
"name": "marble_bust_01_diff",
"uri": "textures/marble_bust_01_diff_4k.jpg"
},
{
"mimeType": "image/jpeg",
"name": "marble_bust_01_arm",
"uri": "textures/marble_bust_01_rough_4k.jpg"
}
],
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 9746,
"max": [
0.14886942505836487,
0.48668384552001953,
0.1551172435283661
],
"min": [
-0.12288019061088562,
-0.028259359300136566,
-0.1445964276790619
],
"type": "VEC3"
},
{
"bufferView": 1,
"componentType": 5126,
"count": 9746,
"type": "VEC3"
},
{
"bufferView": 2,
"componentType": 5126,
"count": 9746,
"type": "VEC2"
},
{
"bufferView": 3,
"componentType": 5123,
"count": 52368,
"type": "SCALAR"
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 116952,
"byteOffset": 0
},
{
"buffer": 0,
"byteLength": 116952,
"byteOffset": 116952
},
{
"buffer": 0,
"byteLength": 77968,
"byteOffset": 233904
},
{
"buffer": 0,
"byteLength": 104736,
"byteOffset": 311872
}
],
"samplers": [
{
"magFilter": 9729,
"minFilter": 9987
}
],
"buffers": [
{
"byteLength": 416608,
"uri": "marble_bust_01.bin"
}
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -22,6 +22,12 @@
#include <EASTL/hash_map.h> #include <EASTL/hash_map.h>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
#include <tiny_gltf.h>
#if defined(LoadImage)
#undef LoadImage
#endif
vec4 vec4
VectorToVec4(const std::vector<double> &vec) VectorToVec4(const std::vector<double> &vec)
{ {

View File

@ -11,7 +11,10 @@
#include "gpu_resource_manager.h" #include "gpu_resource_manager.h"
#include "nodes.h" #include "nodes.h"
#include <tiny_gltf.h> namespace tinygltf
{
struct Image;
}
struct TextureHandle; struct TextureHandle;
struct Texture; struct Texture;

View File

@ -29,14 +29,67 @@
#include <filesystem> #include <filesystem>
constexpr u32 MAX_FRAMES_IN_FLIGHT = 3; constexpr u32 MAX_FRAMES_IN_FLIGHT = 3;
constexpr auto MODEL_FILE = "model/DamagedHelmet.glb"; constexpr auto PIPELINE_CACHE_FILE = "PipelineCacheData.bin";
struct Camera struct Camera
{ {
mat4 m_View; mat4 m_View;
mat4 m_Perspective; mat4 m_Perspective;
vec3 m_Position; vec4 m_Position;
};
struct CameraController
{
constexpr static vec3 UP = vec3(0.0f, 1.0f, 0.0f);
f32 m_Fov;
f32 m_Pitch;
f32 m_Yaw;
f32 m_AspectRatio; f32 m_AspectRatio;
Camera m_Camera;
CameraController(const vec3 &position, const vec3 &target, const f32 vFov, const f32 aspectRatio)
: m_Fov(vFov)
, m_Pitch{0.0f}
, m_Yaw{0.0f}
, m_AspectRatio{aspectRatio}
, m_Camera{
.m_View = lookAt(position, target, UP),
.m_Perspective = glm::perspective(vFov, aspectRatio, 0.1f, 100.0f),
.m_Position = vec4{0.0f, 2.0f, 2.0f, 1.0f},
}
{
}
void
SetAspectRatio(const f32 aspectRatio)
{
m_AspectRatio = aspectRatio;
m_Camera.m_Perspective = glm::perspective(m_Fov, aspectRatio, 0.1f, 100.0f);
}
void
SetPosition(const vec3 &position)
{
m_Camera.m_Position = vec4(position, 1.0f);
f32 cosPitch = cos(m_Pitch);
const vec3 target = vec3(sin(m_Yaw) * cosPitch, sin(m_Pitch), -cos(m_Yaw) * cosPitch);
m_Camera.m_View = lookAt(position, position + target, UP);
}
void
SetPitchYaw(f32 pitch, f32 yaw)
{
m_Pitch = pitch;
m_Yaw = yaw;
f32 cosPitch = cos(m_Pitch);
const vec3 target = vec3(sin(m_Yaw) * cosPitch, sin(m_Pitch), -cos(m_Yaw) * cosPitch);
const vec3 position = vec3{m_Camera.m_Position};
m_Camera.m_View = lookAt(position, position + target, UP);
}
}; };
int int
@ -74,8 +127,10 @@ main(int, char **)
}, },
}; };
auto pipelineCacheData = ReadFileBytes(PIPELINE_CACHE_FILE, false);
QueueAllocation queueAllocation = FindAppropriateQueueAllocation(&deviceToUse); QueueAllocation queueAllocation = FindAppropriateQueueAllocation(&deviceToUse);
Device device = {&context, &deviceToUse, &enabledDeviceFeatures, {queueAllocation}, "Primary Device"}; Device device = {&context, &deviceToUse, &enabledDeviceFeatures, {queueAllocation}, pipelineCacheData, "Primary Device"};
vk::Queue commandQueue = device.GetQueue(queueAllocation.m_Family, 0); vk::Queue commandQueue = device.GetQueue(queueAllocation.m_Family, 0);
Swapchain swapchain = {&window, &device, "Primary Chain"}; Swapchain swapchain = {&window, &device, "Primary Chain"};
GpuResourceManager resourceManager = {&device, 1000}; GpuResourceManager resourceManager = {&device, 1000};
@ -88,9 +143,14 @@ main(int, char **)
vk::Format attachmentFormat = vk::Format::eR8G8B8A8Srgb; vk::Format attachmentFormat = vk::Format::eR8G8B8A8Srgb;
Pipeline pipeline = CreatePipeline(&device, attachmentFormat, &resourceManager); Pipeline pipeline = CreatePipeline(&device, attachmentFormat, &resourceManager);
lightManager.AddDirectional(vec3(0.0f, -1.0f, 0.0f), {0.0f, 0.7f, 0.0f}); //lightManager.AddDirectional(vec3(0.0f, -1.0f, 0.0f), {0.0f, 0.7f, 0.0f});
lightManager.AddPoint(vec3{2.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 15.0f); //lightManager.AddPoint(vec3{2.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 15.0f);
lightManager.AddPoint(vec3{-2.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, 15.0f); //lightManager.AddPoint(vec3{-2.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, 15.0f);
lightManager.AddPoint(vec3{-5.0f, -5.0f, 5.0f}, vec3{1.0f}, 30.0f, 16.0f);
lightManager.AddPoint(vec3{5.0f, -5.0f, 5.0f}, vec3{1.0f}, 30.0f, 16.0f);
lightManager.AddPoint(vec3{-5.0f, 5.0f, 5.0f}, vec3{1.0f}, 30.0f, 16.0f);
lightManager.AddPoint(vec3{5.0f, 5.0f, 5.0f}, vec3{1.0f}, 30.0f, 16.0f);
lightManager.Update(); lightManager.Update();
@ -119,17 +179,12 @@ main(int, char **)
vk::Extent2D internalResolution = {1920, 1080}; vk::Extent2D internalResolution = {1920, 1080};
Camera camera = { CameraController cameraController = {vec3{0.0f, 2.0f, 2.0f}, vec3{0.0f}, 70_deg,
.m_View = lookAt(vec3(0.0f, 2.0f, 2.0f), vec3(0.0f), vec3(0.0f, 1.0f, 0.0f)), Cast<f32>(swapchain.m_Extent.width) / Cast<f32>(swapchain.m_Extent.height)};
.m_Perspective = glm::perspective(
70_deg, Cast<f32>(swapchain.m_Extent.width) / Cast<f32>(swapchain.m_Extent.height), 0.1f, 100.0f),
.m_Position = vec4{0.0f, 2.0f, 2.0f, 1.0f},
.m_AspectRatio = Cast<f32>(swapchain.m_Extent.width) / Cast<f32>(swapchain.m_Extent.height),
};
UniformBuffer ubo; UniformBuffer ubo;
ubo.Init(&device, sizeof camera, "Camera UBO"); ubo.Init(&device, sizeof cameraController.m_Camera, "Camera UBO");
ubo.Write(&device, 0, sizeof camera, &camera); ubo.Write(&device, 0, sizeof cameraController.m_Camera, &cameraController.m_Camera);
vk::DescriptorBufferInfo descriptorBufferInfo = { vk::DescriptorBufferInfo descriptorBufferInfo = {
.buffer = ubo.m_Buffer, .buffer = ubo.m_Buffer,
.offset = 0, .offset = 0,
@ -275,11 +330,12 @@ main(int, char **)
bool rotating = false; bool rotating = false;
bool lockToScreen = true; bool lockToScreen = true;
i32 height = Cast<i32>(internalResolution.height); i32 height = Cast<i32>(internalResolution.height);
vec2 camPitchYaw = vec2(0.0f);
vec3 camPosition = cameraController.m_Camera.m_Position;
vk::Extent2D inputResolution = internalResolution; vk::Extent2D inputResolution = internalResolution;
swapchain.RegisterResizeCallback([&camera](vk::Extent2D extent) { swapchain.RegisterResizeCallback([&cameraController](vk::Extent2D extent) {
camera.m_AspectRatio = Cast<f32>(extent.width) / Cast<f32>(extent.height); cameraController.SetAspectRatio(Cast<f32>(extent.width) / Cast<f32>(extent.height));
camera.m_Perspective = glm::perspective(70_deg, camera.m_AspectRatio, 0.1f, 100.0f);
}); });
Time::Init(); Time::Init();
@ -303,7 +359,7 @@ main(int, char **)
} }
inputResolution.height = height; inputResolution.height = height;
inputResolution.width = Cast<i32>(camera.m_AspectRatio * Cast<f32>(inputResolution.height)); inputResolution.width = Cast<i32>(cameraController.m_AspectRatio * Cast<f32>(inputResolution.height));
if (gui::Button("Change Resolution")) if (gui::Button("Change Resolution"))
{ {
@ -333,6 +389,15 @@ main(int, char **)
gui::Separator(); gui::Separator();
gui::Text("Delta: %0.6f ms", 1000.0f * Time::m_Delta); gui::Text("Delta: %0.6f ms", 1000.0f * Time::m_Delta);
gui::Text("FPS: %0.6f", 1.0f / Time::m_Delta); gui::Text("FPS: %0.6f", 1.0f / Time::m_Delta);
gui::Separator();
if (gui::DragFloat2("Camera Orientation", Recast<f32 *>(&camPitchYaw)))
{
cameraController.SetPitchYaw(glm::radians(camPitchYaw.x), glm::radians(camPitchYaw.y));
}
if (gui::InputFloat3("Camera Position", Recast<f32 *>(&camPosition)))
{
cameraController.SetPosition(camPosition);
}
gui::Checkbox("Rotate", &rotating); gui::Checkbox("Rotate", &rotating);
if (gui::Button("Exit")) if (gui::Button("Exit"))
{ {
@ -348,7 +413,7 @@ main(int, char **)
rotate(model.GetModelTransform(), Cast<f32>(45.0_deg * Time::m_Delta), vec3(0.0f, 1.0f, 0.0f))); rotate(model.GetModelTransform(), Cast<f32>(45.0_deg * Time::m_Delta), vec3(0.0f, 1.0f, 0.0f)));
} }
model.Update(); model.Update();
ubo.Write(&device, 0, sizeof camera, &camera); ubo.Write(&device, 0, sizeof cameraController.m_Camera, &cameraController.m_Camera);
Frame *currentFrame = frameManager.GetNextFrame(&swapchain, &window); Frame *currentFrame = frameManager.GetNextFrame(&swapchain, &window);
@ -505,6 +570,9 @@ main(int, char **)
AbortIfFailed(device.m_Device.waitIdle()); AbortIfFailed(device.m_Device.waitIdle());
pipelineCacheData = device.DumpPipelineCache();
ERROR_IF(!WriteFileBytes(PIPELINE_CACHE_FILE, pipelineCacheData), "Pipeline Cache incorrectly written");
gui::Destroy(&device); gui::Destroy(&device);
for (auto &depthImage : depthImages) for (auto &depthImage : depthImages)

View File

@ -167,7 +167,7 @@ float3 GetPointLightInfluence(float3 Albedo, float2 MetalRough, float3 Position,
float G = (Light.Color & 0x00FF0000) >> 16; float G = (Light.Color & 0x00FF0000) >> 16;
float B = (Light.Color & 0x0000FF00) >> 8; float B = (Light.Color & 0x0000FF00) >> 8;
float3 LightColor = LightAmp * float3(R, G, B) * 0.00392156862f; // 0.00392156862 = 1/255 float3 LightColor = LightAmp * Light.Intensity * float3(R, G, B) * 0.00392156862f; // 0.00392156862 = 1/255
Contrib += GetPBRContrib(Albedo, LightColor, ViewDir, Normal, Metallic, Roughness, F_0, LightDir, LightDistance); Contrib += GetPBRContrib(Albedo, LightColor, ViewDir, Normal, Metallic, Roughness, F_0, LightDir, LightDistance);
} }
@ -209,7 +209,7 @@ float3 GetDirectionalLightInfluence(float3 Albedo, float2 MetalRough, float3 Pos
float G = (Light.Color & 0x00FF0000) >> 16; float G = (Light.Color & 0x00FF0000) >> 16;
float B = (Light.Color & 0x0000FF00) >> 8; float B = (Light.Color & 0x0000FF00) >> 8;
float3 LightColor = LightAmp * float3(R, G, B) * 0.00392156862f; // 0.00392156862 = 1/255 float3 LightColor = LightAmp * Light.Intensity * float3(R, G, B) * 0.00392156862f; // 0.00392156862 = 1/255
Contrib += GetPBRContrib(Albedo, LightColor, ViewDir, Normal, Metallic, Roughness, F_0, LightDir, 1.0f); Contrib += GetPBRContrib(Albedo, LightColor, ViewDir, Normal, Metallic, Roughness, F_0, LightDir, 1.0f);
} }