diff --git a/gpuapi/direct3d/AppCmdBuffer.h b/gpuapi/direct3d/AppCmdBuffer.h index 13171f7..949b78d 100644 --- a/gpuapi/direct3d/AppCmdBuffer.h +++ b/gpuapi/direct3d/AppCmdBuffer.h @@ -20,7 +20,6 @@ #include #include #include -#include void* cmd_shader_load(AppCmdBuffer*, Command*) { return NULL; @@ -31,7 +30,10 @@ void* cmd_shader_load_sync(AppCmdBuffer* cb, Shader* shader, int32* shader_ids) GpuApiContainer* gpu_api = (GpuApiContainer *) cb->gpu_api; - Microsoft::WRL::ComPtr shader_assets[SHADER_TYPE_SIZE]; + ID3DBlob* shader_assets[SHADER_TYPE_SIZE]; + for (int32 i = 0; i < SHADER_TYPE_SIZE; ++i) { + shader_assets[i] = NULL; + } for (int32 i = 0; i < SHADER_TYPE_SIZE; ++i) { if (!shader_ids[i]) { @@ -61,8 +63,8 @@ void* cmd_shader_load_sync(AppCmdBuffer* cb, Shader* shader, int32* shader_ids) // Make shader/program shader->id = program_make( - gpu_api->device.Get(), gpu_api->pipeline_state, gpu_api->root_signature.Get(), - shader_assets[0].Get(), shader_assets[1].Get(), shader_assets[2].Get() + gpu_api->device, &gpu_api->pipeline, gpu_api->pipeline_layout, + shader_assets[0], shader_assets[1], shader_assets[2] ); return NULL; diff --git a/gpuapi/direct3d/DirectXUtils.h b/gpuapi/direct3d/DirectXUtils.h index cdff6ad..89478f5 100644 --- a/gpuapi/direct3d/DirectXUtils.h +++ b/gpuapi/direct3d/DirectXUtils.h @@ -10,21 +10,22 @@ #define TOS_GPUAPI_DIRECTX_UTILS_H #include -#include +#include #include +#include #include "../../../GameEngine/log/Log.h" -#include "../../../EngineDependencies/directx/d3d12.h" -#include "../../../EngineDependencies/directx/d3dx12.h" +// #include "../../../EngineDependencies/directx/d3d12.h" +// #include "../../../EngineDependencies/directx/d3dx12.h" #include "../../stdlib/Types.h" // A more (compile-time) efficient version of the windows macro IID_PPV_ARGS -#define IID_PPVOID(pointer) __uuidof(**(&pointer)), reinterpret_cast(&pointer) +#define IID_PPVOID(pointer) __uuidof(**(pointer)), (void **) (pointer) bool is_directx_supported(D3D_FEATURE_LEVEL version) { IDXGIFactory6* factory = NULL; - if (FAILED(CreateDXGIFactory1(IID_PPVOID(factory)))) { + if (FAILED(CreateDXGIFactory1(IID_PPVOID(&factory)))) { return false; } @@ -91,7 +92,7 @@ int32 max_directx_version() // Returns frame index int32 wait_for_previous_frame( ID3D12Fence* fence, HANDLE fence_event, UINT64* fence_value, - ID3D12CommandQueue* command_queue, IDXGISwapChain3* swapchain + ID3D12CommandQueue* graphics_queue, IDXGISwapChain3* swapchain ) { // WAITING FOR THE FRAME TO COMPLETE BEFORE CONTINUING IS NOT BEST PRACTICE. @@ -102,7 +103,7 @@ int32 wait_for_previous_frame( UINT64 fence_value_temp = *fence_value; // Signal and increment the fence value. - if(FAILED(command_queue->Signal(fence, fence_value_temp))) { + if(FAILED(graphics_queue->Signal(fence, fence_value_temp))) { LOG(true, "DirectX12 Signal"); ASSERT_SIMPLE(false); } @@ -147,10 +148,10 @@ void directx_debug_callback( ASSERT_SIMPLE(false); } -void gpuapi_debug_messenger_setup(Microsoft::WRL::ComPtr& device) +void gpuapi_debug_messenger_setup(ID3D12Device* device) { - Microsoft::WRL::ComPtr info_queue; - if (FAILED(device.As(&info_queue))) { + ID3D12InfoQueue1* info_queue; + if (FAILED(device->QueryInterface(IID_PPVOID(&info_queue)))) { return; } @@ -164,6 +165,16 @@ void gpuapi_debug_messenger_setup(Microsoft::WRL::ComPtr& device) // Set the message count limit to unlimited info_queue->SetMessageCountLimit(0); + + info_queue->Release(); +} + +inline +void gpuapi_create_logical_device(ID3D12Device** device) { + if (FAILED(D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, IID_PPVOID(device)))) { + LOG(true, "DirectX12 D3D12CreateDevice"); + ASSERT_SIMPLE(false); + } } #endif \ No newline at end of file diff --git a/gpuapi/direct3d/GpuApiContainer.h b/gpuapi/direct3d/GpuApiContainer.h index e67be3f..46f1410 100644 --- a/gpuapi/direct3d/GpuApiContainer.h +++ b/gpuapi/direct3d/GpuApiContainer.h @@ -10,40 +10,39 @@ #define TOS_GPUAPI_DIRECTX_GPU_API_CONTAINER_H #include "../../stdlib/Types.h" -#include "../../../EngineDependencies/directx/d3d12.h" -#include "../../../EngineDependencies/directx/d3dx12.h" +// #include "../../../EngineDependencies/directx/d3d12.h" +// #include "../../../EngineDependencies/directx/d3dx12.h" #include #include #include #include -#include struct GpuApiContainer { uint32 frames_in_flight; uint32 framebuffer_idx; - Microsoft::WRL::ComPtr device; - Microsoft::WRL::ComPtr swapchain; + ID3D12Device* device; + IDXGISwapChain4* swapchain; - Microsoft::WRL::ComPtr command_queue; - Microsoft::WRL::ComPtr rtv_heap; + ID3D12CommandQueue* graphics_queue; + ID3D12DescriptorHeap* rtv_heap; // basically = swapchain_image_views uint32 rtv_info_size; // @todo should be dynamic size based on frames_in_flight, no? - Microsoft::WRL::ComPtr render_targets[2]; - Microsoft::WRL::ComPtr command_allocator; - Microsoft::WRL::ComPtr command_list; - Microsoft::WRL::ComPtr pipeline_state; - Microsoft::WRL::ComPtr root_signature; - Microsoft::WRL::ComPtr fence; + ID3D12Resource* framebuffer[2]; + ID3D12CommandAllocator* command_pool; + ID3D12GraphicsCommandList* command_buffer; + ID3D12PipelineState* pipeline; + ID3D12RootSignature* pipeline_layout; + ID3D12Fence* in_flight_fence; UINT64 fence_value = 0; HANDLE fence_event; // ???? - CD3DX12_VIEWPORT m_viewport; - CD3DX12_RECT m_scissorRect; + D3D12_VIEWPORT m_viewport; + D3D12_RECT m_scissorRect; - // @todo This definately doesn't belong here - Microsoft::WRL::ComPtr m_vertexBuffer; + // @todo This definitely doesn't belong here + ID3D12Resource* m_vertexBuffer; D3D12_VERTEX_BUFFER_VIEW m_vertexBufferView; }; diff --git a/gpuapi/direct3d/Shader.h b/gpuapi/direct3d/Shader.h index e983802..f20d299 100644 --- a/gpuapi/direct3d/Shader.h +++ b/gpuapi/direct3d/Shader.h @@ -11,10 +11,9 @@ #include "../../stdlib/Types.h" #include -#include struct Shader { - Microsoft::WRL::ComPtr id; + ID3D12PipelineState* id; uint32 locations[7]; byte data[16]; }; diff --git a/gpuapi/direct3d/ShaderUtils.h b/gpuapi/direct3d/ShaderUtils.h index 6adb404..a2c683e 100644 --- a/gpuapi/direct3d/ShaderUtils.h +++ b/gpuapi/direct3d/ShaderUtils.h @@ -12,10 +12,7 @@ #include #include #include -#include #include -#include "../../../EngineDependencies/directx/d3d12.h" -#include "../../../EngineDependencies/directx/d3dx12.h" #include "../../stdlib/Types.h" #include "../../memory/RingMemory.h" @@ -36,7 +33,7 @@ const char* shader_type_index(ShaderType type) } } -Microsoft::WRL::ComPtr shader_make(const char* type, const char* source, int32 source_size) +ID3DBlob* shader_make(const char* type, const char* source, int32 source_size) { #if DEBUG || INTERNAL uint32 compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; @@ -44,58 +41,96 @@ Microsoft::WRL::ComPtr shader_make(const char* type, const char* sourc uint32 compileFlags = 0; #endif - Microsoft::WRL::ComPtr blob; - Microsoft::WRL::ComPtr errMsgs; - if (FAILED(D3DCompile2(source, source_size, NULL, NULL, NULL, "main", type, compileFlags, 0, 0, NULL, 0, blob.GetAddressOf(), errMsgs.GetAddressOf()))) { + ID3DBlob* blob; + ID3DBlob* errMsgs; + if (FAILED(D3DCompile2(source, source_size, NULL, NULL, NULL, "main", type, compileFlags, 0, 0, NULL, 0, &blob, &errMsgs))) { LOG(true, "DirectX12 D3DCompile2"); ASSERT_SIMPLE(false); } + if (errMsgs) { + errMsgs->Release(); + } + return blob; } ID3D12PipelineState* program_make( ID3D12Device* device, - Microsoft::WRL::ComPtr& pipeline_state, - ID3D12RootSignature* root_signature, + ID3D12PipelineState** pipeline, + ID3D12RootSignature* pipeline_layout, ID3DBlob* vertex_shader, ID3DBlob* fragment_shader, ID3DBlob* ) { // @todo We need to find a way to do this somewhere else: - D3D12_INPUT_ELEMENT_DESC input_element_info[] = - { + D3D12_INPUT_ELEMENT_DESC input_element_info[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } }; D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeline_state_info = {}; pipeline_state_info.InputLayout = { input_element_info, _countof(input_element_info) }; - pipeline_state_info.pRootSignature = root_signature; - pipeline_state_info.VS = CD3DX12_SHADER_BYTECODE(vertex_shader); - pipeline_state_info.PS = CD3DX12_SHADER_BYTECODE(fragment_shader); - pipeline_state_info.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); - pipeline_state_info.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); - pipeline_state_info.DepthStencilState.DepthEnable = FALSE; - pipeline_state_info.DepthStencilState.StencilEnable = FALSE; + pipeline_state_info.pRootSignature = pipeline_layout; + pipeline_state_info.VS = { + .pShaderBytecode = vertex_shader->GetBufferPointer(), + .BytecodeLength = vertex_shader->GetBufferSize() + }; + pipeline_state_info.PS = { + .pShaderBytecode = fragment_shader->GetBufferPointer(), + .BytecodeLength = fragment_shader->GetBufferSize() + }; + pipeline_state_info.RasterizerState = { + .FillMode = D3D12_FILL_MODE_SOLID, + .CullMode = D3D12_CULL_MODE_BACK, + .FrontCounterClockwise = false, + .DepthBias = D3D12_DEFAULT_DEPTH_BIAS, + .DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP, + .SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, + .DepthClipEnable = true, + .MultisampleEnable = false, + .AntialiasedLineEnable = false, + .ForcedSampleCount = 0, + .ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF + }; + + const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = { + false,false, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_LOGIC_OP_NOOP, + D3D12_COLOR_WRITE_ENABLE_ALL, + }; + pipeline_state_info.BlendState = { + .AlphaToCoverageEnable = false, + .IndependentBlendEnable = false, + .RenderTarget = { + defaultRenderTargetBlendDesc, defaultRenderTargetBlendDesc, defaultRenderTargetBlendDesc, defaultRenderTargetBlendDesc, + defaultRenderTargetBlendDesc, defaultRenderTargetBlendDesc, defaultRenderTargetBlendDesc, defaultRenderTargetBlendDesc + } + }; + pipeline_state_info.DepthStencilState.DepthEnable = false; + pipeline_state_info.DepthStencilState.StencilEnable = false; pipeline_state_info.SampleMask = UINT_MAX; pipeline_state_info.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; pipeline_state_info.NumRenderTargets = 1; pipeline_state_info.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; pipeline_state_info.SampleDesc.Count = 1; - if (FAILED(device->CreateGraphicsPipelineState(&pipeline_state_info, IID_PPV_ARGS(&pipeline_state)))) { + if (FAILED(device->CreateGraphicsPipelineState(&pipeline_state_info, IID_PPV_ARGS(pipeline)))) { LOG(true, "DirectX12 CreateGraphicsPipelineState"); ASSERT_SIMPLE(false); } - return pipeline_state.Get(); + // @question When do I ->Release() vertex_shader and fragment_shader? + + return *pipeline; } inline -void pipeline_use(ID3D12GraphicsCommandList* command_list, ID3D12PipelineState* pipelineState) +void pipeline_use(ID3D12GraphicsCommandList* command_buffer, ID3D12PipelineState* pipelineState) { - command_list->SetPipelineState(pipelineState); + command_buffer->SetPipelineState(pipelineState); } #endif \ No newline at end of file diff --git a/gpuapi/vulkan/GpuApiContainer.h b/gpuapi/vulkan/GpuApiContainer.h index 3557567..c8fe93f 100644 --- a/gpuapi/vulkan/GpuApiContainer.h +++ b/gpuapi/vulkan/GpuApiContainer.h @@ -23,7 +23,7 @@ struct GpuApiContainer { VkFormat swapchain_image_format; VkImage* swapchain_images; // length = swapchain_image_count VkImageView* swapchain_image_views; // length = swapchain_image_count - VkFramebuffer* swapchain_framebuffers; // length = swapchain_image_count + VkFramebuffer* framebuffers; // length = swapchain_image_count VkExtent2D swapchain_extent; VkPipelineLayout pipeline_layout; VkQueue graphics_queue; diff --git a/gpuapi/vulkan/ShaderUtils.h b/gpuapi/vulkan/ShaderUtils.h index 25f9e55..0e3ac5f 100644 --- a/gpuapi/vulkan/ShaderUtils.h +++ b/gpuapi/vulkan/ShaderUtils.h @@ -69,9 +69,9 @@ VkShaderModule shader_make(VkDevice device, const char* source, int32 source_siz } inline -void pipeline_use(VkCommandBuffer command_list, VkPipeline pipeline) +void pipeline_use(VkCommandBuffer command_buffer, VkPipeline pipeline) { - vkCmdBindPipeline(command_list, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); } VkPipeline program_make( diff --git a/gpuapi/vulkan/VulkanUtils.h b/gpuapi/vulkan/VulkanUtils.h index 36653d2..55a455f 100644 --- a/gpuapi/vulkan/VulkanUtils.h +++ b/gpuapi/vulkan/VulkanUtils.h @@ -411,7 +411,7 @@ void gpuapi_create_logical_device( } // @question Do we need to handle old swapchains? -void vulkan_swap_chain_create( +void gpuapi_swapchain_create( VkDevice device, VkPhysicalDevice physical_device, VkSurfaceKHR surface, VkSwapchainKHR* swapchain, VkFormat* swapchain_image_format, VkExtent2D* swapchain_extent, Window* window, RingMemory* ring @@ -499,7 +499,7 @@ void vulkan_swap_chain_create( // WARNING: swapchain_images needs to already have reserved enough memory // @todo How can we ensure swapchain_images has enough but not too much space? -void vulkan_swap_chain_images_create( +void vulkan_swapchain_images_create( VkDevice device, VkSwapchainKHR swapchain, VkImage** swapchain_images, uint32* swapchain_image_count, BufferMemory* buf @@ -586,9 +586,9 @@ void vulkan_render_pass_create( } // @todo consider to rename to same name as opengl -// WARNING: swapchain_framebuffers needs to be initialized +// WARNING: framebuffers needs to be initialized void vulkan_framebuffer_create( - VkDevice device, VkFramebuffer* swapchain_framebuffers, + VkDevice device, VkFramebuffer* framebuffers, VkImageView* swapchain_image_views, uint32 swapchain_image_count, VkExtent2D swapchain_extent, VkRenderPass render_pass ) { @@ -607,7 +607,7 @@ void vulkan_framebuffer_create( framebufferInfo.height = swapchain_extent.height; framebufferInfo.layers = 1; - if ((result = vkCreateFramebuffer(device, &framebufferInfo, NULL, &swapchain_framebuffers[i])) != VK_SUCCESS) { + if ((result = vkCreateFramebuffer(device, &framebufferInfo, NULL, &framebuffers[i])) != VK_SUCCESS) { LOG_FORMAT(true, "Vulkan vkCreateFramebuffer: %d", LOG_DATA_INT32, (int32 *) &result); ASSERT_SIMPLE(false); }