Introduce a new Buffer type with DX,VK,MTL implementations.#976
Introduce a new Buffer type with DX,VK,MTL implementations.#976manon-traverse wants to merge 8 commits intollvm:mainfrom
Conversation
lib/API/VK/Device.cpp
Outdated
| if (auto Err = initializeLogicalDevice()) | ||
| return Err; |
There was a problem hiding this comment.
Waaah, I just noticed this. Need to restructure this. Don't want device initialization in buffer creation.
|
|
||
| struct BufferCreateDesc { | ||
| MemoryLocation Location; | ||
| BufferUsage Usage; |
There was a problem hiding this comment.
I don't think I see this Usage flag used anywhere. Is the idea that buffer usage describes the buffer as CBV/UAV/SRV (in DX12 parlance)?
There was a problem hiding this comment.
The Usage tag will later be used to specify the type of buffer (Storage, AccelerationStructure, Constant, etc). I included it here so that the field should be filled in from the start. Perhaps we should apply a constructor on this type to enforce filling in all fields?
| }; | ||
|
|
||
| enum class MemoryLocation { | ||
| GpuOnly, |
There was a problem hiding this comment.
This may be confusing if later on you want to add CPU-visible memory which is still GPU local (ReBAR).
I wonder if the memory locations should just be GpuLocal or HostLocal and then the usage of Readback, Upload, ShaderMutable, or ShaderVisible then dictates the heap/memory-type in conjunction with "MemoryLocation"
There was a problem hiding this comment.
In our closed-source render framework, we use CpuToGpu to express that the resource has to be HOST visible and won't be read from. Whether that resource is actually in GPU Local ReBAR, some form of shared memory or on HOST. I am basically using that as a starting point as it has proven to have worked so far, but I am open for suggestion and changes.
That's why the terms GpuLocal and HostLocal may not fit as well, since it's a detail that the rendering backend should deal with and not necessarily the cross-platform rendering code.
There was a problem hiding this comment.
Sure, but the enum name here is MemoryLocation after all. I think hiding that as an implementation detail totally makes sense, but it may make sense for the type name to then indicate as such. Personally, if the goal is to expose strictly semantics to the user of this API, and the specific memory location is an implementation detail, I would probably opt to just expose the BufferUsage flag alone.
lib/API/DX/Device.cpp
Outdated
| createBuffer(llvm::StringRef Name, BufferCreateDesc &Desc, | ||
| size_t SizeInBytes) override { | ||
|
|
||
| D3D12_HEAP_TYPE HeapType = 0; |
| } | ||
|
|
||
| const D3D12_RESOURCE_FLAGS Flags = | ||
| D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; |
There was a problem hiding this comment.
These flags aren't yet used, but I'm assuming UAV access should be conditional depending on usage
There was a problem hiding this comment.
On Buffers UAV access is kind-of the default. There is no special swizzling or compression like on textures. There may be some exceptions when it comes to acceleration structures that according to the spec shouldn't be UAV. However, I would like to solve that problem once we reach that point.
There was a problem hiding this comment.
Yea that's definitely true (re: difference between buffers and textures), although the semantic difference for buffers is often still meaningful in most engines -- you wouldn't expect to create a UAV descriptor for a read-only buffer for example (unless you live in a BDA-only world)
llvm-beanz
left a comment
There was a problem hiding this comment.
A couple comments. As a meta-comment, we do use clang-tidy to enforce consistent style and coding standards. That is run with -Werror in our bots, so some of the CI failures you're seeing as build failures are Clang-Tidy failures.
Our ReadMe documents setting up Clang-Tidy once you have it installed: https://github.com/llvm/offload-test-suite?tab=readme-ov-file#enabling-clang-tidy
| class DXBuffer : public offloadtest::Buffer { | ||
| public: | ||
| ComPtr<ID3D12Resource> Buffer; | ||
| std::string Name; |
There was a problem hiding this comment.
Should we put the Name and SizeInBytes in the base class? Seems like all the sub-classes have those fields.
There was a problem hiding this comment.
I am not sure! I am a big fan of using Pure Virtual Classes and only doing functionality inheritance without any data inheritance, much like traits in Rust. What is the LLVM approach to this?
lib/API/VK/Device.cpp
Outdated
| default: | ||
| assert(false && "MemoryLocation variant not handled"); | ||
| break; | ||
| } | ||
|
|
There was a problem hiding this comment.
If your switch covers all cases the compiler will emit a diagnostic that we'll catch with -Werror in CI, but that only works if you don't have the default case.
| default: | |
| assert(false && "MemoryLocation variant not handled"); | |
| break; | |
| } | |
| } | |
| assert(MemFlags != 0 && "MemoryLocation variant must not have set flags correctly"); |
There was a problem hiding this comment.
Yes I found that out this morning! Just getting back into C++ after having used Rust for so long.
Yes I saw something along the lines of that. I'll check it out! <3 I have some local changes to the README with steps and pointers that I found difficult to figure out to improve the onboarding in the future. |
7120c5e to
65a94ab
Compare
A first small step towards creating a Render Backend API layer on top of DX12, Vulkan, and Metal.
This introduces a new Buffer type with an implementation for each API as well as a function on the Device class to create one.
The change is smaller than it looks due to a naming conflict that needed to be resolved. The type previously called
Bufferhas been renamed toCPUBuffer.