Compare commits

...

3 commits

Author SHA1 Message Date
xboxones1
49221b2b10
Merge 497fbaa333 into 9ace79a4d2 2025-08-03 20:12:32 -05:00
squidbus
9ace79a4d2
Switch to upstream plume. (#1645)
Some checks are pending
validate-internal / build (push) Waiting to run
2025-08-03 19:52:08 +03:00
xboxones1
497fbaa333
Fix sound for native Linux build 2025-04-07 12:58:59 +09:00
23 changed files with 34 additions and 11783 deletions

View file

@ -52,7 +52,7 @@ jobs:
- name: Install Dependencies (Linux)
run: |-
sudo apt update
sudo apt install -y ninja-build llvm-${{ env.LLVM_VERSION }}-dev libgtk-3-dev
sudo apt install -y ninja-build llvm-${{ env.LLVM_VERSION }}-dev libgtk-3-dev libasound2-dev libpulse-dev libpipewire-0.3-dev
- name: Cache ccache Directory
uses: actions/cache@v4

15
.gitmodules vendored
View file

@ -16,21 +16,9 @@
[submodule "thirdparty/vcpkg"]
path = thirdparty/vcpkg
url = https://github.com/microsoft/vcpkg
[submodule "thirdparty/volk"]
path = thirdparty/volk
url = https://github.com/zeux/volk
[submodule "thirdparty/SDL"]
path = thirdparty/SDL
url = https://github.com/libsdl-org/SDL.git
[submodule "thirdparty/Vulkan-Headers"]
path = thirdparty/Vulkan-Headers
url = https://github.com/KhronosGroup/Vulkan-Headers.git
[submodule "thirdparty/VulkanMemoryAllocator"]
path = thirdparty/VulkanMemoryAllocator
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
[submodule "thirdparty/D3D12MemoryAllocator"]
path = thirdparty/D3D12MemoryAllocator
url = https://github.com/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator.git
[submodule "thirdparty/stb"]
path = thirdparty/stb
url = https://github.com/nothings/stb.git
@ -67,3 +55,6 @@
[submodule "thirdparty/MoltenVK/SPIRV-Cross"]
path = thirdparty/MoltenVK/SPIRV-Cross
url = https://github.com/KhronosGroup/SPIRV-Cross.git
[submodule "thirdparty/plume"]
path = thirdparty/plume
url = https://github.com/renderbag/plume.git

View file

@ -19,6 +19,14 @@ set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
project("UnleashedRecomp-ALL")
if (APPLE)
enable_language(OBJC OBJCXX)
endif()
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
set(SDL_VULKAN_ENABLED ON CACHE BOOL "")
endif()
if (CMAKE_OSX_ARCHITECTURES)
set(UNLEASHED_RECOMP_ARCHITECTURE ${CMAKE_OSX_ARCHITECTURES})
elseif(CMAKE_SYSTEM_PROCESSOR)

View file

@ -116,15 +116,8 @@ set(UNLEASHED_RECOMP_GPU_CXX_SOURCES
"gpu/imgui/imgui_common.cpp"
"gpu/imgui/imgui_font_builder.cpp"
"gpu/imgui/imgui_snapshot.cpp"
"gpu/rhi/plume_vulkan.cpp"
)
if (UNLEASHED_RECOMP_D3D12)
list(APPEND UNLEASHED_RECOMP_GPU_CXX_SOURCES
"gpu/rhi/plume_d3d12.cpp"
)
endif()
set(UNLEASHED_RECOMP_APU_CXX_SOURCES
"apu/audio.cpp"
"apu/embedded_player.cpp"
@ -221,18 +214,10 @@ set(UNLEASHED_RECOMP_THIRDPARTY_INCLUDES
"${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/magic_enum/include"
"${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/stb"
"${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/unordered_dense/include"
"${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/volk"
"${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/Vulkan-Headers/include"
"${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/VulkanMemoryAllocator/include"
"${UNLEASHED_RECOMP_TOOLS_ROOT}/bc_diff"
"${UNLEASHED_RECOMP_TOOLS_ROOT}/XenosRecomp/thirdparty/smol-v/source"
)
if (UNLEASHED_RECOMP_D3D12)
list(APPEND UNLEASHED_RECOMP_THIRDPARTY_INCLUDES "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/D3D12MemoryAllocator/include")
list(APPEND UNLEASHED_RECOMP_THIRDPARTY_SOURCES "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/D3D12MemoryAllocator/src/D3D12MemAlloc.cpp")
endif()
set_source_files_properties(${UNLEASHED_RECOMP_THIRDPARTY_SOURCES} PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
set(UNLEASHED_RECOMP_CXX_SOURCES
@ -377,7 +362,7 @@ if (UNLEASHED_RECOMP_D3D12)
)
endif()
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
if (SDL_VULKAN_ENABLED)
target_compile_definitions(UnleashedRecomp PRIVATE SDL_VULKAN_ENABLED)
endif()
@ -428,6 +413,7 @@ target_link_libraries(UnleashedRecomp PRIVATE
UnleashedRecompLib
xxHash::xxhash
CURL::libcurl
plume
)
target_include_directories(UnleashedRecomp PRIVATE

View file

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2024 renderbag and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load diff

View file

@ -1,481 +0,0 @@
//
// plume
//
// Copyright (c) 2024 renderbag and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file for details.
//
#pragma once
#include "plume_render_interface.h"
#include <map>
#include <mutex>
#include <unordered_map>
#include <directx/d3d12.h>
#include <dxgi1_4.h>
#include "D3D12MemAlloc.h"
namespace plume {
struct D3D12Buffer;
struct D3D12CommandQueue;
struct D3D12Device;
struct D3D12GraphicsPipeline;
struct D3D12Interface;
struct D3D12Pipeline;
struct D3D12Pool;
struct D3D12PipelineLayout;
struct D3D12Texture;
struct D3D12DescriptorHeapAllocator {
enum : uint32_t {
INVALID_OFFSET = 0xFFFFFFFFU
};
// Reference implementation http://diligentgraphics.com/diligent-engine/architecture/d3d12/variable-size-memory-allocations-manager/
struct FreeBlock;
typedef std::map<uint32_t, FreeBlock> OffsetFreeBlockMap;
typedef std::multimap<uint32_t, OffsetFreeBlockMap::iterator> SizeFreeBlockMap;
struct FreeBlock {
uint32_t size;
SizeFreeBlockMap::iterator sizeMapIterator;
FreeBlock(uint32_t size) {
this->size = size;
}
};
ID3D12DescriptorHeap *heap = nullptr;
uint32_t heapSize = 0;
uint32_t freeSize = 0;
D3D12Device *device = nullptr;
D3D12_CPU_DESCRIPTOR_HANDLE cpuDescriptorHandle = {};
D3D12_GPU_DESCRIPTOR_HANDLE gpuDescriptorHandle = {};
UINT descriptorHandleIncrement = 0;
OffsetFreeBlockMap offsetFreeBlockMap;
SizeFreeBlockMap sizeFreeBlockMap;
std::mutex allocationMutex;
D3D12DescriptorHeapAllocator(D3D12Device *device, uint32_t heapSize, D3D12_DESCRIPTOR_HEAP_TYPE heapType);
~D3D12DescriptorHeapAllocator();
void addFreeBlock(uint32_t offset, uint32_t size);
uint32_t allocate(uint32_t size);
void free(uint32_t offset, uint32_t size);
D3D12_CPU_DESCRIPTOR_HANDLE getCPUHandleAt(uint32_t index) const;
D3D12_GPU_DESCRIPTOR_HANDLE getGPUHandleAt(uint32_t index) const;
};
struct D3D12DescriptorSet : RenderDescriptorSet {
D3D12Device *device = nullptr;
struct HeapAllocation {
uint32_t offset = 0;
uint32_t count = 0;
};
HeapAllocation viewAllocation;
HeapAllocation samplerAllocation;
std::vector<RenderDescriptorRangeType> descriptorTypes;
std::vector<uint32_t> descriptorHeapIndices;
uint32_t descriptorTypeMaxIndex = 0;
D3D12DescriptorSet(D3D12Device *device, const RenderDescriptorSetDesc &desc);
~D3D12DescriptorSet() override;
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize, const RenderBufferStructuredView *bufferStructuredView, const RenderBufferFormattedView *bufferFormattedView) override;
void setTexture(uint32_t descriptorIndex, const RenderTexture *texture, RenderTextureLayout textureLayout, const RenderTextureView *textureView) override;
void setSampler(uint32_t descriptorIndex, const RenderSampler *sampler) override;
void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) override;
void setSRV(uint32_t descriptorIndex, ID3D12Resource *resource, const D3D12_SHADER_RESOURCE_VIEW_DESC *viewDesc);
void setUAV(uint32_t descriptorIndex, ID3D12Resource *resource, const D3D12_UNORDERED_ACCESS_VIEW_DESC *viewDesc);
void setCBV(uint32_t descriptorIndex, ID3D12Resource *resource, uint64_t bufferSize);
};
struct D3D12SwapChain : RenderSwapChain {
IDXGISwapChain3 *d3d = nullptr;
HANDLE waitableObject = 0;
D3D12CommandQueue *commandQueue = nullptr;
RenderWindow renderWindow = {};
std::vector<D3D12Texture> textures;
uint32_t textureCount = 0;
RenderFormat format = RenderFormat::UNKNOWN;
DXGI_FORMAT nativeFormat = DXGI_FORMAT_UNKNOWN;
uint32_t width = 0;
uint32_t height = 0;
uint32_t refreshRate = 0;
bool vsyncEnabled = true;
uint32_t maxFrameLatency = 0;
D3D12SwapChain(D3D12CommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency);
~D3D12SwapChain() override;
bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) override;
void wait() override;
bool resize() override;
bool needsResize() const override;
void setVsyncEnabled(bool vsyncEnabled) override;
bool isVsyncEnabled() const override;
uint32_t getWidth() const override;
uint32_t getHeight() const override;
RenderTexture *getTexture(uint32_t textureIndex) override;
uint32_t getTextureCount() const override;
bool acquireTexture(RenderCommandSemaphore *signalSemaphore, uint32_t *textureIndex) override;
RenderWindow getWindow() const override;
bool isEmpty() const override;
uint32_t getRefreshRate() const override;
void getWindowSize(uint32_t &dstWidth, uint32_t &dstHeight) const;
void setTextures();
};
struct D3D12Framebuffer : RenderFramebuffer {
D3D12Device *device = nullptr;
uint32_t width = 0;
uint32_t height = 0;
std::vector<const D3D12Texture *> colorTargets;
const D3D12Texture *depthTarget = nullptr;
std::vector<D3D12_CPU_DESCRIPTOR_HANDLE> colorHandles;
D3D12_CPU_DESCRIPTOR_HANDLE depthHandle = {};
D3D12Framebuffer(D3D12Device *device, const RenderFramebufferDesc &desc);
~D3D12Framebuffer() override;
uint32_t getWidth() const override;
uint32_t getHeight() const override;
};
struct D3D12QueryPool : RenderQueryPool {
D3D12Device *device = nullptr;
ID3D12QueryHeap *d3d = nullptr;
std::vector<uint64_t> results;
std::unique_ptr<RenderBuffer> readbackBuffer;
D3D12QueryPool(D3D12Device *device, uint32_t queryCount);
virtual ~D3D12QueryPool() override;
virtual void queryResults() override;
virtual const uint64_t *getResults() const override;
virtual uint32_t getCount() const override;
};
struct D3D12CommandList : RenderCommandList {
ID3D12GraphicsCommandList9 *d3d = nullptr;
ID3D12CommandAllocator *commandAllocator = nullptr;
D3D12Device *device = nullptr;
RenderCommandListType type = RenderCommandListType::UNKNOWN;
const D3D12Framebuffer *targetFramebuffer = nullptr;
bool targetFramebufferSamplePositionsSet = false;
bool open = false;
const D3D12PipelineLayout *activeComputePipelineLayout = nullptr;
const D3D12PipelineLayout *activeGraphicsPipelineLayout = nullptr;
const D3D12GraphicsPipeline *activeGraphicsPipeline = nullptr;
bool descriptorHeapsSet = false;
D3D12_PRIMITIVE_TOPOLOGY activeTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
bool activeSamplePositions = false;
D3D12CommandList(D3D12Device *device, RenderCommandListType type);
~D3D12CommandList() override;
void begin() override;
void end() override;
void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) override;
void dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) override;
void traceRays(uint32_t width, uint32_t height, uint32_t depth, RenderBufferReference shaderBindingTable, const RenderShaderBindingGroupsInfo &shaderBindingGroupsInfo) override;
void drawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation) override;
void drawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) override;
void setPipeline(const RenderPipeline *pipeline) override;
void setComputePipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
void setComputePushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
void setComputeDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
void setGraphicsPipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
void setGraphicsPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
void setGraphicsDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
void setGraphicsRootDescriptor(RenderBufferReference bufferReference, uint32_t rootDescriptorIndex) override;
void setRaytracingPipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
void setRaytracingPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
void setRaytracingDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
void setIndexBuffer(const RenderIndexBufferView *view) override;
void setVertexBuffers(uint32_t startSlot, const RenderVertexBufferView *views, uint32_t viewCount, const RenderInputSlot *inputSlots) override;
void setViewports(const RenderViewport *viewports, uint32_t count) override;
void setScissors(const RenderRect *scissorRects, uint32_t count) override;
void setFramebuffer(const RenderFramebuffer *framebuffer) override;
void setDepthBias(float depthBias, float depthBiasClamp, float slopeScaledDepthBias) override;
void clearColor(uint32_t attachmentIndex, RenderColor colorValue, const RenderRect *clearRects, uint32_t clearRectsCount) override;
void clearDepth(bool clearDepth, float depthValue, const RenderRect *clearRects, uint32_t clearRectsCount) override;
void copyBufferRegion(RenderBufferReference dstBuffer, RenderBufferReference srcBuffer, uint64_t size) override;
void copyTextureRegion(const RenderTextureCopyLocation &dstLocation, const RenderTextureCopyLocation &srcLocation, uint32_t dstX, uint32_t dstY, uint32_t dstZ, const RenderBox *srcBox) override;
void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) override;
void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect, RenderResolveMode resolveMode) override;
void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) override;
void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) override;
void discardTexture(const RenderTexture* texture) override;
void resetQueryPool(const RenderQueryPool *queryPool, uint32_t queryFirstIndex, uint32_t queryCount) override;
void writeTimestamp(const RenderQueryPool *queryPool, uint32_t queryIndex) override;
void checkDescriptorHeaps();
void notifyDescriptorHeapWasChangedExternally();
void checkTopology();
void checkFramebufferSamplePositions();
void setSamplePositions(const RenderTexture *texture);
void resetSamplePositions();
void setDescriptorSet(const D3D12PipelineLayout *activePipelineLayout, RenderDescriptorSet *descriptorSet, uint32_t setIndex, bool setCompute);
void setRootDescriptorTable(D3D12DescriptorHeapAllocator *heapAllocator, D3D12DescriptorSet::HeapAllocation &heapAllocation, uint32_t rootIndex, bool setCompute);
void setRootDescriptor(const D3D12PipelineLayout *activePipelineLayout, RenderBufferReference bufferReference, uint32_t setIndex, bool setCompute);
};
struct D3D12CommandFence : RenderCommandFence {
ID3D12Fence *d3d = nullptr;
D3D12Device *device = nullptr;
HANDLE fenceEvent = 0;
UINT64 fenceValue = 0;
D3D12CommandFence(D3D12Device *device);
~D3D12CommandFence() override;
};
struct D3D12CommandSemaphore : RenderCommandSemaphore {
ID3D12Fence *d3d = nullptr;
D3D12Device *device = nullptr;
UINT64 semaphoreValue = 0;
D3D12CommandSemaphore(D3D12Device *device);
~D3D12CommandSemaphore() override;
};
struct D3D12CommandQueue : RenderCommandQueue {
ID3D12CommandQueue *d3d = nullptr;
D3D12Device *device = nullptr;
RenderCommandListType type = RenderCommandListType::UNKNOWN;
D3D12CommandQueue(D3D12Device *device, RenderCommandListType type);
~D3D12CommandQueue() override;
std::unique_ptr<RenderSwapChain> createSwapChain(RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t newFrameLatency) override;
void executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount, RenderCommandSemaphore **signalSemaphores, uint32_t signalSemaphoreCount, RenderCommandFence *signalFence) override;
void waitForCommandFence(RenderCommandFence *fence) override;
};
struct D3D12Buffer : RenderBuffer {
ID3D12Resource *d3d = nullptr;
D3D12_RESOURCE_STATES resourceStates = D3D12_RESOURCE_STATE_COMMON;
D3D12Device *device = nullptr;
D3D12MA::Allocation *allocation = nullptr;
D3D12Pool *pool = nullptr;
RenderBufferDesc desc;
D3D12Buffer() = default;
D3D12Buffer(D3D12Device *device, D3D12Pool *pool, const RenderBufferDesc &desc);
~D3D12Buffer() override;
void *map(uint32_t subresource, const RenderRange *readRange) override;
void unmap(uint32_t subresource, const RenderRange *writtenRange) override;
std::unique_ptr<RenderBufferFormattedView> createBufferFormattedView(RenderFormat format) override;
void setName(const std::string &name) override;
uint64_t getDeviceAddress() const override;
};
struct D3D12BufferFormattedView : RenderBufferFormattedView {
RenderFormat format = RenderFormat::UNKNOWN;
D3D12Buffer *buffer = nullptr;
D3D12BufferFormattedView(D3D12Buffer *buffer, RenderFormat format);
~D3D12BufferFormattedView() override;
};
struct D3D12Texture : RenderTexture {
ID3D12Resource *d3d = nullptr;
D3D12_RESOURCE_STATES resourceStates = D3D12_RESOURCE_STATE_COMMON;
RenderTextureLayout layout = RenderTextureLayout::UNKNOWN;
D3D12Device *device = nullptr;
D3D12MA::Allocation *allocation = nullptr;
D3D12Pool *pool = nullptr;
RenderTextureDesc desc;
uint32_t targetAllocatorOffset = 0;
uint32_t targetEntryCount = 0;
bool targetHeapDepth = false;
D3D12Texture() = default;
D3D12Texture(D3D12Device *device, D3D12Pool *pool, const RenderTextureDesc &desc);
~D3D12Texture() override;
std::unique_ptr<RenderTextureView> createTextureView(const RenderTextureViewDesc &desc) override;
void setName(const std::string &name) override;
void createRenderTargetHeap();
void createDepthStencilHeap();
void releaseTargetHeap();
};
struct D3D12TextureView : RenderTextureView {
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
D3D12Texture *texture = nullptr;
RenderTextureViewDimension dimension = RenderTextureViewDimension::UNKNOWN;
uint32_t mipLevels = 0;
uint32_t mipSlice = 0;
uint32_t shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
D3D12TextureView(D3D12Texture *texture, const RenderTextureViewDesc &desc);
~D3D12TextureView() override;
};
struct D3D12AccelerationStructure :RenderAccelerationStructure {
D3D12Device *device = nullptr;
const D3D12Buffer *buffer = nullptr;
uint64_t offset = 0;
uint64_t size = 0;
RenderAccelerationStructureType type = RenderAccelerationStructureType::UNKNOWN;
D3D12AccelerationStructure(D3D12Device *device, const RenderAccelerationStructureDesc &desc);
~D3D12AccelerationStructure() override;
};
struct D3D12Pool : RenderPool {
D3D12MA::Pool *d3d = nullptr;
D3D12Device *device = nullptr;
RenderPoolDesc desc;
D3D12Pool(D3D12Device *device, const RenderPoolDesc &desc, bool gpuUploadHeapFallback);
~D3D12Pool() override;
std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) override;
std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) override;
};
struct D3D12Shader : RenderShader {
const void* data = nullptr;
uint64_t size = 0;
std::string entryPointName;
D3D12Device *device = nullptr;
RenderShaderFormat format = RenderShaderFormat::UNKNOWN;
D3D12Shader(D3D12Device *device, const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format);
~D3D12Shader() override;
};
struct D3D12Sampler : RenderSampler {
D3D12_SAMPLER_DESC samplerDesc = {};
D3D12Device *device = nullptr;
RenderBorderColor borderColor = RenderBorderColor::UNKNOWN;
RenderShaderVisibility shaderVisibility = RenderShaderVisibility::UNKNOWN;
D3D12Sampler(D3D12Device *device, const RenderSamplerDesc &desc);
~D3D12Sampler() override;
};
struct D3D12Pipeline : RenderPipeline {
enum class Type {
Unknown,
Compute,
Graphics,
Raytracing
};
D3D12Device *device = nullptr;
Type type = Type::Unknown;
D3D12Pipeline(D3D12Device *device, Type type);
virtual ~D3D12Pipeline() override;
};
struct D3D12ComputePipeline : D3D12Pipeline {
ID3D12PipelineState *d3d = nullptr;
D3D12ComputePipeline(D3D12Device *device, const RenderComputePipelineDesc &desc);
~D3D12ComputePipeline() override;
virtual void setName(const std::string& name) const override;
virtual RenderPipelineProgram getProgram(const std::string &name) const override;
};
struct D3D12GraphicsPipeline : D3D12Pipeline {
ID3D12PipelineState *d3d = nullptr;
std::vector<RenderInputSlot> inputSlots;
D3D12_PRIMITIVE_TOPOLOGY topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
D3D12GraphicsPipeline(D3D12Device *device, const RenderGraphicsPipelineDesc &desc);
~D3D12GraphicsPipeline() override;
virtual void setName(const std::string& name) const override;
virtual RenderPipelineProgram getProgram(const std::string &name) const override;
};
struct D3D12RaytracingPipeline : D3D12Pipeline {
ID3D12StateObject *stateObject = nullptr;
ID3D12StateObjectProperties *stateObjectProperties = nullptr;
std::vector<void *> programShaderIdentifiers;
std::unordered_map<std::string, RenderPipelineProgram> nameProgramMap;
const D3D12PipelineLayout *pipelineLayout = nullptr;
D3D12RaytracingPipeline(D3D12Device *device, const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline);
~D3D12RaytracingPipeline() override;
virtual void setName(const std::string& name) const override;
virtual RenderPipelineProgram getProgram(const std::string &name) const override;
};
struct D3D12PipelineLayout : RenderPipelineLayout {
ID3D12RootSignature *rootSignature = nullptr;
D3D12Device *device = nullptr;
std::vector<RenderPushConstantRange> pushConstantRanges;
std::vector<uint32_t> setViewRootIndices;
std::vector<uint32_t> setSamplerRootIndices;
std::vector<std::pair<uint32_t, RenderRootDescriptorType>> rootDescriptorRootIndicesAndTypes;
uint32_t setCount = 0;
uint32_t rootCount = 0;
D3D12PipelineLayout(D3D12Device *device, const RenderPipelineLayoutDesc &desc);
~D3D12PipelineLayout() override;
};
struct D3D12Device : RenderDevice {
ID3D12Device8 *d3d = nullptr;
D3D12Interface *renderInterface = nullptr;
IDXGIAdapter1 *adapter = nullptr;
D3D12MA::Allocator *allocator = nullptr;
D3D_SHADER_MODEL shaderModel = D3D_SHADER_MODEL(0);
std::unique_ptr<RenderPipelineLayout> rtDummyGlobalPipelineLayout;
std::unique_ptr<RenderPipelineLayout> rtDummyLocalPipelineLayout;
std::unique_ptr<D3D12DescriptorHeapAllocator> viewHeapAllocator;
std::unique_ptr<D3D12DescriptorHeapAllocator> samplerHeapAllocator;
std::unique_ptr<D3D12DescriptorHeapAllocator> colorTargetHeapAllocator;
std::unique_ptr<D3D12DescriptorHeapAllocator> depthTargetHeapAllocator;
std::unique_ptr<D3D12Pool> customUploadPool;
RenderDeviceCapabilities capabilities;
RenderDeviceDescription description;
uint64_t timestampFrequency = 1;
bool gpuUploadHeapFallback = false;
D3D12Device(D3D12Interface *renderInterface, const std::string &preferredDeviceName);
~D3D12Device() override;
std::unique_ptr<RenderCommandList> createCommandList(RenderCommandListType type) override;
std::unique_ptr<RenderDescriptorSet> createDescriptorSet(const RenderDescriptorSetDesc &desc) override;
std::unique_ptr<RenderShader> createShader(const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format) override;
std::unique_ptr<RenderSampler> createSampler(const RenderSamplerDesc &desc) override;
std::unique_ptr<RenderPipeline> createComputePipeline(const RenderComputePipelineDesc &desc) override;
std::unique_ptr<RenderPipeline> createGraphicsPipeline(const RenderGraphicsPipelineDesc &desc) override;
std::unique_ptr<RenderPipeline> createRaytracingPipeline(const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline) override;
std::unique_ptr<RenderCommandQueue> createCommandQueue(RenderCommandListType type) override;
std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) override;
std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) override;
std::unique_ptr<RenderAccelerationStructure> createAccelerationStructure(const RenderAccelerationStructureDesc &desc) override;
std::unique_ptr<RenderPool> createPool(const RenderPoolDesc &desc) override;
std::unique_ptr<RenderPipelineLayout> createPipelineLayout(const RenderPipelineLayoutDesc &desc) override;
std::unique_ptr<RenderCommandFence> createCommandFence() override;
std::unique_ptr<RenderCommandSemaphore> createCommandSemaphore() override;
std::unique_ptr<RenderFramebuffer> createFramebuffer(const RenderFramebufferDesc &desc) override;
std::unique_ptr<RenderQueryPool> createQueryPool(uint32_t queryCount) override;
void setBottomLevelASBuildInfo(RenderBottomLevelASBuildInfo &buildInfo, const RenderBottomLevelASMesh *meshes, uint32_t meshCount, bool preferFastBuild, bool preferFastTrace) override;
void setTopLevelASBuildInfo(RenderTopLevelASBuildInfo &buildInfo, const RenderTopLevelASInstance *instances, uint32_t instanceCount, bool preferFastBuild, bool preferFastTrace) override;
void setShaderBindingTableInfo(RenderShaderBindingTableInfo &tableInfo, const RenderShaderBindingGroups &groups, const RenderPipeline *pipeline, RenderDescriptorSet **descriptorSets, uint32_t descriptorSetCount) override;
const RenderDeviceCapabilities &getCapabilities() const override;
const RenderDeviceDescription &getDescription() const override;
RenderSampleCounts getSampleCountsSupported(RenderFormat format) const override;
void waitIdle() const override;
void release();
bool isValid() const;
};
struct D3D12Interface : RenderInterface {
IDXGIFactory4 *dxgiFactory = nullptr;
RenderInterfaceCapabilities capabilities;
std::vector<std::string> deviceNames;
D3D12Interface();
~D3D12Interface() override;
std::unique_ptr<RenderDevice> createDevice(const std::string &preferredDeviceName) override;
const RenderInterfaceCapabilities &getCapabilities() const override;
const std::vector<std::string> &getDeviceNames() const override;
bool isValid() const;
};
};

