Skip to content

Commit 0bf7cfc

Browse files
committed
Move RTV/DSV to texture creation rather than createGraphicsCommands
1 parent 62c07cb commit 0bf7cfc

File tree

2 files changed

+83
-78
lines changed

2 files changed

+83
-78
lines changed

lib/API/DX/Device.cpp

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,16 @@ class DXBuffer : public offloadtest::Buffer {
287287
class DXTexture : public offloadtest::Texture {
288288
public:
289289
ComPtr<ID3D12Resource> Resource;
290+
// TODO:
291+
// RTV/DSV views own a dedicated single-descriptor heap and are created at
292+
// texture creation time. Ideally SRV/UAV views would also live here, but
293+
// they currently require a shared CBV_SRV_UAV heap whose indices are
294+
// determined at pipeline bind time. Moving them here would require a
295+
// descriptor heap allocator, which is not yet implemented.
296+
//
297+
// Either an RTV or DSV descriptor, depending on Desc.Usage.
298+
ComPtr<ID3D12DescriptorHeap> ViewHeap;
299+
D3D12_CPU_DESCRIPTOR_HANDLE ViewHandle = {};
290300
std::string Name;
291301
TextureCreateDesc Desc;
292302

@@ -359,8 +369,6 @@ class DXDevice : public offloadtest::Device {
359369
std::shared_ptr<DXTexture> RT;
360370
std::shared_ptr<DXBuffer> RTReadback;
361371
std::shared_ptr<DXTexture> DS;
362-
ComPtr<ID3D12DescriptorHeap> RTVHeap;
363-
ComPtr<ID3D12DescriptorHeap> DSVHeap;
364372
ComPtr<ID3D12Resource> VB;
365373

366374
llvm::SmallVector<DescriptorTable> DescTables;
@@ -455,7 +463,31 @@ class DXDevice : public offloadtest::Device {
455463
"Failed to create texture."))
456464
return Err;
457465

458-
return std::make_shared<DXTexture>(DeviceTexture, Name, Desc);
466+
auto Tex = std::make_shared<DXTexture>(DeviceTexture, Name, Desc);
467+
468+
bool IsRT = (Desc.Usage & TextureUsage::RenderTarget) != 0;
469+
bool IsDS = (Desc.Usage & TextureUsage::DepthStencil) != 0;
470+
if (IsRT || IsDS) {
471+
D3D12_DESCRIPTOR_HEAP_DESC HeapDesc = {};
472+
HeapDesc.NumDescriptors = 1;
473+
HeapDesc.Type =
474+
IsRT ? D3D12_DESCRIPTOR_HEAP_TYPE_RTV : D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
475+
HeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
476+
if (auto Err = HR::toError(Device->CreateDescriptorHeap(
477+
&HeapDesc, IID_PPV_ARGS(&Tex->ViewHeap)),
478+
IsRT ? "Failed to create RTV heap."
479+
: "Failed to create DSV heap."))
480+
return Err;
481+
Tex->ViewHandle = Tex->ViewHeap->GetCPUDescriptorHandleForHeapStart();
482+
if (IsRT)
483+
Device->CreateRenderTargetView(DeviceTexture.Get(), nullptr,
484+
Tex->ViewHandle);
485+
else
486+
Device->CreateDepthStencilView(DeviceTexture.Get(), nullptr,
487+
Tex->ViewHandle);
488+
}
489+
490+
return Tex;
459491
}
460492

461493
static llvm::Expected<DXDevice> create(ComPtr<IDXCoreAdapter> Adapter,
@@ -1579,34 +1611,6 @@ class DXDevice : public offloadtest::Device {
15791611
}
15801612

15811613
llvm::Error createGraphicsCommands(Pipeline &P, InvocationState &IS) {
1582-
// Create descriptor heap for the render target view. We do this later and
1583-
// separately from other descriptors just as a convenience since we need the
1584-
// descriptor handle to bind the render target.
1585-
D3D12_DESCRIPTOR_HEAP_DESC RTVHeapDesc = {};
1586-
RTVHeapDesc.NumDescriptors = 1;
1587-
RTVHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
1588-
RTVHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
1589-
if (auto Err = HR::toError(Device->CreateDescriptorHeap(
1590-
&RTVHeapDesc, IID_PPV_ARGS(&IS.RTVHeap)),
1591-
"Failed to create RTV heap"))
1592-
return Err;
1593-
const D3D12_CPU_DESCRIPTOR_HANDLE RTVHandle =
1594-
IS.RTVHeap->GetCPUDescriptorHandleForHeapStart();
1595-
Device->CreateRenderTargetView(IS.RT->Resource.Get(), nullptr, RTVHandle);
1596-
1597-
// Create descriptor heap and view for the depth/stencil buffer.
1598-
D3D12_DESCRIPTOR_HEAP_DESC DSVHeapDesc = {};
1599-
DSVHeapDesc.NumDescriptors = 1;
1600-
DSVHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
1601-
DSVHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
1602-
if (auto Err = HR::toError(Device->CreateDescriptorHeap(
1603-
&DSVHeapDesc, IID_PPV_ARGS(&IS.DSVHeap)),
1604-
"Failed to create DSV heap"))
1605-
return Err;
1606-
const D3D12_CPU_DESCRIPTOR_HANDLE DSVHandle =
1607-
IS.DSVHeap->GetCPUDescriptorHandleForHeapStart();
1608-
Device->CreateDepthStencilView(IS.DS->Resource.Get(), nullptr, DSVHandle);
1609-
16101614
IS.CmdList->SetGraphicsRootSignature(IS.RootSig.Get());
16111615
if (IS.DescHeap) {
16121616
ID3D12DescriptorHeap *const Heaps[] = {IS.DescHeap.Get()};
@@ -1616,7 +1620,8 @@ class DXDevice : public offloadtest::Device {
16161620
}
16171621
IS.CmdList->SetPipelineState(IS.PSO.Get());
16181622

1619-
IS.CmdList->OMSetRenderTargets(1, &RTVHandle, false, &DSVHandle);
1623+
IS.CmdList->OMSetRenderTargets(1, &IS.RT->ViewHandle, false,
1624+
&IS.DS->ViewHandle);
16201625

16211626
const auto *DepthCV =
16221627
std::get_if<ClearDepthStencil>(&*IS.DS->Desc.OptimizedClearValue);
@@ -1625,7 +1630,7 @@ class DXDevice : public offloadtest::Device {
16251630
std::errc::invalid_argument,
16261631
"Depth/stencil clear value must be a ClearDepthStencil.");
16271632
IS.CmdList->ClearDepthStencilView(
1628-
DSVHandle, D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL,
1633+
IS.DS->ViewHandle, D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL,
16291634
DepthCV->Depth, DepthCV->Stencil, 0, nullptr);
16301635

16311636
D3D12_VIEWPORT VP = {};

lib/API/VK/Device.cpp

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,12 @@ class VulkanTexture : public offloadtest::Texture {
362362
VkDevice Dev;
363363
VkImage Image;
364364
VkDeviceMemory Memory;
365+
// TODO:
366+
// RenderTarget and DepthStencil views are created at texture creation time.
367+
// Ideally Sampled/Storage image views would also live here, but they are
368+
// currently created during descriptor set setup, which determines their
369+
// binding layout.
370+
VkImageView View = VK_NULL_HANDLE;
365371
std::string Name;
366372
TextureCreateDesc Desc;
367373

@@ -370,6 +376,8 @@ class VulkanTexture : public offloadtest::Texture {
370376
: Dev(Dev), Image(Image), Memory(Memory), Name(Name), Desc(Desc) {}
371377

372378
~VulkanTexture() override {
379+
if (View)
380+
vkDestroyImageView(Dev, View, nullptr);
373381
vkDestroyImage(Dev, Image, nullptr);
374382
vkFreeMemory(Dev, Memory, nullptr);
375383
}
@@ -721,8 +729,37 @@ class VulkanDevice : public offloadtest::Device {
721729
"Failed to bind image memory.");
722730
}
723731

724-
return std::make_shared<VulkanTexture>(Device, Image, DeviceMemory, Name,
725-
Desc);
732+
auto Tex = std::make_shared<VulkanTexture>(Device, Image, DeviceMemory,
733+
Name, Desc);
734+
735+
bool IsRT = (Desc.Usage & TextureUsage::RenderTarget) != 0;
736+
bool IsDS = (Desc.Usage & TextureUsage::DepthStencil) != 0;
737+
if (IsRT || IsDS) {
738+
VkImageViewCreateInfo ViewCi = {};
739+
ViewCi.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
740+
ViewCi.viewType = VK_IMAGE_VIEW_TYPE_2D;
741+
ViewCi.format = getVulkanFormat(Desc.Format);
742+
ViewCi.subresourceRange.baseMipLevel = 0;
743+
ViewCi.subresourceRange.levelCount = 1;
744+
ViewCi.subresourceRange.baseArrayLayer = 0;
745+
ViewCi.subresourceRange.layerCount = 1;
746+
ViewCi.image = Image;
747+
if (IsRT) {
748+
ViewCi.components = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
749+
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
750+
ViewCi.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
751+
} else {
752+
ViewCi.subresourceRange.aspectMask =
753+
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
754+
}
755+
if (vkCreateImageView(Device, &ViewCi, nullptr, &Tex->View)) {
756+
// Tex destructor will clean up Image + Memory.
757+
return llvm::createStringError(std::errc::device_or_resource_busy,
758+
"Failed to create image view.");
759+
}
760+
}
761+
762+
return Tex;
726763
}
727764

728765
const Capabilities &getCapabilities() override {
@@ -1462,8 +1499,7 @@ class VulkanDevice : public offloadtest::Device {
14621499
llvm::Error createRenderPass(Pipeline &P, InvocationState &IS) {
14631500
std::array<VkAttachmentDescription, 2> Attachments = {};
14641501

1465-
Attachments[0].format = getVKFormat(P.Bindings.RTargetBufferPtr->Format,
1466-
P.Bindings.RTargetBufferPtr->Channels);
1502+
Attachments[0].format = getVulkanFormat(IS.RenderTarget->Desc.Format);
14671503
Attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
14681504
Attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
14691505
Attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
@@ -1472,7 +1508,7 @@ class VulkanDevice : public offloadtest::Device {
14721508
Attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
14731509
Attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
14741510

1475-
Attachments[1].format = VK_FORMAT_D32_SFLOAT_S8_UINT;
1511+
Attachments[1].format = getVulkanFormat(IS.DepthStencil->Desc.Format);
14761512
Attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
14771513
Attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
14781514
Attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
@@ -1543,52 +1579,16 @@ class VulkanDevice : public offloadtest::Device {
15431579
}
15441580

15451581
llvm::Error createFrameBuffer(Pipeline &P, InvocationState &IS) {
1546-
std::array<VkImageView, 2> Views = {};
1547-
VkImageViewCreateInfo ViewCreateInfo = {};
1548-
ViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1549-
ViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1550-
ViewCreateInfo.format = getVKFormat(P.Bindings.RTargetBufferPtr->Format,
1551-
P.Bindings.RTargetBufferPtr->Channels);
1552-
ViewCreateInfo.components = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
1553-
VK_COMPONENT_SWIZZLE_B,
1554-
VK_COMPONENT_SWIZZLE_A};
1555-
ViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1556-
ViewCreateInfo.subresourceRange.baseMipLevel = 0;
1557-
ViewCreateInfo.subresourceRange.baseArrayLayer = 0;
1558-
ViewCreateInfo.subresourceRange.layerCount = 1;
1559-
ViewCreateInfo.subresourceRange.levelCount = 1;
1560-
ViewCreateInfo.image = IS.RenderTarget->Image;
1561-
if (vkCreateImageView(Device, &ViewCreateInfo, nullptr, &Views[0]))
1562-
return llvm::createStringError(
1563-
std::errc::device_or_resource_busy,
1564-
"Failed to create frame buffer image view.");
1565-
IS.ImageViews.push_back(Views[0]);
1566-
1567-
VkImageViewCreateInfo DepthStencilViewCi = {};
1568-
DepthStencilViewCi.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1569-
DepthStencilViewCi.viewType = VK_IMAGE_VIEW_TYPE_2D;
1570-
DepthStencilViewCi.format = VK_FORMAT_D32_SFLOAT_S8_UINT;
1571-
DepthStencilViewCi.subresourceRange = {};
1572-
DepthStencilViewCi.subresourceRange.aspectMask =
1573-
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1574-
DepthStencilViewCi.subresourceRange.baseMipLevel = 0;
1575-
DepthStencilViewCi.subresourceRange.levelCount = 1;
1576-
DepthStencilViewCi.subresourceRange.baseArrayLayer = 0;
1577-
DepthStencilViewCi.subresourceRange.layerCount = 1;
1578-
DepthStencilViewCi.image = IS.DepthStencil->Image;
1579-
if (vkCreateImageView(Device, &DepthStencilViewCi, nullptr, &Views[1]))
1580-
return llvm::createStringError(
1581-
std::errc::device_or_resource_busy,
1582-
"Failed to create depth stencil image view.");
1583-
IS.ImageViews.push_back(Views[1]);
1582+
std::array<VkImageView, 2> Views = {IS.RenderTarget->View,
1583+
IS.DepthStencil->View};
15841584

15851585
VkFramebufferCreateInfo FbufCreateInfo = {};
15861586
FbufCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
15871587
FbufCreateInfo.renderPass = IS.RenderPass;
15881588
FbufCreateInfo.attachmentCount = Views.size();
15891589
FbufCreateInfo.pAttachments = Views.data();
1590-
FbufCreateInfo.width = P.Bindings.RTargetBufferPtr->OutputProps.Width;
1591-
FbufCreateInfo.height = P.Bindings.RTargetBufferPtr->OutputProps.Height;
1590+
FbufCreateInfo.width = IS.RenderTarget->Desc.Width;
1591+
FbufCreateInfo.height = IS.RenderTarget->Desc.Height;
15921592
FbufCreateInfo.layers = 1;
15931593

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

0 commit comments

Comments
 (0)