Skip to content

Commit 2be7872

Browse files
committed
Move RTV/DSV to texture creation rather than createGraphicsCommands
1 parent 6da4502 commit 2be7872

2 files changed

Lines changed: 83 additions & 78 deletions

File tree

lib/API/DX/Device.cpp

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,16 @@ class DXBuffer : public offloadtest::Buffer {
298298
class DXTexture : public offloadtest::Texture {
299299
public:
300300
ComPtr<ID3D12Resource> Resource;
301+
// TODO:
302+
// RTV/DSV views own a dedicated single-descriptor heap and are created at
303+
// texture creation time. Ideally SRV/UAV views would also live here, but
304+
// they currently require a shared CBV_SRV_UAV heap whose indices are
305+
// determined at pipeline bind time. Moving them here would require a
306+
// descriptor heap allocator, which is not yet implemented.
307+
//
308+
// Either an RTV or DSV descriptor, depending on Desc.Usage.
309+
ComPtr<ID3D12DescriptorHeap> ViewHeap;
310+
D3D12_CPU_DESCRIPTOR_HANDLE ViewHandle = {};
301311
std::string Name;
302312
TextureCreateDesc Desc;
303313

@@ -370,8 +380,6 @@ class DXDevice : public offloadtest::Device {
370380
std::shared_ptr<DXTexture> RT;
371381
std::shared_ptr<DXBuffer> RTReadback;
372382
std::shared_ptr<DXTexture> DS;
373-
ComPtr<ID3D12DescriptorHeap> RTVHeap;
374-
ComPtr<ID3D12DescriptorHeap> DSVHeap;
375383
ComPtr<ID3D12Resource> VB;
376384

377385
llvm::SmallVector<DescriptorTable> DescTables;
@@ -466,7 +474,31 @@ class DXDevice : public offloadtest::Device {
466474
"Failed to create texture."))
467475
return Err;
468476

469-
return std::make_shared<DXTexture>(DeviceTexture, Name, Desc);
477+
auto Tex = std::make_shared<DXTexture>(DeviceTexture, Name, Desc);
478+
479+
bool IsRT = (Desc.Usage & TextureUsage::RenderTarget) != 0;
480+
bool IsDS = (Desc.Usage & TextureUsage::DepthStencil) != 0;
481+
if (IsRT || IsDS) {
482+
D3D12_DESCRIPTOR_HEAP_DESC HeapDesc = {};
483+
HeapDesc.NumDescriptors = 1;
484+
HeapDesc.Type =
485+
IsRT ? D3D12_DESCRIPTOR_HEAP_TYPE_RTV : D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
486+
HeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
487+
if (auto Err = HR::toError(Device->CreateDescriptorHeap(
488+
&HeapDesc, IID_PPV_ARGS(&Tex->ViewHeap)),
489+
IsRT ? "Failed to create RTV heap."
490+
: "Failed to create DSV heap."))
491+
return Err;
492+
Tex->ViewHandle = Tex->ViewHeap->GetCPUDescriptorHandleForHeapStart();
493+
if (IsRT)
494+
Device->CreateRenderTargetView(DeviceTexture.Get(), nullptr,
495+
Tex->ViewHandle);
496+
else
497+
Device->CreateDepthStencilView(DeviceTexture.Get(), nullptr,
498+
Tex->ViewHandle);
499+
}
500+
501+
return Tex;
470502
}
471503

472504
static llvm::Expected<std::unique_ptr<offloadtest::Device>>
@@ -1590,34 +1622,6 @@ class DXDevice : public offloadtest::Device {
15901622
}
15911623

15921624
llvm::Error createGraphicsCommands(Pipeline &P, InvocationState &IS) {
1593-
// Create descriptor heap for the render target view. We do this later and
1594-
// separately from other descriptors just as a convenience since we need the
1595-
// descriptor handle to bind the render target.
1596-
D3D12_DESCRIPTOR_HEAP_DESC RTVHeapDesc = {};
1597-
RTVHeapDesc.NumDescriptors = 1;
1598-
RTVHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
1599-
RTVHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
1600-
if (auto Err = HR::toError(Device->CreateDescriptorHeap(
1601-
&RTVHeapDesc, IID_PPV_ARGS(&IS.RTVHeap)),
1602-
"Failed to create RTV heap"))
1603-
return Err;
1604-
const D3D12_CPU_DESCRIPTOR_HANDLE RTVHandle =
1605-
IS.RTVHeap->GetCPUDescriptorHandleForHeapStart();
1606-
Device->CreateRenderTargetView(IS.RT->Resource.Get(), nullptr, RTVHandle);
1607-
1608-
// Create descriptor heap and view for the depth/stencil buffer.
1609-
D3D12_DESCRIPTOR_HEAP_DESC DSVHeapDesc = {};
1610-
DSVHeapDesc.NumDescriptors = 1;
1611-
DSVHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
1612-
DSVHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
1613-
if (auto Err = HR::toError(Device->CreateDescriptorHeap(
1614-
&DSVHeapDesc, IID_PPV_ARGS(&IS.DSVHeap)),
1615-
"Failed to create DSV heap"))
1616-
return Err;
1617-
const D3D12_CPU_DESCRIPTOR_HANDLE DSVHandle =
1618-
IS.DSVHeap->GetCPUDescriptorHandleForHeapStart();
1619-
Device->CreateDepthStencilView(IS.DS->Resource.Get(), nullptr, DSVHandle);
1620-
16211625
IS.CmdList->SetGraphicsRootSignature(IS.RootSig.Get());
16221626
if (IS.DescHeap) {
16231627
ID3D12DescriptorHeap *const Heaps[] = {IS.DescHeap.Get()};
@@ -1627,7 +1631,8 @@ class DXDevice : public offloadtest::Device {
16271631
}
16281632
IS.CmdList->SetPipelineState(IS.PSO.Get());
16291633

1630-
IS.CmdList->OMSetRenderTargets(1, &RTVHandle, false, &DSVHandle);
1634+
IS.CmdList->OMSetRenderTargets(1, &IS.RT->ViewHandle, false,
1635+
&IS.DS->ViewHandle);
16311636

16321637
const auto *DepthCV =
16331638
std::get_if<ClearDepthStencil>(&*IS.DS->Desc.OptimizedClearValue);
@@ -1636,7 +1641,7 @@ class DXDevice : public offloadtest::Device {
16361641
std::errc::invalid_argument,
16371642
"Depth/stencil clear value must be a ClearDepthStencil.");
16381643
IS.CmdList->ClearDepthStencilView(
1639-
DSVHandle, D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL,
1644+
IS.DS->ViewHandle, D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL,
16401645
DepthCV->Depth, DepthCV->Stencil, 0, nullptr);
16411646

16421647
D3D12_VIEWPORT VP = {};

lib/API/VK/Device.cpp

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,12 @@ class VulkanTexture : public offloadtest::Texture {
397397
VkDevice Dev;
398398
VkImage Image;
399399
VkDeviceMemory Memory;
400+
// TODO:
401+
// RenderTarget and DepthStencil views are created at texture creation time.
402+
// Ideally Sampled/Storage image views would also live here, but they are
403+
// currently created during descriptor set setup, which determines their
404+
// binding layout.
405+
VkImageView View = VK_NULL_HANDLE;
400406
std::string Name;
401407
TextureCreateDesc Desc;
402408

@@ -405,6 +411,8 @@ class VulkanTexture : public offloadtest::Texture {
405411
: Dev(Dev), Image(Image), Memory(Memory), Name(Name), Desc(Desc) {}
406412

407413
~VulkanTexture() override {
414+
if (View)
415+
vkDestroyImageView(Dev, View, nullptr);
408416
vkDestroyImage(Dev, Image, nullptr);
409417
vkFreeMemory(Dev, Memory, nullptr);
410418
}
@@ -758,8 +766,37 @@ class VulkanDevice : public offloadtest::Device {
758766
"Failed to bind image memory.");
759767
}
760768

761-
return std::make_shared<VulkanTexture>(Device, Image, DeviceMemory, Name,
762-
Desc);
769+
auto Tex = std::make_shared<VulkanTexture>(Device, Image, DeviceMemory,
770+
Name, Desc);
771+
772+
bool IsRT = (Desc.Usage & TextureUsage::RenderTarget) != 0;
773+
bool IsDS = (Desc.Usage & TextureUsage::DepthStencil) != 0;
774+
if (IsRT || IsDS) {
775+
VkImageViewCreateInfo ViewCi = {};
776+
ViewCi.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
777+
ViewCi.viewType = VK_IMAGE_VIEW_TYPE_2D;
778+
ViewCi.format = getVulkanFormat(Desc.Format);
779+
ViewCi.subresourceRange.baseMipLevel = 0;
780+
ViewCi.subresourceRange.levelCount = 1;
781+
ViewCi.subresourceRange.baseArrayLayer = 0;
782+
ViewCi.subresourceRange.layerCount = 1;
783+
ViewCi.image = Image;
784+
if (IsRT) {
785+
ViewCi.components = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
786+
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
787+
ViewCi.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
788+
} else {
789+
ViewCi.subresourceRange.aspectMask =
790+
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
791+
}
792+
if (vkCreateImageView(Device, &ViewCi, nullptr, &Tex->View)) {
793+
// Tex destructor will clean up Image + Memory.
794+
return llvm::createStringError(std::errc::device_or_resource_busy,
795+
"Failed to create image view.");
796+
}
797+
}
798+
799+
return Tex;
763800
}
764801

765802
const Capabilities &getCapabilities() override {
@@ -1510,8 +1547,7 @@ class VulkanDevice : public offloadtest::Device {
15101547
llvm::Error createRenderPass(Pipeline &P, InvocationState &IS) {
15111548
std::array<VkAttachmentDescription, 2> Attachments = {};
15121549

1513-
Attachments[0].format = getVKFormat(P.Bindings.RTargetBufferPtr->Format,
1514-
P.Bindings.RTargetBufferPtr->Channels);
1550+
Attachments[0].format = getVulkanFormat(IS.RenderTarget->Desc.Format);
15151551
Attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
15161552
Attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
15171553
Attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
@@ -1520,7 +1556,7 @@ class VulkanDevice : public offloadtest::Device {
15201556
Attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
15211557
Attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
15221558

1523-
Attachments[1].format = VK_FORMAT_D32_SFLOAT_S8_UINT;
1559+
Attachments[1].format = getVulkanFormat(IS.DepthStencil->Desc.Format);
15241560
Attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
15251561
Attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
15261562
Attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
@@ -1591,52 +1627,16 @@ class VulkanDevice : public offloadtest::Device {
15911627
}
15921628

15931629
llvm::Error createFrameBuffer(Pipeline &P, InvocationState &IS) {
1594-
std::array<VkImageView, 2> Views = {};
1595-
VkImageViewCreateInfo ViewCreateInfo = {};
1596-
ViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1597-
ViewCreateInfo.viewType = getImageViewType(ResourceKind::Texture2D);
1598-
ViewCreateInfo.format = getVKFormat(P.Bindings.RTargetBufferPtr->Format,
1599-
P.Bindings.RTargetBufferPtr->Channels);
1600-
ViewCreateInfo.components = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
1601-
VK_COMPONENT_SWIZZLE_B,
1602-
VK_COMPONENT_SWIZZLE_A};
1603-
ViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1604-
ViewCreateInfo.subresourceRange.baseMipLevel = 0;
1605-
ViewCreateInfo.subresourceRange.baseArrayLayer = 0;
1606-
ViewCreateInfo.subresourceRange.layerCount = 1;
1607-
ViewCreateInfo.subresourceRange.levelCount = 1;
1608-
ViewCreateInfo.image = IS.RenderTarget->Image;
1609-
if (vkCreateImageView(Device, &ViewCreateInfo, nullptr, &Views[0]))
1610-
return llvm::createStringError(
1611-
std::errc::device_or_resource_busy,
1612-
"Failed to create frame buffer image view.");
1613-
IS.ImageViews.push_back(Views[0]);
1614-
1615-
VkImageViewCreateInfo DepthStencilViewCi = {};
1616-
DepthStencilViewCi.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1617-
DepthStencilViewCi.viewType = getImageViewType(ResourceKind::Texture2D);
1618-
DepthStencilViewCi.format = VK_FORMAT_D32_SFLOAT_S8_UINT;
1619-
DepthStencilViewCi.subresourceRange = {};
1620-
DepthStencilViewCi.subresourceRange.aspectMask =
1621-
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1622-
DepthStencilViewCi.subresourceRange.baseMipLevel = 0;
1623-
DepthStencilViewCi.subresourceRange.levelCount = 1;
1624-
DepthStencilViewCi.subresourceRange.baseArrayLayer = 0;
1625-
DepthStencilViewCi.subresourceRange.layerCount = 1;
1626-
DepthStencilViewCi.image = IS.DepthStencil->Image;
1627-
if (vkCreateImageView(Device, &DepthStencilViewCi, nullptr, &Views[1]))
1628-
return llvm::createStringError(
1629-
std::errc::device_or_resource_busy,
1630-
"Failed to create depth stencil image view.");
1631-
IS.ImageViews.push_back(Views[1]);
1630+
std::array<VkImageView, 2> Views = {IS.RenderTarget->View,
1631+
IS.DepthStencil->View};
16321632

16331633
VkFramebufferCreateInfo FbufCreateInfo = {};
16341634
FbufCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
16351635
FbufCreateInfo.renderPass = IS.RenderPass;
16361636
FbufCreateInfo.attachmentCount = Views.size();
16371637
FbufCreateInfo.pAttachments = Views.data();
1638-
FbufCreateInfo.width = P.Bindings.RTargetBufferPtr->OutputProps.Width;
1639-
FbufCreateInfo.height = P.Bindings.RTargetBufferPtr->OutputProps.Height;
1638+
FbufCreateInfo.width = IS.RenderTarget->Desc.Width;
1639+
FbufCreateInfo.height = IS.RenderTarget->Desc.Height;
16401640
FbufCreateInfo.layers = 1;
16411641

16421642
if (vkCreateFramebuffer(Device, &FbufCreateInfo, nullptr, &IS.FrameBuffer))

0 commit comments

Comments
 (0)