View file

@ -1,262 +0,0 @@
//
// plume
//
// Copyright (c) 2024 renderbag and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file for details.
//
#pragma once
#include <climits>
#include "plume_render_interface_types.h"
namespace plume {
// Interfaces.
struct RenderBufferFormattedView {
virtual ~RenderBufferFormattedView() { }
};
struct RenderBuffer {
virtual ~RenderBuffer() { }
virtual void *map(uint32_t subresource = 0, const RenderRange *readRange = nullptr) = 0;
virtual void unmap(uint32_t subresource = 0, const RenderRange *writtenRange = nullptr) = 0;
virtual std::unique_ptr<RenderBufferFormattedView> createBufferFormattedView(RenderFormat format) = 0;
virtual void setName(const std::string &name) = 0;
virtual uint64_t getDeviceAddress() const = 0;
// Concrete implementation shortcuts.
inline RenderBufferReference at(uint64_t offset) const {
return RenderBufferReference(this, offset);
}
};
struct RenderTextureView {
virtual ~RenderTextureView() { }
};
struct RenderTexture {
virtual ~RenderTexture() { }
virtual std::unique_ptr<RenderTextureView> createTextureView(const RenderTextureViewDesc &desc) = 0;
virtual void setName(const std::string &name) = 0;
};
struct RenderAccelerationStructure {
virtual ~RenderAccelerationStructure() { }
};
struct RenderShader {
virtual ~RenderShader() { }
};
struct RenderSampler {
virtual ~RenderSampler() { }
};
struct RenderPipeline {
virtual ~RenderPipeline() { }
virtual void setName(const std::string& name) const = 0;
virtual RenderPipelineProgram getProgram(const std::string &name) const = 0;
};
struct RenderPipelineLayout {
virtual ~RenderPipelineLayout() { }
};
struct RenderCommandFence {
virtual ~RenderCommandFence() { }
};
struct RenderCommandSemaphore {
virtual ~RenderCommandSemaphore() { }
};
struct RenderDescriptorSet {
// Descriptor indices correspond to the index assuming the descriptor set is one contiguous array. They DO NOT correspond to the bindings, which can be sparse.
// User code should derive these indices on its own by looking at the order the bindings were assigned during set creation along with the descriptor count and
// assume it was all allocated in one contiguous array. This allows efficient mapping between Vulkan and D3D12's descriptor models.
virtual ~RenderDescriptorSet() { }
virtual void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize = 0, const RenderBufferStructuredView *bufferStructuredView = nullptr, const RenderBufferFormattedView *bufferFormattedView = nullptr) = 0;
virtual void setTexture(uint32_t descriptorIndex, const RenderTexture *texture, RenderTextureLayout textureLayout, const RenderTextureView *textureView = nullptr) = 0;
virtual void setSampler(uint32_t descriptorIndex, const RenderSampler *sampler) = 0;
virtual void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) = 0;
};
struct RenderSwapChain {
virtual ~RenderSwapChain() { }
virtual bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) = 0;
virtual void wait() = 0;
virtual bool resize() = 0;
virtual bool needsResize() const = 0;
virtual void setVsyncEnabled(bool vsyncEnabled) = 0;
virtual bool isVsyncEnabled() const = 0;
virtual uint32_t getWidth() const = 0;
virtual uint32_t getHeight() const = 0;
virtual RenderTexture *getTexture(uint32_t textureIndex) = 0;
virtual uint32_t getTextureCount() const = 0;
virtual bool acquireTexture(RenderCommandSemaphore *signalSemaphore, uint32_t *textureIndex) = 0;
virtual RenderWindow getWindow() const = 0;
virtual bool isEmpty() const = 0;
// Only valid if displayTiming is enabled in capabilities.
virtual uint32_t getRefreshRate() const = 0;
};
struct RenderFramebuffer {
virtual ~RenderFramebuffer() { }
virtual uint32_t getWidth() const = 0;
virtual uint32_t getHeight() const = 0;
};
struct RenderCommandList {
virtual ~RenderCommandList() { }
virtual void begin() = 0;
virtual void end() = 0;
virtual void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) = 0;
virtual void dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) = 0;
virtual void traceRays(uint32_t width, uint32_t height, uint32_t depth, RenderBufferReference shaderBindingTable, const RenderShaderBindingGroupsInfo &shaderBindingGroupsInfo) = 0;
virtual void drawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation) = 0;
virtual void drawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) = 0;
virtual void setPipeline(const RenderPipeline *pipeline) = 0;
virtual void setComputePipelineLayout(const RenderPipelineLayout *pipelineLayout) = 0;
virtual void setComputePushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) = 0;
virtual void setComputeDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) = 0;
virtual void setGraphicsPipelineLayout(const RenderPipelineLayout *pipelineLayout) = 0;
virtual void setGraphicsPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) = 0;
virtual void setGraphicsDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) = 0;
virtual void setGraphicsRootDescriptor(RenderBufferReference bufferReference, uint32_t rootDescriptorIndex) = 0;
virtual void setRaytracingPipelineLayout(const RenderPipelineLayout *pipelineLayout) = 0;
virtual void setRaytracingPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) = 0;
virtual void setRaytracingDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) = 0;
virtual void setIndexBuffer(const RenderIndexBufferView *view) = 0;
virtual void setVertexBuffers(uint32_t startSlot, const RenderVertexBufferView *views, uint32_t viewCount, const RenderInputSlot *inputSlots) = 0;
virtual void setViewports(const RenderViewport *viewports, uint32_t count) = 0;
virtual void setScissors(const RenderRect *scissorRects, uint32_t count) = 0;
virtual void setFramebuffer(const RenderFramebuffer *framebuffer) = 0;
virtual void setDepthBias(float depthBias, float depthBiasClamp, float slopeScaledDepthBias) = 0;
virtual void clearColor(uint32_t attachmentIndex = 0, RenderColor colorValue = RenderColor(), const RenderRect *clearRects = nullptr, uint32_t clearRectsCount = 0) = 0;
virtual void clearDepth(bool clearDepth = true, float depthValue = 1.0f, const RenderRect *clearRects = nullptr, uint32_t clearRectsCount = 0) = 0;
virtual void copyBufferRegion(RenderBufferReference dstBuffer, RenderBufferReference srcBuffer, uint64_t size) = 0;
virtual void copyTextureRegion(const RenderTextureCopyLocation &dstLocation, const RenderTextureCopyLocation &srcLocation, uint32_t dstX = 0, uint32_t dstY = 0, uint32_t dstZ = 0, const RenderBox *srcBox = nullptr) = 0;
virtual void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) = 0;
virtual void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) = 0;
virtual void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) = 0;
virtual void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect = nullptr, RenderResolveMode resolveMode = RenderResolveMode::AVERAGE) = 0;
virtual void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) = 0;
virtual void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) = 0;
virtual void discardTexture(const RenderTexture* texture) = 0; // D3D12 only.
virtual void resetQueryPool(const RenderQueryPool *queryPool, uint32_t queryFirstIndex, uint32_t queryCount) = 0;
virtual void writeTimestamp(const RenderQueryPool *queryPool, uint32_t queryIndex) = 0;
// Concrete implementation shortcuts.
inline void barriers(RenderBarrierStages stages, const RenderBufferBarrier &barrier) {
barriers(stages, &barrier, 1, nullptr, 0);
}
inline void barriers(RenderBarrierStages stages, const RenderTextureBarrier &barrier) {
barriers(stages, nullptr, 0, &barrier, 1);
}
inline void barriers(RenderBarrierStages stages, const RenderBufferBarrier &bufferBarrier, const RenderTextureBarrier &textureBarrier) {
barriers(stages, &bufferBarrier, 1, &textureBarrier, 1);
}
inline void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount) {
barriers(stages, bufferBarriers, bufferBarriersCount, nullptr, 0);
}
inline void barriers(RenderBarrierStages stages, const std::vector<RenderBufferBarrier> &bufferBarriers) {
barriers(stages, bufferBarriers.data(), uint32_t(bufferBarriers.size()), nullptr, 0);
}
inline void barriers(RenderBarrierStages stages, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) {
barriers(stages, nullptr, 0, textureBarriers, textureBarriersCount);
}
inline void barriers(RenderBarrierStages stages, const std::vector<RenderTextureBarrier> &textureBarriers) {
barriers(stages, nullptr, 0, textureBarriers.data(), uint32_t(textureBarriers.size()));
}
inline void barriers(RenderBarrierStages stages, const std::vector<RenderBufferBarrier> &bufferBarriers, const std::vector<RenderTextureBarrier> &textureBarriers) {
barriers(stages, bufferBarriers.data(), uint32_t(bufferBarriers.size()), textureBarriers.data(), uint32_t(textureBarriers.size()));
}
inline void setViewports(const RenderViewport &viewport) {
setViewports(&viewport, 1);
}
inline void setScissors(const RenderRect &scissorRect) {
setScissors(&scissorRect, 1);
}
};
struct RenderCommandQueue {
virtual ~RenderCommandQueue() { }
virtual std::unique_ptr<RenderSwapChain> createSwapChain(RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency) = 0;
virtual void executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores = nullptr, uint32_t waitSemaphoreCount = 0, RenderCommandSemaphore **signalSemaphores = nullptr, uint32_t signalSemaphoreCount = 0, RenderCommandFence *signalFence = nullptr) = 0;
virtual void waitForCommandFence(RenderCommandFence *fence) = 0;
// Concrete implementation shortcuts.
inline void executeCommandLists(const RenderCommandList *commandList, RenderCommandFence *signalFence = nullptr) {
executeCommandLists(commandList != nullptr ? &commandList : nullptr, commandList != nullptr ? 1 : 0, nullptr, 0, nullptr, 0, signalFence);
}
};
struct RenderPool {
virtual ~RenderPool() { }
virtual std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) = 0;
virtual std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) = 0;
};
struct RenderQueryPool {
virtual ~RenderQueryPool() { }
virtual void queryResults() = 0;
virtual const uint64_t *getResults() const = 0;
virtual uint32_t getCount() const = 0;
};
struct RenderDevice {
virtual ~RenderDevice() { }
virtual std::unique_ptr<RenderCommandList> createCommandList(RenderCommandListType type) = 0;
virtual std::unique_ptr<RenderDescriptorSet> createDescriptorSet(const RenderDescriptorSetDesc &desc) = 0;
virtual std::unique_ptr<RenderShader> createShader(const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format) = 0;
virtual std::unique_ptr<RenderSampler> createSampler(const RenderSamplerDesc &desc) = 0;
virtual std::unique_ptr<RenderPipeline> createComputePipeline(const RenderComputePipelineDesc &desc) = 0;
virtual std::unique_ptr<RenderPipeline> createGraphicsPipeline(const RenderGraphicsPipelineDesc &desc) = 0;
virtual std::unique_ptr<RenderPipeline> createRaytracingPipeline(const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline = nullptr) = 0;
virtual std::unique_ptr<RenderCommandQueue> createCommandQueue(RenderCommandListType type) = 0;
virtual std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) = 0;
virtual std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) = 0;
virtual std::unique_ptr<RenderAccelerationStructure> createAccelerationStructure(const RenderAccelerationStructureDesc &desc) = 0;
virtual std::unique_ptr<RenderPool> createPool(const RenderPoolDesc &desc) = 0;
virtual std::unique_ptr<RenderPipelineLayout> createPipelineLayout(const RenderPipelineLayoutDesc &desc) = 0;
virtual std::unique_ptr<RenderCommandFence> createCommandFence() = 0;
virtual std::unique_ptr<RenderCommandSemaphore> createCommandSemaphore() = 0;
virtual std::unique_ptr<RenderFramebuffer> createFramebuffer(const RenderFramebufferDesc &desc) = 0;
virtual std::unique_ptr<RenderQueryPool> createQueryPool(uint32_t queryCount) = 0;
virtual void setBottomLevelASBuildInfo(RenderBottomLevelASBuildInfo &buildInfo, const RenderBottomLevelASMesh *meshes, uint32_t meshCount, bool preferFastBuild = true, bool preferFastTrace = false) = 0;
virtual void setTopLevelASBuildInfo(RenderTopLevelASBuildInfo &buildInfo, const RenderTopLevelASInstance *instances, uint32_t instanceCount, bool preferFastBuild = true, bool preferFastTrace = false) = 0;
virtual void setShaderBindingTableInfo(RenderShaderBindingTableInfo &tableInfo, const RenderShaderBindingGroups &groups, const RenderPipeline *pipeline, RenderDescriptorSet **descriptorSets, uint32_t descriptorSetCount) = 0;
virtual const RenderDeviceCapabilities &getCapabilities() const = 0;
virtual const RenderDeviceDescription &getDescription() const = 0;
virtual RenderSampleCounts getSampleCountsSupported(RenderFormat format) const = 0;
virtual void waitIdle() const = 0;
};
struct RenderInterface {
virtual ~RenderInterface() { }
virtual std::unique_ptr<RenderDevice> createDevice(const std::string &preferredDeviceName = "") = 0;
virtual const std::vector<std::string> &getDeviceNames() const = 0;
virtual const RenderInterfaceCapabilities &getCapabilities() const = 0;
};
extern void RenderInterfaceTest(RenderInterface *renderInterface);
extern void TestInitialize(RenderInterface* renderInterface, RenderWindow window);
extern void TestDraw();
extern void TestResize();
extern void TestShutdown();
};
#include "plume_render_interface_builders.h"

