Implement Vulkan.

This commit is contained in:
Skyth 2024-10-07 20:50:39 +03:00
parent 51df78e5c9
commit c07b827a5e
12 changed files with 4716 additions and 50 deletions

9
.gitmodules vendored
View file

@ -14,3 +14,12 @@
[submodule "thirdparty/ddspp"]
path = thirdparty/ddspp
url = https://github.com/redorav/ddspp.git
[submodule "thirdparty/Vulkan-Headers"]
path = thirdparty/Vulkan-Headers
url = https://github.com/KhronosGroup/Vulkan-Headers
[submodule "thirdparty/VulkanMemoryAllocator"]
path = thirdparty/VulkanMemoryAllocator
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
[submodule "thirdparty/volk"]
path = thirdparty/volk
url = https://github.com/zeux/volk.git

View file

@ -43,6 +43,7 @@ set(SWA_GPU_CXX_SOURCES
"gpu/window.cpp"
"gpu/video.cpp"
"gpu/rhi/rt64_d3d12.cpp"
"gpu/rhi/rt64_vulkan.cpp"
)
set(SWA_APU_CXX_SOURCES
@ -85,7 +86,12 @@ target_include_directories(UnleashedRecomp PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${SWA_THIRDPARTY_ROOT}/ddspp
${SWA_THIRDPARTY_ROOT}/D3D12MemoryAllocator/include
${SWA_THIRDPARTY_ROOT}/D3D12MemoryAllocator/src)
${SWA_THIRDPARTY_ROOT}/D3D12MemoryAllocator/src
${SWA_THIRDPARTY_ROOT}/volk
${SWA_THIRDPARTY_ROOT}/Vulkan-Headers/include
${SWA_THIRDPARTY_ROOT}/VulkanMemoryAllocator/include
${SWA_THIRDPARTY_ROOT}/VulkanMemoryAllocator/src
)
target_precompile_headers(UnleashedRecomp PUBLIC ${SWA_PRECOMPILED_HEADERS})

View file

