Skip to content

Commit

Permalink
Resource usage (#26)
Browse files Browse the repository at this point in the history
* BufferUsage enum

* TextureUsage enum

* implement IDevice::getFormatSupport

* speed up format test

* refactor test-resource-state test
  • Loading branch information
skallweitNV authored Sep 9, 2024
1 parent 8f463ca commit 281c483
Show file tree
Hide file tree
Showing 64 changed files with 686 additions and 876 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
- replace IDevice::getFormatSupportedResourceStates with IDevice::getFormatSupport
- rename TextureDesc::allowedStates -> TextureDesc::usage and introduce TextureUsage enum
- rename BufferDesc::allowedStates -> BufferDesc::usage and introduce BufferUsage enum
- rename IQueryPool::Desc -> QueryPoolDesc, add label to QueryPoolDesc
- rename IFence::Desc -> FenceDesc, add label to FenceDesc
- implement dynamic rendering in Vulkan
Expand Down
10 changes: 10 additions & 0 deletions YONGQUESTIONS.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

Pipeline refactor
- can we remove runtime specialization? we have to!
- specialize() doesn't lead to a program layout that can be used

Shader program
- can we always create shader program from a "linked program"
- we cannot just have a single linked program passed in
- d3d12 has support for "libraries" where we have individual entry points with different specializations
- how should the interface to create shader programs look like?
113 changes: 72 additions & 41 deletions include/slang-rhi.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@
#define SLANG_RHI_API
#endif

// clang-format off
/// Implement logical operators on a class enum for making it usable as a flags enum.
#define SLANG_RHI_ENUM_CLASS_OPERATORS(e_) \
inline e_ operator& (e_ a, e_ b) { return static_cast<e_>(static_cast<int>(a)& static_cast<int>(b)); } \
inline e_ operator| (e_ a, e_ b) { return static_cast<e_>(static_cast<int>(a)| static_cast<int>(b)); } \
inline e_& operator|= (e_& a, e_ b) { a = a | b; return a; }; \
inline e_& operator&= (e_& a, e_ b) { a = a & b; return a; }; \
inline e_ operator~ (e_ a) { return static_cast<e_>(~static_cast<int>(a)); } \
inline bool is_set(e_ val, e_ flag) { return (val & flag) != static_cast<e_>(0); } \
inline void flip_bit(e_& val, e_ flag) { val = is_set(val, flag) ? (val & (~flag)) : (val | flag); }
// clang-format on

// Needed for building on cygwin with gcc
#undef Always
#undef None
Expand Down Expand Up @@ -266,6 +278,27 @@ struct FormatInfo
GfxCount blockHeight;
};

enum class FormatSupport
{
None = 0x0,

Buffer = 0x1,
IndexBuffer = 0x2,
VertexBuffer = 0x4,

Texture = 0x8,
DepthStencil = 0x10,
RenderTarget = 0x20,
Blendable = 0x40,

ShaderLoad = 0x80,
ShaderSample = 0x100,
ShaderUavLoad = 0x200,
ShaderUavStore = 0x400,
ShaderAtomic = 0x800,
};
SLANG_RHI_ENUM_CLASS_OPERATORS(FormatSupport);

enum class InputSlotClass
{
PerVertex,
Expand Down Expand Up @@ -313,42 +346,6 @@ enum class ResourceState
AccelerationStructureBuildInput,
PixelShaderResource,
NonPixelShaderResource,
_Count
};

struct ResourceStateSet
{
public:
void add(ResourceState state) { m_bitFields |= (1LL << (uint32_t)state); }
template<typename... TResourceState>
void add(ResourceState s, TResourceState... states)
{
add(s);
add(states...);
}
bool contains(ResourceState state) const { return (m_bitFields & (1LL << (uint32_t)state)) != 0; }
ResourceStateSet()
: m_bitFields(0)
{
}
ResourceStateSet(const ResourceStateSet& other) = default;
ResourceStateSet(ResourceState state) { add(state); }
template<typename... TResourceState>
ResourceStateSet(TResourceState... states)
{
add(states...);
}

ResourceStateSet operator&(const ResourceStateSet& that) const
{
ResourceStateSet result;
result.m_bitFields = this->m_bitFields & that.m_bitFields;
return result;
}

private:
uint64_t m_bitFields = 0;
void add() {}
};

/// Describes how memory for the resource should be allocated for CPU access.
Expand Down Expand Up @@ -467,6 +464,23 @@ struct MemoryRange
uint64_t size;
};

enum class BufferUsage
{
None = 0,
VertexBuffer = 0x1,
IndexBuffer = 0x2,
ConstantBuffer = 0x4,
ShaderResource = 0x8,
UnorderedAccess = 0x10,
IndirectArgument = 0x20,
CopySource = 0x40,
CopyDestination = 0x80,
AccelerationStructure = 0x100,
AccelerationStructureBuildInput = 0x200,
ShaderTable = 0x400,
};
SLANG_RHI_ENUM_CLASS_OPERATORS(BufferUsage);