View file

@ -1,281 +0,0 @@
//
// plume
//
// Copyright (c) 2024 renderbag and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file for details.
//
#pragma once
#include <unordered_set>
namespace plume {
struct RenderDescriptorSetBuilder {
std::list<std::vector<const RenderSampler *>> samplerPointerVectorList;
std::vector<RenderDescriptorRange> descriptorRanges;
RenderDescriptorSetDesc descriptorSetDesc;
bool open = false;
uint32_t setIndex = 0;
RenderDescriptorSetBuilder() = default;
void begin() {
assert(!open && "Builder must be closed.");
descriptorSetDesc = RenderDescriptorSetDesc();
samplerPointerVectorList.clear();
descriptorRanges.clear();
open = true;
setIndex = 0;
}
uint32_t addConstantBuffer(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::CONSTANT_BUFFER, binding, count, nullptr));
}
uint32_t addFormattedBuffer(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::FORMATTED_BUFFER, binding, count, nullptr));
}
uint32_t addReadWriteFormattedBuffer(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::READ_WRITE_FORMATTED_BUFFER, binding, count, nullptr));
}
uint32_t addTexture(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::TEXTURE, binding, count, nullptr));
}
uint32_t addReadWriteTexture(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::READ_WRITE_TEXTURE, binding, count, nullptr));
}
uint32_t addSampler(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::SAMPLER, binding, count, nullptr));
}
uint32_t addImmutableSampler(uint32_t binding, const RenderSampler *immutableSampler) {
assert(immutableSampler != nullptr);
return addImmutableSampler(binding, &immutableSampler);
}
uint32_t addImmutableSampler(uint32_t binding, const RenderSampler **immutableSampler, uint32_t count = 1) {
assert(immutableSampler != nullptr);
samplerPointerVectorList.emplace_back(std::vector<const RenderSampler *>(immutableSampler, immutableSampler + count));
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::SAMPLER, binding, count, samplerPointerVectorList.back().data()));
}
uint32_t addStructuredBuffer(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::STRUCTURED_BUFFER, binding, count, nullptr));
}
uint32_t addReadWriteStructuredBuffer(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::READ_WRITE_STRUCTURED_BUFFER, binding, count, nullptr));
}
uint32_t addByteAddressBuffer(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::BYTE_ADDRESS_BUFFER, binding, count, nullptr));
}
uint32_t addReadWriteByteAddressBuffer(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::READ_WRITE_BYTE_ADDRESS_BUFFER, binding, count, nullptr));
}
uint32_t addAccelerationStructure(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::ACCELERATION_STRUCTURE, binding, count, nullptr));
}
uint32_t addRange(const RenderDescriptorRange &range) {
assert(open && "Builder must be open.");
uint32_t returnValue = setIndex;
descriptorRanges.emplace_back(range);
descriptorSetDesc.descriptorRangesCount++;
setIndex += range.count;
return returnValue;
}
void end(bool lastRangeIsBoundless = false, uint32_t boundlessRangeSize = 0) {
assert(open && "Builder must be open.");
descriptorSetDesc.lastRangeIsBoundless = lastRangeIsBoundless;
descriptorSetDesc.boundlessRangeSize = boundlessRangeSize;
descriptorSetDesc.descriptorRanges = descriptorRanges.data();
open = false;
}
std::unique_ptr<RenderDescriptorSet> create(RenderDevice *device) const {
assert(!open && "Builder must be closed.");
return device->createDescriptorSet(descriptorSetDesc);
}
};
struct RenderDescriptorSetBase {
RenderDescriptorSetBuilder builder;
std::unique_ptr<RenderDescriptorSet> descriptorSet;
void create(RenderDevice *device) {
descriptorSet = builder.create(device);
}
RenderDescriptorSet *get() const {
return descriptorSet.get();
}
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize = 0, const RenderBufferStructuredView *bufferStructuredView = nullptr, const RenderBufferFormattedView *bufferFormattedView = nullptr) {
descriptorSet->setBuffer(descriptorIndex, buffer, bufferSize, bufferStructuredView, bufferFormattedView);
}
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize, const RenderBufferStructuredView &bufferStructuredView) {
descriptorSet->setBuffer(descriptorIndex, buffer, bufferSize, &bufferStructuredView);
}
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize, const RenderBufferFormattedView *bufferFormattedView) {
descriptorSet->setBuffer(descriptorIndex, buffer, bufferSize, nullptr, bufferFormattedView);
}
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, const RenderBufferStructuredView &bufferStructuredView) {
descriptorSet->setBuffer(descriptorIndex, buffer, 0, &bufferStructuredView);
}
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, const RenderBufferFormattedView *bufferFormattedView) {
descriptorSet->setBuffer(descriptorIndex, buffer, 0, nullptr, bufferFormattedView);
}
void setTexture(uint32_t descriptorIndex, const RenderTexture *texture, const RenderTextureLayout textureLayout, const RenderTextureView *textureView = nullptr) {
descriptorSet->setTexture(descriptorIndex, texture, textureLayout, textureView);
}
void setSampler(uint32_t descriptorIndex, const RenderSampler *sampler) {
descriptorSet->setSampler(descriptorIndex, sampler);
}
void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) {
descriptorSet->setAccelerationStructure(descriptorIndex, accelerationStructure);
}
};
struct RenderDescriptorSetInclusionFilter {
const uint32_t *bindings = nullptr;
uint32_t bindingsCount = 0;
};
struct RenderPipelineLayoutBuilder {
std::vector<RenderPushConstantRange> pushConstantRanges;
std::list<std::vector<const RenderSampler *>> samplerPointerVectorList;
std::vector<RenderDescriptorRange> descriptorRanges;
std::vector<RenderDescriptorSetDesc> descriptorSetDescs;
std::vector<uint32_t> descriptorRangeIndexPerSet;
std::vector<RenderRootDescriptorDesc> rootDescriptorDescs;
RenderPipelineLayoutDesc layoutDesc;
bool open = false;
// Start filling the description.
void begin(bool isLocal = false, bool allowInputLayout = false) {
assert(!open && "Builder must be closed.");
layoutDesc = RenderPipelineLayoutDesc();
layoutDesc.isLocal = isLocal;
layoutDesc.allowInputLayout = allowInputLayout;
pushConstantRanges.clear();
samplerPointerVectorList.clear();
descriptorRanges.clear();
descriptorSetDescs.clear();
descriptorRangeIndexPerSet.clear();
rootDescriptorDescs.clear();
open = true;
}
// Returns push constant index.
uint32_t addPushConstant(uint32_t binding, uint32_t set, uint32_t size, RenderShaderStageFlags stageFlags, uint32_t offset = 0) {
assert(open && "Builder must be open.");
uint32_t returnValue = layoutDesc.pushConstantRangesCount;
pushConstantRanges.emplace_back(RenderPushConstantRange(binding, set, offset, size, stageFlags));
layoutDesc.pushConstantRangesCount++;
return returnValue;
}
// Returns set index.
uint32_t addDescriptorSet(const RenderDescriptorSetDesc &descriptorSetDesc) {
assert(open && "Builder must be open.");
uint32_t returnValue = layoutDesc.descriptorSetDescsCount;
descriptorRangeIndexPerSet.emplace_back(uint32_t(descriptorRanges.size()));
descriptorSetDescs.emplace_back(descriptorSetDesc);
for (uint32_t j = 0; j < descriptorSetDesc.descriptorRangesCount; j++) {
descriptorRanges.emplace_back(descriptorSetDesc.descriptorRanges[j]);
// Copy the immutable sampler pointers to a local vector list.
if (descriptorRanges.back().immutableSampler != nullptr) {
const RenderSampler **immutableSampler = descriptorRanges.back().immutableSampler;
samplerPointerVectorList.emplace_back(std::vector<const RenderSampler *>(immutableSampler, immutableSampler + descriptorRanges.back().count));
descriptorRanges.back().immutableSampler = samplerPointerVectorList.back().data();
}
}
layoutDesc.descriptorSetDescsCount++;
return returnValue;
}
// Returns set index.
uint32_t addDescriptorSet(const RenderDescriptorSetBuilder &descriptorSetBuilder) {
return addDescriptorSet(descriptorSetBuilder.descriptorSetDesc);
}
// Returns set index.
uint32_t addDescriptorSet(const RenderDescriptorSetBase &descriptorSetBase) {
return addDescriptorSet(descriptorSetBase.builder);
}
// Returns root descriptor index. D3D12 only.
uint32_t addRootDescriptor(uint32_t shaderRegister, uint32_t registerSpace, RenderRootDescriptorType type) {
assert(open && "Builder must be open.");
uint32_t returnValue = layoutDesc.rootDescriptorDescsCount;
rootDescriptorDescs.emplace_back(shaderRegister, registerSpace, type);
++layoutDesc.rootDescriptorDescsCount;
return returnValue;
}
// Finish the description.
void end() {
assert(open && "Builder must be open.");
if (layoutDesc.pushConstantRangesCount > 0) {
layoutDesc.pushConstantRanges = pushConstantRanges.data();
}
if (layoutDesc.descriptorSetDescsCount > 0) {
for (uint32_t i = 0; i < layoutDesc.descriptorSetDescsCount; i++) {
const uint32_t rangeIndex = descriptorRangeIndexPerSet[i];
descriptorSetDescs[i].descriptorRanges = &descriptorRanges[rangeIndex];
}
layoutDesc.descriptorSetDescs = descriptorSetDescs.data();
}
if (layoutDesc.rootDescriptorDescsCount > 0) {
layoutDesc.rootDescriptorDescs = rootDescriptorDescs.data();
}
open = false;
}
// Create a pipeline layout with the final description.
std::unique_ptr<RenderPipelineLayout> create(RenderDevice *device) const {
assert(!open && "Builder must be closed.");
return device->createPipelineLayout(layoutDesc);
}
};
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,463 +0,0 @@
//
// plume
//
// Copyright (c) 2024 renderbag and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file for details.
//
#pragma once
#include "plume_render_interface.h"
#include <mutex>
#include <set>
#include <unordered_map>
#include <unordered_set>
#if defined(_WIN64)
#define VK_USE_PLATFORM_WIN32_KHR
#elif defined(__ANDROID__)
#define VK_USE_PLATFORM_ANDROID_KHR
#elif defined(__linux__)
#define VK_USE_PLATFORM_XLIB_KHR
#elif defined(__APPLE__)
#define VK_USE_PLATFORM_METAL_EXT
#endif
// For VK_KHR_portability_subset
#define VK_ENABLE_BETA_EXTENSIONS
#include <volk.h>
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnullability-completeness"
#endif
#include <vk_mem_alloc.h>
#ifdef __clang__
#pragma clang diagnostic pop
#endif
namespace plume {
struct VulkanCommandQueue;
struct VulkanDevice;
struct VulkanInterface;
struct VulkanPool;
struct VulkanQueue;
struct VulkanBuffer : RenderBuffer {
VkBuffer vk = VK_NULL_HANDLE;
VulkanDevice *device = nullptr;
VulkanPool *pool = nullptr;
VmaAllocation allocation = VK_NULL_HANDLE;
VmaAllocationInfo allocationInfo = {};
RenderBufferDesc desc;
RenderBarrierStages barrierStages = RenderBarrierStage::NONE;
VulkanBuffer() = default;
VulkanBuffer(VulkanDevice *device, VulkanPool *pool, const RenderBufferDesc &desc);
~VulkanBuffer() override;
void *map(uint32_t subresource, const RenderRange *readRange) override;
void unmap(uint32_t subresource, const RenderRange *writtenRange) override;
std::unique_ptr<RenderBufferFormattedView> createBufferFormattedView(RenderFormat format) override;
void setName(const std::string &name) override;
uint64_t getDeviceAddress() const override;
};
struct VulkanBufferFormattedView : RenderBufferFormattedView {
VkBufferView vk = VK_NULL_HANDLE;
VulkanBuffer *buffer = nullptr;
VulkanBufferFormattedView(VulkanBuffer *buffer, RenderFormat format);
~VulkanBufferFormattedView() override;
};
struct VulkanTexture : RenderTexture {
VkImage vk = VK_NULL_HANDLE;
VkImageView imageView = VK_NULL_HANDLE;
VkFormat imageFormat = VK_FORMAT_UNDEFINED;
VkImageSubresourceRange imageSubresourceRange = {};
VulkanDevice *device = nullptr;
VulkanPool *pool = nullptr;
VmaAllocation allocation = VK_NULL_HANDLE;
VmaAllocationInfo allocationInfo = {};
RenderTextureLayout textureLayout = RenderTextureLayout::UNKNOWN;
RenderBarrierStages barrierStages = RenderBarrierStage::NONE;
bool ownership = false;
RenderTextureDesc desc;
VulkanTexture() = default;
VulkanTexture(VulkanDevice *device, VulkanPool *pool, const RenderTextureDesc &desc);
VulkanTexture(VulkanDevice *device, VkImage image);
~VulkanTexture() override;
void createImageView(VkFormat format);
std::unique_ptr<RenderTextureView> createTextureView(const RenderTextureViewDesc &desc) override;
void setName(const std::string &name) override;
void fillSubresourceRange();
};
struct VulkanTextureView : RenderTextureView {
VkImageView vk = VK_NULL_HANDLE;
VulkanTexture *texture = nullptr;
VulkanTextureView(VulkanTexture *texture, const RenderTextureViewDesc &desc);
~VulkanTextureView() override;
};
struct VulkanAccelerationStructure : RenderAccelerationStructure {
VkAccelerationStructureKHR vk = VK_NULL_HANDLE;
VulkanDevice *device = nullptr;
RenderAccelerationStructureType type = RenderAccelerationStructureType::UNKNOWN;
VulkanAccelerationStructure(VulkanDevice *device, const RenderAccelerationStructureDesc &desc);
~VulkanAccelerationStructure() override;
};
struct VulkanDescriptorSetLayout {
VkDescriptorSetLayout vk = VK_NULL_HANDLE;
std::vector<VkDescriptorSetLayoutBinding> setBindings;
std::vector<uint32_t> descriptorIndexBases;
std::vector<uint32_t> descriptorBindingIndices;
VulkanDevice *device = nullptr;
VulkanDescriptorSetLayout(VulkanDevice *device, const RenderDescriptorSetDesc &descriptorSetDesc);
~VulkanDescriptorSetLayout();
};
struct VulkanPipelineLayout : RenderPipelineLayout {
VkPipelineLayout vk = VK_NULL_HANDLE;
std::vector<VkPushConstantRange> pushConstantRanges;
std::vector<VulkanDescriptorSetLayout *> descriptorSetLayouts;
VulkanDevice *device = nullptr;
VulkanPipelineLayout(VulkanDevice *device, const RenderPipelineLayoutDesc &desc);
~VulkanPipelineLayout() override;
};
struct VulkanShader : RenderShader {
VkShaderModule vk = VK_NULL_HANDLE;
std::string entryPointName;
VulkanDevice *device = nullptr;
RenderShaderFormat format = RenderShaderFormat::UNKNOWN;
VulkanShader(VulkanDevice *device, const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format);
~VulkanShader() override;
};
struct VulkanSampler : RenderSampler {
VkSampler vk = VK_NULL_HANDLE;
VulkanDevice *device = nullptr;
VulkanSampler(VulkanDevice *device, const RenderSamplerDesc &desc);
~VulkanSampler();
};
struct VulkanPipeline : RenderPipeline {
enum class Type {
Unknown,
Compute,
Graphics,
Raytracing
};
VulkanDevice *device = nullptr;
Type type = Type::Unknown;
VulkanPipeline(VulkanDevice *device, Type type);
virtual ~VulkanPipeline() override;
};
struct VulkanComputePipeline : VulkanPipeline {
VkPipeline vk = VK_NULL_HANDLE;
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
VulkanComputePipeline(VulkanDevice *device, const RenderComputePipelineDesc &desc);
~VulkanComputePipeline() override;
void setName(const std::string& name) const override;
RenderPipelineProgram getProgram(const std::string &name) const override;
};
struct VulkanGraphicsPipeline : VulkanPipeline {
VkPipeline vk = VK_NULL_HANDLE;
VkRenderPass renderPass = VK_NULL_HANDLE;
VulkanGraphicsPipeline(VulkanDevice *device, const RenderGraphicsPipelineDesc &desc);
~VulkanGraphicsPipeline() override;
void setName(const std::string& name) const override;
RenderPipelineProgram getProgram(const std::string &name) const override;
static VkRenderPass createRenderPass(VulkanDevice *device, const VkFormat *renderTargetFormat, uint32_t renderTargetCount, VkFormat depthTargetFormat, VkSampleCountFlagBits sampleCount);
};
struct VulkanRaytracingPipeline : VulkanPipeline {
VkPipeline vk = VK_NULL_HANDLE;
std::unordered_map<std::string, RenderPipelineProgram> nameProgramMap;
uint32_t groupCount = 0;
uint32_t descriptorSetCount = 0;
VulkanRaytracingPipeline(VulkanDevice *device, const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline);
~VulkanRaytracingPipeline() override;
void setName(const std::string& name) const override;
RenderPipelineProgram getProgram(const std::string &name) const override;
};
struct VulkanDescriptorSet : RenderDescriptorSet {
VkDescriptorSet vk = VK_NULL_HANDLE;
VulkanDescriptorSetLayout *setLayout = nullptr;
VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
VulkanDevice *device = nullptr;
VulkanDescriptorSet(VulkanDevice *device, const RenderDescriptorSetDesc &desc);
~VulkanDescriptorSet() override;
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize, const RenderBufferStructuredView *bufferStructuredView, const RenderBufferFormattedView *bufferFormattedView) override;
void setTexture(uint32_t descriptorIndex, const RenderTexture *texture, RenderTextureLayout textureLayout, const RenderTextureView *textureView) override;
void setSampler(uint32_t descriptorIndex, const RenderSampler *sampler) override;
void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) override;
void setDescriptor(uint32_t descriptorIndex, const VkDescriptorBufferInfo *bufferInfo, const VkDescriptorImageInfo *imageInfo, const VkBufferView *texelBufferView, void *pNext);
static VkDescriptorPool createDescriptorPool(VulkanDevice *device, const std::unordered_map<VkDescriptorType, uint32_t> &typeCounts, bool lastRangeIsBoundless);
};
struct VulkanSwapChain : RenderSwapChain {
VkSwapchainKHR vk = VK_NULL_HANDLE;
VulkanCommandQueue *commandQueue = nullptr;
VkSurfaceKHR surface = VK_NULL_HANDLE;
RenderWindow renderWindow = {};
uint32_t textureCount = 0;
uint64_t presentCount = 0;
RenderFormat format = RenderFormat::UNKNOWN;
uint32_t width = 0;
uint32_t height = 0;
VkSwapchainCreateInfoKHR createInfo = {};
VkSurfaceFormatKHR pickedSurfaceFormat = {};
VkPresentModeKHR createdPresentMode = VK_PRESENT_MODE_FIFO_KHR;
VkPresentModeKHR requiredPresentMode = VK_PRESENT_MODE_FIFO_KHR;
VkCompositeAlphaFlagBitsKHR pickedAlphaFlag = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
std::vector<VulkanTexture> textures;
uint64_t currentPresentId = 0;
bool immediatePresentModeSupported = false;
uint32_t maxFrameLatency = 0;
VulkanSwapChain(VulkanCommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency);
~VulkanSwapChain() override;
bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) override;
void wait() override;
bool resize() override;
bool needsResize() const override;
void setVsyncEnabled(bool vsyncEnabled) override;
bool isVsyncEnabled() const override;
uint32_t getWidth() const override;
uint32_t getHeight() const override;
RenderTexture *getTexture(uint32_t textureIndex) override;
uint32_t getTextureCount() const override;
bool acquireTexture(RenderCommandSemaphore *signalSemaphore, uint32_t *textureIndex) override;
RenderWindow getWindow() const override;
bool isEmpty() const override;
uint32_t getRefreshRate() const override;
void getWindowSize(uint32_t &dstWidth, uint32_t &dstHeight) const;
void releaseSwapChain();
void releaseImageViews();
};
struct VulkanFramebuffer : RenderFramebuffer {
VulkanDevice *device = nullptr;
VkFramebuffer vk = VK_NULL_HANDLE;
VkRenderPass renderPass = VK_NULL_HANDLE;
std::vector<const VulkanTexture *> colorAttachments;
const VulkanTexture *depthAttachment = nullptr;
bool depthAttachmentReadOnly = false;
uint32_t width = 0;
uint32_t height = 0;
VulkanFramebuffer(VulkanDevice *device, const RenderFramebufferDesc &desc);
~VulkanFramebuffer() override;
uint32_t getWidth() const override;
uint32_t getHeight() const override;
bool contains(const VulkanTexture *attachment) const;
};
struct VulkanQueryPool : RenderQueryPool {
VulkanDevice *device = nullptr;
std::vector<uint64_t> results;
VkQueryPool vk = VK_NULL_HANDLE;
VulkanQueryPool(VulkanDevice *device, uint32_t queryCount);
virtual ~VulkanQueryPool() override;
virtual void queryResults() override;
virtual const uint64_t *getResults() const override;
virtual uint32_t getCount() const override;
};
struct VulkanCommandList : RenderCommandList {
VkCommandBuffer vk = VK_NULL_HANDLE;
VkCommandPool commandPool = VK_NULL_HANDLE;
VulkanDevice *device = nullptr;
RenderCommandListType type = RenderCommandListType::UNKNOWN;
const VulkanFramebuffer *targetFramebuffer = nullptr;
const VulkanPipelineLayout *activeComputePipelineLayout = nullptr;
const VulkanPipelineLayout *activeGraphicsPipelineLayout = nullptr;
const VulkanPipelineLayout *activeRaytracingPipelineLayout = nullptr;
VkRenderPass activeRenderPass = VK_NULL_HANDLE;
VulkanCommandList(VulkanDevice *device, RenderCommandListType type);
~VulkanCommandList() override;
void begin() override;
void end() override;
void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) override;
void dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) override;
void traceRays(uint32_t width, uint32_t height, uint32_t depth, RenderBufferReference shaderBindingTable, const RenderShaderBindingGroupsInfo &shaderBindingGroupsInfo) override;
void drawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation) override;
void drawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) override;
void setPipeline(const RenderPipeline *pipeline) override;
void setComputePipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
void setComputePushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
void setComputeDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
void setGraphicsPipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
void setGraphicsPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
void setGraphicsDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
void setGraphicsRootDescriptor(RenderBufferReference bufferReference, uint32_t rootDescriptorIndex) override;
void setRaytracingPipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
void setRaytracingPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
void setRaytracingDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
void setIndexBuffer(const RenderIndexBufferView *view) override;
void setVertexBuffers(uint32_t startSlot, const RenderVertexBufferView *views, uint32_t viewCount, const RenderInputSlot *inputSlots) override;
void setViewports(const RenderViewport *viewports, uint32_t count) override;
void setScissors(const RenderRect *scissorRects, uint32_t count) override;
void setFramebuffer(const RenderFramebuffer *framebuffer) override;
void setDepthBias(float depthBias, float depthBiasClamp, float slopeScaledDepthBias) override;
void clearColor(uint32_t attachmentIndex, RenderColor colorValue, const RenderRect *clearRects, uint32_t clearRectsCount) override;
void clearDepth(bool clearDepth, float depthValue, const RenderRect *clearRects, uint32_t clearRectsCount) override;
void copyBufferRegion(RenderBufferReference dstBuffer, RenderBufferReference srcBuffer, uint64_t size) override;
void copyTextureRegion(const RenderTextureCopyLocation &dstLocation, const RenderTextureCopyLocation &srcLocation, uint32_t dstX, uint32_t dstY, uint32_t dstZ, const RenderBox *srcBox) override;
void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) override;
void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect, RenderResolveMode resolveMode) override;
void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) override;
void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) override;
void discardTexture(const RenderTexture* texture) override;
void resetQueryPool(const RenderQueryPool *queryPool, uint32_t queryFirstIndex, uint32_t queryCount) override;
void writeTimestamp(const RenderQueryPool *queryPool, uint32_t queryIndex) override;
void checkActiveRenderPass();
void endActiveRenderPass();
void setDescriptorSet(VkPipelineBindPoint bindPoint, const VulkanPipelineLayout *pipelineLayout, const RenderDescriptorSet *descriptorSet, uint32_t setIndex);
};
struct VulkanCommandFence : RenderCommandFence {
VkFence vk = VK_NULL_HANDLE;
VulkanDevice *device = nullptr;
VulkanCommandFence(VulkanDevice *device);
~VulkanCommandFence() override;
};
struct VulkanCommandSemaphore : RenderCommandSemaphore {
VkSemaphore vk = VK_NULL_HANDLE;
VulkanDevice *device = nullptr;
VulkanCommandSemaphore(VulkanDevice *device);
~VulkanCommandSemaphore() override;
};
struct VulkanCommandQueue : RenderCommandQueue {
VulkanQueue *queue = nullptr;
VulkanDevice *device = nullptr;
uint32_t familyIndex = 0;
uint32_t queueIndex = 0;
std::unordered_set<VulkanSwapChain *> swapChains;
VulkanCommandQueue(VulkanDevice *device, RenderCommandListType commandListType);
~VulkanCommandQueue() override;
std::unique_ptr<RenderSwapChain> createSwapChain(RenderWindow renderWindow, uint32_t bufferCount, RenderFormat format, uint32_t maxFrameLatency) override;
void executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount, RenderCommandSemaphore **signalSemaphores, uint32_t signalSemaphoreCount, RenderCommandFence *signalFence) override;
void waitForCommandFence(RenderCommandFence *fence) override;
};
struct VulkanPool : RenderPool {
VmaPool vk = VK_NULL_HANDLE;
VulkanDevice *device = nullptr;
VulkanPool(VulkanDevice *device, const RenderPoolDesc &desc);
~VulkanPool() override;
std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) override;
std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) override;
};
struct VulkanQueue {
VkQueue vk;
std::unique_ptr<std::mutex> mutex;
std::unordered_set<const VulkanCommandQueue *> virtualQueues;
};
struct VulkanQueueFamily {
std::vector<VulkanQueue> queues;
void add(VulkanCommandQueue *virtualQueue);
void remove(VulkanCommandQueue *virtualQueue);
};
struct VulkanDevice : RenderDevice {
VkDevice vk = VK_NULL_HANDLE;
VulkanInterface *renderInterface = nullptr;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
VkPhysicalDeviceProperties physicalDeviceProperties = {};
VmaAllocator allocator = VK_NULL_HANDLE;
uint32_t queueFamilyIndices[3] = {};
std::vector<VulkanQueueFamily> queueFamilies;
RenderDeviceCapabilities capabilities;
RenderDeviceDescription description;
VkPhysicalDeviceRayTracingPipelinePropertiesKHR rtPipelineProperties = {};
VkPhysicalDeviceSampleLocationsPropertiesEXT sampleLocationProperties = {};
std::unique_ptr<RenderBuffer> nullBuffer = nullptr;
bool loadStoreOpNoneSupported = false;
bool nullDescriptorSupported = false;
VulkanDevice(VulkanInterface *renderInterface, const std::string &preferredDeviceName);
~VulkanDevice() override;
std::unique_ptr<RenderCommandList> createCommandList(RenderCommandListType type) override;
std::unique_ptr<RenderDescriptorSet> createDescriptorSet(const RenderDescriptorSetDesc &desc) override;
std::unique_ptr<RenderShader> createShader(const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format) override;
std::unique_ptr<RenderSampler> createSampler(const RenderSamplerDesc &desc) override;
std::unique_ptr<RenderPipeline> createComputePipeline(const RenderComputePipelineDesc &desc) override;
std::unique_ptr<RenderPipeline> createGraphicsPipeline(const RenderGraphicsPipelineDesc &desc) override;
std::unique_ptr<RenderPipeline> createRaytracingPipeline(const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline) override;
std::unique_ptr<RenderCommandQueue> createCommandQueue(RenderCommandListType type) override;
std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) override;
std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) override;
std::unique_ptr<RenderAccelerationStructure> createAccelerationStructure(const RenderAccelerationStructureDesc &desc) override;
std::unique_ptr<RenderPool> createPool(const RenderPoolDesc &desc) override;
std::unique_ptr<RenderPipelineLayout> createPipelineLayout(const RenderPipelineLayoutDesc &desc) override;
std::unique_ptr<RenderCommandFence> createCommandFence() override;
std::unique_ptr<RenderCommandSemaphore> createCommandSemaphore() override;
std::unique_ptr<RenderFramebuffer> createFramebuffer(const RenderFramebufferDesc &desc) override;
std::unique_ptr<RenderQueryPool> createQueryPool(uint32_t queryCount) override;
void setBottomLevelASBuildInfo(RenderBottomLevelASBuildInfo &buildInfo, const RenderBottomLevelASMesh *meshes, uint32_t meshCount, bool preferFastBuild, bool preferFastTrace) override;
void setTopLevelASBuildInfo(RenderTopLevelASBuildInfo &buildInfo, const RenderTopLevelASInstance *instances, uint32_t instanceCount, bool preferFastBuild, bool preferFastTrace) override;
void setShaderBindingTableInfo(RenderShaderBindingTableInfo &tableInfo, const RenderShaderBindingGroups &groups, const RenderPipeline *pipeline, RenderDescriptorSet **descriptorSets, uint32_t descriptorSetCount) override;
const RenderDeviceCapabilities &getCapabilities() const override;
const RenderDeviceDescription &getDescription() const override;
RenderSampleCounts getSampleCountsSupported(RenderFormat format) const override;
void waitIdle() const override;
void release();
bool isValid() const;
};
struct VulkanInterface : RenderInterface {
VkInstance instance = VK_NULL_HANDLE;
VkApplicationInfo appInfo = {};
RenderInterfaceCapabilities capabilities;
std::vector<std::string> deviceNames;
# if SDL_VULKAN_ENABLED
VulkanInterface(RenderWindow sdlWindow);
# else
VulkanInterface();
# endif
~VulkanInterface() override;
std::unique_ptr<RenderDevice> createDevice(const std::string &preferredDeviceName) override;
const RenderInterfaceCapabilities &getCapabilities() const override;
const std::vector<std::string> &getDeviceNames() const override;
bool isValid() const;
};
};