@ -1441,10 +1441,6 @@ namespace RT64 {
}
}
bool D3D12CommandList::isOpen() {
return open;
}
void D3D12CommandList::begin() {
assert(!open);
@ -1622,13 +1618,18 @@ namespace RT64 {
activeComputePipelineLayout = interfacePipelineLayout;
}
void D3D12CommandList::setComputePushConstants(uint32_t rangeIndex, const void *data) {
void D3D12CommandList::setComputePushConstants(uint32_t rangeIndex, const void *data, uint32_t offset, uint32_t size) {
assert(activeComputePipelineLayout != nullptr);
assert(rangeIndex < activeComputePipelineLayout->pushConstantRanges.size());
const RenderPushConstantRange &range = activeComputePipelineLayout->pushConstantRanges[rangeIndex];
assert((range.offset == 0) && "Offset behavior should be verified when compared to Vulkan.");
d3d->SetComputeRoot32BitConstants(rangeIndex, (range.size + sizeof(uint32_t) - 1) / sizeof(uint32_t), data, 0);
if (size == 0) {
size = range.size;
}
d3d->SetComputeRoot32BitConstants(rangeIndex, (size + sizeof(uint32_t) - 1) / sizeof(uint32_t), data, (offset + sizeof(uint32_t) - 1) / sizeof(uint32_t));
}
void D3D12CommandList::setComputeDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) {
@ -1643,13 +1644,18 @@ namespace RT64 {
activeGraphicsPipelineLayout = interfacePipelineLayout;
}
void D3D12CommandList::setGraphicsPushConstants(uint32_t rangeIndex, const void *data) {
void D3D12CommandList::setGraphicsPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset, uint32_t size) {
assert(activeGraphicsPipelineLayout != nullptr);
assert(rangeIndex < activeGraphicsPipelineLayout->pushConstantRanges.size());
const RenderPushConstantRange &range = activeGraphicsPipelineLayout->pushConstantRanges[rangeIndex];
assert((range.offset == 0) && "Offset behavior should be verified when compared to Vulkan.");
d3d->SetGraphicsRoot32BitConstants(rangeIndex, (range.size + sizeof(uint32_t) - 1) / sizeof(uint32_t), data, 0);
if (size == 0) {
size = range.size;
}
d3d->SetGraphicsRoot32BitConstants(rangeIndex, (size + sizeof(uint32_t) - 1) / sizeof(uint32_t), data, (offset + sizeof(uint32_t) - 1) / sizeof(uint32_t));
}
void D3D12CommandList::setGraphicsDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) {
@ -1664,8 +1670,8 @@ namespace RT64 {
setComputePipelineLayout(pipelineLayout);
}
void D3D12CommandList::setRaytracingPushConstants(uint32_t rangeIndex, const void *data) {
setComputePushConstants(rangeIndex, data);
void D3D12CommandList::setRaytracingPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset, uint32_t size) {
setComputePushConstants(rangeIndex, data, offset, size);
}
void D3D12CommandList::setRaytracingDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) {
@ -2302,6 +2308,10 @@ namespace RT64 {
setObjectName(d3d, name);
}
uint64_t D3D12Buffer::getDeviceAddress() const {
return d3d->GetGPUVirtualAddress();
}
// D3D12BufferFormattedView
D3D12BufferFormattedView::D3D12BufferFormattedView(D3D12Buffer *buffer, RenderFormat format) {
@ -2675,7 +2685,9 @@ namespace RT64 {
psoDesc.PS.BytecodeLength = (pixelShader != nullptr) ? pixelShader->d3d.size() : 0;
psoDesc.SampleMask = UINT_MAX;
psoDesc.SampleDesc.Count = desc.multisampling.sampleCount;
psoDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF;
if (desc.primitiveTopology == RenderPrimitiveTopology::LINE_STRIP || desc.primitiveTopology == RenderPrimitiveTopology::TRIANGLE_STRIP) {
psoDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF;
}
psoDesc.PrimitiveTopologyType = toTopologyType(desc.primitiveTopology);
psoDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
psoDesc.RasterizerState.DepthClipEnable = desc.depthClipEnabled;

View file

@ -159,7 +159,6 @@ namespace RT64 {
D3D12CommandList(D3D12Device *device, RenderCommandListType type);
~D3D12CommandList() override;
bool isOpen() override;
void begin() override;
void end() override;
void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) override;
@ -169,14 +168,14 @@ namespace RT64 {
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) 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) 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) 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;
@ -250,6 +249,7 @@ namespace RT64 {
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 {

View file

@ -21,6 +21,7 @@ namespace RT64 {
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 {
@ -104,7 +105,6 @@ namespace RT64 {
struct RenderCommandList {
virtual ~RenderCommandList() { }
virtual bool isOpen() = 0;
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;
@ -114,14 +114,14 @@ namespace RT64 {
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) = 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) = 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) = 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;

View file

@ -405,7 +405,8 @@ namespace RT64 {
RENDER_TARGET = 1U << 0,
DEPTH_TARGET = 1U << 1,
STORAGE = 1U << 2,
UNORDERED_ACCESS = 1U << 3
UNORDERED_ACCESS = 1U << 3,
CUBE = 1U << 4
};
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,409 @@
//
// RT64
//
#pragma once
#include "rt64_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
#endif
#include "volk.h"
#include "vk_mem_alloc.h"
namespace RT64 {
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;
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;
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;
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 pickedPresentMode = VK_PRESENT_MODE_FIFO_KHR;
VkCompositeAlphaFlagBitsKHR pickedAlphaFlag = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
std::vector<VulkanTexture> textures;
VulkanSwapChain(VulkanCommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format);
~VulkanSwapChain() override;
bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) override;
bool resize() override;
bool needsResize() 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 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 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) 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 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) 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 = {};
bool loadStoreOpNoneSupported = false;
VulkanDevice(VulkanInterface *renderInterface);
~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;
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 release();
bool isValid() const;
};
struct VulkanInterface : RenderInterface {
VkInstance instance = VK_NULL_HANDLE;
VkApplicationInfo appInfo = {};
RenderInterfaceCapabilities capabilities;
VulkanInterface();
~VulkanInterface() override;
std::unique_ptr<RenderDevice> createDevice() override;
const RenderInterfaceCapabilities &getCapabilities() const override;
bool isValid() const;
};
};

View file

@ -62,7 +62,7 @@ static bool g_scissorTestEnable = false;
static RenderRect g_scissorRect;
static RenderVertexBufferView g_vertexBufferViews[16];
static RenderInputSlot g_inputSlots[16];
static RenderIndexBufferView g_indexBufferView;
static RenderIndexBufferView g_indexBufferView({}, 0, RenderFormat::R16_UINT);
struct DirtyStates
{
@ -104,6 +104,7 @@ static void SetDirtyValue(bool& dirtyState, T& dest, const T& src)
}
}
static bool g_vulkan = false;
static std::unique_ptr<RenderInterface> g_interface;
static std::unique_ptr<RenderDevice> g_device;
@ -122,6 +123,8 @@ static std::unique_ptr<RenderCommandList> g_copyCommandList;
static std::unique_ptr<RenderCommandFence> g_copyCommandFence;
static std::unique_ptr<RenderSwapChain> g_swapChain;
static std::unique_ptr<RenderCommandSemaphore> g_acquireSemaphores[NUM_FRAMES];
static uint32_t g_backBufferIndex;
static GuestSurface* g_backBuffer;
struct std::unique_ptr<RenderDescriptorSet> g_textureDescriptorSet;
@ -201,7 +204,7 @@ struct UploadAllocator
auto& buffer = buffers[index];
if (buffer.buffer == nullptr)
{
buffer.buffer = g_device->createBuffer(RenderBufferDesc::UploadBuffer(UploadBuffer::SIZE));
buffer.buffer = g_device->createBuffer(RenderBufferDesc::UploadBuffer(UploadBuffer::SIZE, RenderBufferFlag::CONSTANT | RenderBufferFlag::VERTEX | RenderBufferFlag::INDEX));
buffer.memory = reinterpret_cast<uint8_t*>(buffer.buffer->map());
}
@ -472,7 +475,7 @@ static void CreateHostDevice()
Window::Init();
g_interface = CreateD3D12Interface();
g_interface = g_vulkan ? CreateVulkanInterface() : CreateD3D12Interface();
g_device = g_interface->createDevice();
g_queue = g_device->createCommandQueue(RenderCommandListType::DIRECT);
@ -488,6 +491,13 @@ static void CreateHostDevice()
g_copyCommandFence = g_device->createCommandFence();
g_swapChain = g_queue->createSwapChain(Window::s_windowHandle, 2, RenderFormat::R8G8B8A8_UNORM);
g_swapChain->resize();
if (g_vulkan)
{
for (auto& acquireSemaphore : g_acquireSemaphores)
acquireSemaphore = g_device->createCommandSemaphore();
}
RenderPipelineLayoutBuilder pipelineLayoutBuilder;
pipelineLayoutBuilder.begin(false, true);
@ -512,9 +522,16 @@ static void CreateHostDevice()
g_samplerDescriptorSet = descriptorSetBuilder.create(g_device.get());
pipelineLayoutBuilder.addDescriptorSet(descriptorSetBuilder);
pipelineLayoutBuilder.addRootDescriptor(0, 4, RenderRootDescriptorType::CONSTANT_BUFFER);
pipelineLayoutBuilder.addRootDescriptor(1, 4, RenderRootDescriptorType::CONSTANT_BUFFER);
pipelineLayoutBuilder.addRootDescriptor(2, 4, RenderRootDescriptorType::CONSTANT_BUFFER);
if (g_vulkan)
{
pipelineLayoutBuilder.addPushConstant(0, 4, 24, RenderShaderStageFlag::VERTEX | RenderShaderStageFlag::PIXEL);
}
else
{
pipelineLayoutBuilder.addRootDescriptor(0, 4, RenderRootDescriptorType::CONSTANT_BUFFER);
pipelineLayoutBuilder.addRootDescriptor(1, 4, RenderRootDescriptorType::CONSTANT_BUFFER);
pipelineLayoutBuilder.addRootDescriptor(2, 4, RenderRootDescriptorType::CONSTANT_BUFFER);
}
pipelineLayoutBuilder.end();
g_pipelineLayout = pipelineLayoutBuilder.create(g_device.get());
@ -528,9 +545,9 @@ static void BeginCommandList()
g_pipelineState.renderTargetFormat = g_backBuffer->format;
g_pipelineState.depthStencilFormat = RenderFormat::UNKNOWN;
uint32_t textureIndex = 0;
g_swapChain->acquireTexture(nullptr, &textureIndex);
g_backBuffer->texture = g_swapChain->getTexture(textureIndex);
bool acquired = g_swapChain->acquireTexture(g_acquireSemaphores[g_frame].get(), &g_backBufferIndex);
assert(acquired);
g_backBuffer->texture = g_swapChain->getTexture(g_backBufferIndex);
auto& commandList = g_commandLists[g_frame];
@ -779,9 +796,22 @@ static void Present()
auto& commandList = g_commandLists[g_frame];
commandList->barriers(RenderBarrierStage::GRAPHICS, RenderTextureBarrier(g_backBuffer->texture, RenderTextureLayout::PRESENT));
commandList->end();
g_queue->executeCommandLists(commandList.get(), g_commandFences[g_frame].get());
g_swapChain->present(0, nullptr, 0);
if (g_vulkan)
{
const RenderCommandList* commandLists[] = { commandList.get() };
RenderCommandSemaphore* waitSemaphores[] = { g_acquireSemaphores[g_frame].get()};
g_queue->executeCommandLists(
commandLists, std::size(commandLists),
waitSemaphores, std::size(waitSemaphores),
nullptr, 0,
g_commandFences[g_frame].get());
}
else
{
g_queue->executeCommandLists(commandList.get(), g_commandFences[g_frame].get());
}
g_swapChain->present(g_backBufferIndex, nullptr, 0);
g_frame = g_nextFrame;
g_nextFrame = (g_frame + 1) % NUM_FRAMES;
@ -856,10 +886,11 @@ static GuestTexture* CreateTexture(uint32_t width, uint32_t height, uint32_t dep
desc.mipLevels = levels;
desc.arraySize = 1;
desc.format = ConvertFormat(format);
desc.flags = (desc.format == RenderFormat::D32_FLOAT) ? RenderTextureFlag::DEPTH_TARGET : RenderTextureFlag::NONE;
texture->texture = g_device->createTexture(desc);
RenderTextureViewDesc viewDesc;
viewDesc.format = desc.format == RenderFormat::D32_FLOAT ? RenderFormat::R32_FLOAT : desc.format;
viewDesc.format = desc.format;
viewDesc.dimension = texture->type == ResourceType::VolumeTexture ? RenderTextureViewDimension::TEXTURE_3D : RenderTextureViewDimension::TEXTURE_2D;
viewDesc.mipLevels = levels;
texture->textureView = texture->texture->createTextureView(viewDesc);
@ -878,7 +909,7 @@ static GuestTexture* CreateTexture(uint32_t width, uint32_t height, uint32_t dep
static GuestBuffer* CreateVertexBuffer(uint32_t length)
{
auto buffer = g_userHeap.AllocPhysical<GuestBuffer>(ResourceType::VertexBuffer);
buffer->buffer = g_device->createBuffer(RenderBufferDesc::VertexBuffer(length, RenderHeapType::DEFAULT));
buffer->buffer = g_device->createBuffer(RenderBufferDesc::VertexBuffer(length, RenderHeapType::DEFAULT, RenderBufferFlag::INDEX));
buffer->dataSize = length;
#ifdef _DEBUG
buffer->buffer->setName(std::format("Vertex Buffer {:X}", g_memory.MapVirtual(buffer)));
@ -1204,7 +1235,7 @@ static void FlushRenderState(GuestDevice* device)
constexpr size_t BOOL_MASK = 0x100000000000000ull;
if ((device->dirtyFlags[4].get() & BOOL_MASK) != 0)
{
uint32_t booleans = device->vertexShaderBoolConstants [0].get() & 0xFF;
uint32_t booleans = device->vertexShaderBoolConstants[0].get() & 0xFF;
booleans |= (device->pixelShaderBoolConstants[0].get() & 0xFF) << 16;
SetDirtyValue(g_dirtyStates.sharedConstants, g_sharedConstants.booleans, booleans);
@ -1250,15 +1281,30 @@ static void FlushRenderState(GuestDevice* device)
SetDirtyValue(g_dirtyStates.sharedConstants, g_sharedConstants.samplerIndices[i], descriptorIndex);
}
device->dirtyFlags[3] = device->dirtyFlags[3].get() & ~mask;
}
}
auto& uploadAllocator = g_uploadAllocators[g_frame];
auto setRootDescriptor = [&](RenderBufferReference reference, size_t index)
{
if (g_vulkan)
{
uint64_t address = reference.ref->getDeviceAddress() + reference.offset;
commandList->setGraphicsPushConstants(0, &address, 8 * index, 8);
}
else
{
commandList->setGraphicsRootDescriptor(reference, index);
}
};
if (g_dirtyStates.sharedConstants)
{
auto sharedConstants = uploadAllocator.allocate<false>(&g_sharedConstants, sizeof(g_sharedConstants), 0x100);
commandList->setGraphicsRootDescriptor(sharedConstants, 2);
setRootDescriptor(sharedConstants, 2);
}
if (g_dirtyStates.scissorRect)
@ -1275,8 +1321,7 @@ static void FlushRenderState(GuestDevice* device)
if (g_dirtyStates.vertexShaderConstants || device->dirtyFlags[0] != 0)
{
auto vertexShaderConstants = uploadAllocator.allocate<true>(device->vertexShaderFloatConstants, 0x1000, 0x100);
commandList->setGraphicsRootDescriptor(vertexShaderConstants, 0);
setRootDescriptor(vertexShaderConstants, 0);
device->dirtyFlags[0] = 0;
}
@ -1289,14 +1334,13 @@ static void FlushRenderState(GuestDevice* device)
g_inputSlots + g_dirtyStates.vertexStreamFirst);
}
if (g_dirtyStates.indices)
if (g_dirtyStates.indices && (!g_vulkan || g_indexBufferView.buffer.ref != nullptr))
commandList->setIndexBuffer(&g_indexBufferView);
if (g_dirtyStates.pixelShaderConstants || device->dirtyFlags[1] != 0)
{
auto pixelShaderConstants = uploadAllocator.allocate<true>(device->pixelShaderFloatConstants, 0xE00, 0x100);
commandList->setGraphicsRootDescriptor(pixelShaderConstants, 1);
setRootDescriptor(pixelShaderConstants, 1);
device->dirtyFlags[1] = 0;
}
@ -1555,14 +1599,60 @@ static GuestVertexDeclaration* CreateVertexDeclaration(GuestVertexElement* verte
static std::vector<RenderInputElement> inputElements;
inputElements.clear();
struct Location
{
uint32_t usage;
uint32_t usageIndex;
uint32_t location;
};
constexpr Location locations[] =
{
{ D3DDECLUSAGE_POSITION, 0, 0 },
{ D3DDECLUSAGE_NORMAL, 0, 1 },
{ D3DDECLUSAGE_TANGENT, 0, 2 },
{ D3DDECLUSAGE_BINORMAL, 0, 3 },
{ D3DDECLUSAGE_TEXCOORD, 0, 4 },
{ D3DDECLUSAGE_TEXCOORD, 1, 5 },
{ D3DDECLUSAGE_TEXCOORD, 2, 6 },
{ D3DDECLUSAGE_TEXCOORD, 3, 7 },
{ D3DDECLUSAGE_COLOR, 0, 8 },
{ D3DDECLUSAGE_BLENDINDICES, 0, 9 },
{ D3DDECLUSAGE_BLENDWEIGHT, 0, 10 },
{ D3DDECLUSAGE_COLOR, 1, 11 },
{ D3DDECLUSAGE_TEXCOORD, 4, 12 },
{ D3DDECLUSAGE_TEXCOORD, 5, 13 },
{ D3DDECLUSAGE_TEXCOORD, 6, 14 },
{ D3DDECLUSAGE_TEXCOORD, 7, 15 },
{ D3DDECLUSAGE_POSITION, 1, 15 }
};
vertexElement = vertexElements;
while (vertexElement->stream != 0xFF && vertexElement->type != D3DDECLTYPE_UNUSED)
{
if (vertexElement->usage == D3DDECLUSAGE_POSITION && vertexElement->usageIndex == 2)
{
++vertexElement;
continue;
}
auto& inputElement = inputElements.emplace_back();
inputElement.semanticName = ConvertDeclUsage(vertexElement->usage);
inputElement.semanticIndex = vertexElement->usageIndex;
inputElement.location = (vertexElement->usage * 4) + vertexElement->usageIndex;
inputElement.location = ~0;
for (auto& location : locations)
{
if (location.usage == vertexElement->usage && location.usageIndex == vertexElement->usageIndex)
{
inputElement.location = location.location;
break;
}
}
assert(inputElement.location != ~0);
inputElement.format = ConvertDeclType(vertexElement->type);
inputElement.slotIndex = vertexElement->stream;
inputElement.alignedByteOffset = vertexElement->offset;
@ -1611,7 +1701,18 @@ static GuestVertexDeclaration* CreateVertexDeclaration(GuestVertexElement* verte
auto addInputElement = [&](uint32_t usage, uint32_t usageIndex)
{
uint32_t location = (usage * 4) + usageIndex;
uint32_t location = ~0;
for (auto& alsoLocation : locations)
{
if (alsoLocation.usage == usage && alsoLocation.usageIndex == usageIndex)
{
location = alsoLocation.location;
break;
}
}
assert(location != ~0);
for (auto& inputElement : inputElements)
{
@ -1642,7 +1743,6 @@ static GuestVertexDeclaration* CreateVertexDeclaration(GuestVertexElement* verte
addInputElement(D3DDECLUSAGE_TEXCOORD, 2);
addInputElement(D3DDECLUSAGE_TEXCOORD, 3);
addInputElement(D3DDECLUSAGE_COLOR, 0);
addInputElement(D3DDECLUSAGE_COLOR, 1);
addInputElement(D3DDECLUSAGE_BLENDWEIGHT, 0);
addInputElement(D3DDECLUSAGE_BLENDINDICES, 0);
@ -1671,11 +1771,30 @@ static void SetVertexDeclaration(GuestDevice* device, GuestVertexDeclaration* ve
device->vertexDeclaration = vertexDeclaration;
}
static std::unique_ptr<RenderShader> CreateShader(const uint32_t* function)
{
if (*function == 0)
{
const uint32_t dxilSize = *(function + 1);
const uint32_t spirvSize = *(function + 2);
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(function + 3);
if (g_vulkan)
{
return g_device->createShader(bytes + dxilSize, spirvSize, "main", RenderShaderFormat::SPIRV);
}
else
{
return g_device->createShader(bytes, dxilSize, "main", RenderShaderFormat::DXIL);
}
}
return nullptr;
}
static GuestShader* CreateVertexShader(const uint32_t* function)
{
auto vertexShader = g_userHeap.AllocPhysical<GuestShader>(ResourceType::VertexShader);
if (*function == 0x43425844)
vertexShader->shader = g_device->createShader(function, function[6], "main", RenderShaderFormat::DXIL);
vertexShader->shader = CreateShader(function);
return vertexShader;
}
@ -1705,15 +1824,14 @@ static void SetStreamSource(GuestDevice* device, uint32_t index, GuestBuffer* bu
static void SetIndices(GuestDevice* device, GuestBuffer* buffer)
{
SetDirtyValue(g_dirtyStates.indices, g_indexBufferView.buffer, buffer != nullptr ? buffer->buffer->at(0) : RenderBufferReference{});
SetDirtyValue(g_dirtyStates.indices, g_indexBufferView.format, buffer != nullptr ? buffer->format : RenderFormat::UNKNOWN);
SetDirtyValue(g_dirtyStates.indices, g_indexBufferView.format, buffer != nullptr ? buffer->format : RenderFormat::R16_UINT);
SetDirtyValue(g_dirtyStates.indices, g_indexBufferView.size, buffer != nullptr ? buffer->dataSize : 0u);
}
static GuestShader* CreatePixelShader(const uint32_t* function)
{
auto pixelShader = g_userHeap.AllocPhysical<GuestShader>(ResourceType::PixelShader);
if (*function == 0x43425844)
pixelShader->shader = g_device->createShader(function, function[6], "main", RenderShaderFormat::DXIL);
pixelShader->shader = CreateShader(function);
return pixelShader;
}
@ -2031,6 +2149,7 @@ static void MakePictureData(GuestPictureData* pictureData, uint8_t* data, uint32
desc.mipLevels = ddsDesc.numMips;
desc.arraySize = ddsDesc.type == ddspp::TextureType::Cubemap ? ddsDesc.arraySize * 6 : ddsDesc.arraySize;
desc.format = ConvertDXGIFormat(ddsDesc.format);
desc.flags = ddsDesc.type == ddspp::TextureType::Cubemap ? RenderTextureFlag::CUBE : RenderTextureFlag::NONE;
texture->texture = g_device->createTexture(desc);
#ifdef _DEBUG
texture->texture->setName(reinterpret_cast<char*>(g_memory.Translate(pictureData->name + 2)));
@ -2108,6 +2227,8 @@ static void MakePictureData(GuestPictureData* pictureData, uint8_t* data, uint32
ExecuteCopyCommandList([&]
{
g_copyCommandList->barriers(RenderBarrierStage::COPY, RenderTextureBarrier(texture->texture.get(), RenderTextureLayout::COPY_DEST));
for (size_t i = 0; i < slices.size(); i++)
{
auto& slice = slices[i];

1
thirdparty/Vulkan-Headers vendored Submodule

@ -0,0 +1 @@
Subproject commit 14345dab231912ee9601136e96ca67a6e1f632e7

1
thirdparty/VulkanMemoryAllocator vendored Submodule

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

1
thirdparty/volk vendored Submodule

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