Skip to content

Commit

Permalink
Create bindless UnorderedAccessViews for each slice/mipmap
Browse files Browse the repository at this point in the history
  • Loading branch information
Benualdo committed Nov 10, 2024
1 parent c8f50d2 commit edee0f8
Show file tree
Hide file tree
Showing 11 changed files with 279 additions and 48 deletions.
62 changes: 61 additions & 1 deletion .github/workflows/Build_Win64_DX12.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,64 @@ jobs:
git add -f "bin\x64\Final_DX12\renderer.dll"
git commit -m "$commitMessage"
git push
git push
- name: Send Discord Notification
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
run: |
$versionContent = Get-Content "src/version.h"
$major, $minor, $patch = "", "", ""
foreach ($line in $versionContent) {
if ($line -match '#define VG_FRAMEWORK_VERSION_MAJOR (\d+)') {
$major = $matches[1]
} elseif ($line -match '#define VG_FRAMEWORK_VERSION_MINOR (\d+)') {
$minor = $matches[1]
} elseif ($line -match '#define VG_FRAMEWORK_VERSION_PATCH (\d+)') {
$patch = $matches[1]
}
}
$fullVersion = "$major.$minor.$patch"
$commitContent = Get-Content "src/commit.h"
$gitRevision = ""
foreach ($line in $commitContent) {
if ($line -like '*#define GIT_REVISION*') {
$parts = $line -split '"'
$gitRevision = $parts[1]
break
}
}
$jsonPayload = @"
{
"username": "GitHub",
"content": "",
"embeds": [
{
"type": "rich",
"title": "VGFramework $fullVersion ($gitRevision)",
"description": "A new version of VGFramework is available",
"color": 15579707,
"thumbnail": {
"url": "https://github.com/vimontgames/vgframework/blob/master/doc/img/newversion.png?raw=true"
},
"author": {
"name": "$($env:GITHUB_ACTOR)",
"url": "https://github.com/$($env:GITHUB_ACTOR)",
"icon_url": "https://avatars.githubusercontent.com/u/$($env:GITHUB_ACTOR_ID)?v=4"
},
"url": "https://github.com/vimontgames/vgframework"
}
]
}
"@
# Send the notification using curl
$RESPONSE = curl -H "Content-Type: application/json" -X POST -d $jsonPayload $WEBHOOK_URL
# Output the response from the server
Write-Output "Webhook server response: $RESPONSE"
Binary file added doc/img/newversion.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions src/engine/World/World.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ namespace vg::engine

VG_SAFE_RELEASE(m_physicsWorld);
VG_SAFE_RELEASE(m_environmentCubemap);
VG_SAFE_RELEASE(m_irradianceCubemap);
VG_SAFE_RELEASE(m_specularReflectionCubemap);
VG_SAFE_DELETE(m_debugDrawData);

for (uint j = 0; j < enumCount<BaseSceneType>(); ++j)
Expand Down Expand Up @@ -419,8 +421,8 @@ namespace vg::engine

// Reset cubemap
VG_SAFE_RELEASE_ASYNC(m_environmentCubemap);
VG_SAFE_RELEASE_ASYNC(m_irradianceCubemap);
VG_SAFE_RELEASE_ASYNC(m_specularReflectionCubemap);
//VG_SAFE_RELEASE_ASYNC(m_irradianceCubemap);
//VG_SAFE_RELEASE_ASYNC(m_specularReflectionCubemap);

// Use default ambient
m_irradianceIntensity = options->GetDefaultIrradianceIntensity();
Expand Down
5 changes: 3 additions & 2 deletions src/gfx/Resource/Texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ namespace vg::gfx
gfx::BindlessTextureHandle m_stencilTextureHandle;
};
};

gfx::BindlessRWTextureHandle m_rwTextureHandle;

// [slice][mip]
core::vector<core::vector<gfx::BindlessRWTextureHandle>> m_rwTextureHandles;
};
}
}
Expand Down
11 changes: 9 additions & 2 deletions src/gfx/Resource/Texture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,14 @@ namespace vg::gfx
bindlessTable->freeBindlessTextureHandle(m_textureHandle);
}

