diff options
-rw-r--r-- | MODULE.bazel.lock | 2 | ||||
-rw-r--r-- | deimos/core/os_win32.cpp | 2 | ||||
-rw-r--r-- | deimos/core/status.cpp | 7 | ||||
-rw-r--r-- | deimos/core/status.h | 10 | ||||
-rw-r--r-- | deimos/render/BUILD | 11 | ||||
-rw-r--r-- | deimos/render/backend.h | 19 | ||||
-rw-r--r-- | deimos/vulkan/BUILD | 1 | ||||
-rw-r--r-- | deimos/vulkan/vulkan_backend.cpp | 59 | ||||
-rw-r--r-- | deimos/vulkan/vulkan_backend.h | 6 | ||||
-rw-r--r-- | deimos/vulkan/vulkan_device_functions.inc | 4 | ||||
-rw-r--r-- | main/main.cpp | 8 |
11 files changed, 108 insertions, 21 deletions
diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index c4194d4..fa9bc9d 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -1110,7 +1110,7 @@ }, "@@rules_java~//java:extensions.bzl%toolchains": { "general": { - "bzlTransitiveDigest": "tJHbmWnq7m+9eUBnUdv7jZziQ26FmcGL9C5/hU3Q9UQ=", + "bzlTransitiveDigest": "0N5b5J9fUzo0sgvH4F3kIEaeXunz4Wy2/UtSFV/eXUY=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, diff --git a/deimos/core/os_win32.cpp b/deimos/core/os_win32.cpp index 84fc3a3..9a8233d 100644 --- a/deimos/core/os_win32.cpp +++ b/deimos/core/os_win32.cpp @@ -169,7 +169,7 @@ public: if (hwnd == nullptr)
{
- return InternalError("Error while creating Win32 window");
+ return RuntimeError("Error while creating Win32 window");
}
::ShowWindow(hwnd, SW_SHOW);
diff --git a/deimos/core/status.cpp b/deimos/core/status.cpp index 10965bc..2d9e7c2 100644 --- a/deimos/core/status.cpp +++ b/deimos/core/status.cpp @@ -18,14 +18,15 @@ StringView StatusCodeToString(StatusCode code) case StatusCode::kInvalidArgument: return StringView("Invalid argument");
case StatusCode::kUnimplemented: return StringView("Unimplemented");
case StatusCode::kInternal: return StringView("Internal error");
+ case StatusCode::kRuntime: return StringView("Runtime error");
}
}
struct StatusRep
{
- Atomic<int32_t> ref_count;
- StatusCode code{};
- StringView message;
+ Atomic<int32_t> ref_count;
+ StatusCode code{};
+ StringView message;
};
Status::Status(StatusCode code, StringView message)
diff --git a/deimos/core/status.h b/deimos/core/status.h index 8141dad..3738ae9 100644 --- a/deimos/core/status.h +++ b/deimos/core/status.h @@ -14,6 +14,7 @@ enum class StatusCode : uint32_t kInvalidArgument,
kUnimplemented,
kInternal,
+ kRuntime,
};
StringView StatusCodeToString(StatusCode code);
@@ -106,6 +107,11 @@ inline Status InternalError(StringView message = {}) return Status(StatusCode::kInternal, message);
}
+inline Status RuntimeError(StringView message = {})
+{
+ return Status(StatusCode::kRuntime, message);
+}
+
namespace statusor_internals
{
};
@@ -150,7 +156,7 @@ public: Expects(!m_status.ok());
if (m_status.ok())
{
- m_status = InternalError("StatusOr constructed from OK");
+ m_status = InvalidArgumentError("StatusOr constructed from OK");
}
}
@@ -159,7 +165,7 @@ public: Expects(!m_status.ok());
if (m_status.ok())
{
- m_status = InternalError("StatusOr constructed from OK");
+ m_status = InvalidArgumentError("StatusOr constructed from OK");
}
}
diff --git a/deimos/render/BUILD b/deimos/render/BUILD new file mode 100644 index 0000000..a94c085 --- /dev/null +++ b/deimos/render/BUILD @@ -0,0 +1,11 @@ +cc_library(
+ name = "render",
+ hdrs = [
+ "backend.h",
+ ],
+ deps = [
+ "//deimos/core",
+ ],
+ visibility = ["//:__subpackages__"],
+)
+
diff --git a/deimos/render/backend.h b/deimos/render/backend.h new file mode 100644 index 0000000..cba8d90 --- /dev/null +++ b/deimos/render/backend.h @@ -0,0 +1,19 @@ +#pragma once
+
+#include <deimos/core/base.h>
+
+namespace deimos
+{
+
+class IRenderBackend
+{
+public:
+ IRenderBackend() = default;
+ deimos_NO_COPY_MOVE(IRenderBackend);
+ virtual ~IRenderBackend() = default;
+
+ virtual void BeginFrame() = 0;
+ virtual void EndFrame() = 0;
+};
+
+} // namespace deimos
diff --git a/deimos/vulkan/BUILD b/deimos/vulkan/BUILD index 238261f..8d4ef3a 100644 --- a/deimos/vulkan/BUILD +++ b/deimos/vulkan/BUILD @@ -16,6 +16,7 @@ cc_library( deps = [
"//deimos/core",
"//3rd_party/vulkan",
+ "//deimos/render",
],
visibility = ["//:__subpackages__"],
)
diff --git a/deimos/vulkan/vulkan_backend.cpp b/deimos/vulkan/vulkan_backend.cpp index 173e671..87e4451 100644 --- a/deimos/vulkan/vulkan_backend.cpp +++ b/deimos/vulkan/vulkan_backend.cpp @@ -7,21 +7,22 @@ #include <deimos/core/temp_allocator.h>
#include <deimos/core/log.h>
#include <deimos/core/os.h>
+#include <deimos/render/backend.h>
namespace
{
using namespace deimos;
-LogApi* log_api;
-OsApi* os_api;
-ApiRegistry* api_registry;
+LogApi* log_api;
+OsApi* os_api;
+ApiRegistry* api_registry;
TempAllocatorApi* temp_api;
-VulkanLoaderApi* vulkan_loader_api;
+VulkanLoaderApi* vulkan_loader_api;
const VkAllocationCallbacks* kVkAlloc = nullptr;
-class VulkanBackendImpl : public IVulkanBackend
+class VulkanBackendImpl : public IVulkanBackend, public IRenderBackend
{
VulkanApi* m_vk;
VkInstance m_instance;
@@ -31,6 +32,13 @@ class VulkanBackendImpl : public IVulkanBackend VkDevice m_device;
VkQueue m_queue = VK_NULL_HANDLE;
+ struct FrameResources
+ {
+ VkCommandPool cmd_pool = VK_NULL_HANDLE;
+ };
+
+ FrameResources m_frame_resources;
+
public:
VulkanBackendImpl(
VulkanApi* vk,
@@ -45,6 +53,33 @@ public: m_vk->GetDeviceQueue(m_device, m_queue_family, 0, &m_queue);
Ensures(m_queue != VK_NULL_HANDLE);
}
+
+ IRenderBackend* AsRenderBackend() override
+ {
+ return this;
+ }
+
+ void BeginFrame() override
+ {
+ VkCommandPoolCreateInfo create_info;
+ create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+ create_info.pNext = nullptr;
+ create_info.flags = 0;
+ create_info.queueFamilyIndex = m_queue_family;
+
+ VkResult res = m_vk->CreateCommandPool(m_device, &create_info, kVkAlloc, &m_frame_resources.cmd_pool);
+ if (res != VK_SUCCESS)
+ {
+ log_api->LogError("Couldn't allocate Vulkan command pool: $", (int)res);
+ return;
+ }
+ }
+
+ void EndFrame() override
+ {
+ m_vk->DeviceWaitIdle(m_device);
+ m_vk->DestroyCommandPool(m_device, m_frame_resources.cmd_pool, kVkAlloc);
+ }
};
StatusOr<VkInstance> CreateInstance(VulkanApi* vk)
@@ -85,7 +120,7 @@ StatusOr<VkInstance> CreateInstance(VulkanApi* vk) const VkResult res = vk->CreateInstance(&create_info, kVkAlloc, &instance);
if (res != VK_SUCCESS)
{
- return InternalError("vkCreateInstance failed");
+ return RuntimeError("vkCreateInstance failed");
}
return instance;
@@ -105,7 +140,7 @@ StatusOr<VkSurfaceKHR> CreateSurface(VulkanApi* vk, VkInstance instance, OsWindo const VkResult res = vk->CreateWin32SurfaceKHR(instance, &create_info, kVkAlloc, &surface);
if (res != VK_SUCCESS)
{
- return InternalError("vkCreateWin32SurfaceKHR failed");
+ return RuntimeError("vkCreateWin32SurfaceKHR failed");
}
return surface;
@@ -119,7 +154,7 @@ StatusOr<uint32_t> FindQueueFamily(VulkanApi* vk, VkPhysicalDevice physical_devi vk->GetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, nullptr);
if (queue_family_count == 0)
{
- return InternalError("No queue on this physical device");
+ return RuntimeError("No queue on this physical device");
}
log_api->LogInfo("Physical device has $ queue families", queue_family_count);
@@ -143,7 +178,7 @@ StatusOr<uint32_t> FindQueueFamily(VulkanApi* vk, VkPhysicalDevice physical_devi }
}
- return InternalError("Couldn't find a suitable queue");
+ return RuntimeError("Couldn't find a suitable queue");
}
Status FindPhysicalDevice(
@@ -159,7 +194,7 @@ Status FindPhysicalDevice( vk->EnumeratePhysicalDevices(instance, &physical_device_count, nullptr);
if (physical_device_count == 0)
{
- return InternalError("No Vulkan device found");
+ return RuntimeError("No Vulkan device found");
}
log_api->LogInfo("Found $ physical devices", physical_device_count);
@@ -196,7 +231,7 @@ Status FindPhysicalDevice( log_api->LogInfo("Incompatible because: $", maybe_queue_family);
}
- return InternalError("No suitable device found");
+ return RuntimeError("No suitable device found");
}
StatusOr<VkDevice> CreateDevice(VulkanApi* vk, VkPhysicalDevice physical_device, uint32_t queue_family)
@@ -233,7 +268,7 @@ StatusOr<VkDevice> CreateDevice(VulkanApi* vk, VkPhysicalDevice physical_device, const VkResult res = vk->CreateDevice(physical_device, &create_info, kVkAlloc, &device);
if (res != VK_SUCCESS)
{
- return InternalError("vkCreateDeviceFailed");
+ return RuntimeError("vkCreateDeviceFailed");
}
return device;
diff --git a/deimos/vulkan/vulkan_backend.h b/deimos/vulkan/vulkan_backend.h index 90aaf2a..031c81b 100644 --- a/deimos/vulkan/vulkan_backend.h +++ b/deimos/vulkan/vulkan_backend.h @@ -8,11 +8,17 @@ namespace deimos class ApiRegistry;
class Allocator;
+class IRenderBackend;
struct OsWindow;
class IVulkanBackend
{
public:
+ IVulkanBackend() = default;
+ deimos_NO_COPY_MOVE(IVulkanBackend); + virtual ~IVulkanBackend() = default;
+
+ virtual IRenderBackend* AsRenderBackend() = 0;
};
class VulkanBackendApi
diff --git a/deimos/vulkan/vulkan_device_functions.inc b/deimos/vulkan/vulkan_device_functions.inc index 8267fb9..f83ebb7 100644 --- a/deimos/vulkan/vulkan_device_functions.inc +++ b/deimos/vulkan/vulkan_device_functions.inc @@ -1,4 +1,8 @@ // NOLINTBEGIN
FN(DestroyDevice)
FN(GetDeviceQueue)
+FN(CreateCommandPool)
+FN(ResetCommandPool)
+FN(DestroyCommandPool)
+FN(DeviceWaitIdle)
// NOLINTEND
diff --git a/main/main.cpp b/main/main.cpp index 0f0de71..3269bef 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -5,6 +5,7 @@ #include <deimos/core/status.h>
#include <deimos/vulkan/vulkan_loader.h>
#include <deimos/vulkan/vulkan_backend.h>
+#include <deimos/render/backend.h>
using namespace deimos;
@@ -13,7 +14,6 @@ static AllocatorApi* allocator_api; static OsApi* os_api;
static VulkanBackendApi* vulkan_backend_api;
-
int main(int /* argc */, char* /* argv */[])
{
auto* api_registry = InitializeGlobalApiRegistry();
@@ -48,11 +48,15 @@ int main(int /* argc */, char* /* argv */[]) }
vulkan = s.value();
log_api->LogInfo("Vulkan backend created");
- } + }
+
+ IRenderBackend* render = vulkan->AsRenderBackend();
while (!os_api->window->QuitRequested(window))
{
os_api->window->Update(window);
+ render->BeginFrame();
+ render->EndFrame();
}
log_api->LogInfo("Goodbye");
|