View file

@ -1838,7 +1838,7 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
g_queue = g_device->createCommandQueue(RenderCommandListType::DIRECT);
for (auto& commandList : g_commandLists)
commandList = g_device->createCommandList(RenderCommandListType::DIRECT);
commandList = g_queue->createCommandList();
for (auto& commandFence : g_commandFences)
commandFence = g_device->createCommandFence();
@ -1847,7 +1847,7 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
queryPool = g_device->createQueryPool(NUM_QUERIES);
g_copyQueue = g_device->createCommandQueue(RenderCommandListType::COPY);
g_copyCommandList = g_device->createCommandList(RenderCommandListType::COPY);
g_copyCommandList = g_copyQueue->createCommandList();
g_copyCommandFence = g_device->createCommandFence();
uint32_t bufferCount = 2;
@ -2075,23 +2075,21 @@ void Video::WaitForGPU()
{
g_waitForGPUCount++;
if (g_vulkan)
// Wait for all queued frames to finish.
for (size_t i = 0; i < NUM_FRAMES; i++)
{
g_device->waitIdle();
}
else
{
for (size_t i = 0; i < NUM_FRAMES; i++)
if (g_commandListStates[i])
{
if (g_commandListStates[i])
{
g_queue->waitForCommandFence(g_commandFences[i].get());
g_commandListStates[i] = false;
}
g_queue->waitForCommandFence(g_commandFences[i].get());
g_commandListStates[i] = false;
}
g_queue->executeCommandLists(nullptr, g_commandFences[0].get());
g_queue->waitForCommandFence(g_commandFences[0].get());
}
// Execute an empty command list and wait for it to end to guarantee that any remaining presentation has finished.
g_commandLists[0]->begin();
g_commandLists[0]->end();
g_queue->executeCommandLists(g_commandLists[0].get(), g_commandFences[0].get());
g_queue->waitForCommandFence(g_commandFences[0].get());
}
static uint32_t CreateDevice(uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5, be<uint32_t>* a6)
@ -5737,7 +5735,7 @@ static bool LoadTexture(GuestTexture& texture, const uint8_t* data, size_t dataS
auto copyTextureRegion = [&](Slice& slice, uint32_t subresourceIndex)
{
g_copyCommandList->copyTextureRegion(
RenderTextureCopyLocation::Subresource(texture.texture, subresourceIndex),
RenderTextureCopyLocation::Subresource(texture.texture, subresourceIndex % ddsDesc.numMips, subresourceIndex / ddsDesc.numMips),
RenderTextureCopyLocation::PlacedFootprint(uploadBuffer.get(), desc.format, slice.width, slice.height, slice.depth, (slice.dstRowPitch * 8) / ddsDesc.bitsPerPixelOrBlock * ddsDesc.blockWidth, slice.dstOffset));
};

View file

@ -4,7 +4,7 @@
/////////////////////////////////////////////////////////////////////#define PSO_CACHING
//#define PSO_CACHING_CLEANUP
#include "rhi/plume_render_interface.h"
#include <plume_render_interface.h>
#define D3DCLEAR_TARGET 0x1
#define D3DCLEAR_ZBUFFER 0x10

View file

@ -218,7 +218,7 @@ void GameWindow::Init(const char* sdlVideoDriver)
#elif defined(__linux__)
s_renderWindow = { info.info.x11.display, info.info.x11.window };
#elif defined(__APPLE__)
s_renderWindow.window = s_pWindow;
s_renderWindow.window = info.info.cocoa.window;
s_renderWindow.view = SDL_Metal_GetLayer(SDL_Metal_CreateView(s_pWindow));
#else
static_assert(false, "Unknown platform.");

View file

@ -1,6 +1,6 @@
#pragma once
#include <gpu/rhi/plume_render_interface_types.h>
#include <plume_render_interface_types.h>
#include <user/config.h>
#include <sdl_events.h>

View file

@ -20,6 +20,7 @@ add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/nativefiledialog-extended"
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/o1heap")
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/SDL")
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/SDL_mixer")
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/plume")
if (APPLE)
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/MoltenVK")

@ -1 +0,0 @@
Subproject commit e00c4a7c85cf9c28c6f4a6cc75032736f416410f

View file

@ -75,7 +75,7 @@ file(GLOB_RECURSE MVK_SOURCES CONFIGURE_DEPENDS
file(GLOB MVK_SRC_INCLUDES LIST_DIRECTORIES ON ${MVK_DIR}/MoltenVK/*)
set(MVK_INCLUDES
${MVK_SRC_INCLUDES} ${MVK_GENERATED_INCLUDES} ${MVK_DIR}/include
${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/Vulkan-Headers/include)
${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/plume/contrib/Vulkan-Headers/include)
add_library(MoltenVK SHARED ${MVK_SOURCES})
target_include_directories(MoltenVK PRIVATE ${MVK_INCLUDES})

@ -1 +0,0 @@
Subproject commit 75ad707a587e1469fb53a901b9b68fe9f6fbc11f

@ -1 +0,0 @@
Subproject commit 1c35ba99ce775f8342d87a83a3f0f696f99c2a39

1
thirdparty/plume vendored Submodule

@ -0,0 +1 @@
Subproject commit fffeb35f836d8c945697ec82b735e77db401e2de

1
thirdparty/volk vendored

@ -1 +0,0 @@
Subproject commit 447e21b5d92ed8d5271b0d39b071f938fcfa875f