if (m_rwTextureHandle.isValid())
bindlessTable->freeBindlessRWTextureHandle(m_rwTextureHandle);
for (uint s = 0; s < m_rwTextureHandles.size(); ++s)
{
for (uint m = 0; m < m_rwTextureHandles[s].size(); ++m)
{
auto & rwTextureHandle = m_rwTextureHandles[s][m];
if (rwTextureHandle.isValid())
bindlessTable->freeBindlessRWTextureHandle(rwTextureHandle);
}
}
}
}
5 changes: 3 additions & 2 deletions src/gfx/Resource/Texture.inl
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ namespace vg::gfx
//--------------------------------------------------------------------------------------
VG_INLINE const gfx::BindlessRWTextureHandle Texture::getRWTextureHandle() const
{
VG_ASSERT(m_rwTextureHandle.isValid());
return m_rwTextureHandle;
const auto & rwTextureHandle = m_rwTextureHandles[0][0];
VG_ASSERT(rwTextureHandle.isValid());
return rwTextureHandle;
}

//--------------------------------------------------------------------------------------
Expand Down
60 changes: 49 additions & 11 deletions src/gfx/Resource/dx12/Texture_dx12.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,19 +433,57 @@ namespace vg::gfx::dx12
VG_ASSERT_ENUM_NOT_IMPLEMENTED(_texDesc.type);
break;

case TextureType::TextureCube:
{
VG_ASSERT(_texDesc.slices == 6);

m_rwTextureHandles.resize(_texDesc.slices);
for (uint s = 0; s < _texDesc.slices; ++s)
m_rwTextureHandles[s].resize(_texDesc.mipmaps);

for (uint s = 0; s < _texDesc.slices; ++s)
{
for (uint m = 0; m < _texDesc.mipmaps; ++m)
{
BindlessTable * bindlessTable = device->getBindlessTable();
auto rwTextureHandle = bindlessTable->allocBindlessRWTextureHandle(static_cast<gfx::Texture *>(this));
D3D12_CPU_DESCRIPTOR_HANDLE d3d12RWTextureDescriptorHandle = bindlessTable->getd3d12CPUDescriptorHandle(rwTextureHandle);

D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc;
uavDesc.Format = getd3d12ResourceFormat(_texDesc.format);
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
uavDesc.Texture2D.MipSlice = m;
uavDesc.Texture2D.PlaneSlice = 0;
d3d12device->CreateUnorderedAccessView(m_resource.getd3d12TextureResource(), nullptr, &uavDesc, d3d12RWTextureDescriptorHandle);
bindlessTable->updated3d12descriptor(rwTextureHandle);

m_rwTextureHandles[s][m] = rwTextureHandle;
}
}
}
break;

case TextureType::Texture2D:
{
BindlessTable * bindlessTable = device->getBindlessTable();
m_rwTextureHandle = bindlessTable->allocBindlessRWTextureHandle(static_cast<gfx::Texture *>(this));
D3D12_CPU_DESCRIPTOR_HANDLE d3d12RWTextureDescriptorHandle = bindlessTable->getd3d12CPUDescriptorHandle(m_rwTextureHandle);

D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc;
uavDesc.Format = getd3d12ResourceFormat(_texDesc.format);
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
uavDesc.Texture2D.MipSlice = 0;
uavDesc.Texture2D.PlaneSlice = 0;
d3d12device->CreateUnorderedAccessView(m_resource.getd3d12TextureResource(), nullptr, &uavDesc, d3d12RWTextureDescriptorHandle);
bindlessTable->updated3d12descriptor(getRWTextureHandle());
m_rwTextureHandles.resize(1); // 1 slice
m_rwTextureHandles[0].resize(_texDesc.mipmaps);

for (uint m = 0; m < _texDesc.mipmaps; ++m)
{
BindlessTable * bindlessTable = device->getBindlessTable();
auto rwTextureHandle = bindlessTable->allocBindlessRWTextureHandle(static_cast<gfx::Texture *>(this));
D3D12_CPU_DESCRIPTOR_HANDLE d3d12RWTextureDescriptorHandle = bindlessTable->getd3d12CPUDescriptorHandle(rwTextureHandle);

D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc;
uavDesc.Format = getd3d12ResourceFormat(_texDesc.format);
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
uavDesc.Texture2D.MipSlice = m;
uavDesc.Texture2D.PlaneSlice = 0;
d3d12device->CreateUnorderedAccessView(m_resource.getd3d12TextureResource(), nullptr, &uavDesc, d3d12RWTextureDescriptorHandle);
bindlessTable->updated3d12descriptor(rwTextureHandle);

m_rwTextureHandles[0][m] = rwTextureHandle;
}
}
break;
}
Expand Down
3 changes: 2 additions & 1 deletion src/gfx/Resource/vulkan/Texture_vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace vg::gfx::vulkan
static VkImageViewType getVulkanImageViewType (TextureType _texType);

