1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-02 19:24:12 +01:00

[dxvk] Removed explicit image barriers for render passes

Instead, the color format and layout will now be set in
the render pass description. This slows down render pass
lookups but may improve efficiency and work around driver
bugs.
This commit is contained in:
Philip Rebohle 2018-01-22 19:21:46 +01:00
parent 1da23755b7
commit 0900dfd0e3
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
6 changed files with 114 additions and 137 deletions

View File

@ -1108,9 +1108,6 @@ namespace dxvk {
&& (m_state.om.framebuffer != nullptr)) {
m_flags.set(DxvkContextFlag::GpRenderPassBound);
this->transformLayoutsRenderPassBegin(
m_state.om.framebuffer->renderTargets());
const DxvkFramebufferSize fbSize
= m_state.om.framebuffer->size();
@ -1139,9 +1136,6 @@ namespace dxvk {
if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) {
m_flags.clr(DxvkContextFlag::GpRenderPassBound);
m_cmd->cmdEndRenderPass();
this->transformLayoutsRenderPassEnd(
m_state.om.framebuffer->renderTargets());
}
}
@ -1493,97 +1487,4 @@ namespace dxvk {
m_barriers.recordCommands(m_cmd);
}
void DxvkContext::transformLayoutsRenderPassBegin(
const DxvkRenderTargets& renderTargets) {
// Ensure that all color attachments are in the optimal layout.
// Any image that is used as a present source requires special
// care as we cannot use it for reading.
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
const Rc<DxvkImageView> target = renderTargets.getColorTarget(i);
if ((target != nullptr)
&& (target->imageInfo().layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)) {
VkImageLayout srcLayout = target->imageInfo().layout;
if (srcLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
srcLayout = VK_IMAGE_LAYOUT_UNDEFINED;
m_barriers.accessImage(
target->image(),
target->subresources(),
srcLayout,
target->imageInfo().stages,
target->imageInfo().access,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
}
}
// Transform the depth-stencil view to the optimal layout
const Rc<DxvkImageView> dsTarget = renderTargets.getDepthTarget();
if ((dsTarget != nullptr)
&& (dsTarget->imageInfo().layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)) {
m_barriers.accessImage(
dsTarget->image(),
dsTarget->subresources(),
dsTarget->imageInfo().layout,
dsTarget->imageInfo().stages,
dsTarget->imageInfo().access,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);
}
m_barriers.recordCommands(m_cmd);
}
void DxvkContext::transformLayoutsRenderPassEnd(
const DxvkRenderTargets& renderTargets) {
// Transform color attachments back to their original layouts and
// make sure that they can be used for subsequent draw or compute
// operations. Swap chain images are treated like any other image.
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
const Rc<DxvkImageView> target = renderTargets.getColorTarget(i);
if (target != nullptr) {
m_barriers.accessImage(
target->image(),
target->subresources(),
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
target->imageInfo().layout,
target->imageInfo().stages,
target->imageInfo().access);
}
}
// Transform the depth-stencil attachment back to its original layout.
const Rc<DxvkImageView> dsTarget = renderTargets.getDepthTarget();
if (dsTarget != nullptr) {
m_barriers.accessImage(
dsTarget->image(),
dsTarget->subresources(),
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
dsTarget->imageInfo().layout,
dsTarget->imageInfo().stages,
dsTarget->imageInfo().access);
}
m_barriers.recordCommands(m_cmd);
}
}

View File

@ -561,12 +561,6 @@ namespace dxvk {
void commitComputeBarriers();
void transformLayoutsRenderPassBegin(
const DxvkRenderTargets& renderTargets);
void transformLayoutsRenderPassEnd(
const DxvkRenderTargets& renderTargets);
};
}

View File

