aboutsummaryrefslogtreecommitdiffstats
path: root/api-test
diff options
context:
space:
mode:
Diffstat (limited to 'api-test')
-rw-r--r--api-test/CMakeLists.txt4
-rw-r--r--api-test/dx12-command-buffer.cpp47
-rw-r--r--api-test/dx12-device.cpp278
-rw-r--r--api-test/main.cpp246
-rw-r--r--api-test/vk-command-buffer.cpp (renamed from api-test/command-buffer.cpp)4
-rw-r--r--api-test/vk-device.cpp4
6 files changed, 439 insertions, 144 deletions
diff --git a/api-test/CMakeLists.txt b/api-test/CMakeLists.txt
index 846b0fd..d8ae739 100644
--- a/api-test/CMakeLists.txt
+++ b/api-test/CMakeLists.txt
@@ -2,10 +2,12 @@ add_executable(
api-test
main.cpp
vk-device.cpp
- command-buffer.cpp
+ vk-command-buffer.cpp
vk-bindless.cpp
vk-utils.cpp
dx12-device.cpp
+ dx12-command-buffer.cpp
+ ${CMAKE_SOURCE_DIR}/thirdparty/D3D12MemAlloc.cpp
${CMAKE_SOURCE_DIR}/src/window.cpp
${CMAKE_SOURCE_DIR}/src/utils.cpp
${CMAKE_SOURCE_DIR}/src/vulkan-loader.cpp
diff --git a/api-test/dx12-command-buffer.cpp b/api-test/dx12-command-buffer.cpp
new file mode 100644
index 0000000..0310dfd
--- /dev/null
+++ b/api-test/dx12-command-buffer.cpp
@@ -0,0 +1,47 @@
+#include "dx12-command-buffer.hpp"
+
+#include "dx12-device.hpp"
+
+namespace dx12 {
+ void command_buffer::start() const {
+ HRESULT hr = command_allocator->Reset();
+ assert(hr == S_OK);
+
+ hr = dx12_command_buffer->Reset(command_allocator, nullptr);
+ assert(hr == S_OK);
+
+ auto& device = dx12::device::get_render_device();
+ dx12_command_buffer->SetDescriptorHeaps(2U, dx12::device::get_bindless_model().get_heaps());
+ }
+
+ void command_buffer::stop() const {
+ HRESULT hr = dx12_command_buffer->Close();
+ assert(hr == S_OK);
+ }
+
+ void command_buffer::copy(handle<device_buffer> src_buffer, handle<device_texture> dst_texture, uint64_t offset) const {
+ auto& dst = device::get_render_device().get_texture(dst_texture);
+ D3D12_TEXTURE_COPY_LOCATION dst_copy_location {
+ .pResource = dst.resource,
+ .Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
+ .SubresourceIndex = 0U,
+ };
+
+ auto& src = device::get_render_device().get_buffer(src_buffer);
+ D3D12_TEXTURE_COPY_LOCATION src_copy_location {
+ .pResource = src.resource,
+ .Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
+ .PlacedFootprint = {
+ .Offset = offset,
+ .Footprint = {
+ .Format = dst.format,
+ .Width = dst.width,
+ .Height = dst.height,
+ .Depth = dst.depth,
+ .RowPitch = static_cast<UINT>(dst.row_pitch),
+ },
+ },
+ };
+ dx12_command_buffer->CopyTextureRegion(&dst_copy_location, 0U, 0U, 0U, &src_copy_location, nullptr);
+ }
+}
diff --git a/api-test/dx12-device.cpp b/api-test/dx12-device.cpp
index e603fef..ac328ed 100644
--- a/api-test/dx12-device.cpp
+++ b/api-test/dx12-device.cpp
@@ -3,69 +3,237 @@
#include <cstdint>
#include <cstdio>
-dx12device dx12device::render_device = dx12device();
+#include "dx12-command-buffer.hpp"
-void dx12device::init() {
- SUCCEEDED(CreateDXGIFactory(IID_PPV_ARGS(&factory)));
+namespace dx12 {
+ device device::render_device = dx12::device();
- uint32_t index = 0U;
- while (factory->EnumAdapters(index, &adapter) != DXGI_ERROR_NOT_FOUND) {
- DXGI_ADAPTER_DESC desc;
- SUCCEEDED(adapter->GetDesc(&desc));
- printf("%S\n", desc.Description);
- index++;
+ void device::init() {
+ HRESULT hr = S_OK;
+ hr = CreateDXGIFactory2(DXGI_CREATE_FACTORY_DEBUG, IID_PPV_ARGS(&factory));
+ assert(hr == S_OK);
+
+ uint32_t index = 0U;
+ while (factory->EnumAdapters(index, &adapter) != DXGI_ERROR_NOT_FOUND) {
+ DXGI_ADAPTER_DESC desc;
+ SUCCEEDED(adapter->GetDesc(&desc));
+ printf("%S\n", desc.Description);
+ index++;
+ }
+
+ SUCCEEDED(factory->EnumAdapters(0U, &adapter));
+
+ if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debug_interface)))) {
+ debug_interface->EnableDebugLayer();
+ }
+
+ hr = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_12_0, IID_PPV_ARGS(&device));
+ assert(hr == S_OK);
+
+ queues[static_cast<uint32_t>(QueueType::GRAPHICS)].type = D3D12_COMMAND_LIST_TYPE_DIRECT;
+ D3D12_COMMAND_QUEUE_DESC queue_desc{
+ .Type = queues[static_cast<uint32_t>(QueueType::GRAPHICS)].type,
+ .Priority = D3D12_COMMAND_QUEUE_PRIORITY::D3D12_COMMAND_QUEUE_PRIORITY_HIGH,
+ .Flags = D3D12_COMMAND_QUEUE_FLAGS::D3D12_COMMAND_QUEUE_FLAG_NONE,
+ .NodeMask = 0U,
+ };
+ device->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&queues[static_cast<uint32_t>(QueueType::GRAPHICS)].dx_queue));
+ assert(hr == S_OK);
+
+ queue_desc.Type = queues[static_cast<uint32_t>(QueueType::ASYNC_COMPUTE)].type = D3D12_COMMAND_LIST_TYPE_COMPUTE;
+ queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY::D3D12_COMMAND_QUEUE_PRIORITY_HIGH,
+ device->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&queues[static_cast<uint32_t>(QueueType::ASYNC_COMPUTE)].dx_queue));
+ assert(hr == S_OK);
+
+ queue_desc.Type = queues[static_cast<uint32_t>(QueueType::TRANSFER)].type = D3D12_COMMAND_LIST_TYPE_COPY;
+ queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY::D3D12_COMMAND_QUEUE_PRIORITY_HIGH,
+ device->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&queues[static_cast<uint32_t>(QueueType::TRANSFER)].dx_queue));
+ assert(hr == S_OK);
+
+ hr = device->CreateFence(0U, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));
+ assert(hr == S_OK);
+
+ D3D12MA::ALLOCATOR_DESC allocator_desc {
+ .pDevice = device,
+ .pAdapter = adapter,
+ };
+
+ hr = D3D12MA::CreateAllocator(&allocator_desc, &allocator);
+ assert(hr == S_OK);
+
+ model.init();
}
- SUCCEEDED(factory->EnumAdapters(0U, &adapter));
+ handle<device_surface> device::create_surface(const surface_desc& desc) {
+ device_surface surface {
+ };
+ DXGI_SAMPLE_DESC sample_desc{
+ .Count = 1U,
+ .Quality = 0U,
+ };
+ DXGI_SWAP_CHAIN_DESC1 swapchain_desc1{
+ .Width = 0U,
+ .Height = 0U,
+ .Format = desc.surface_format,
+ .Stereo = FALSE,
+ .SampleDesc = sample_desc,
+ .BufferUsage = desc.usages,
+ .BufferCount = desc.image_count,
+ .Scaling = DXGI_SCALING_NONE,
+ .SwapEffect = desc.present_mode,
+ .AlphaMode = DXGI_ALPHA_MODE_IGNORE,
+ .Flags = 0U,
+ };
+ HRESULT hr = factory->CreateSwapChainForHwnd(queues[static_cast<uint32_t>(QueueType::GRAPHICS)].dx_queue, desc.window_handle, &swapchain_desc1, nullptr, nullptr, &surface.swapchain);
+ assert(hr == S_OK);
- SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_12_0, IID_PPV_ARGS(&device)));
+ return surfaces.add(surface);
+ }
- D3D12_COMMAND_QUEUE_DESC queue_desc{
- .Type = D3D12_COMMAND_LIST_TYPE::D3D12_COMMAND_LIST_TYPE_DIRECT,
- .Priority = D3D12_COMMAND_QUEUE_PRIORITY::D3D12_COMMAND_QUEUE_PRIORITY_HIGH,
- .Flags = D3D12_COMMAND_QUEUE_FLAGS::D3D12_COMMAND_QUEUE_FLAG_NONE,
- .NodeMask = 0U,
- };
- SUCCEEDED(device->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&queues[0U].dx_queue)));
+ handle<device_buffer> device::create_buffer(const buffer_desc& desc) {
+ device_buffer buffer {
+ .size = desc.size,
+ };
- queue_desc.Type = D3D12_COMMAND_LIST_TYPE::D3D12_COMMAND_LIST_TYPE_COMPUTE;
- queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY::D3D12_COMMAND_QUEUE_PRIORITY_HIGH,
- SUCCEEDED(device->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&queues[1U].dx_queue)));
+ DXGI_SAMPLE_DESC sample_desc {
+ .Count = 1U,
+ .Quality = 0U,
+ };
+ D3D12_RESOURCE_DESC resource_desc {
+ .Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
+ .Alignment = 0U,
+ .Width = buffer.size,
+ .Height = 1U,
+ .DepthOrArraySize = 1U,
+ .MipLevels = 1U,
+ .Format = DXGI_FORMAT_UNKNOWN,
+ .SampleDesc = sample_desc,
+ .Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
+ .Flags = desc.usages,
+ };
+ D3D12MA::ALLOCATION_DESC allocation_desc {
+ .HeapType = desc.heap_type,
+ };
+ HRESULT hr = allocator->CreateResource(&allocation_desc, &resource_desc, desc.states, nullptr, &buffer.alloc, IID_PPV_ARGS(&buffer.resource));
+ assert(hr == S_OK);
- queue_desc.Type = D3D12_COMMAND_LIST_TYPE::D3D12_COMMAND_LIST_TYPE_COPY;
- queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY::D3D12_COMMAND_QUEUE_PRIORITY_HIGH,
- SUCCEEDED(device->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&queues[2U].dx_queue)));
-}
+ if (desc.map) {
+ hr = buffer.resource->Map(0U, nullptr, &buffer.mapped_ptr);
+ assert(hr == S_OK);
+ }
+
+ return buffers.add(buffer);
+ }
-handle<dx12::device_surface> dx12device::create_surface(const dx12::surface_desc& desc) {
- dx12::device_surface surface {
- };
- DXGI_MODE_DESC mode_desc{
- .Width = 0U,
- .Height = 0U,
- .RefreshRate = {
- .Numerator = 1U,
- .Denominator = 60U,
- },
- .Format = desc.surface_format,
- .ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED,
- .Scaling = DXGI_MODE_SCALING_CENTERED,
- };
- DXGI_SAMPLE_DESC sample_desc{
- .Count = 1U,
- .Quality = 0U,
- };
- DXGI_SWAP_CHAIN_DESC swapchain_desc{
- .BufferDesc = mode_desc,
- .SampleDesc = sample_desc,
- .BufferUsage = desc.usages,
- .BufferCount = desc.image_count,
- .OutputWindow = desc.window_handle,
- .Windowed = TRUE,
- .SwapEffect = desc.present_mode,
- .Flags = 0U,
- };
- HRESULT hr = factory->CreateSwapChain(queues[static_cast<uint32_t>(dx12::QueueType::GRAPHICS)].dx_queue, &swapchain_desc, &surface.swapchain);
+ handle<device_texture> device::create_texture(const texture_desc& desc) {
+ device_texture texture {
+ .width = desc.width,
+ .height = desc.height,
+ .depth = desc.depth,
+ .mips = desc.mips,
+ .format = desc.format,
+ };
- return surfaces.add(surface);
+ DXGI_SAMPLE_DESC sample_desc {
+ .Count = 1U,
+ .Quality = 0U,
+ };
+ D3D12_RESOURCE_DESC resource_desc {
+ .Dimension = desc.type,
+ .Alignment = 0U,
+ .Width = texture.width,
+ .Height = texture.height,
+ .DepthOrArraySize = static_cast<uint16_t>(texture.depth),
+ .MipLevels = static_cast<uint16_t>(texture.mips),
+ .Format = desc.format,
+ .SampleDesc = sample_desc,
+ .Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
+ .Flags = desc.usages,
+ };
+ D3D12MA::ALLOCATION_DESC allocation_desc {
+ .HeapType = D3D12_HEAP_TYPE_DEFAULT,
+ };
+
+ HRESULT hr = allocator->CreateResource(&allocation_desc, &resource_desc, desc.states, nullptr, &texture.alloc, IID_PPV_ARGS(&texture.resource));
+ assert(hr == S_OK);
+
+ D3D12_PLACED_SUBRESOURCE_FOOTPRINT place_footprint;
+ UINT num_rows = 0U;
+ UINT64 total_bytes = 0U;
+ device->GetCopyableFootprints(&resource_desc, 0U, 1U, 0U, &place_footprint, &num_rows, &texture.row_pitch, &total_bytes);
+
+ return textures.add(texture);
+ }
+
+ void device::allocate_command_buffers(command_buffer* buffers, size_t count, QueueType type) {
+ HRESULT hr = S_OK;
+ for (uint32_t index = 0U; index < count; index++) {
+ buffers[index].queue_type = type;
+
+ auto list_type = queues[static_cast<uint32_t>(type)].type;
+ hr = device->CreateCommandAllocator(list_type, IID_PPV_ARGS(&buffers[index].command_allocator));
+ assert(hr == S_OK);
+
+ hr = device->CreateCommandList(0U, list_type, buffers[index].command_allocator, nullptr, IID_PPV_ARGS(&buffers[index].dx12_command_buffer));
+ assert(hr == S_OK);
+
+ hr = buffers[index].dx12_command_buffer->Close();
+ assert(hr == S_OK);
+ }
+ }
+
+ uint32_t device::submit(command_buffer* buffers, uint32_t count) {
+ assert((max_submitable_command_buffers - count) >= 0);
+ const auto queue_type = buffers[0].queue_type;
+ auto& queue = queues[static_cast<uint32_t>(buffers[0].queue_type)];
+ ID3D12CommandList* lists[max_submitable_command_buffers] = { nullptr };
+
+ for (auto index{ 0U }; index < count; index++) {
+ assert(queue_type == buffers[index].queue_type);
+
+ lists[index] = buffers[index].dx12_command_buffer;
+ }
+
+ queue.dx_queue->ExecuteCommandLists(count, lists);
+ HRESULT hr = queue.dx_queue->Signal(fence, ++fence_value);
+ assert(hr == S_OK);
+
+ for (uint32_t index = 0U; index < count; index++) {
+ auto& buffer = buffers[index];
+
+ hr = buffer.dx12_command_buffer->Reset(buffer.command_allocator, nullptr);
+ assert(hr == S_OK);
+ }
+
+ return fence_value;
+ }
+
+ void device::wait() {
+ for (auto& queue : queues) {
+ queue.dx_queue->Wait(fence, fence_value);
+ }
+ }
+
+ void device::bindless_model::init() {
+ ID3D12Device* device = device::get_render_device().get_device();
+
+ D3D12_DESCRIPTOR_HEAP_DESC resources_descriptor_heap_desc {
+ .Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
+ .NumDescriptors = D3D12_MAX_SHADER_VISIBLE_DESCRIPTOR_HEAP_SIZE_TIER_2,
+ .Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,
+ .NodeMask = 0U,
+ };
+
+ HRESULT hr = device->CreateDescriptorHeap(&resources_descriptor_heap_desc, IID_PPV_ARGS(&resources_heap));
+ assert(hr == S_OK);
+
+ D3D12_DESCRIPTOR_HEAP_DESC samplers_descriptor_heap_desc {
+ .Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
+ .NumDescriptors = D3D12_MAX_SHADER_VISIBLE_SAMPLER_HEAP_SIZE,
+ .Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,
+ .NodeMask = 0U,
+ };
+ hr = device->CreateDescriptorHeap(&samplers_descriptor_heap_desc, IID_PPV_ARGS(&samplers_heap));
+ assert(hr == S_OK);
+ }
}
diff --git a/api-test/main.cpp b/api-test/main.cpp
index f61fa13..e1c5af6 100644
--- a/api-test/main.cpp
+++ b/api-test/main.cpp
@@ -2,7 +2,9 @@
#include <cstdio>
#include <array>
#include <chrono>
-#include <vk_mem_alloc.h>
+
+#include <Windows.h>
+#include <debugapi.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
@@ -14,9 +16,11 @@
#include "utils.hpp"
#ifdef VK
+#include <vk_mem_alloc.h>
#include "vk-device.hpp"
#else
#include "dx12-device.hpp"
+#include "dx12-command-buffer.hpp"
#endif
struct device_texture;
@@ -64,22 +68,22 @@ void ui(uint32_t frame_time) {
ImGui::Render();
}
-void update_buffers(ImDrawData* draw_data, const device_buffer& vertex_buffer, const device_buffer& index_buffer) {
- off_t vertex_offset = 0;
- off_t index_offset = 0;
- for (auto index {0} ; index < draw_data->CmdListsCount; index++) {
- auto* cmd_list = draw_data->CmdLists[index];
-
- size_t vertex_bytes_size = sizeof(ImDrawVert) * cmd_list->VtxBuffer.size();
- auto* vtx_ptr = static_cast<uint8_t*>(vertex_buffer.mapped_ptr) + vertex_offset;
- memcpy(vtx_ptr, cmd_list->VtxBuffer.Data, vertex_bytes_size);
- vertex_offset += static_cast<off_t>(vertex_bytes_size);
-
- size_t index_bytes_size = sizeof(ImDrawIdx) * cmd_list->IdxBuffer.size();
- memcpy(static_cast<uint8_t*>(index_buffer.mapped_ptr) + index_offset, cmd_list->IdxBuffer.Data, index_bytes_size);
- index_offset += static_cast<off_t>(index_bytes_size);
- }
-}
+// void update_buffers(ImDrawData* draw_data, const device_buffer& vertex_buffer, const device_buffer& index_buffer) {
+// off_t vertex_offset = 0;
+// off_t index_offset = 0;
+// for (auto index {0} ; index < draw_data->CmdListsCount; index++) {
+// auto* cmd_list = draw_data->CmdLists[index];
+//
+// size_t vertex_bytes_size = sizeof(ImDrawVert) * cmd_list->VtxBuffer.size();
+// auto* vtx_ptr = static_cast<uint8_t*>(vertex_buffer.mapped_ptr) + vertex_offset;
+// memcpy(vtx_ptr, cmd_list->VtxBuffer.Data, vertex_bytes_size);
+// vertex_offset += static_cast<off_t>(vertex_bytes_size);
+//
+// size_t index_bytes_size = sizeof(ImDrawIdx) * cmd_list->IdxBuffer.size();
+// memcpy(static_cast<uint8_t*>(index_buffer.mapped_ptr) + index_offset, cmd_list->IdxBuffer.Data, index_bytes_size);
+// index_offset += static_cast<off_t>(index_bytes_size);
+// }
+// }
int main() {
@@ -110,80 +114,105 @@ int main() {
#ifdef VK
auto& device = vkdevice::get_render_device();
#else
- auto& device = dx12device::get_render_device();
+ auto& device = dx12::device::get_render_device();
#endif
device.init();
// auto main_scene = scene(camera(position, target, v_fov, aspect_ratio, aperture, focus_distance), window_width, window_height);
-#ifdef VK
auto surface_handle = device.create_surface({
.window_handle = wnd.handle,
+#ifdef VK
.surface_format = {
.format = VK_FORMAT_B8G8R8A8_UNORM,
.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
},
.present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR,
.usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
- });
#else
- auto surface_handle = device.create_surface({
- .window_handle = wnd.handle,
- .surface_format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ .surface_format = DXGI_FORMAT_R16G16B16A16_FLOAT,
.present_mode = DXGI_SWAP_EFFECT_FLIP_DISCARD,
- .usages = DXGI_USAGE_UNORDERED_ACCESS | DXGI_USAGE_RENDER_TARGET_OUTPUT,
- });
+ .usages = DXGI_USAGE_RENDER_TARGET_OUTPUT,
#endif
+ });
auto& surface = device.get_surface(surface_handle);
-#ifdef VK
constexpr size_t image_size = 1024U;
constexpr size_t image_count = 4U;
auto staging_buffer_handle = device.create_buffer({
.size = image_size * image_size * sizeof(uint32_t) * image_count,
+#ifdef VK
.usages = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
.memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+#else
+
+ .map = true,
+ .states = D3D12_RESOURCE_STATE_COPY_SOURCE,
+ .usages = D3D12_RESOURCE_FLAG_NONE,
+ .heap_type = D3D12_HEAP_TYPE_UPLOAD,
+#endif
});
const auto& staging_buffer = device.get_buffer(staging_buffer_handle);
// API test code
- // int width;
- // int height;
- // int channels;
- // uint8_t* data = stbi_load("../models/sponza/466164707995436622.jpg", &width, &height, &channels, 4);
- // size_t size = static_cast<size_t>(width) * height * 4U;
- // memcpy(staging_buffer.mapped_ptr, data, size);
+ int width;
+ int height;
+ int channels;
+ uint8_t* data = stbi_load("../models/sponza/466164707995436622.jpg", &width, &height, &channels, 4);
+ size_t size = static_cast<size_t>(width) * height * 4U;
+ memcpy(staging_buffer.mapped_ptr, data, size);
- // auto gpu_texture_handle = device.create_texture({
- // .width = static_cast<uint32_t>(width),
- // .height = static_cast<uint32_t>(height),
- // .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
- // .format = VK_FORMAT_R8G8B8A8_UNORM,
- // .type = VK_IMAGE_TYPE_2D,
- // });
+ auto gpu_texture_handle = device.create_texture({
+ .width = static_cast<uint32_t>(width),
+ .height = static_cast<uint32_t>(height),
+#ifdef VK
+ .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+ .format = VK_FORMAT_R8G8B8A8_UNORM,
+ .type = VK_IMAGE_TYPE_2D,
+#else
+ .states = D3D12_RESOURCE_STATE_COPY_DEST,
+ .usages = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
+ .format = DXGI_FORMAT_R8G8B8A8_UNORM,
+ .type = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
+#endif
+ });
- // off_t offset = width * height * 4;
- // data = stbi_load("../models/sponza/715093869573992647.jpg", &width, &height, &channels, 4);
- // size = static_cast<size_t>(width) * height * 4U;
- // auto* addr = static_cast<void*>(static_cast<uint8_t*>(staging_buffer.mapped_ptr) + offset);
- // memcpy(addr, data, size);
+ off_t offset = width * height * 4;
+ data = stbi_load("../models/sponza/715093869573992647.jpg", &width, &height, &channels, 4);
+ size = static_cast<size_t>(width) * height * 4U;
+ auto* addr = static_cast<void*>(static_cast<uint8_t*>(staging_buffer.mapped_ptr) + offset);
+ memcpy(addr, data, size);
- // auto second_texture = device.create_texture({
- // .width = static_cast<uint32_t>(width),
- // .height = static_cast<uint32_t>(height),
- // .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
- // .format = VK_FORMAT_R8G8B8A8_UNORM,
- // .type = VK_IMAGE_TYPE_2D,
- // });
+ auto second_texture = device.create_texture({
+ .width = static_cast<uint32_t>(width),
+ .height = static_cast<uint32_t>(height),
+#ifdef VK
+ .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
+ .format = VK_FORMAT_R8G8B8A8_UNORM,
+ .type = VK_IMAGE_TYPE_2D,
+#else
+ .states = D3D12_RESOURCE_STATE_COPY_DEST,
+ .usages = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
+ .format = DXGI_FORMAT_R8G8B8A8_UNORM,
+ .type = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
+#endif
+ });
+
+ auto output_texture_handle = device.create_texture({
+ .width = static_cast<uint32_t>(width),
+ .height = static_cast<uint32_t>(height),
+#ifdef VK
+ .usages = VK_IMAGE_USAGE_STORAGE_BIT,
+ .format = VK_FORMAT_R8G8B8A8_UNORM,
+ .type = VK_IMAGE_TYPE_2D,
+#else
+ .usages = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
+ .format = DXGI_FORMAT_R8G8B8A8_UNORM,
+ .type = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
+#endif
+ });
- // auto output_texture_handle = device.create_texture({
- // .width = static_cast<uint32_t>(width),
- // .height = static_cast<uint32_t>(height),
- // .usages = VK_IMAGE_USAGE_STORAGE_BIT,
- // .format = VK_FORMAT_R8G8B8A8_UNORM,
- // .type = VK_IMAGE_TYPE_2D,
- // });
uint8_t *pixels = nullptr;
int atlas_width;
@@ -192,9 +221,16 @@ int main() {
const auto ui_texture_handle = device.create_texture({
.width = static_cast<uint32_t>(atlas_width),
.height = static_cast<uint32_t>(atlas_height),
+#ifdef VK
.usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
.format = VK_FORMAT_R8G8B8A8_UNORM,
.type = VK_IMAGE_TYPE_2D,
+#else
+ .states = D3D12_RESOURCE_STATE_COPY_DEST,
+ .usages = D3D12_RESOURCE_FLAG_NONE,
+ .format = DXGI_FORMAT_R8G8B8A8_UNORM,
+ .type = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
+#endif
});
const auto& ui_texture = device.get_texture(ui_texture_handle);
io.Fonts->SetTexID(*(void **)&ui_texture_handle.id);
@@ -206,20 +242,27 @@ int main() {
auto vertex_buffer_handle = device.create_buffer({
.size = Mb * sizeof(uint32_t),
+#ifdef VK
.usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+#else
+ #endif
});
auto vertex_buffer = device.get_buffer(vertex_buffer_handle);
auto index_buffer_handle = device.create_buffer({
.size = Mb * sizeof(uint32_t),
+#ifdef VK
.usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
.memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+#else
+#endif
});
auto index_buffer = device.get_buffer(index_buffer_handle);
+#ifdef VK
auto code = read_file("shaders/test.comp.spv");
auto compute = device.create_compute_pipeline({
.cs_code = code,
@@ -233,24 +276,45 @@ int main() {
auto tonemapping = device.create_compute_pipeline({
.cs_code = tonemapping_code,
});
+#endif
const auto acc_handle = device.create_texture({
.width = static_cast<uint32_t>(window_width),
.height = static_cast<uint32_t>(window_height),
+#ifdef VK
.usages = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.type = VK_IMAGE_TYPE_2D,
+#else
+ .states = D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
+ .usages = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
+ .format = DXGI_FORMAT_R32G32B32A32_FLOAT,
+ .type = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
+#endif
});
+
+#ifdef VK
auto acc_storage_index = device.get_texture(acc_handle).get_storage_index();
+#endif
const auto result_handle = device.create_texture({
.width = static_cast<uint32_t>(window_width),
.height = static_cast<uint32_t>(window_height),
+#ifdef VK
.usages = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.type = VK_IMAGE_TYPE_2D,
+#else
+ .states = D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
+ .usages = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
+ .format = DXGI_FORMAT_R32G32B32A32_FLOAT,
+ .type = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
+#endif
});
+#ifdef VK
auto result_storage_index = device.get_texture(result_handle).get_storage_index();
+#endif
+#ifdef VK
std::array<VkFormat, 1U> formats { surface.surface_format.format };
auto vertex_code = read_file("shaders/api-test-ui.vert.spv");
auto fragment_code = read_file("shaders/api-test-ui.frag.spv");
@@ -259,47 +323,58 @@ int main() {
.fs_code = fragment_code,
.color_attachments_format = formats
});
+#endif
+#ifdef VK
std::array<graphics_command_buffer, 4U> graphics_command_buffers;
device.allocate_command_buffers(graphics_command_buffers.data(), graphics_command_buffers.size(), QueueType::GRAPHICS);
+#else
+ std::array<dx12::graphics_command_buffer, 4U> graphics_command_buffers;
+ device.allocate_command_buffers(graphics_command_buffers.data(), graphics_command_buffers.size(), dx12::QueueType::GRAPHICS);
+#endif
// API test code
- // RD_START_CAPTURE;
+ RD_START_CAPTURE;
- // graphics_command_buffers[0].start();
+ graphics_command_buffers[0].start();
- // graphics_command_buffers[0].barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
- // graphics_command_buffers[0].barrier(second_texture, VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
- // graphics_command_buffers[0].barrier(ui_texture_handle, VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
- // graphics_command_buffers[0].copy(staging_buffer_handle, gpu_texture_handle);
- // graphics_command_buffers[0].copy(staging_buffer_handle, second_texture, static_cast<VkDeviceSize>(offset));
- // graphics_command_buffers[0].copy(staging_buffer_handle, ui_texture_handle, static_cast<VkDeviceSize>(ui_offset));
+#ifdef VK
+ graphics_command_buffers[0].barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+ graphics_command_buffers[0].barrier(second_texture, VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+ graphics_command_buffers[0].barrier(ui_texture_handle, VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+#endif
- // graphics_command_buffers[0].barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL);
- // graphics_command_buffers[0].barrier(second_texture, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL);
+ graphics_command_buffers[0].copy(staging_buffer_handle, gpu_texture_handle);
+ graphics_command_buffers[0].copy(staging_buffer_handle, second_texture, offset);
+ graphics_command_buffers[0].copy(staging_buffer_handle, ui_texture_handle, ui_offset);
+#ifdef VK
+ graphics_command_buffers[0].barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL);
+ graphics_command_buffers[0].barrier(second_texture, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL);
- // {
- // graphics_command_buffers[0].dispatch({
- // .pipeline = compute,
- // .group_size = { .vec = { image_size, image_size, 1U }},
- // .local_group_size = { .vec = { 8U, 8U, 1U }},
- // .params = {
- // device.get_texture(second_texture).get_storage_index(), // Input 1
- // device.get_texture(gpu_texture_handle).get_storage_index(), // Input 2
- // device.get_texture(output_texture_handle).get_storage_index(), // Output
- // },
- // });
- // }
+ {
+ graphics_command_buffers[0].dispatch({
+ .pipeline = compute,
+ .group_size = { .vec = { image_size, image_size, 1U }},
+ .local_group_size = { .vec = { 8U, 8U, 1U }},
+ .params = {
+ device.get_texture(second_texture).get_storage_index(), // Input 1
+ device.get_texture(gpu_texture_handle).get_storage_index(), // Input 2
+ device.get_texture(output_texture_handle).get_storage_index(), // Output
+ },
+ });
+ }
- // graphics_command_buffers[0].barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ graphics_command_buffers[0].barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+#endif
- // graphics_command_buffers[0].stop();
+ graphics_command_buffers[0].stop();
- // device.submit(graphics_command_buffers.data(), 1);
- // device.wait();
+ device.submit(graphics_command_buffers.data(), 1);
+ device.wait();
- // RD_END_CAPTURE;
+ RD_END_CAPTURE;
+#ifdef VK
std::array<handle<device_texture>, 1U> color_attachment {};
constexpr uint32_t virtual_frames_count = 2U;
uint32_t frame_time = 1U;
@@ -473,6 +548,7 @@ int main() {
device.destroy_buffer(staging_buffer_handle);
device.destroy_buffer(vertex_buffer_handle);
device.destroy_buffer(index_buffer_handle);
+ device.deinit();
ImGui::DestroyContext();
#endif // VK
diff --git a/api-test/command-buffer.cpp b/api-test/vk-command-buffer.cpp
index d694f9f..bdb0e40 100644
--- a/api-test/command-buffer.cpp
+++ b/api-test/vk-command-buffer.cpp
@@ -1,4 +1,4 @@
-#include "command-buffer.hpp"
+#include "vk-command-buffer.hpp"
#include <vulkan/vulkan_core.h>
@@ -82,7 +82,7 @@ void command_buffer::barrier(handle<device_texture> texture_handle, VkPipelineSt
texture.access = access;
}
-void command_buffer::copy(handle<device_buffer> buffer_handle, ::handle<device_texture> texture_handle, VkDeviceSize offset) const {
+void command_buffer::copy(handle<device_buffer> buffer_handle, ::handle<device_texture> texture_handle, uint64_t offset) const {
auto& device = vkdevice::get_render_device();
const auto& buffer = device.get_buffer(buffer_handle);
const auto& texture = device.get_texture(texture_handle);
diff --git a/api-test/vk-device.cpp b/api-test/vk-device.cpp
index 024b570..a3c5119 100644
--- a/api-test/vk-device.cpp
+++ b/api-test/vk-device.cpp
@@ -8,6 +8,7 @@
#include "vk-utils.hpp"
#include "vulkan-loader.hpp"
+#include "vk-command-buffer.hpp"
vkdevice vkdevice::render_device = vkdevice();
@@ -44,7 +45,7 @@ void vkdevice::init() {
timeline_semaphore = get_semaphore(semaphore);
}
-vkdevice::~vkdevice() {
+void vkdevice::deinit() {
vkDeviceWaitIdle(device);
bindless_model::destroy_bindless_model(bindless);
@@ -66,6 +67,7 @@ vkdevice::~vkdevice() {
vkDestroyInstance(instance, nullptr);
}
+
void vkdevice::wait() { vkDeviceWaitIdle(device); };
handle<device_texture> vkdevice::create_texture(const texture_desc& desc) {