private:
VkImageView m_vkImageView;
VkImageView m_vkImageView; // This is the default image view with all slices/mipmaps (used for ShaderResourceView)
core::vector<core::vector<VkImageView>> m_vkSliceMipImageViews; // Separate image view for each slice/mip level (used for RWTextures)
};
}
132 changes: 110 additions & 22 deletions src/gfx/Resource/vulkan/Texture_vulkan.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,12 @@ namespace vg::gfx::vulkan
m_resource.setVulkanImage(vkImage, vmaAlloc);
}

if (_texDesc.isShaderResource() || _texDesc.isBackbuffer())
VkImageViewCreateInfo vkImageViewDesc = {};

if (_texDesc.isShaderResource() || _texDesc.isBackbuffer() || asBool(BindFlags::UnorderedAccess & _texDesc.resource.m_bindFlags))
{
auto createVulkanShaderResourceView = [&](const TextureDesc & _texDesc, bool _stencil = false)
{
VkImageViewCreateInfo vkImageViewDesc = {};

vkImageViewDesc.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
vkImageViewDesc.pNext = nullptr;
vkImageViewDesc.format = getVulkanPixelFormat(_texDesc.format);
Expand Down Expand Up @@ -307,24 +307,103 @@ namespace vg::gfx::vulkan

if (asBool(BindFlags::UnorderedAccess & _texDesc.resource.m_bindFlags))
{
BindlessTable * bindlessTable = device->getBindlessTable();
m_rwTextureHandle = bindlessTable->allocBindlessRWTextureHandle(static_cast<gfx::Texture *>(this));

VkDescriptorImageInfo tex_descs = {};
tex_descs.imageView = m_vkImageView;
tex_descs.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
tex_descs.sampler = nullptr;

VkWriteDescriptorSet writes = {};
writes.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes.dstBinding = BINDLESS_RWTEXTURE_BINDING;
writes.descriptorCount = 1;
writes.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
writes.pImageInfo = &tex_descs;
writes.dstSet = device->getVulkanBindlessDescriptors();
writes.dstArrayElement = m_rwTextureHandle - BINDLESS_RWTEXTURE_START;

vkUpdateDescriptorSets(device->getVulkanDevice(), 1, &writes, 0, nullptr);
switch (_texDesc.type)
{
default:
VG_ASSERT_ENUM_NOT_IMPLEMENTED(_texDesc.type);
break;

case TextureType::TextureCube:
{
VG_ASSERT(_texDesc.slices == 6);

m_vkSliceMipImageViews.resize(_texDesc.slices);
m_rwTextureHandles.resize(_texDesc.slices);

for (uint s = 0; s < _texDesc.slices; ++s)
{
m_vkSliceMipImageViews[s].resize(_texDesc.mipmaps);
m_rwTextureHandles[s].resize(_texDesc.mipmaps);
}

for (uint s = 0; s < _texDesc.slices; ++s)
{
for (uint m = 0; m < _texDesc.mipmaps; ++m)
{
BindlessTable * bindlessTable = device->getBindlessTable();
auto rwTextureHandle = bindlessTable->allocBindlessRWTextureHandle(static_cast<gfx::Texture *>(this));

VkImageViewCreateInfo vkMipImageViewDesc = vkImageViewDesc;
vkMipImageViewDesc.viewType = VK_IMAGE_VIEW_TYPE_2D;
vkMipImageViewDesc.subresourceRange.baseMipLevel = m;
vkMipImageViewDesc.subresourceRange.levelCount = 1;
vkMipImageViewDesc.subresourceRange.baseArrayLayer = s;
vkMipImageViewDesc.subresourceRange.layerCount = 1;

VG_VERIFY_VULKAN(vkCreateImageView(device->getVulkanDevice(), &vkMipImageViewDesc, nullptr, &m_vkSliceMipImageViews[s][m]));

VkDescriptorImageInfo tex_descs = {};
tex_descs.imageView = m_vkSliceMipImageViews[s][m];
tex_descs.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
tex_descs.sampler = nullptr;

VkWriteDescriptorSet writes = {};
writes.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes.dstBinding = BINDLESS_RWTEXTURE_BINDING;
writes.descriptorCount = 1;
writes.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
writes.pImageInfo = &tex_descs;
writes.dstSet = device->getVulkanBindlessDescriptors();
writes.dstArrayElement = rwTextureHandle - BINDLESS_RWTEXTURE_START;

vkUpdateDescriptorSets(device->getVulkanDevice(), 1, &writes, 0, nullptr);

m_rwTextureHandles[s][m] = rwTextureHandle;
}
}
}
break;

case TextureType::Texture2D:
{
m_vkSliceMipImageViews.resize(1);
m_vkSliceMipImageViews[0].resize(_texDesc.mipmaps);

m_rwTextureHandles.resize(1);
m_rwTextureHandles[0].resize(_texDesc.mipmaps);

for (uint m = 0; m < _texDesc.mipmaps; ++m)
{
BindlessTable * bindlessTable = device->getBindlessTable();
auto rwTextureHandle = bindlessTable->allocBindlessRWTextureHandle(static_cast<gfx::Texture *>(this));

VkImageViewCreateInfo vkMipImageViewDesc = vkImageViewDesc;
vkMipImageViewDesc.subresourceRange.baseMipLevel = m;
vkMipImageViewDesc.subresourceRange.levelCount = 1;

VG_VERIFY_VULKAN(vkCreateImageView(device->getVulkanDevice(), &vkMipImageViewDesc, nullptr, &m_vkSliceMipImageViews[0][m]));

VkDescriptorImageInfo tex_descs = {};
tex_descs.imageView = m_vkSliceMipImageViews[0][m];
tex_descs.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
tex_descs.sampler = nullptr;

VkWriteDescriptorSet writes = {};
writes.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes.dstBinding = BINDLESS_RWTEXTURE_BINDING;
writes.descriptorCount = 1;
writes.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
writes.pImageInfo = &tex_descs;
writes.dstSet = device->getVulkanBindlessDescriptors();
writes.dstArrayElement = rwTextureHandle - BINDLESS_RWTEXTURE_START;

vkUpdateDescriptorSets(device->getVulkanDevice(), 1, &writes, 0, nullptr);

m_rwTextureHandles[0][m] = rwTextureHandle;
}
}
break;
}
}
}
}
Expand All @@ -333,9 +412,18 @@ namespace vg::gfx::vulkan
Texture::~Texture()
{
auto * device = gfx::Device::get();
auto & vkDevice = device->getVulkanDevice();

// Swapchain must be destroyed using PFN_vkDestroySwapchainKHR
if (!getTexDesc().isBackbuffer())
vkDestroyImageView(device->getVulkanDevice(), m_vkImageView, nullptr);
{
vkDestroyImageView(vkDevice, m_vkImageView, nullptr);

for (uint s = 0; s < m_vkSliceMipImageViews.size(); ++s)
{
for (uint m = 0; m < m_vkSliceMipImageViews[s].size(); ++m)
vkDestroyImageView(vkDevice, m_vkSliceMipImageViews[s][m], nullptr);
}
}
}
}
Loading

0 comments on commit edee0f8

Please sign in to comment.