diff options
| author | Yong He <yonghe@outlook.com> | 2021-04-24 00:17:43 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-04-24 00:17:43 -0700 |
| commit | 9a5672d7b8a155117a2c3f8375e3b8a5b43d91b7 (patch) | |
| tree | 9be3ea214ea735e41e8fdaef9824e84212a30cbb /tools | |
| parent | 697017e6fae8c252638abc298ec1556de2e41314 (diff) | |
Remove resource `Usage` from `gfx` interface. (#1813)
* Fix `model-viewer` crash when using Vulkan.
Fixing an issue in shader object layout creation for to make sure a correct descriptor set layout is calculated for types that need an implicit constant buffer.
* Fix formatting.
* Fixes.
* Fix memory leak in vulkan.
* Remove resource `Usage` from `gfx` interface.
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/gfx/cpu/render-cpu.cpp | 8 | ||||
| -rw-r--r-- | tools/gfx/cuda/render-cuda.cpp | 294 | ||||
| -rw-r--r-- | tools/gfx/d3d11/render-d3d11.cpp | 118 | ||||
| -rw-r--r-- | tools/gfx/d3d12/render-d3d12.cpp | 137 | ||||
| -rw-r--r-- | tools/gfx/open-gl/render-gl.cpp | 85 | ||||
| -rw-r--r-- | tools/gfx/renderer-shared.h | 2 | ||||
| -rw-r--r-- | tools/gfx/resource-desc-utils.cpp | 20 | ||||
| -rw-r--r-- | tools/gfx/resource-desc-utils.h | 99 | ||||
| -rw-r--r-- | tools/gfx/simple-transient-resource-heap.h | 8 | ||||
| -rw-r--r-- | tools/gfx/transient-resource-heap-base.h | 22 | ||||
| -rw-r--r-- | tools/gfx/vulkan/render-vk.cpp | 209 | ||||
| -rw-r--r-- | tools/gfx/vulkan/vk-util.cpp | 30 | ||||
| -rw-r--r-- | tools/gfx/vulkan/vk-util.h | 2 | ||||
| -rw-r--r-- | tools/platform/gui.cpp | 48 | ||||
| -rw-r--r-- | tools/platform/model.cpp | 40 | ||||
| -rw-r--r-- | tools/render-test/render-test-main.cpp | 58 | ||||
| -rw-r--r-- | tools/render-test/shader-renderer-util.cpp | 66 | ||||
| -rw-r--r-- | tools/render-test/shader-renderer-util.h | 4 |
18 files changed, 703 insertions, 547 deletions
diff --git a/tools/gfx/cpu/render-cpu.cpp b/tools/gfx/cpu/render-cpu.cpp index 8dd1ccae6..af1641e60 100644 --- a/tools/gfx/cpu/render-cpu.cpp +++ b/tools/gfx/cpu/render-cpu.cpp @@ -1196,13 +1196,11 @@ public: } virtual SLANG_NO_THROW Result SLANG_MCALL createTextureResource( - IResource::Usage initialUsage, const ITextureResource::Desc& desc, const ITextureResource::SubresourceData* initData, ITextureResource** outResource) override { - TextureResource::Desc srcDesc(desc); - srcDesc.setDefaults(initialUsage); + TextureResource::Desc srcDesc = fixupTextureDesc(desc); RefPtr<CPUTextureResource> texture = new CPUTextureResource(srcDesc); @@ -1213,11 +1211,11 @@ public: } virtual SLANG_NO_THROW Result SLANG_MCALL createBufferResource( - IResource::Usage initialUsage, - const IBufferResource::Desc& desc, + const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) override { + auto desc = fixupBufferDesc(descIn); RefPtr<CPUBufferResource> resource = new CPUBufferResource(desc); SLANG_RETURN_ON_FAIL(resource->init()); if (initData) diff --git a/tools/gfx/cuda/render-cuda.cpp b/tools/gfx/cuda/render-cuda.cpp index 9d6b08122..14699915b 100644 --- a/tools/gfx/cuda/render-cuda.cpp +++ b/tools/gfx/cuda/render-cuda.cpp @@ -457,11 +457,14 @@ public: virtual SLANG_NO_THROW Result SLANG_MCALL initBuffer(IDevice* device, size_t bufferSize) { BufferResource::Desc bufferDesc; - bufferDesc.init(bufferSize); + bufferDesc.type = IResource::Type::Buffer; + bufferDesc.defaultState = ResourceState::ConstantBuffer; + bufferDesc.allowedStates = + ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination); + bufferDesc.sizeInBytes = bufferSize; bufferDesc.cpuAccessFlags |= IResource::AccessFlag::Write; ComPtr<IBufferResource> constantBuffer; - SLANG_RETURN_ON_FAIL(device->createBufferResource( - IResource::Usage::ConstantBuffer, bufferDesc, nullptr, constantBuffer.writeRef())); + SLANG_RETURN_ON_FAIL(device->createBufferResource(bufferDesc, nullptr, constantBuffer.writeRef())); bufferResource = static_cast<MemoryCUDAResource*>(constantBuffer.get()); return SLANG_OK; } @@ -1379,13 +1382,11 @@ public: } virtual SLANG_NO_THROW Result SLANG_MCALL createTextureResource( - IResource::Usage initialUsage, const ITextureResource::Desc& desc, const ITextureResource::SubresourceData* initData, ITextureResource** outResource) override { - TextureResource::Desc srcDesc(desc); - srcDesc.setDefaults(initialUsage); + TextureResource::Desc srcDesc = fixupTextureDesc(desc); RefPtr<TextureCUDAResource> tex = new TextureCUDAResource(srcDesc); tex->m_cudaContext = m_context; @@ -1568,183 +1569,180 @@ public: } // Work space for holding data for uploading if it needs to be rearranged - List<uint8_t> workspace; - for (int mipLevel = 0; mipLevel < desc.numMipLevels; ++mipLevel) + if (initData) { - int mipWidth = width >> mipLevel; - int mipHeight = height >> mipLevel; - int mipDepth = depth >> mipLevel; - - mipWidth = (mipWidth == 0) ? 1 : mipWidth; - mipHeight = (mipHeight == 0) ? 1 : mipHeight; - mipDepth = (mipDepth == 0) ? 1 : mipDepth; - - // If it's a cubemap then the depth is always 6 - if (desc.type == IResource::Type::TextureCube) + List<uint8_t> workspace; + for (int mipLevel = 0; mipLevel < desc.numMipLevels; ++mipLevel) { - mipDepth = 6; - } + int mipWidth = width >> mipLevel; + int mipHeight = height >> mipLevel; + int mipDepth = depth >> mipLevel; - auto dstArray = tex->m_cudaArray; - if (tex->m_cudaMipMappedArray) - { - // Get the array for the mip level - SLANG_CUDA_RETURN_ON_FAIL( - cuMipmappedArrayGetLevel(&dstArray, tex->m_cudaMipMappedArray, mipLevel)); - } - SLANG_ASSERT(dstArray); + mipWidth = (mipWidth == 0) ? 1 : mipWidth; + mipHeight = (mipHeight == 0) ? 1 : mipHeight; + mipDepth = (mipDepth == 0) ? 1 : mipDepth; - // Check using the desc to see if it's plausible - { - CUDA_ARRAY_DESCRIPTOR arrayDesc; - SLANG_CUDA_RETURN_ON_FAIL(cuArrayGetDescriptor(&arrayDesc, dstArray)); + // If it's a cubemap then the depth is always 6 + if (desc.type == IResource::Type::TextureCube) + { + mipDepth = 6; + } - SLANG_ASSERT(mipWidth == arrayDesc.Width); - SLANG_ASSERT( - mipHeight == arrayDesc.Height || (mipHeight == 1 && arrayDesc.Height == 0)); - } + auto dstArray = tex->m_cudaArray; + if (tex->m_cudaMipMappedArray) + { + // Get the array for the mip level + SLANG_CUDA_RETURN_ON_FAIL( + cuMipmappedArrayGetLevel(&dstArray, tex->m_cudaMipMappedArray, mipLevel)); + } + SLANG_ASSERT(dstArray); - const void* srcDataPtr = nullptr; + // Check using the desc to see if it's plausible + { + CUDA_ARRAY_DESCRIPTOR arrayDesc; + SLANG_CUDA_RETURN_ON_FAIL(cuArrayGetDescriptor(&arrayDesc, dstArray)); - if (desc.arraySize > 1) - { - SLANG_ASSERT( - desc.type == IResource::Type::Texture1D || - desc.type == IResource::Type::Texture2D || - desc.type == IResource::Type::TextureCube); + SLANG_ASSERT(mipWidth == arrayDesc.Width); + SLANG_ASSERT( + mipHeight == arrayDesc.Height || (mipHeight == 1 && arrayDesc.Height == 0)); + } - // TODO(JS): Here I assume that arrays are just held contiguously within a 'face' - // This seems reasonable and works with the Copy3D. - const size_t faceSizeInBytes = elementSize * mipWidth * mipHeight; + const void* srcDataPtr = nullptr; - Index faceCount = desc.arraySize; - if (desc.type == IResource::Type::TextureCube) + if (desc.arraySize > 1) { - faceCount *= 6; - } + SLANG_ASSERT( + desc.type == IResource::Type::Texture1D || + desc.type == IResource::Type::Texture2D || + desc.type == IResource::Type::TextureCube); - const size_t mipSizeInBytes = faceSizeInBytes * faceCount; - workspace.setCount(mipSizeInBytes); + // TODO(JS): Here I assume that arrays are just held contiguously within a + // 'face' This seems reasonable and works with the Copy3D. + const size_t faceSizeInBytes = elementSize * mipWidth * mipHeight; - // We need to add the face data from each mip - // We iterate over face count so we copy all of the cubemap faces - if (initData) - { - for (Index j = 0; j < faceCount; j++) + Index faceCount = desc.arraySize; + if (desc.type == IResource::Type::TextureCube) { - const auto srcData = initData[mipLevel + j * desc.numMipLevels].data; - // Copy over to the workspace to make contiguous - ::memcpy( - workspace.begin() + faceSizeInBytes * j, srcData, - faceSizeInBytes); + faceCount *= 6; } - } - - srcDataPtr = workspace.getBuffer(); - } - else - { - if (desc.type == IResource::Type::TextureCube) - { - size_t faceSizeInBytes = elementSize * mipWidth * mipHeight; - workspace.setCount(faceSizeInBytes * 6); + const size_t mipSizeInBytes = faceSizeInBytes * faceCount; + workspace.setCount(mipSizeInBytes); - // Copy the data over to make contiguous - for (Index j = 0; j < 6; j++) + // We need to add the face data from each mip + // We iterate over face count so we copy all of the cubemap faces + for (Index j = 0; j < faceCount; j++) { - const auto srcData = - initData[mipLevel + j * desc.numMipLevels].data; + const auto srcData = initData[mipLevel + j * desc.numMipLevels].data; + // Copy over to the workspace to make contiguous ::memcpy( - workspace.getBuffer() + faceSizeInBytes * j, srcData, - faceSizeInBytes); + workspace.begin() + faceSizeInBytes * j, srcData, faceSizeInBytes); } srcDataPtr = workspace.getBuffer(); } else { - const auto srcData = initData[mipLevel].data; - srcDataPtr = srcData; + if (desc.type == IResource::Type::TextureCube) + { + size_t faceSizeInBytes = elementSize * mipWidth * mipHeight; + + workspace.setCount(faceSizeInBytes * 6); + // Copy the data over to make contiguous + for (Index j = 0; j < 6; j++) + { + const auto srcData = + initData[mipLevel + j * desc.numMipLevels].data; + ::memcpy( + workspace.getBuffer() + faceSizeInBytes * j, + srcData, + faceSizeInBytes); + } + srcDataPtr = workspace.getBuffer(); + } + else + { + const auto srcData = initData[mipLevel].data; + srcDataPtr = srcData; + } } - } - - if (desc.arraySize > 1) - { - SLANG_ASSERT( - desc.type == IResource::Type::Texture1D || - desc.type == IResource::Type::Texture2D || - desc.type == IResource::Type::TextureCube); - - CUDA_MEMCPY3D copyParam; - memset(©Param, 0, sizeof(copyParam)); - - copyParam.dstMemoryType = CU_MEMORYTYPE_ARRAY; - copyParam.dstArray = dstArray; - - copyParam.srcMemoryType = CU_MEMORYTYPE_HOST; - copyParam.srcHost = srcDataPtr; - copyParam.srcPitch = mipWidth * elementSize; - copyParam.WidthInBytes = copyParam.srcPitch; - copyParam.Height = mipHeight; - // Set the depth to the array length - copyParam.Depth = desc.arraySize; - if (desc.type == IResource::Type::TextureCube) + if (desc.arraySize > 1) { - copyParam.Depth *= 6; - } + SLANG_ASSERT( + desc.type == IResource::Type::Texture1D || + desc.type == IResource::Type::Texture2D || + desc.type == IResource::Type::TextureCube); - SLANG_CUDA_RETURN_ON_FAIL(cuMemcpy3D(©Param)); - } - else - { - switch (desc.type) - { - case IResource::Type::Texture1D: - case IResource::Type::Texture2D: - { - CUDA_MEMCPY2D copyParam; - memset(©Param, 0, sizeof(copyParam)); - copyParam.dstMemoryType = CU_MEMORYTYPE_ARRAY; - copyParam.dstArray = dstArray; - copyParam.srcMemoryType = CU_MEMORYTYPE_HOST; - copyParam.srcHost = srcDataPtr; - copyParam.srcPitch = mipWidth * elementSize; - copyParam.WidthInBytes = copyParam.srcPitch; - copyParam.Height = mipHeight; - SLANG_CUDA_RETURN_ON_FAIL(cuMemcpy2D(©Param)); - break; - } - case IResource::Type::Texture3D: - case IResource::Type::TextureCube: - { - CUDA_MEMCPY3D copyParam; - memset(©Param, 0, sizeof(copyParam)); + CUDA_MEMCPY3D copyParam; + memset(©Param, 0, sizeof(copyParam)); - copyParam.dstMemoryType = CU_MEMORYTYPE_ARRAY; - copyParam.dstArray = dstArray; + copyParam.dstMemoryType = CU_MEMORYTYPE_ARRAY; + copyParam.dstArray = dstArray; - copyParam.srcMemoryType = CU_MEMORYTYPE_HOST; - copyParam.srcHost = srcDataPtr; - copyParam.srcPitch = mipWidth * elementSize; - copyParam.WidthInBytes = copyParam.srcPitch; - copyParam.Height = mipHeight; - copyParam.Depth = mipDepth; + copyParam.srcMemoryType = CU_MEMORYTYPE_HOST; + copyParam.srcHost = srcDataPtr; + copyParam.srcPitch = mipWidth * elementSize; + copyParam.WidthInBytes = copyParam.srcPitch; + copyParam.Height = mipHeight; + // Set the depth to the array length + copyParam.Depth = desc.arraySize; - SLANG_CUDA_RETURN_ON_FAIL(cuMemcpy3D(©Param)); - break; + if (desc.type == IResource::Type::TextureCube) + { + copyParam.Depth *= 6; } - default: + SLANG_CUDA_RETURN_ON_FAIL(cuMemcpy3D(©Param)); + } + else + { + switch (desc.type) { - SLANG_ASSERT(!"Not implemented"); - break; + case IResource::Type::Texture1D: + case IResource::Type::Texture2D: + { + CUDA_MEMCPY2D copyParam; + memset(©Param, 0, sizeof(copyParam)); + copyParam.dstMemoryType = CU_MEMORYTYPE_ARRAY; + copyParam.dstArray = dstArray; + copyParam.srcMemoryType = CU_MEMORYTYPE_HOST; + copyParam.srcHost = srcDataPtr; + copyParam.srcPitch = mipWidth * elementSize; + copyParam.WidthInBytes = copyParam.srcPitch; + copyParam.Height = mipHeight; + SLANG_CUDA_RETURN_ON_FAIL(cuMemcpy2D(©Param)); + break; + } + case IResource::Type::Texture3D: + case IResource::Type::TextureCube: + { + CUDA_MEMCPY3D copyParam; + memset(©Param, 0, sizeof(copyParam)); + + copyParam.dstMemoryType = CU_MEMORYTYPE_ARRAY; + copyParam.dstArray = dstArray; + + copyParam.srcMemoryType = CU_MEMORYTYPE_HOST; + copyParam.srcHost = srcDataPtr; + copyParam.srcPitch = mipWidth * elementSize; + copyParam.WidthInBytes = copyParam.srcPitch; + copyParam.Height = mipHeight; + copyParam.Depth = mipDepth; + + SLANG_CUDA_RETURN_ON_FAIL(cuMemcpy3D(©Param)); + break; + } + + default: + { + SLANG_ASSERT(!"Not implemented"); + break; + } } } } } - // Set up texture sampling parameters, and create final texture obj { @@ -1772,7 +1770,7 @@ public: // time we create a resource, and then allocate the surface or // texture objects as part of view creation. // - if( desc.bindFlags & IResource::BindFlag::UnorderedAccess ) + if (desc.allowedStates.contains(ResourceState::UnorderedAccess)) { SLANG_CUDA_RETURN_ON_FAIL(cuSurfObjectCreate(&tex->m_cudaSurfObj, &resDesc)); } @@ -1796,11 +1794,11 @@ public: } virtual SLANG_NO_THROW Result SLANG_MCALL createBufferResource( - IResource::Usage initialUsage, - const IBufferResource::Desc& desc, + const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) override { + auto desc = fixupBufferDesc(descIn); RefPtr<MemoryCUDAResource> resource = new MemoryCUDAResource(desc); resource->m_cudaContext = m_context; SLANG_CUDA_RETURN_ON_FAIL(cudaMallocManaged(&resource->m_cudaMemory, desc.sizeInBytes)); diff --git a/tools/gfx/d3d11/render-d3d11.cpp b/tools/gfx/d3d11/render-d3d11.cpp index a011f2760..bbc213bb6 100644 --- a/tools/gfx/d3d11/render-d3d11.cpp +++ b/tools/gfx/d3d11/render-d3d11.cpp @@ -75,12 +75,10 @@ public: virtual void setStencilReference(uint32_t referenceValue) override; virtual SLANG_NO_THROW Result SLANG_MCALL createTextureResource( - IResource::Usage initialUsage, const ITextureResource::Desc& desc, const ITextureResource::SubresourceData* initData, ITextureResource** outResource) override; virtual SLANG_NO_THROW Result SLANG_MCALL createBufferResource( - IResource::Usage initialUsage, const IBufferResource::Desc& desc, const void* initData, IBufferResource** outResource) override; @@ -177,14 +175,12 @@ protected: public: typedef BufferResource Parent; - BufferResourceImpl(const IBufferResource::Desc& desc, IResource::Usage initialUsage): - Parent(desc), - m_initialUsage(initialUsage) + BufferResourceImpl(const IBufferResource::Desc& desc): + Parent(desc) { } MapFlavor m_mapFlavor; - Usage m_initialUsage; ComPtr<ID3D11Buffer> m_buffer; ComPtr<ID3D11Buffer> m_staging; }; @@ -193,12 +189,10 @@ protected: public: typedef TextureResource Parent; - TextureResourceImpl(const Desc& desc, Usage initialUsage) : - Parent(desc), - m_initialUsage(initialUsage) + TextureResourceImpl(const Desc& desc) + : Parent(desc) { } - Usage m_initialUsage; ComPtr<ID3D11Resource> m_resource; }; @@ -314,10 +308,19 @@ protected: ComPtr<ID3D11Resource> d3dResource; m_swapChain->GetBuffer(0, IID_PPV_ARGS(d3dResource.writeRef())); ITextureResource::Desc imageDesc = {}; - imageDesc.init2D( - IResource::Type::Texture2D, m_desc.format, m_desc.width, m_desc.height, 0); - RefPtr<TextureResourceImpl> image = - new TextureResourceImpl(imageDesc, IResource::Usage::RenderTarget); + imageDesc.type = IResource::Type::Texture2D; + imageDesc.arraySize = 0; + imageDesc.numMipLevels = 1; + imageDesc.size.width = m_desc.width; + imageDesc.size.height = m_desc.height; + imageDesc.size.depth = 1; + imageDesc.format = m_desc.format; + imageDesc.defaultState = ResourceState::Present; + imageDesc.allowedStates = ResourceStateSet( + ResourceState::Present, + ResourceState::CopyDestination, + ResourceState::RenderTarget); + RefPtr<TextureResourceImpl> image = new TextureResourceImpl(imageDesc); image->m_resource = d3dResource; for (uint32_t i = 0; i < m_desc.imageCount; i++) { @@ -1199,11 +1202,15 @@ protected: // ComPtr<IBufferResource> bufferResourcePtr; - IBufferResource::Desc bufferDesc; - bufferDesc.init(specializedOrdinaryDataSize); + IBufferResource::Desc bufferDesc = {}; + bufferDesc.type = IResource::Type::Buffer; + bufferDesc.sizeInBytes = specializedOrdinaryDataSize; + bufferDesc.defaultState = ResourceState::ConstantBuffer; + bufferDesc.allowedStates = + ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination); bufferDesc.cpuAccessFlags |= IResource::AccessFlag::Write; - SLANG_RETURN_ON_FAIL(device->createBufferResource( - IResource::Usage::ConstantBuffer, bufferDesc, nullptr, bufferResourcePtr.writeRef())); + SLANG_RETURN_ON_FAIL( + device->createBufferResource(bufferDesc, nullptr, bufferResourcePtr.writeRef())); m_ordinaryDataBuffer = static_cast<BufferResourceImpl*>(bufferResourcePtr.get()); // Once the buffer is allocated, we can use `_writeOrdinaryData` to fill it in. @@ -1896,33 +1903,40 @@ SlangResult D3D11Device::readTextureResource( } } -static D3D11_BIND_FLAG _calcResourceFlag(IResource::BindFlag::Enum bindFlag) +static D3D11_BIND_FLAG _calcResourceFlag(ResourceState state) { - typedef IResource::BindFlag BindFlag; - switch (bindFlag) - { - case BindFlag::VertexBuffer: return D3D11_BIND_VERTEX_BUFFER; - case BindFlag::IndexBuffer: return D3D11_BIND_INDEX_BUFFER; - case BindFlag::ConstantBuffer: return D3D11_BIND_CONSTANT_BUFFER; - case BindFlag::StreamOutput: return D3D11_BIND_STREAM_OUTPUT; - case BindFlag::RenderTarget: return D3D11_BIND_RENDER_TARGET; - case BindFlag::DepthStencil: return D3D11_BIND_DEPTH_STENCIL; - case BindFlag::UnorderedAccess: return D3D11_BIND_UNORDERED_ACCESS; - case BindFlag::PixelShaderResource: return D3D11_BIND_SHADER_RESOURCE; - case BindFlag::NonPixelShaderResource: return D3D11_BIND_SHADER_RESOURCE; - default: return D3D11_BIND_FLAG(0); + 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: + return D3D11_BIND_SHADER_RESOURCE; + default: + return D3D11_BIND_FLAG(0); } } -static int _calcResourceBindFlags(int bindFlags) +static int _calcResourceBindFlags(ResourceStateSet allowedStates) { int dstFlags = 0; - while (bindFlags) + for (uint32_t i = 0; i < (uint32_t)ResourceState::_Count; i++) { - int lsb = bindFlags & -bindFlags; - - dstFlags |= _calcResourceFlag(IResource::BindFlag::Enum(lsb)); - bindFlags &= ~lsb; + auto state = (ResourceState)i; + if (allowedStates.contains(state)) + dstFlags |= _calcResourceFlag(state); } return dstFlags; } @@ -1940,12 +1954,11 @@ static int _calcResourceAccessFlags(int accessFlags) } } -Result D3D11Device::createTextureResource(IResource::Usage initialUsage, const ITextureResource::Desc& descIn, const ITextureResource::SubresourceData* initData, ITextureResource** outResource) +Result D3D11Device::createTextureResource(const ITextureResource::Desc& descIn, const ITextureResource::SubresourceData* initData, ITextureResource** outResource) { - TextureResource::Desc srcDesc(descIn); - srcDesc.setDefaults(initialUsage); + TextureResource::Desc srcDesc = fixupTextureDesc(descIn); - const int effectiveArraySize = srcDesc.calcEffectiveArraySize(); + const int effectiveArraySize = calcEffectiveArraySize(srcDesc); const DXGI_FORMAT format = D3DUtil::getMapFormat(srcDesc.format); if (format == DXGI_FORMAT_UNKNOWN) @@ -1953,7 +1966,7 @@ Result D3D11Device::createTextureResource(IResource::Usage initialUsage, const I return SLANG_FAIL; } - const int bindFlags = _calcResourceBindFlags(srcDesc.bindFlags); + const int bindFlags = _calcResourceBindFlags(srcDesc.allowedStates); // Set up the initialize data List<D3D11_SUBRESOURCE_DATA> subRes; @@ -1967,7 +1980,7 @@ Result D3D11Device::createTextureResource(IResource::Usage initialUsage, const I { for (int j = 0; j < srcDesc.numMipLevels; j++) { - const int mipHeight = ITextureResource::Size::calcMipSize(srcDesc.size.height, j); + const int mipHeight = calcMipSize(srcDesc.size.height, j); D3D11_SUBRESOURCE_DATA& data = subRes[subResourceIndex]; auto& srcData = initData[subResourceIndex]; @@ -1985,7 +1998,7 @@ Result D3D11Device::createTextureResource(IResource::Usage initialUsage, const I const int accessFlags = _calcResourceAccessFlags(srcDesc.cpuAccessFlags); - RefPtr<TextureResourceImpl> texture(new TextureResourceImpl(srcDesc, initialUsage)); + RefPtr<TextureResourceImpl> texture(new TextureResourceImpl(srcDesc)); switch (srcDesc.type) { @@ -2062,12 +2075,11 @@ Result D3D11Device::createTextureResource(IResource::Usage initialUsage, const I return SLANG_OK; } -Result D3D11Device::createBufferResource(IResource::Usage initialUsage, const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) +Result D3D11Device::createBufferResource(const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) { - IBufferResource::Desc srcDesc(descIn); - srcDesc.setDefaults(initialUsage); + IBufferResource::Desc srcDesc = fixupBufferDesc(descIn); - auto d3dBindFlags = _calcResourceBindFlags(srcDesc.bindFlags); + auto d3dBindFlags = _calcResourceBindFlags(srcDesc.allowedStates); size_t alignedSizeInBytes = srcDesc.sizeInBytes; @@ -2096,14 +2108,14 @@ Result D3D11Device::createBufferResource(IResource::Usage initialUsage, const IB // If written by CPU, make it dynamic if ((descIn.cpuAccessFlags & IResource::AccessFlag::Write) && - ((descIn.bindFlags & IResource::BindFlag::UnorderedAccess) == 0)) + !descIn.allowedStates.contains(ResourceState::UnorderedAccess)) { bufferDesc.Usage = D3D11_USAGE_DYNAMIC; } - switch (initialUsage) + switch (descIn.defaultState) { - case IResource::Usage::ConstantBuffer: + case ResourceState::ConstantBuffer: { // We'll just assume ConstantBuffers are dynamic for now bufferDesc.Usage = D3D11_USAGE_DYNAMIC; @@ -2134,7 +2146,7 @@ Result D3D11Device::createBufferResource(IResource::Usage initialUsage, const IB D3D11_SUBRESOURCE_DATA subResourceData = { 0 }; subResourceData.pSysMem = initData; - RefPtr<BufferResourceImpl> buffer(new BufferResourceImpl(srcDesc, initialUsage)); + RefPtr<BufferResourceImpl> buffer(new BufferResourceImpl(srcDesc)); SLANG_RETURN_ON_FAIL(m_device->CreateBuffer(&bufferDesc, initData ? &subResourceData : nullptr, buffer->m_buffer.writeRef())); diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp index fd1121d1b..a752222d6 100644 --- a/tools/gfx/d3d12/render-d3d12.cpp +++ b/tools/gfx/d3d12/render-d3d12.cpp @@ -63,8 +63,6 @@ struct ID3D12GraphicsCommandList1 {}; namespace gfx { using namespace Slang; -static D3D12_RESOURCE_STATES _calcResourceState(IResource::Usage usage); - class D3D12Device : public RendererBase { public: @@ -81,12 +79,10 @@ public: ISwapchain** outSwapchain) override; virtual SLANG_NO_THROW Result SLANG_MCALL createTextureResource( - IResource::Usage initialUsage, const ITextureResource::Desc& desc, const ITextureResource::SubresourceData* initData, ITextureResource** outResource) override; virtual SLANG_NO_THROW Result SLANG_MCALL createBufferResource( - IResource::Usage initialUsage, const IBufferResource::Desc& desc, const void* initData, IBufferResource** outResource) override; @@ -189,16 +185,15 @@ public: public: typedef BufferResource Parent; - BufferResourceImpl(IResource::Usage initialUsage, const Desc& desc): - Parent(desc), m_initialUsage(initialUsage) - , m_defaultState(_calcResourceState(initialUsage)) + BufferResourceImpl(const Desc& desc) + : Parent(desc) + , m_defaultState(D3DUtil::translateResourceState(desc.defaultState)) { } D3D12Resource m_resource; ///< The resource typically in gpu memory D3D12Resource m_uploadResource; ///< If the resource can be written to, and is in gpu memory (ie not Memory backed), will have upload resource - Usage m_initialUsage; D3D12_RESOURCE_STATES m_defaultState; }; @@ -207,10 +202,10 @@ public: public: typedef TextureResource Parent; - TextureResourceImpl(const Desc& desc): - Parent(desc) + TextureResourceImpl(const Desc& desc) + : Parent(desc) + , m_defaultState(D3DUtil::translateResourceState(desc.defaultState)) { - m_defaultState = _calcResourceState(desc.initialUsage); } D3D12Resource m_resource; @@ -528,10 +523,13 @@ public: { ComPtr<IBufferResource> bufferResourcePtr; IBufferResource::Desc bufferDesc; - bufferDesc.init(desc.constantBufferSize); + bufferDesc.type = IResource::Type::Buffer; + bufferDesc.defaultState = ResourceState::ConstantBuffer; + bufferDesc.allowedStates = + ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination); + bufferDesc.sizeInBytes = desc.constantBufferSize; bufferDesc.cpuAccessFlags |= IResource::AccessFlag::Write; SLANG_RETURN_ON_FAIL(device->createBufferResource( - IResource::Usage::ConstantBuffer, bufferDesc, nullptr, bufferResourcePtr.writeRef())); @@ -2796,10 +2794,6 @@ public: for (UInt i = 0; i < slotCount; i++) { BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(buffers[i]); - if (buffer) - { - assert(buffer->m_initialUsage == IResource::Usage::VertexBuffer); - } BoundVertexBuffer& boundBuffer = m_boundVertexBuffers[startSlot + i]; boundBuffer.m_buffer = buffer; @@ -3210,9 +3204,18 @@ public: ComPtr<ID3D12Resource> d3dResource; m_swapChain->GetBuffer(i, IID_PPV_ARGS(d3dResource.writeRef())); ITextureResource::Desc imageDesc = {}; - imageDesc.setDefaults(IResource::Usage::RenderTarget); - imageDesc.init2D( - IResource::Type::Texture2D, m_desc.format, m_desc.width, m_desc.height, 0); + imageDesc.allowedStates = ResourceStateSet( + ResourceState::Present, + ResourceState::RenderTarget, + ResourceState::CopyDestination); + imageDesc.type = IResource::Type::Texture2D; + imageDesc.arraySize = 0; + imageDesc.format = m_desc.format; + imageDesc.size.width = m_desc.width; + imageDesc.size.height = m_desc.height; + imageDesc.size.depth = 1; + imageDesc.numMipLevels = 1; + imageDesc.defaultState = ResourceState::Present; RefPtr<TextureResourceImpl> image = new TextureResourceImpl(imageDesc); image->m_resource.setResource(d3dResource.get()); image->m_defaultState = D3D12_RESOURCE_STATE_PRESENT; @@ -4033,53 +4036,32 @@ SlangResult D3D12Device::readTextureResource( outPixelSize); } -static D3D12_RESOURCE_STATES _calcResourceState(IResource::Usage usage) +static D3D12_RESOURCE_FLAGS _calcResourceFlag(ResourceState state) { - typedef IResource::Usage Usage; - switch (usage) + switch (state) { - case Usage::VertexBuffer: return D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER; - case Usage::IndexBuffer: return D3D12_RESOURCE_STATE_INDEX_BUFFER; - case Usage::ConstantBuffer: return D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER; - case Usage::StreamOutput: return D3D12_RESOURCE_STATE_STREAM_OUT; - case Usage::RenderTarget: return D3D12_RESOURCE_STATE_RENDER_TARGET; - case Usage::DepthWrite: return D3D12_RESOURCE_STATE_DEPTH_WRITE; - case Usage::DepthRead: return D3D12_RESOURCE_STATE_DEPTH_READ; - case Usage::UnorderedAccess: return D3D12_RESOURCE_STATE_UNORDERED_ACCESS; - case Usage::PixelShaderResource: return D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; - case Usage::NonPixelShaderResource: return D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; - case Usage::ShaderResource: return D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | - D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; - case Usage::GenericRead: return D3D12_RESOURCE_STATE_GENERIC_READ; - case Usage::CopySource: return D3D12_RESOURCE_STATE_COPY_SOURCE; - case Usage::CopyDest: return D3D12_RESOURCE_STATE_COPY_DEST; - default: return D3D12_RESOURCE_STATES(0); - } -} - -static D3D12_RESOURCE_FLAGS _calcResourceFlag(IResource::BindFlag::Enum bindFlag) -{ - typedef IResource::BindFlag BindFlag; - switch (bindFlag) - { - case BindFlag::RenderTarget: return D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; - case BindFlag::DepthStencil: return D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; - case BindFlag::UnorderedAccess: return D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; - default: return D3D12_RESOURCE_FLAG_NONE; + case ResourceState::RenderTarget: + return D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + case ResourceState::DepthRead: + case ResourceState::DepthWrite: + return D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; + case ResourceState::UnorderedAccess: + return D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + default: + return D3D12_RESOURCE_FLAG_NONE; } } -static D3D12_RESOURCE_FLAGS _calcResourceBindFlags(IResource::Usage initialUsage, int bindFlags) +static D3D12_RESOURCE_FLAGS _calcResourceFlags(ResourceStateSet states) { int dstFlags = 0; - while (bindFlags) + for (uint32_t i = 0; i < (uint32_t)ResourceState::_Count; i++) { - int lsb = bindFlags & -bindFlags; - - dstFlags |= _calcResourceFlag(IResource::BindFlag::Enum(lsb)); - bindFlags &= ~lsb; + auto state = (ResourceState)i; + if (states.contains(state)) + dstFlags |= _calcResourceFlag(state); } - return D3D12_RESOURCE_FLAGS(dstFlags); + return (D3D12_RESOURCE_FLAGS)dstFlags; } static D3D12_RESOURCE_DIMENSION _calcResourceDimension(IResource::Type type) @@ -4098,13 +4080,12 @@ static D3D12_RESOURCE_DIMENSION _calcResourceDimension(IResource::Type type) } } -Result D3D12Device::createTextureResource(IResource::Usage initialUsage, const ITextureResource::Desc& descIn, const ITextureResource::SubresourceData* initData, ITextureResource** outResource) +Result D3D12Device::createTextureResource(const ITextureResource::Desc& descIn, const ITextureResource::SubresourceData* initData, ITextureResource** outResource) { // Description of uploading on Dx12 // https://msdn.microsoft.com/en-us/library/windows/desktop/dn899215%28v=vs.85%29.aspx - TextureResource::Desc srcDesc(descIn); - srcDesc.setDefaults(initialUsage); + TextureResource::Desc srcDesc = fixupTextureDesc(descIn); const DXGI_FORMAT pixelFormat = D3DUtil::getMapFormat(srcDesc.format); if (pixelFormat == DXGI_FORMAT_UNKNOWN) @@ -4112,7 +4093,7 @@ Result D3D12Device::createTextureResource(IResource::Usage initialUsage, const I return SLANG_FAIL; } - const int arraySize = srcDesc.calcEffectiveArraySize(); + const int arraySize = calcEffectiveArraySize(srcDesc); const D3D12_RESOURCE_DIMENSION dimension = _calcResourceDimension(srcDesc.type); if (dimension == D3D12_RESOURCE_DIMENSION_UNKNOWN) @@ -4138,20 +4119,7 @@ Result D3D12Device::createTextureResource(IResource::Usage initialUsage, const I resourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE; resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - switch (initialUsage) - { - case IResource::Usage::RenderTarget: - resourceDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; - break; - case IResource::Usage::DepthWrite: - resourceDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; - break; - case IResource::Usage::UnorderedAccess: - resourceDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; - break; - default: - break; - } + resourceDesc.Flags |= _calcResourceFlags(srcDesc.allowedStates); resourceDesc.Alignment = 0; @@ -4251,7 +4219,7 @@ Result D3D12Device::createTextureResource(IResource::Usage initialUsage, const I const D3D12_PLACED_SUBRESOURCE_FOOTPRINT& layout = layouts[j]; const D3D12_SUBRESOURCE_FOOTPRINT& footprint = layout.Footprint; - const TextureResource::Size mipSize = srcDesc.size.calcMipSize(j); + const TextureResource::Size mipSize = calcMipSize(srcDesc.size, j); assert(footprint.Width == mipSize.width && footprint.Height == mipSize.height && footprint.Depth == mipSize.depth); @@ -4314,10 +4282,10 @@ Result D3D12Device::createTextureResource(IResource::Usage initialUsage, const I } { auto encodeInfo = encodeResourceCommands(); - const D3D12_RESOURCE_STATES finalState = _calcResourceState(initialUsage); { D3D12BarrierSubmitter submitter(encodeInfo.d3dCommandList); - texture->m_resource.transition(D3D12_RESOURCE_STATE_COPY_DEST, finalState, submitter); + texture->m_resource.transition( + D3D12_RESOURCE_STATE_COPY_DEST, texture->m_defaultState, submitter); } submitResourceCommandsAndWait(encodeInfo); } @@ -4326,10 +4294,9 @@ Result D3D12Device::createTextureResource(IResource::Usage initialUsage, const I return SLANG_OK; } -Result D3D12Device::createBufferResource(IResource::Usage initialUsage, const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) +Result D3D12Device::createBufferResource(const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) { - BufferResource::Desc srcDesc(descIn); - srcDesc.setDefaults(initialUsage); + BufferResource::Desc srcDesc = fixupBufferDesc(descIn); // Always align up to 256 bytes, since that is required for constant buffers. // @@ -4337,14 +4304,14 @@ Result D3D12Device::createBufferResource(IResource::Usage initialUsage, const IB // const size_t alignedSizeInBytes = D3DUtil::calcAligned(srcDesc.sizeInBytes, 256); - RefPtr<BufferResourceImpl> buffer(new BufferResourceImpl(initialUsage, srcDesc)); + RefPtr<BufferResourceImpl> buffer(new BufferResourceImpl(srcDesc)); D3D12_RESOURCE_DESC bufferDesc; _initBufferResourceDesc(alignedSizeInBytes, bufferDesc); - bufferDesc.Flags = _calcResourceBindFlags(initialUsage, srcDesc.bindFlags); + bufferDesc.Flags |= _calcResourceFlags(srcDesc.allowedStates); - const D3D12_RESOURCE_STATES initialState = _calcResourceState(initialUsage); + const D3D12_RESOURCE_STATES initialState = buffer->m_defaultState; SLANG_RETURN_ON_FAIL(createBuffer(bufferDesc, initData, srcDesc.sizeInBytes, buffer->m_uploadResource, initialState, buffer->m_resource)); returnComPtr(outResource, buffer); diff --git a/tools/gfx/open-gl/render-gl.cpp b/tools/gfx/open-gl/render-gl.cpp index fb8502485..d5735add5 100644 --- a/tools/gfx/open-gl/render-gl.cpp +++ b/tools/gfx/open-gl/render-gl.cpp @@ -108,12 +108,10 @@ public: virtual void setStencilReference(uint32_t referenceValue) override; virtual SLANG_NO_THROW Result SLANG_MCALL createTextureResource( - IResource::Usage initialUsage, const ITextureResource::Desc& desc, const ITextureResource::SubresourceData* initData, ITextureResource** outResource) override; virtual SLANG_NO_THROW Result SLANG_MCALL createBufferResource( - IResource::Usage initialUsage, const IBufferResource::Desc& desc, const void* initData, IBufferResource** outResource) override; @@ -213,11 +211,10 @@ public: public: typedef BufferResource Parent; - BufferResourceImpl(Usage initialUsage, const Desc& desc, WeakSink<GLDevice>* renderer, GLuint id, GLenum target): + BufferResourceImpl(const Desc& desc, WeakSink<GLDevice>* renderer, GLuint id, GLenum target): Parent(desc), m_renderer(renderer), m_handle(id), - m_initialUsage(initialUsage), m_target(target), m_size(desc.sizeInBytes) {} @@ -229,7 +226,6 @@ public: } } - Usage m_initialUsage; RefPtr<WeakSink<GLDevice>> m_renderer; GLuint m_handle; GLenum m_target; @@ -241,9 +237,8 @@ public: public: typedef TextureResource Parent; - TextureResourceImpl(Usage initialUsage, const Desc& desc, WeakSink<GLDevice>* renderer): + TextureResourceImpl(const Desc& desc, WeakSink<GLDevice>* renderer): Parent(desc), - m_initialUsage(initialUsage), m_renderer(renderer) { m_target = 0; @@ -258,7 +253,6 @@ public: } } - Usage m_initialUsage; RefPtr<WeakSink<GLDevice>> m_renderer; GLenum m_target; GLuint m_handle; @@ -471,15 +465,21 @@ public: m_images.clear(); for (uint32_t i = 0; i < m_desc.imageCount; i++) { - ITextureResource::Desc texDesc = {}; - texDesc.init2D( - IResource::Type::Texture2D, - gfx::Format::RGBA_Unorm_UInt8, - m_desc.width, - m_desc.height, - 1); - RefPtr<TextureResourceImpl> tex = new TextureResourceImpl( - IResource::Usage::RenderTarget, texDesc, m_renderer); + ITextureResource::Desc imageDesc = {}; + imageDesc.allowedStates = ResourceStateSet( + ResourceState::Present, + ResourceState::RenderTarget, + ResourceState::CopyDestination); + imageDesc.type = IResource::Type::Texture2D; + imageDesc.arraySize = 0; + imageDesc.format = m_desc.format; + imageDesc.size.width = m_desc.width; + imageDesc.size.height = m_desc.height; + imageDesc.size.depth = 1; + imageDesc.numMipLevels = 1; + imageDesc.defaultState = ResourceState::Present; + RefPtr<TextureResourceImpl> tex = + new TextureResourceImpl(imageDesc, m_renderer); tex->m_handle = m_backBuffer; m_images.add(tex); } @@ -1414,10 +1414,14 @@ public: ComPtr<IBufferResource> bufferResourcePtr; IBufferResource::Desc bufferDesc; - bufferDesc.init(specializedOrdinaryDataSize); + bufferDesc.type = IResource::Type::Buffer; + bufferDesc.sizeInBytes = specializedOrdinaryDataSize; + bufferDesc.defaultState = ResourceState::ConstantBuffer; + bufferDesc.allowedStates = + ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination); bufferDesc.cpuAccessFlags |= IResource::AccessFlag::Write; - SLANG_RETURN_ON_FAIL(device->createBufferResource( - IResource::Usage::ConstantBuffer, bufferDesc, nullptr, bufferResourcePtr.writeRef())); + SLANG_RETURN_ON_FAIL( + device->createBufferResource(bufferDesc, nullptr, bufferResourcePtr.writeRef())); m_ordinaryDataBuffer = static_cast<BufferResourceImpl*>(bufferResourcePtr.get()); // Once the buffer is allocated, we can use `_writeOrdinaryData` to fill it in. @@ -2373,13 +2377,11 @@ SLANG_NO_THROW Result SLANG_MCALL GLDevice::readTextureResource( } SLANG_NO_THROW Result SLANG_MCALL GLDevice::createTextureResource( - IResource::Usage initialUsage, const ITextureResource::Desc& descIn, const ITextureResource::SubresourceData* initData, ITextureResource** outResource) { - TextureResource::Desc srcDesc(descIn); - srcDesc.setDefaults(initialUsage); + TextureResource::Desc srcDesc = fixupTextureDesc(descIn); GlPixelFormat pixelFormat = _getGlPixelFormat(srcDesc.format); if (pixelFormat == GlPixelFormat::Unknown) @@ -2393,13 +2395,13 @@ SLANG_NO_THROW Result SLANG_MCALL GLDevice::createTextureResource( const GLenum format = info.format; const GLenum formatType = info.formatType; - RefPtr<TextureResourceImpl> texture(new TextureResourceImpl(initialUsage, srcDesc, m_weakRenderer)); + RefPtr<TextureResourceImpl> texture(new TextureResourceImpl(srcDesc, m_weakRenderer)); GLenum target = 0; GLuint handle = 0; glGenTextures(1, &handle); - const int effectiveArraySize = srcDesc.calcEffectiveArraySize(); + const int effectiveArraySize = calcEffectiveArraySize(srcDesc); // Set on texture so will be freed if failure texture->m_handle = handle; @@ -2575,38 +2577,37 @@ SLANG_NO_THROW Result SLANG_MCALL GLDevice::createTextureResource( return SLANG_OK; } -static GLenum _calcUsage(IResource::Usage usage) +static GLenum _calcUsage(ResourceState state) { - typedef IResource::Usage Usage; - switch (usage) + switch (state) { - case Usage::ConstantBuffer: return GL_DYNAMIC_DRAW; - default: return GL_STATIC_READ; + case ResourceState::ConstantBuffer: + return GL_DYNAMIC_DRAW; + default: + return GL_STATIC_READ; } } -static GLenum _calcTarget(IResource::Usage usage) +static GLenum _calcTarget(ResourceState state) { - typedef IResource::Usage Usage; - switch (usage) + switch (state) { - case Usage::ConstantBuffer: return GL_UNIFORM_BUFFER; - default: return GL_SHADER_STORAGE_BUFFER; + case ResourceState::ConstantBuffer: + return GL_UNIFORM_BUFFER; + default: + return GL_SHADER_STORAGE_BUFFER; } } SLANG_NO_THROW Result SLANG_MCALL GLDevice::createBufferResource( - IResource::Usage initialUsage, const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) { - BufferResource::Desc desc(descIn); - desc.setDefaults(initialUsage); + BufferResource::Desc desc = fixupBufferDesc(descIn); - const GLenum target = _calcTarget(initialUsage); - // TODO: should derive from desc... - const GLenum usage = _calcUsage(initialUsage); + const GLenum target = _calcTarget(desc.defaultState); + const GLenum usage = _calcUsage(desc.defaultState); GLuint bufferID = 0; glGenBuffers(1, &bufferID); @@ -2614,7 +2615,7 @@ SLANG_NO_THROW Result SLANG_MCALL GLDevice::createBufferResource( glBufferData(target, descIn.sizeInBytes, initData, usage); - RefPtr<BufferResourceImpl> resourceImpl = new BufferResourceImpl(initialUsage, desc, m_weakRenderer, bufferID, target); + RefPtr<BufferResourceImpl> resourceImpl = new BufferResourceImpl(desc, m_weakRenderer, bufferID, target); returnComPtr(outResource, resourceImpl); return SLANG_OK; } diff --git a/tools/gfx/renderer-shared.h b/tools/gfx/renderer-shared.h index b19e0539b..ed045c617 100644 --- a/tools/gfx/renderer-shared.h +++ b/tools/gfx/renderer-shared.h @@ -5,6 +5,8 @@ #include "core/slang-basic.h" #include "core/slang-com-object.h" +#include "resource-desc-utils.h" + namespace gfx { diff --git a/tools/gfx/resource-desc-utils.cpp b/tools/gfx/resource-desc-utils.cpp new file mode 100644 index 000000000..93609cd0e --- /dev/null +++ b/tools/gfx/resource-desc-utils.cpp @@ -0,0 +1,20 @@ +#include "resource-desc-utils.h" + +namespace gfx +{ +IBufferResource::Desc fixupBufferDesc(const IBufferResource::Desc& desc) +{ + IBufferResource::Desc result = desc; + result.allowedStates.add(result.defaultState); + return result; +} + +ITextureResource::Desc fixupTextureDesc(const ITextureResource::Desc& desc) +{ + ITextureResource::Desc rs = desc; + if (desc.numMipLevels == 0) + rs.numMipLevels = calcNumMipLevels(desc.type, desc.size); + rs.allowedStates.add(rs.defaultState); + return rs; +} +} diff --git a/tools/gfx/resource-desc-utils.h b/tools/gfx/resource-desc-utils.h new file mode 100644 index 000000000..11150ce2a --- /dev/null +++ b/tools/gfx/resource-desc-utils.h @@ -0,0 +1,99 @@ +#pragma once + +#include "slang-gfx.h" +#include "core/slang-math.h" + +namespace gfx +{ + +inline int calcMipSize(int size, int level) +{ + size = size >> level; + return size > 0 ? size : 1; +} + +inline ITextureResource::Size calcMipSize(ITextureResource::Size size, int mipLevel) +{ + ITextureResource::Size rs; + rs.width = calcMipSize(size.width, mipLevel); + rs.height = calcMipSize(size.height, mipLevel); + rs.depth = calcMipSize(size.depth, mipLevel); + return rs; +} + +/// Calculate the effective array size - in essence the amount if mip map sets needed. +/// In practice takes into account if the arraySize is 0 (it's not an array, but it will still have +/// at least one mip set) and if the type is a cubemap (multiplies the amount of mip sets by 6) +inline int calcEffectiveArraySize(const ITextureResource::Desc& desc) +{ + const int arrSize = (desc.arraySize > 0) ? desc.arraySize : 1; + + switch (desc.type) + { + case IResource::Type::Texture1D: // fallthru + case IResource::Type::Texture2D: + { + return arrSize; + } + case IResource::Type::TextureCube: + return arrSize * 6; + case IResource::Type::Texture3D: + return 1; + default: + return 0; + } +} + +/// Given the type works out the maximum dimension size +inline int calcMaxDimension(ITextureResource::Size size, IResource::Type type) +{ + switch (type) + { + case IResource::Type::Texture1D: + return size.width; + case IResource::Type::Texture3D: + return Slang::Math::Max(Slang::Math::Max(size.width, size.height), size.depth); + case IResource::Type::TextureCube: // fallthru + case IResource::Type::Texture2D: + { + return Slang::Math::Max(size.width, size.height); + } + default: + return 0; + } +} + +/// Given the type, calculates the number of mip maps. 0 on error +inline int calcNumMipLevels(IResource::Type type, ITextureResource::Size size) +{ + const int maxDimensionSize = calcMaxDimension(size, type); + return (maxDimensionSize > 0) ? (Slang::Math::Log2Floor(maxDimensionSize) + 1) : 0; +} +/// Calculate the total number of sub resources. 0 on error. +inline int calcNumSubResources(const ITextureResource::Desc& desc) +{ + const int numMipMaps = + (desc.numMipLevels > 0) ? desc.numMipLevels : calcNumMipLevels(desc.type, desc.size); + const int arrSize = (desc.arraySize > 0) ? desc.arraySize : 1; + + switch (desc.type) + { + case IResource::Type::Texture1D: + case IResource::Type::Texture2D: + case IResource::Type::Texture3D: + { + return numMipMaps * arrSize; + } + case IResource::Type::TextureCube: + { + // There are 6 faces to a cubemap + return numMipMaps * arrSize * 6; + } + default: + return 0; + } +} + +IBufferResource::Desc fixupBufferDesc(const IBufferResource::Desc& desc); +ITextureResource::Desc fixupTextureDesc(const ITextureResource::Desc& desc); +} diff --git a/tools/gfx/simple-transient-resource-heap.h b/tools/gfx/simple-transient-resource-heap.h index 55731ddd0..d8ab3517d 100644 --- a/tools/gfx/simple-transient-resource-heap.h +++ b/tools/gfx/simple-transient-resource-heap.h @@ -31,11 +31,13 @@ public: { m_device = device; IBufferResource::Desc bufferDesc = {}; - bufferDesc.setDefaults(IResource::Usage::ConstantBuffer); + bufferDesc.type = IResource::Type::Buffer; + bufferDesc.allowedStates = ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination); + bufferDesc.defaultState = ResourceState::ConstantBuffer; bufferDesc.sizeInBytes = desc.constantBufferSize; bufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; - SLANG_RETURN_ON_FAIL(device->createBufferResource( - IResource::Usage::ConstantBuffer, bufferDesc, nullptr, m_constantBuffer.writeRef())); + SLANG_RETURN_ON_FAIL( + device->createBufferResource(bufferDesc, nullptr, m_constantBuffer.writeRef())); return SLANG_OK; } virtual SLANG_NO_THROW Result SLANG_MCALL diff --git a/tools/gfx/transient-resource-heap-base.h b/tools/gfx/transient-resource-heap-base.h index 769f63f54..ef8a61616 100644 --- a/tools/gfx/transient-resource-heap-base.h +++ b/tools/gfx/transient-resource-heap-base.h @@ -41,11 +41,13 @@ public: Slang::ComPtr<IBufferResource> bufferPtr; IBufferResource::Desc bufferDesc; bufferDesc.type = IResource::Type::Buffer; - bufferDesc.setDefaults(IResource::Usage::ConstantBuffer); - bufferDesc.init(desc.constantBufferSize); + bufferDesc.defaultState = ResourceState::ConstantBuffer; + bufferDesc.allowedStates = + ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination); + bufferDesc.sizeInBytes = desc.constantBufferSize; bufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; - SLANG_RETURN_ON_FAIL(m_device->createBufferResource( - IResource::Usage::ConstantBuffer, bufferDesc, nullptr, bufferPtr.writeRef())); + SLANG_RETURN_ON_FAIL( + m_device->createBufferResource(bufferDesc, nullptr, bufferPtr.writeRef())); m_constantBuffers.add(static_cast<TBufferResource*>(bufferPtr.get())); } @@ -85,17 +87,19 @@ public: Slang::ComPtr<IBufferResource> bufferPtr; IBufferResource::Desc bufferDesc; bufferDesc.type = IResource::Type::Buffer; - bufferDesc.setDefaults(IResource::Usage::ConstantBuffer); + bufferDesc.defaultState = ResourceState::ConstantBuffer; + bufferDesc.allowedStates = + ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination); bufferDesc.cpuAccessFlags |= IResource::AccessFlag::Write; size_t lastConstantBufferSize = 0; if (m_constantBuffers.getCount()) { lastConstantBufferSize = m_constantBuffers.getLast()->getDesc()->sizeInBytes; } - bufferDesc.init(Slang::Math::Max( - lastConstantBufferSize * 2, Slang::Math::Max(size, size_t(4 << 20)))); - SLANG_RETURN_ON_FAIL(m_device->createBufferResource( - IResource::Usage::ConstantBuffer, bufferDesc, nullptr, bufferPtr.writeRef())); + bufferDesc.sizeInBytes = Slang::Math::Max( + lastConstantBufferSize * 2, Slang::Math::Max(size, size_t(4 << 20))); + SLANG_RETURN_ON_FAIL( + m_device->createBufferResource(bufferDesc, nullptr, bufferPtr.writeRef())); bufferId = m_constantBuffers.getCount(); bufferAllocOffset = 0; m_constantBuffers.add(static_cast<TBufferResource*>(bufferPtr.get())); diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp index 389b46c8e..55d0f2ee6 100644 --- a/tools/gfx/vulkan/render-vk.cpp +++ b/tools/gfx/vulkan/render-vk.cpp @@ -67,12 +67,10 @@ public: const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) override; virtual SLANG_NO_THROW Result SLANG_MCALL createTextureResource( - IResource::Usage initialUsage, const ITextureResource::Desc& desc, const ITextureResource::SubresourceData* initData, ITextureResource** outResource) override; virtual SLANG_NO_THROW Result SLANG_MCALL createBufferResource( - IResource::Usage initialUsage, const IBufferResource::Desc& desc, const void* initData, IBufferResource** outResource) override; @@ -165,15 +163,13 @@ public: public: typedef BufferResource Parent; - BufferResourceImpl(IResource::Usage initialUsage, const IBufferResource::Desc& desc, VKDevice* renderer): - Parent(desc), - m_renderer(renderer), - m_initialUsage(initialUsage) + BufferResourceImpl(const IBufferResource::Desc& desc, VKDevice* renderer) + : Parent(desc) + , m_renderer(renderer) { assert(renderer); } - IResource::Usage m_initialUsage; RefPtr<VKDevice> m_renderer; Buffer m_buffer; Buffer m_uploadBuffer; @@ -183,10 +179,9 @@ public: { public: typedef TextureResource Parent; - TextureResourceImpl(const Desc& desc, Usage initialUsage, VKDevice* device) : - Parent(desc), - m_initialUsage(initialUsage), - m_device(device) + TextureResourceImpl(const Desc& desc, VKDevice* device) + : Parent(desc) + , m_device(device) { } ~TextureResourceImpl() @@ -199,8 +194,6 @@ public: } } - Usage m_initialUsage; - VkImage m_image = VK_NULL_HANDLE; VkFormat m_vkformat = VK_FORMAT_R8G8B8A8_UNORM; VkDeviceMemory m_imageMemory = VK_NULL_HANDLE; @@ -3005,11 +2998,6 @@ public: for (Index i = 0; i < Index(slotCount); i++) { BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(buffers[i]); - if (buffer) - { - assert(buffer->m_initialUsage == IResource::Usage::VertexBuffer); - } - BoundVertexBuffer& boundBuffer = m_boundVertexBuffers[startSlot + i]; boundBuffer.m_buffer = buffer; boundBuffer.m_stride = int(strides[i]); @@ -3618,11 +3606,19 @@ public: for (uint32_t i = 0; i < m_desc.imageCount; i++) { ITextureResource::Desc imageDesc = {}; - - imageDesc.init2D( - IResource::Type::Texture2D, m_desc.format, m_desc.width, m_desc.height, 1); - RefPtr<TextureResourceImpl> image = new TextureResourceImpl( - imageDesc, gfx::IResource::Usage::RenderTarget, m_renderer); + imageDesc.allowedStates = ResourceStateSet( + ResourceState::Present, + ResourceState::RenderTarget, + ResourceState::CopyDestination); + imageDesc.type = IResource::Type::Texture2D; + imageDesc.arraySize = 0; + imageDesc.format = m_desc.format; + imageDesc.size.width = m_desc.width; + imageDesc.size.height = m_desc.height; + imageDesc.size.depth = 1; + imageDesc.numMipLevels = 1; + imageDesc.defaultState = ResourceState::Present; + RefPtr<TextureResourceImpl> image = new TextureResourceImpl(imageDesc, m_renderer); image->m_image = vkImages[i]; image->m_imageMemory = 0; image->m_vkformat = m_vkformat; @@ -4604,56 +4600,69 @@ SlangResult VKDevice::readBufferResource( return SLANG_OK; } -static VkBufferUsageFlagBits _calcBufferUsageFlags(IResource::BindFlag::Enum bind) +static VkBufferUsageFlagBits _calcBufferUsageFlags(ResourceState state) { - typedef IResource::BindFlag BindFlag; - - switch (bind) + switch (state) { - case BindFlag::VertexBuffer: return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - case BindFlag::IndexBuffer: return VK_BUFFER_USAGE_INDEX_BUFFER_BIT; - case BindFlag::ConstantBuffer: return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; - case BindFlag::StreamOutput: - case BindFlag::RenderTarget: - case BindFlag::DepthStencil: - { - assert(!"Not supported yet"); + case ResourceState::VertexBuffer: + return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + case ResourceState::IndexBuffer: + return VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + case ResourceState::ConstantBuffer: + return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + case ResourceState::StreamOutput: + return VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT; + case ResourceState::RenderTarget: + case ResourceState::DepthRead: + case ResourceState::DepthWrite: + { + assert(!"Invalid resource state for buffer resource."); return VkBufferUsageFlagBits(0); } - case BindFlag::UnorderedAccess: return VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; - case BindFlag::PixelShaderResource: return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - case BindFlag::NonPixelShaderResource: return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - default: return VkBufferUsageFlagBits(0); + case ResourceState::UnorderedAccess: + return VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; + case ResourceState::ShaderResource: + return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + case ResourceState::CopySource: + return VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + case ResourceState::CopyDestination: + return VK_BUFFER_USAGE_TRANSFER_DST_BIT; + default: + return VkBufferUsageFlagBits(0); } } -static VkBufferUsageFlagBits _calcBufferUsageFlags(int bindFlags) +static VkBufferUsageFlagBits _calcBufferUsageFlags(ResourceStateSet states) { int dstFlags = 0; - while (bindFlags) + for (uint32_t i = 0; i < (uint32_t)ResourceState::_Count; i++) { - int lsb = bindFlags & -bindFlags; - dstFlags |= _calcBufferUsageFlags(IResource::BindFlag::Enum(lsb)); - bindFlags &= ~lsb; + auto state = (ResourceState)i; + if (states.contains(state)) + dstFlags |= _calcBufferUsageFlags(state); } return VkBufferUsageFlagBits(dstFlags); } -static VkImageUsageFlagBits _calcImageUsageFlags(IResource::BindFlag::Enum bind) +static VkImageUsageFlagBits _calcImageUsageFlags(ResourceState state) { - typedef IResource::BindFlag BindFlag; - - switch (bind) + switch (state) { - case BindFlag::RenderTarget: return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - case BindFlag::DepthStencil: return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - case BindFlag::NonPixelShaderResource: - case BindFlag::PixelShaderResource: - { - // Ignore - return VkImageUsageFlagBits(0); - } - default: + case ResourceState::RenderTarget: + return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + case ResourceState::DepthWrite: + return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + case ResourceState::DepthRead: + return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; + case ResourceState::ShaderResource: + return VK_IMAGE_USAGE_SAMPLED_BIT; + case ResourceState::UnorderedAccess: + return VK_IMAGE_USAGE_STORAGE_BIT; + case ResourceState::CopySource: + return VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + case ResourceState::CopyDestination: + return VK_IMAGE_USAGE_TRANSFER_DST_BIT; + default: { assert(!"Unsupported"); return VkImageUsageFlagBits(0); @@ -4661,29 +4670,25 @@ static VkImageUsageFlagBits _calcImageUsageFlags(IResource::BindFlag::Enum bind) } } -static VkImageUsageFlagBits _calcImageUsageFlags(int bindFlags) +static VkImageUsageFlagBits _calcImageUsageFlags(ResourceStateSet states) { int dstFlags = 0; - while (bindFlags) + for (uint32_t i = 0; i < (uint32_t)ResourceState::_Count; i++) { - int lsb = bindFlags & -bindFlags; - dstFlags |= _calcImageUsageFlags(IResource::BindFlag::Enum(lsb)); - bindFlags &= ~lsb; + auto state = (ResourceState)i; + if (states.contains(state)) + dstFlags |= _calcImageUsageFlags(state); } return VkImageUsageFlagBits(dstFlags); } -static VkImageUsageFlags _calcImageUsageFlags(int bindFlags, int cpuAccessFlags, const void* initData) +static VkImageUsageFlags _calcImageUsageFlags( + ResourceStateSet states, + int cpuAccessFlags, + const void* initData) { - VkImageUsageFlags usage = _calcImageUsageFlags(bindFlags); - - usage |= VK_IMAGE_USAGE_SAMPLED_BIT; + VkImageUsageFlags usage = _calcImageUsageFlags(states); - if (cpuAccessFlags & IResource::AccessFlag::Read) - { - // If it can be read from, set this - usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; - } if ((cpuAccessFlags & IResource::AccessFlag::Write) || initData) { usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; @@ -4826,10 +4831,9 @@ size_t calcNumRows(Format format, int height) return (size_t)height; } -Result VKDevice::createTextureResource(IResource::Usage initialUsage, const ITextureResource::Desc& descIn, const ITextureResource::SubresourceData* initData, ITextureResource** outResource) +Result VKDevice::createTextureResource(const ITextureResource::Desc& descIn, const ITextureResource::SubresourceData* initData, ITextureResource** outResource) { - TextureResource::Desc desc(descIn); - desc.setDefaults(initialUsage); + TextureResource::Desc desc = fixupTextureDesc(descIn); const VkFormat format = VulkanUtil::getVkFormat(desc.format); if (format == VK_FORMAT_UNDEFINED) @@ -4838,9 +4842,9 @@ Result VKDevice::createTextureResource(IResource::Usage initialUsage, const ITex return SLANG_FAIL; } - const int arraySize = desc.calcEffectiveArraySize(); + const int arraySize = calcEffectiveArraySize(desc); - RefPtr<TextureResourceImpl> texture(new TextureResourceImpl(desc, initialUsage, this)); + RefPtr<TextureResourceImpl> texture(new TextureResourceImpl(desc, this)); texture->m_vkformat = format; // Create the image { @@ -4888,7 +4892,7 @@ Result VKDevice::createTextureResource(IResource::Usage initialUsage, const ITex imageInfo.format = format; imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; - imageInfo.usage = _calcImageUsageFlags(desc.bindFlags, desc.cpuAccessFlags, initData); + imageInfo.usage = _calcImageUsageFlags(desc.allowedStates, desc.cpuAccessFlags, initData); imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; @@ -4934,7 +4938,7 @@ Result VKDevice::createTextureResource(IResource::Usage initialUsage, const ITex // Calculate how large an array entry is for (int j = 0; j < numMipMaps; ++j) { - const TextureResource::Size mipSize = desc.size.calcMipSize(j); + const TextureResource::Size mipSize = calcMipSize(desc.size, j); auto rowSizeInBytes = calcRowSize(desc.format, mipSize.width); auto numRows = calcNumRows(desc.format, mipSize.height); @@ -5042,30 +5046,25 @@ Result VKDevice::createTextureResource(IResource::Usage initialUsage, const ITex } } } - _transitionImageLayout(texture->m_image, format, *texture->getDesc(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + auto defaultLayout = VulkanUtil::getImageLayoutFromState(desc.defaultState); + _transitionImageLayout( + texture->m_image, + format, + *texture->getDesc(), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + defaultLayout); } else { - switch (initialUsage) + auto defaultLayout = VulkanUtil::getImageLayoutFromState(desc.defaultState); + if (defaultLayout != VK_IMAGE_LAYOUT_UNDEFINED) { - case IResource::Usage::RenderTarget: _transitionImageLayout( texture->m_image, format, *texture->getDesc(), VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - break; - case IResource::Usage::DepthWrite: - _transitionImageLayout( - texture->m_image, - format, - *texture->getDesc(), - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - break; - default: - break; + defaultLayout); } } m_deviceQueue.flushAndWait(); @@ -5073,29 +5072,27 @@ Result VKDevice::createTextureResource(IResource::Usage initialUsage, const ITex return SLANG_OK; } -Result VKDevice::createBufferResource(IResource::Usage initialUsage, const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) +Result VKDevice::createBufferResource(const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) { - BufferResource::Desc desc(descIn); - desc.setDefaults(initialUsage); + BufferResource::Desc desc = fixupBufferDesc(descIn); const size_t bufferSize = desc.sizeInBytes; VkMemoryPropertyFlags reqMemoryProperties = 0; - VkBufferUsageFlags usage = _calcBufferUsageFlags(desc.bindFlags) | - VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + VkBufferUsageFlags usage = _calcBufferUsageFlags(desc.allowedStates); - switch (initialUsage) + if (initData) { - case IResource::Usage::ConstantBuffer: - { - reqMemoryProperties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - break; - } - default: break; + usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; + } + + if (desc.allowedStates.contains(ResourceState::ConstantBuffer)) + { + reqMemoryProperties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; } - RefPtr<BufferResourceImpl> buffer(new BufferResourceImpl(initialUsage, desc, this)); + RefPtr<BufferResourceImpl> buffer(new BufferResourceImpl(desc, this)); SLANG_RETURN_ON_FAIL(buffer->m_buffer.init(m_api, desc.sizeInBytes, usage, reqMemoryProperties)); if ((desc.cpuAccessFlags & IResource::AccessFlag::Write) || initData) diff --git a/tools/gfx/vulkan/vk-util.cpp b/tools/gfx/vulkan/vk-util.cpp index 46ffb01fd..135fe3732 100644 --- a/tools/gfx/vulkan/vk-util.cpp +++ b/tools/gfx/vulkan/vk-util.cpp @@ -77,6 +77,36 @@ VkPipelineBindPoint VulkanUtil::getPipelineBindPoint(PipelineType pipelineType) } } +VkImageLayout VulkanUtil::getImageLayoutFromState(ResourceState state) +{ + switch (state) + { + case ResourceState::ShaderResource: + return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + case ResourceState::UnorderedAccess: + return VK_IMAGE_LAYOUT_GENERAL; + case ResourceState::Present: + return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + case ResourceState::CopySource: + return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + case ResourceState::CopyDestination: + return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + case ResourceState::RenderTarget: + return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + case ResourceState::DepthWrite: + return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + case ResourceState::DepthRead: + return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; + case ResourceState::ResolveSource: + return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + case ResourceState::ResolveDestination: + return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + default: + return VK_IMAGE_LAYOUT_UNDEFINED; + } + return VkImageLayout(); +} + /* static */Slang::Result VulkanUtil::handleFail(VkResult res) { if (res != VK_SUCCESS) diff --git a/tools/gfx/vulkan/vk-util.h b/tools/gfx/vulkan/vk-util.h index 0b14f7f84..a39fe5115 100644 --- a/tools/gfx/vulkan/vk-util.h +++ b/tools/gfx/vulkan/vk-util.h @@ -42,6 +42,8 @@ struct VulkanUtil static VkShaderStageFlags getShaderStage(SlangStage stage); static VkPipelineBindPoint getPipelineBindPoint(PipelineType pipelineType); + + static VkImageLayout getImageLayoutFromState(ResourceState state); }; } // renderer_test diff --git a/tools/platform/gui.cpp b/tools/platform/gui.cpp index 63cf3d51b..ba6fc35f8 100644 --- a/tools/platform/gui.cpp +++ b/tools/platform/gui.cpp @@ -139,16 +139,23 @@ GUI::GUI( io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); { - gfx::ITextureResource::Desc desc; - desc.init2D(IResource::Type::Texture2D, Format::RGBA_Unorm_UInt8, width, height, 1); - desc.setDefaults(IResource::Usage::PixelShaderResource); + gfx::ITextureResource::Desc desc = {}; + desc.type = IResource::Type::Texture2D; + desc.format = Format::RGBA_Unorm_UInt8; + desc.arraySize = 0; + desc.size.width = width; + desc.size.height = height; + desc.size.depth = 1; + desc.numMipLevels = 1; + desc.defaultState = ResourceState::ShaderResource; + desc.allowedStates = + ResourceStateSet(ResourceState::ShaderResource, ResourceState::CopyDestination); ITextureResource::SubresourceData initData = {}; initData.data = pixels; initData.strideY = width * 4 * sizeof(unsigned char); - auto texture = - device->createTextureResource(IResource::Usage::PixelShaderResource, desc, &initData); + auto texture = device->createTextureResource(desc, &initData); gfx::IResourceView::Desc viewDesc; viewDesc.format = desc.format; @@ -204,19 +211,22 @@ void GUI::endFrame(ITransientResourceHeap* transientHeap, IFramebuffer* framebuf // Allocate transient vertex/index buffers to hold the data for this frame. gfx::IBufferResource::Desc vertexBufferDesc; - vertexBufferDesc.init(vertexCount * sizeof(ImDrawVert)); - vertexBufferDesc.setDefaults(IResource::Usage::VertexBuffer); + vertexBufferDesc.type = IResource::Type::Buffer; + vertexBufferDesc.defaultState = ResourceState::VertexBuffer; + vertexBufferDesc.allowedStates = + ResourceStateSet(ResourceState::VertexBuffer, ResourceState::CopyDestination); + vertexBufferDesc.sizeInBytes = vertexCount * sizeof(ImDrawVert); vertexBufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; - auto vertexBuffer = - device->createBufferResource(IResource::Usage::VertexBuffer, vertexBufferDesc); + auto vertexBuffer = device->createBufferResource(vertexBufferDesc); gfx::IBufferResource::Desc indexBufferDesc; - indexBufferDesc.init(indexCount * sizeof(ImDrawIdx)); - indexBufferDesc.setDefaults(IResource::Usage::IndexBuffer); + indexBufferDesc.type = IResource::Type::Buffer; + indexBufferDesc.sizeInBytes = indexCount * sizeof(ImDrawIdx); + indexBufferDesc.allowedStates = + ResourceStateSet(ResourceState::IndexBuffer, ResourceState::CopyDestination); + indexBufferDesc.defaultState = ResourceState::IndexBuffer; indexBufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; - auto indexBuffer = device->createBufferResource( - IResource::Usage::IndexBuffer, - indexBufferDesc); + auto indexBuffer = device->createBufferResource(indexBufferDesc); auto cmdBuf = transientHeap->createCommandBuffer(); auto encoder = cmdBuf->encodeResourceCommands(); { @@ -238,11 +248,13 @@ void GUI::endFrame(ITransientResourceHeap* transientHeap, IFramebuffer* framebuf // Allocate a transient constant buffer for projection matrix gfx::IBufferResource::Desc constantBufferDesc; - constantBufferDesc.init(sizeof(glm::mat4x4)); - constantBufferDesc.setDefaults(IResource::Usage::ConstantBuffer); + constantBufferDesc.type = IResource::Type::Buffer; + constantBufferDesc.allowedStates = + ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination); + constantBufferDesc.defaultState = ResourceState::ConstantBuffer; + constantBufferDesc.sizeInBytes = sizeof(glm::mat4x4); constantBufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; - auto constantBuffer = - device->createBufferResource(IResource::Usage::ConstantBuffer, constantBufferDesc); + auto constantBuffer = device->createBufferResource(constantBufferDesc); { float L = draw_data->DisplayPos.x; diff --git a/tools/platform/model.cpp b/tools/platform/model.cpp index fadfcc0e2..57acf9ecd 100644 --- a/tools/platform/model.cpp +++ b/tools/platform/model.cpp @@ -189,12 +189,16 @@ ComPtr<ITextureResource> loadTextureImage( int mipCount = (int) subresourceInitData.size(); - ITextureResource::Desc desc; - desc.init2D(IResource::Type::Texture2D, format, extentX, extentY, mipCount); - - auto texture = - device->createTextureResource(IResource::Usage::PixelShaderResource, desc, subresourceInitData.data()); - + ITextureResource::Desc desc = {}; + desc.type = IResource::Type::Texture2D; + desc.defaultState = ResourceState::ShaderResource; + desc.allowedStates = ResourceStateSet(ResourceState::ShaderResource); + desc.format = format; + desc.size.width = extentX; + desc.size.height = extentY; + desc.size.depth = 1; + desc.numMipLevels = mipCount; + auto texture = device->createTextureResource(desc, subresourceInitData.data()); free(data); return texture; @@ -542,23 +546,23 @@ SlangResult ModelLoader::load( modelData.meshes = meshes.data(); IBufferResource::Desc vertexBufferDesc; - vertexBufferDesc.init(modelData.vertexCount * sizeof(Vertex)); - vertexBufferDesc.setDefaults(IResource::Usage::VertexBuffer); + vertexBufferDesc.type = IResource::Type::Buffer; + vertexBufferDesc.sizeInBytes = modelData.vertexCount * sizeof(Vertex); + vertexBufferDesc.allowedStates = + ResourceStateSet(ResourceState::VertexBuffer, ResourceState::CopyDestination); + vertexBufferDesc.defaultState = ResourceState::VertexBuffer; - modelData.vertexBuffer = device->createBufferResource( - IResource::Usage::VertexBuffer, - vertexBufferDesc, - flatVertices.data()); + modelData.vertexBuffer = device->createBufferResource(vertexBufferDesc, flatVertices.data()); if(!modelData.vertexBuffer) return SLANG_FAIL; IBufferResource::Desc indexBufferDesc; - indexBufferDesc.init(modelData.indexCount * sizeof(Index)); - vertexBufferDesc.setDefaults(IResource::Usage::IndexBuffer); + indexBufferDesc.type = IResource::Type::Buffer; + indexBufferDesc.sizeInBytes = modelData.indexCount * sizeof(Index); + indexBufferDesc.allowedStates = + ResourceStateSet(ResourceState::IndexBuffer, ResourceState::CopyDestination); + indexBufferDesc.defaultState = ResourceState::IndexBuffer; - modelData.indexBuffer = device->createBufferResource( - IResource::Usage::IndexBuffer, - indexBufferDesc, - flatIndices.data()); + modelData.indexBuffer = device->createBufferResource(indexBufferDesc, flatIndices.data()); if(!modelData.indexBuffer) return SLANG_FAIL; *outModel = callbacks->createModel(modelData); diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp index 43273acf6..d3c0ef1a9 100644 --- a/tools/render-test/render-test-main.cpp +++ b/tools/render-test/render-test-main.cpp @@ -213,7 +213,7 @@ struct AssignValsFromLayoutContext ComPtr<ITextureResource> texture; SLANG_RETURN_ON_FAIL(ShaderRendererUtil::generateTextureResource( - textureEntry->textureDesc, textureBindFlags, device, texture)); + textureEntry->textureDesc, ResourceState::ShaderResource, device, texture)); auto sampler = _createSamplerState(device, samplerEntry->samplerDesc); @@ -229,13 +229,11 @@ struct AssignValsFromLayoutContext return SLANG_OK; } - static const int textureBindFlags = IResource::BindFlag::NonPixelShaderResource | IResource::BindFlag::PixelShaderResource; - SlangResult assignTexture(ShaderCursor const& dstCursor, ShaderInputLayout::TextureVal* srcVal) { ComPtr<ITextureResource> texture; SLANG_RETURN_ON_FAIL(ShaderRendererUtil::generateTextureResource( - srcVal->textureDesc, textureBindFlags, device, texture)); + srcVal->textureDesc, ResourceState::ShaderResource, device, texture)); // TODO: support UAV textures... @@ -494,10 +492,13 @@ SlangResult RenderTestApp::initialize( inputElements, SLANG_COUNT_OF(inputElements), inputLayout.writeRef())); IBufferResource::Desc vertexBufferDesc; - vertexBufferDesc.init(kVertexCount * sizeof(Vertex)); + vertexBufferDesc.type = IResource::Type::Buffer; + vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex); + vertexBufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; + vertexBufferDesc.defaultState = ResourceState::VertexBuffer; + vertexBufferDesc.allowedStates = ResourceStateSet(ResourceState::VertexBuffer); SLANG_RETURN_ON_FAIL(device->createBufferResource( - IResource::Usage::VertexBuffer, vertexBufferDesc, kVertexData, m_vertexBuffer.writeRef())); @@ -537,27 +538,28 @@ void RenderTestApp::_initializeRenderPass() m_queue = m_device->createCommandQueue(queueDesc); gfx::ITextureResource::Desc depthBufferDesc; - depthBufferDesc.setDefaults(gfx::IResource::Usage::DepthWrite); - depthBufferDesc.init2D( - gfx::IResource::Type::Texture2D, - gfx::Format::D_Float32, - gWindowWidth, - gWindowHeight, - 0); - - ComPtr<gfx::ITextureResource> depthBufferResource = m_device->createTextureResource( - gfx::IResource::Usage::DepthWrite, depthBufferDesc, nullptr); + depthBufferDesc.type = IResource::Type::Texture2D; + depthBufferDesc.size.width = gWindowWidth; + depthBufferDesc.size.height = gWindowHeight; + depthBufferDesc.size.depth = 1; + depthBufferDesc.numMipLevels = 1; + depthBufferDesc.format = Format::D_Float32; + depthBufferDesc.defaultState = ResourceState::DepthWrite; + depthBufferDesc.allowedStates = ResourceState::DepthWrite; + + ComPtr<gfx::ITextureResource> depthBufferResource = + m_device->createTextureResource(depthBufferDesc, nullptr); gfx::ITextureResource::Desc colorBufferDesc; - colorBufferDesc.setDefaults(gfx::IResource::Usage::RenderTarget); - colorBufferDesc.init2D( - gfx::IResource::Type::Texture2D, - gfx::Format::RGBA_Unorm_UInt8, - gWindowWidth, - gWindowHeight, - 0); - m_colorBuffer = m_device->createTextureResource( - gfx::IResource::Usage::RenderTarget, colorBufferDesc, nullptr); + colorBufferDesc.type = IResource::Type::Texture2D; + colorBufferDesc.size.width = gWindowWidth; + colorBufferDesc.size.height = gWindowHeight; + colorBufferDesc.size.depth = 1; + colorBufferDesc.numMipLevels = 1; + colorBufferDesc.format = Format::RGBA_Unorm_UInt8; + colorBufferDesc.defaultState = ResourceState::RenderTarget; + colorBufferDesc.allowedStates = ResourceState::RenderTarget; + m_colorBuffer = m_device->createTextureResource(colorBufferDesc, nullptr); gfx::IResourceView::Desc colorBufferViewDesc; memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc)); @@ -677,10 +679,12 @@ Result RenderTestApp::writeBindingOutput(const char* fileName) auto stagingBufferDesc = bufferDesc; stagingBufferDesc.cpuAccessFlags = IResource::AccessFlag::Read; - stagingBufferDesc.bindFlags = 0; + stagingBufferDesc.allowedStates = + ResourceStateSet(ResourceState::CopyDestination, ResourceState::CopySource); + stagingBufferDesc.defaultState = ResourceState::CopyDestination; ComPtr<IBufferResource> stagingBuffer; - SLANG_RETURN_ON_FAIL(m_device->createBufferResource(IResource::Usage::CopyDest, stagingBufferDesc, nullptr, stagingBuffer.writeRef())); + SLANG_RETURN_ON_FAIL(m_device->createBufferResource(stagingBufferDesc, nullptr, stagingBuffer.writeRef())); ComPtr<ICommandBuffer> commandBuffer; SLANG_RETURN_ON_FAIL( diff --git a/tools/render-test/shader-renderer-util.cpp b/tools/render-test/shader-renderer-util.cpp index d6441d3ac..6775b4142 100644 --- a/tools/render-test/shader-renderer-util.cpp +++ b/tools/render-test/shader-renderer-util.cpp @@ -2,6 +2,8 @@ #include "shader-renderer-util.h" +#include "tools/gfx/resource-desc-utils.h" + namespace renderer_test { using namespace Slang; @@ -9,24 +11,23 @@ using Slang::Result; /* static */ Result ShaderRendererUtil::generateTextureResource( const InputTextureDesc& inputDesc, - int bindFlags, + ResourceState defaultState, IDevice* device, ComPtr<ITextureResource>& textureOut) { TextureData texData; generateTextureData(texData, inputDesc); - return createTextureResource(inputDesc, texData, bindFlags, device, textureOut); + return createTextureResource(inputDesc, texData, defaultState, device, textureOut); } /* static */ Result ShaderRendererUtil::createTextureResource( const InputTextureDesc& inputDesc, const TextureData& texData, - int bindFlags, + ResourceState defaultState, IDevice* device, ComPtr<ITextureResource>& textureOut) { - ITextureResource::Desc textureResourceDesc; - textureResourceDesc.init(IResource::Type::Unknown); + ITextureResource::Desc textureResourceDesc = {}; // Default to RGBA_Unorm_UInt8 const Format format = (inputDesc.format == Format::Unknown) ? Format::RGBA_Unorm_UInt8 : inputDesc.format; @@ -34,7 +35,9 @@ using Slang::Result; textureResourceDesc.format = format; textureResourceDesc.numMipLevels = texData.mipLevels; textureResourceDesc.arraySize = inputDesc.arrayLength; - textureResourceDesc.bindFlags = bindFlags; + textureResourceDesc.allowedStates = + ResourceStateSet(defaultState, ResourceState::CopyDestination, ResourceState::CopySource); + textureResourceDesc.defaultState = defaultState; // It's the same size in all dimensions switch (inputDesc.dimension) @@ -42,27 +45,32 @@ using Slang::Result; case 1: { textureResourceDesc.type = IResource::Type::Texture1D; - textureResourceDesc.size.init(inputDesc.size); + textureResourceDesc.size.width = inputDesc.size; + textureResourceDesc.size.height = 1; + textureResourceDesc.size.depth = 1; + break; } case 2: { textureResourceDesc.type = inputDesc.isCube ? IResource::Type::TextureCube : IResource::Type::Texture2D; - textureResourceDesc.size.init(inputDesc.size, inputDesc.size); + textureResourceDesc.size.width = inputDesc.size; + textureResourceDesc.size.height = inputDesc.size; + textureResourceDesc.size.depth = 1; break; } case 3: { textureResourceDesc.type = IResource::Type::Texture3D; - textureResourceDesc.size.init(inputDesc.size, inputDesc.size, inputDesc.size); + textureResourceDesc.size.width = inputDesc.size; + textureResourceDesc.size.height = inputDesc.size; + textureResourceDesc.size.depth = inputDesc.size; break; } } - const int effectiveArraySize = textureResourceDesc.calcEffectiveArraySize(); - const int numSubResources = textureResourceDesc.calcNumSubResources(); - - IResource::Usage initialUsage = IResource::Usage::GenericRead; + const int effectiveArraySize = calcEffectiveArraySize(textureResourceDesc); + const int numSubResources = calcNumSubResources(textureResourceDesc); List<ITextureResource::SubresourceData> initSubresources; int subResourceCounter = 0; @@ -71,8 +79,8 @@ using Slang::Result; for( int m = 0; m < textureResourceDesc.numMipLevels; ++m ) { int subResourceIndex = subResourceCounter++; - const int mipWidth = ITextureResource::Size::calcMipSize(textureResourceDesc.size.width, m); - const int mipHeight = ITextureResource::Size::calcMipSize(textureResourceDesc.size.width, m); + const int mipWidth = calcMipSize(textureResourceDesc.size.width, m); + const int mipHeight = calcMipSize(textureResourceDesc.size.height, m); auto strideY = mipWidth * sizeof(uint32_t); auto strideZ = mipHeight * strideY; @@ -86,7 +94,7 @@ using Slang::Result; } } - textureOut = device->createTextureResource(IResource::Usage::GenericRead, textureResourceDesc, initSubresources.getBuffer()); + textureOut = device->createTextureResource(textureResourceDesc, initSubresources.getBuffer()); return textureOut ? SLANG_OK : SLANG_FAIL; } @@ -98,23 +106,19 @@ using Slang::Result; IDevice* device, Slang::ComPtr<IBufferResource>& bufferOut) { - IResource::Usage initialUsage = IResource::Usage::GenericRead; - IBufferResource::Desc srcDesc; - srcDesc.init(bufferSize); + srcDesc.type = IResource::Type::Buffer; + srcDesc.sizeInBytes = bufferSize; srcDesc.format = inputDesc.format; - - int bindFlags = 0; - { - bindFlags |= IResource::BindFlag::UnorderedAccess | IResource::BindFlag::PixelShaderResource | IResource::BindFlag::NonPixelShaderResource; - srcDesc.elementSize = inputDesc.stride; - initialUsage = IResource::Usage::UnorderedAccess; - } - - srcDesc.bindFlags = bindFlags; - - ComPtr<IBufferResource> bufferResource = - device->createBufferResource(initialUsage, srcDesc, initData); + srcDesc.elementSize = inputDesc.stride; + srcDesc.defaultState = ResourceState::UnorderedAccess; + srcDesc.allowedStates = ResourceStateSet( + ResourceState::CopyDestination, + ResourceState::CopySource, + ResourceState::UnorderedAccess, + ResourceState::ShaderResource); + + ComPtr<IBufferResource> bufferResource = device->createBufferResource(srcDesc, initData); if (!bufferResource) { return SLANG_FAIL; diff --git a/tools/render-test/shader-renderer-util.h b/tools/render-test/shader-renderer-util.h index b4028fd06..1a1edf997 100644 --- a/tools/render-test/shader-renderer-util.h +++ b/tools/render-test/shader-renderer-util.h @@ -16,7 +16,7 @@ struct ShaderRendererUtil /// Generate a texture using the InputTextureDesc and construct a TextureResource using the Renderer with the contents static Slang::Result generateTextureResource( const InputTextureDesc& inputDesc, - int bindFlags, + ResourceState defaultState, IDevice* device, ComPtr<ITextureResource>& textureOut); @@ -24,7 +24,7 @@ struct ShaderRendererUtil static Slang::Result createTextureResource( const InputTextureDesc& inputDesc, const TextureData& texData, - int bindFlags, + ResourceState defaultState, IDevice* device, ComPtr<ITextureResource>& textureOut); |