struct BufferDesc
{
/// Total size in bytes.
Expand All @@ -478,8 +492,8 @@ struct BufferDesc

MemoryType memoryType = MemoryType::DeviceLocal;

BufferUsage usage = BufferUsage::None;
ResourceState defaultState = ResourceState::Undefined;
ResourceStateSet allowedStates = ResourceStateSet();

bool isShared = false;

Expand Down Expand Up @@ -522,6 +536,22 @@ struct BufferRange
Size size;
};

enum class TextureUsage
{
None = 0x0,
ShaderResource = 0x1,
UnorderedAccess = 0x2,
RenderTarget = 0x4,
DepthRead = 0x8,
DepthWrite = 0x10,
Present = 0x20,
CopySource = 0x40,
CopyDestination = 0x80,
ResolveSource = 0x100,
ResolveDestination = 0x200,
};
SLANG_RHI_ENUM_CLASS_OPERATORS(TextureUsage);

enum class TextureType
{
Texture1D, ///< A 1d texture
Expand Down Expand Up @@ -625,9 +655,11 @@ struct Extents
struct TextureDesc
{
TextureType type = TextureType::Texture2D;
ResourceState defaultState = ResourceState::Undefined;
ResourceStateSet allowedStates = ResourceStateSet();

MemoryType memoryType = MemoryType::DeviceLocal;

TextureUsage usage = TextureUsage::None;
ResourceState defaultState = ResourceState::Undefined;
bool isShared = false;

Extents size;
Expand Down Expand Up @@ -2122,8 +2154,7 @@ class IDevice : public ISlangUnknown
virtual SLANG_NO_THROW Result SLANG_MCALL
getFeatures(const char** outFeatures, Size bufferSize, GfxCount* outFeatureCount) = 0;

virtual SLANG_NO_THROW Result SLANG_MCALL
getFormatSupportedResourceStates(Format format, ResourceStateSet* outStates) = 0;
virtual SLANG_NO_THROW Result SLANG_MCALL getFormatSupport(Format format, FormatSupport* outFormatSupport) = 0;

virtual SLANG_NO_THROW Result SLANG_MCALL getSlangSession(slang::ISession** outSlangSession) = 0;

Expand Down
2 changes: 1 addition & 1 deletion src/cuda/cuda-device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ DeviceImpl::createTexture(const TextureDesc& desc, const SubresourceData* initDa
// time we create a resource, and then allocate the surface or
// texture objects as part of view creation.
//
if (desc.allowedStates.contains(ResourceState::UnorderedAccess))
if (is_set(desc.usage, TextureUsage::UnorderedAccess))
{
// On CUDA surfaces only support a single MIP map
SLANG_RHI_ASSERT(desc.numMipLevels == 1);
Expand Down
6 changes: 3 additions & 3 deletions src/d3d11/d3d11-device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ Result DeviceImpl::createTexture(const TextureDesc& descIn, const SubresourceDat
return SLANG_FAIL;
}

const int bindFlags = _calcResourceBindFlags(srcDesc.allowedStates);
const int bindFlags = _calcResourceBindFlags(srcDesc.usage);

// Set up the initialize data
std::vector<D3D11_SUBRESOURCE_DATA> subRes;
Expand Down Expand Up @@ -609,7 +609,7 @@ Result DeviceImpl::createBuffer(const BufferDesc& descIn, const void* initData,
{
BufferDesc srcDesc = fixupBufferDesc(descIn);

auto d3dBindFlags = _calcResourceBindFlags(srcDesc.allowedStates);
auto d3dBindFlags = _calcResourceBindFlags(srcDesc.usage);

size_t alignedSizeInBytes = srcDesc.size;

Expand All @@ -636,7 +636,7 @@ Result DeviceImpl::createBuffer(const BufferDesc& descIn, const void* initData,
bufferDesc.Usage = D3D11_USAGE_DEFAULT;

// If written by CPU, make it dynamic
if (descIn.memoryType == MemoryType::Upload && !descIn.allowedStates.contains(ResourceState::UnorderedAccess))
if (descIn.memoryType == MemoryType::Upload && !is_set(descIn.usage, BufferUsage::UnorderedAccess))
{
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
}
Expand Down
60 changes: 26 additions & 34 deletions src/d3d11/d3d11-helper-functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,44 +18,36 @@ bool isSupportedNVAPIOp(IUnknown* dev, uint32_t op)
#endif
}

D3D11_BIND_FLAG calcResourceFlag(ResourceState state)
int _calcResourceBindFlags(BufferUsage usage)
{
switch (state)
{
case ResourceState::VertexBuffer:
return D3D11_BIND_VERTEX_BUFFER;
case ResourceState::IndexBuffer:
return D3D11_BIND_INDEX_BUFFER;
case ResourceState::ConstantBuffer:
return D3D11_BIND_CONSTANT_BUFFER;
case ResourceState::StreamOutput:
return D3D11_BIND_STREAM_OUTPUT;
case ResourceState::RenderTarget:
return D3D11_BIND_RENDER_TARGET;
case ResourceState::DepthRead:
case ResourceState::DepthWrite:
return D3D11_BIND_DEPTH_STENCIL;
case ResourceState::UnorderedAccess:
return D3D11_BIND_UNORDERED_ACCESS;
case ResourceState::ShaderResource:
case ResourceState::PixelShaderResource:
case ResourceState::NonPixelShaderResource:
return D3D11_BIND_SHADER_RESOURCE;
default:
return D3D11_BIND_FLAG(0);
}
int flags = 0;
if (is_set(usage, BufferUsage::VertexBuffer))
flags |= D3D11_BIND_VERTEX_BUFFER;
if (is_set(usage, BufferUsage::IndexBuffer))
flags |= D3D11_BIND_INDEX_BUFFER;
if (is_set(usage, BufferUsage::ConstantBuffer))
flags |= D3D11_BIND_CONSTANT_BUFFER;
if (is_set(usage, BufferUsage::ShaderResource))
flags |= D3D11_BIND_SHADER_RESOURCE;
if (is_set(usage, BufferUsage::UnorderedAccess))
flags |= D3D11_BIND_UNORDERED_ACCESS;
return flags;
}

int _calcResourceBindFlags(ResourceStateSet allowedStates)
int _calcResourceBindFlags(TextureUsage usage)
{
int dstFlags = 0;
for (uint32_t i = 0; i < (uint32_t)ResourceState::_Count; i++)
{
auto state = (ResourceState)i;
if (allowedStates.contains(state))
dstFlags |= calcResourceFlag(state);
}
return dstFlags;
int flags = 0;
if (is_set(usage, TextureUsage::RenderTarget))
flags |= D3D11_BIND_RENDER_TARGET;
if (is_set(usage, TextureUsage::DepthRead))
flags |= D3D11_BIND_DEPTH_STENCIL;
if (is_set(usage, TextureUsage::DepthWrite))
flags |= D3D11_BIND_DEPTH_STENCIL;
if (is_set(usage, TextureUsage::ShaderResource))
flags |= D3D11_BIND_SHADER_RESOURCE;
if (is_set(usage, TextureUsage::UnorderedAccess))
flags |= D3D11_BIND_UNORDERED_ACCESS;
return flags;
}

int _calcResourceAccessFlags(MemoryType memType)
Expand Down
4 changes: 2 additions & 2 deletions src/d3d11/d3d11-helper-functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,8 @@ struct BindingOffset : SimpleBindingOffset

bool isSupportedNVAPIOp(IUnknown* dev, uint32_t op);

D3D11_BIND_FLAG calcResourceFlag(ResourceState state);
int _calcResourceBindFlags(ResourceStateSet allowedStates);
int _calcResourceBindFlags(BufferUsage usage);
int _calcResourceBindFlags(TextureUsage usage);
int _calcResourceAccessFlags(MemoryType memType);

D3D11_FILTER_TYPE translateFilterMode(TextureFilteringMode mode);
Expand Down
2 changes: 1 addition & 1 deletion src/d3d11/d3d11-shader-object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ Result ShaderObjectImpl::_ensureOrdinaryDataBufferCreatedIfNeeded(
ComPtr<IBuffer> buffer;
BufferDesc bufferDesc = {};
bufferDesc.size = specializedOrdinaryDataSize;
bufferDesc.usage = BufferUsage::ConstantBuffer | BufferUsage::CopyDestination;
bufferDesc.defaultState = ResourceState::ConstantBuffer;
bufferDesc.allowedStates = ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination);
bufferDesc.memoryType = MemoryType::Upload;
SLANG_RETURN_ON_FAIL(device->createBuffer(bufferDesc, nullptr, buffer.writeRef()));
m_ordinaryDataBuffer = static_cast<BufferImpl*>(buffer.get());
Expand Down
3 changes: 1 addition & 2 deletions src/d3d11/d3d11-swap-chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@ void SwapchainImpl::createSwapchainBufferImages()
imageDesc.size.height = m_desc.height;
imageDesc.size.depth = 1;
imageDesc.format = m_desc.format;
imageDesc.usage = TextureUsage::Present | TextureUsage::CopyDestination | TextureUsage::RenderTarget;
imageDesc.defaultState = ResourceState::Present;
imageDesc.allowedStates =
ResourceStateSet(ResourceState::Present, ResourceState::CopyDestination, ResourceState::RenderTarget);
RefPtr<TextureImpl> image = new TextureImpl(imageDesc);
image->m_resource = d3dResource;
for (GfxIndex i = 0; i < m_desc.imageCount; i++)
Expand Down
Loading

0 comments on commit 281c483

Please sign in to comment.