@ -11,13 +11,19 @@ namespace dxvk {
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
if (m_colorTargets.at(i) != nullptr) {
result.setColorFormat(i, m_colorTargets.at(i)->info().format);
result.setColorFormat(i, DxvkRenderTargetFormat {
m_colorTargets.at(i)->imageInfo().format,
m_colorTargets.at(i)->imageInfo().layout,
m_colorTargets.at(i)->imageInfo().layout });
result.setSampleCount(m_colorTargets.at(i)->image()->info().sampleCount);
}
}
if (m_depthTarget != nullptr) {
result.setDepthFormat(m_depthTarget->info().format);
result.setDepthFormat(DxvkRenderTargetFormat {
m_depthTarget->imageInfo().format,
m_depthTarget->imageInfo().layout,
m_depthTarget->imageInfo().layout });
result.setSampleCount(m_depthTarget->image()->info().sampleCount);
}

View File

@ -2,23 +2,38 @@
namespace dxvk {
DxvkRenderPassFormat::DxvkRenderPassFormat() {
for (uint32_t i = 0; i < MaxNumRenderTargets; i++)
m_color[i] = VK_FORMAT_UNDEFINED;
m_depth = VK_FORMAT_UNDEFINED;
m_samples = VK_SAMPLE_COUNT_1_BIT;
bool DxvkRenderTargetFormat::operator == (const DxvkRenderTargetFormat& other) const {
return this->format == other.format
&& this->initialLayout == other.initialLayout
&& this->finalLayout == other.finalLayout;
}
bool DxvkRenderTargetFormat::operator != (const DxvkRenderTargetFormat& other) const {
return !this->operator == (other);
}
size_t DxvkRenderTargetFormat::hash() const {
std::hash<VkFormat> fhash;
std::hash<VkImageLayout> lhash;
DxvkHashState result;
result.add(fhash(this->format));
result.add(lhash(this->initialLayout));
result.add(lhash(this->finalLayout));
return result;
}
size_t DxvkRenderPassFormat::hash() const {
DxvkHashState result;
std::hash<VkFormat> fhash;
std::hash<VkSampleCountFlagBits> shash;
DxvkHashState result;
for (uint32_t i = 0; i < MaxNumRenderTargets; i++)
result.add(fhash(m_color[i]));
result.add(m_color[i].hash());
result.add(fhash(m_depth));
result.add(m_depth.hash());
result.add(shash(m_samples));
return result;
}
@ -49,17 +64,19 @@ namespace dxvk {
// Render passes may not require the previous
// contents of the attachments to be preserved.
if (fmt.getDepthFormat() != VK_FORMAT_UNDEFINED) {
const DxvkRenderTargetFormat depthFmt = fmt.getDepthFormat();
if (depthFmt.format != VK_FORMAT_UNDEFINED) {
VkAttachmentDescription desc;
desc.flags = 0;
desc.format = fmt.getDepthFormat();
desc.format = depthFmt.format;
desc.samples = fmt.getSampleCount();
desc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
desc.initialLayout = depthFmt.initialLayout;
desc.finalLayout = depthFmt.finalLayout;
depthRef.attachment = attachments.size();
depthRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
@ -68,20 +85,22 @@ namespace dxvk {
}
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
const DxvkRenderTargetFormat colorFmt = fmt.getColorFormat(i);
colorRef[i].attachment = VK_ATTACHMENT_UNUSED;
colorRef[i].layout = VK_IMAGE_LAYOUT_UNDEFINED;
if (fmt.getColorFormat(i) != VK_FORMAT_UNDEFINED) {
if (colorFmt.format != VK_FORMAT_UNDEFINED) {
VkAttachmentDescription desc;
desc.flags = 0;
desc.format = fmt.getColorFormat(i);
desc.format = colorFmt.format;
desc.samples = fmt.getSampleCount();
desc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
desc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
desc.initialLayout = colorFmt.initialLayout;
desc.finalLayout = colorFmt.finalLayout;
colorRef[i].attachment = attachments.size();
colorRef[i].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
@ -98,10 +117,47 @@ namespace dxvk {
subpass.colorAttachmentCount = colorRef.size();
subpass.pColorAttachments = colorRef.data();
subpass.pResolveAttachments = nullptr;
subpass.pDepthStencilAttachment = fmt.getDepthFormat() != VK_FORMAT_UNDEFINED ? &depthRef : nullptr;
subpass.pDepthStencilAttachment = depthFmt.format != VK_FORMAT_UNDEFINED ? &depthRef : nullptr;
subpass.preserveAttachmentCount = 0;
subpass.pPreserveAttachments = nullptr;
std::array<VkSubpassDependency, 2> subpassDeps = {{
{ VK_SUBPASS_EXTERNAL, 0,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
VK_ACCESS_SHADER_READ_BIT |
VK_ACCESS_SHADER_WRITE_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_TRANSFER_READ_BIT |
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 0 },
{ 0, VK_SUBPASS_EXTERNAL,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
VK_ACCESS_SHADER_READ_BIT |
VK_ACCESS_SHADER_WRITE_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_TRANSFER_READ_BIT |
VK_ACCESS_TRANSFER_WRITE_BIT, 0 },
}};
VkRenderPassCreateInfo info;
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
info.pNext = nullptr;
@ -110,8 +166,8 @@ namespace dxvk {
info.pAttachments = attachments.data();
info.subpassCount = 1;
info.pSubpasses = &subpass;
info.dependencyCount = 0;
info.pDependencies = nullptr;
info.dependencyCount = subpassDeps.size();
info.pDependencies = subpassDeps.data();
if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &m_renderPass) != VK_SUCCESS)
throw DxvkError("DxvkRenderPass::DxvkRenderPass: Failed to create render pass object");

View File

@ -9,6 +9,24 @@
namespace dxvk {
/**
* \brief Format and layout info for a sigle render target
*
* Stores the format, initial layout and
* final layout of a render target.
*/
struct DxvkRenderTargetFormat {
VkFormat format = VK_FORMAT_UNDEFINED;
VkImageLayout initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
VkImageLayout finalLayout = VK_IMAGE_LAYOUT_UNDEFINED;
bool operator == (const DxvkRenderTargetFormat& other) const;
bool operator != (const DxvkRenderTargetFormat& other) const;
size_t hash() const;
};
/**
* \brief Render pass format
*
@ -19,8 +37,6 @@ namespace dxvk {
public:
DxvkRenderPassFormat();
/**
* \brief Retrieves color target format
*
@ -29,7 +45,7 @@ namespace dxvk {
* \param [in] id Color target index
* \returns Color target format
*/
VkFormat getColorFormat(uint32_t id) const {
DxvkRenderTargetFormat getColorFormat(uint32_t id) const {
return m_color.at(id);
}
@ -39,7 +55,7 @@ namespace dxvk {
* If the color target has not been defined,
* this will return \c VK_FORMAT_UNDEFINED.
*/
VkFormat getDepthFormat() const {
DxvkRenderTargetFormat getDepthFormat() const {
return m_depth;
}
@ -60,7 +76,7 @@ namespace dxvk {
* \param [in] id Color target index
* \param [in] fmt Color target format
*/
void setColorFormat(uint32_t id, VkFormat fmt) {
void setColorFormat(uint32_t id, DxvkRenderTargetFormat fmt) {
m_color.at(id) = fmt;
}
@ -68,7 +84,7 @@ namespace dxvk {
* \brief Sets depth-stencil format
* \param [in] fmt Depth-stencil format
*/
void setDepthFormat(VkFormat fmt) {
void setDepthFormat(DxvkRenderTargetFormat fmt) {
m_depth = fmt;
}
@ -91,9 +107,9 @@ namespace dxvk {
private:
std::array<VkFormat, MaxNumRenderTargets> m_color;
VkFormat m_depth;
VkSampleCountFlagBits m_samples;
std::array<DxvkRenderTargetFormat, MaxNumRenderTargets> m_color;
DxvkRenderTargetFormat m_depth;
VkSampleCountFlagBits m_samples = VK_SAMPLE_COUNT_1_BIT;
};

View File

@ -132,7 +132,11 @@ namespace dxvk {
// Create the render pass object
DxvkRenderPassFormat renderTargetFormat;
renderTargetFormat.setColorFormat(0, fmt.format);
renderTargetFormat.setColorFormat(0,
DxvkRenderTargetFormat { fmt.format,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR });
m_renderPass = new DxvkRenderPass(
m_vkd, renderTargetFormat);