EDIT: More tight render graph system(barrier resource cond)
This commit is contained in:
@@ -230,20 +230,35 @@ bool RenderGraph::compile()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ImageState
|
struct ImageState
|
||||||
{
|
{
|
||||||
bool initialized = false;
|
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
// Accumulate read stages/accesses since last barrier or write.
|
||||||
VkPipelineStageFlags2 stage = VK_PIPELINE_STAGE_2_NONE;
|
VkPipelineStageFlags2 readStage = VK_PIPELINE_STAGE_2_NONE;
|
||||||
VkAccessFlags2 access = 0;
|
VkAccessFlags2 readAccess = 0;
|
||||||
};
|
// Track last write since last barrier.
|
||||||
|
VkPipelineStageFlags2 writeStage = VK_PIPELINE_STAGE_2_NONE;
|
||||||
|
VkAccessFlags2 writeAccess = 0;
|
||||||
|
};
|
||||||
|
|
||||||
struct BufferState
|
struct BufferState
|
||||||
{
|
{
|
||||||
bool initialized = false;
|
VkPipelineStageFlags2 readStage = VK_PIPELINE_STAGE_2_NONE;
|
||||||
VkPipelineStageFlags2 stage = VK_PIPELINE_STAGE_2_NONE;
|
VkAccessFlags2 readAccess = 0;
|
||||||
VkAccessFlags2 access = 0;
|
VkPipelineStageFlags2 writeStage = VK_PIPELINE_STAGE_2_NONE;
|
||||||
};
|
VkAccessFlags2 writeAccess = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto access_has_write = [](VkAccessFlags2 access) -> bool {
|
||||||
|
constexpr VkAccessFlags2 WRITE_MASK =
|
||||||
|
VK_ACCESS_2_TRANSFER_WRITE_BIT |
|
||||||
|
VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT |
|
||||||
|
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT |
|
||||||
|
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
|
||||||
|
VK_ACCESS_2_HOST_WRITE_BIT |
|
||||||
|
VK_ACCESS_2_MEMORY_WRITE_BIT;
|
||||||
|
return (access & WRITE_MASK) != 0;
|
||||||
|
};
|
||||||
|
|
||||||
auto is_depth_format = [](VkFormat format) {
|
auto is_depth_format = [](VkFormat format) {
|
||||||
switch (format)
|
switch (format)
|
||||||
@@ -410,10 +425,57 @@ bool RenderGraph::compile()
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const size_t imageCount = _resources.image_count();
|
const size_t imageCount = _resources.image_count();
|
||||||
const size_t bufferCount = _resources.buffer_count();
|
const size_t bufferCount = _resources.buffer_count();
|
||||||
std::vector<ImageState> imageStates(imageCount);
|
std::vector<ImageState> imageStates(imageCount);
|
||||||
std::vector<BufferState> bufferStates(bufferCount);
|
std::vector<BufferState> bufferStates(bufferCount);
|
||||||
|
|
||||||
|
// Seed initial states from imported/transient records. If an imported image has a known
|
||||||
|
// starting layout but no stage/access, be conservative and assume an unknown prior write.
|
||||||
|
for (size_t i = 0; i < imageCount; ++i)
|
||||||
|
{
|
||||||
|
const RGImageRecord *rec = _resources.get_image(RGImageHandle{static_cast<uint32_t>(i)});
|
||||||
|
if (!rec) continue;
|
||||||
|
imageStates[i].layout = rec->initialLayout;
|
||||||
|
if (rec->initialLayout == VK_IMAGE_LAYOUT_UNDEFINED) continue;
|
||||||
|
|
||||||
|
VkPipelineStageFlags2 st = rec->initialStage;
|
||||||
|
VkAccessFlags2 ac = rec->initialAccess;
|
||||||
|
if (st == VK_PIPELINE_STAGE_2_NONE && ac == 0)
|
||||||
|
{
|
||||||
|
st = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
|
||||||
|
ac = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT;
|
||||||
|
}
|
||||||
|
if (access_has_write(ac))
|
||||||
|
{
|
||||||
|
imageStates[i].writeStage = st;
|
||||||
|
imageStates[i].writeAccess = ac;
|
||||||
|
}
|
||||||
|
else if (ac != 0)
|
||||||
|
{
|
||||||
|
imageStates[i].readStage = st;
|
||||||
|
imageStates[i].readAccess = ac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < bufferCount; ++i)
|
||||||
|
{
|
||||||
|
const RGBufferRecord *rec = _resources.get_buffer(RGBufferHandle{static_cast<uint32_t>(i)});
|
||||||
|
if (!rec) continue;
|
||||||
|
VkPipelineStageFlags2 st = rec->initialStage;
|
||||||
|
VkAccessFlags2 ac = rec->initialAccess;
|
||||||
|
if (st == VK_PIPELINE_STAGE_2_NONE) st = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT;
|
||||||
|
if (access_has_write(ac))
|
||||||
|
{
|
||||||
|
bufferStates[i].writeStage = st;
|
||||||
|
bufferStates[i].writeAccess = ac;
|
||||||
|
}
|
||||||
|
else if (ac != 0)
|
||||||
|
{
|
||||||
|
bufferStates[i].readStage = st;
|
||||||
|
bufferStates[i].readAccess = ac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Track first/last use for lifetime diagnostics and future aliasing
|
// Track first/last use for lifetime diagnostics and future aliasing
|
||||||
std::vector<int> imageFirst(imageCount, -1), imageLast(imageCount, -1);
|
std::vector<int> imageFirst(imageCount, -1), imageLast(imageCount, -1);
|
||||||
@@ -457,26 +519,50 @@ bool RenderGraph::compile()
|
|||||||
|
|
||||||
ImageUsageInfo desired = usage_info_image(usage);
|
ImageUsageInfo desired = usage_info_image(usage);
|
||||||
|
|
||||||
ImageState prev = imageStates[id];
|
ImageState &state = imageStates[id];
|
||||||
VkImageLayout prevLayout = prev.initialized ? prev.layout : _resources.initial_layout(RGImageHandle{id});
|
const VkImageLayout prevLayout = state.layout;
|
||||||
VkPipelineStageFlags2 srcStage = prev.initialized
|
const bool layoutChange = prevLayout != desired.layout;
|
||||||
? prev.stage
|
const bool desiredWrite = access_has_write(desired.access);
|
||||||
: (prevLayout == VK_IMAGE_LAYOUT_UNDEFINED
|
const bool prevHasWrite = state.writeAccess != 0;
|
||||||
? VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT
|
const bool prevHasReads = state.readAccess != 0;
|
||||||
: VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
|
|
||||||
VkAccessFlags2 srcAccess = prev.initialized
|
|
||||||
? prev.access
|
|
||||||
: (prevLayout == VK_IMAGE_LAYOUT_UNDEFINED
|
|
||||||
? VkAccessFlags2{0}
|
|
||||||
: (VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT));
|
|
||||||
|
|
||||||
bool needBarrier = !prev.initialized
|
bool needBarrier = layoutChange || (prevHasReads && desiredWrite);
|
||||||
|| prevLayout != desired.layout
|
if (prevHasWrite)
|
||||||
|| prev.stage != desired.stage
|
{
|
||||||
|| prev.access != desired.access;
|
// Keep previous behavior: don't force a barrier if we stay in the exact same write state.
|
||||||
|
if (!(desiredWrite && !layoutChange && state.writeStage == desired.stage && state.writeAccess == desired.access))
|
||||||
|
{
|
||||||
|
needBarrier = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (needBarrier)
|
if (needBarrier)
|
||||||
{
|
{
|
||||||
|
VkPipelineStageFlags2 srcStage = VK_PIPELINE_STAGE_2_NONE;
|
||||||
|
VkAccessFlags2 srcAccess = 0;
|
||||||
|
if (prevHasWrite)
|
||||||
|
{
|
||||||
|
srcStage = state.writeStage;
|
||||||
|
srcAccess = state.writeAccess;
|
||||||
|
}
|
||||||
|
else if (prevHasReads)
|
||||||
|
{
|
||||||
|
srcStage = state.readStage;
|
||||||
|
srcAccess = state.readAccess;
|
||||||
|
}
|
||||||
|
else if (prevLayout == VK_IMAGE_LAYOUT_UNDEFINED)
|
||||||
|
{
|
||||||
|
srcStage = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT;
|
||||||
|
srcAccess = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Known layout but unknown access; be conservative.
|
||||||
|
srcStage = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
|
||||||
|
srcAccess = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT;
|
||||||
|
}
|
||||||
|
if (srcStage == VK_PIPELINE_STAGE_2_NONE) srcStage = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT;
|
||||||
|
|
||||||
VkImageMemoryBarrier2 barrier{.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2};
|
VkImageMemoryBarrier2 barrier{.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2};
|
||||||
barrier.srcStageMask = srcStage;
|
barrier.srcStageMask = srcStage;
|
||||||
barrier.srcAccessMask = srcAccess;
|
barrier.srcAccessMask = srcAccess;
|
||||||
@@ -525,10 +611,28 @@ bool RenderGraph::compile()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
imageStates[id].initialized = true;
|
if (needBarrier)
|
||||||
imageStates[id].layout = desired.layout;
|
{
|
||||||
imageStates[id].stage = desired.stage;
|
state.readStage = VK_PIPELINE_STAGE_2_NONE;
|
||||||
imageStates[id].access = desired.access;
|
state.readAccess = 0;
|
||||||
|
state.writeStage = VK_PIPELINE_STAGE_2_NONE;
|
||||||
|
state.writeAccess = 0;
|
||||||
|
}
|
||||||
|
state.layout = desired.layout;
|
||||||
|
if (desiredWrite)
|
||||||
|
{
|
||||||
|
state.readStage = VK_PIPELINE_STAGE_2_NONE;
|
||||||
|
state.readAccess = 0;
|
||||||
|
state.writeStage = desired.stage;
|
||||||
|
state.writeAccess = desired.access;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state.writeStage = VK_PIPELINE_STAGE_2_NONE;
|
||||||
|
state.writeAccess = 0;
|
||||||
|
state.readStage |= desired.stage;
|
||||||
|
state.readAccess |= desired.access;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bufferCount == 0) continue;
|
if (bufferCount == 0) continue;
|
||||||
@@ -563,24 +667,37 @@ bool RenderGraph::compile()
|
|||||||
|
|
||||||
BufferUsageInfo desired = usage_info_buffer(usage);
|
BufferUsageInfo desired = usage_info_buffer(usage);
|
||||||
|
|
||||||
BufferState prev = bufferStates[id];
|
BufferState &state = bufferStates[id];
|
||||||
VkPipelineStageFlags2 srcStage = prev.initialized
|
const bool desiredWrite = access_has_write(desired.access);
|
||||||
? prev.stage
|
const bool prevHasWrite = state.writeAccess != 0;
|
||||||
: _resources.initial_stage(RGBufferHandle{id});
|
const bool prevHasReads = state.readAccess != 0;
|
||||||
if (srcStage == VK_PIPELINE_STAGE_2_NONE)
|
|
||||||
{
|
|
||||||
srcStage = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT;
|
|
||||||
}
|
|
||||||
VkAccessFlags2 srcAccess = prev.initialized
|
|
||||||
? prev.access
|
|
||||||
: _resources.initial_access(RGBufferHandle{id});
|
|
||||||
|
|
||||||
bool needBarrier = !prev.initialized
|
bool needBarrier = (prevHasReads && desiredWrite);
|
||||||
|| prev.stage != desired.stage
|
if (prevHasWrite)
|
||||||
|| prev.access != desired.access;
|
{
|
||||||
|
// Keep previous behavior: no barrier if staying in the exact same write state.
|
||||||
|
if (!(desiredWrite && state.writeStage == desired.stage && state.writeAccess == desired.access))
|
||||||
|
{
|
||||||
|
needBarrier = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (needBarrier)
|
if (needBarrier)
|
||||||
{
|
{
|
||||||
|
VkPipelineStageFlags2 srcStage = VK_PIPELINE_STAGE_2_NONE;
|
||||||
|
VkAccessFlags2 srcAccess = 0;
|
||||||
|
if (prevHasWrite)
|
||||||
|
{
|
||||||
|
srcStage = state.writeStage;
|
||||||
|
srcAccess = state.writeAccess;
|
||||||
|
}
|
||||||
|
else if (prevHasReads)
|
||||||
|
{
|
||||||
|
srcStage = state.readStage;
|
||||||
|
srcAccess = state.readAccess;
|
||||||
|
}
|
||||||
|
if (srcStage == VK_PIPELINE_STAGE_2_NONE) srcStage = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT;
|
||||||
|
|
||||||
VkBufferMemoryBarrier2 barrier{.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2};
|
VkBufferMemoryBarrier2 barrier{.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2};
|
||||||
barrier.srcStageMask = srcStage;
|
barrier.srcStageMask = srcStage;
|
||||||
barrier.srcAccessMask = srcAccess;
|
barrier.srcAccessMask = srcAccess;
|
||||||
@@ -616,11 +733,29 @@ bool RenderGraph::compile()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bufferStates[id].initialized = true;
|
if (needBarrier)
|
||||||
bufferStates[id].stage = desired.stage;
|
{
|
||||||
bufferStates[id].access = desired.access;
|
state.readStage = VK_PIPELINE_STAGE_2_NONE;
|
||||||
|
state.readAccess = 0;
|
||||||
|
state.writeStage = VK_PIPELINE_STAGE_2_NONE;
|
||||||
|
state.writeAccess = 0;
|
||||||
|
}
|
||||||
|
if (desiredWrite)
|
||||||
|
{
|
||||||
|
state.readStage = VK_PIPELINE_STAGE_2_NONE;
|
||||||
|
state.readAccess = 0;
|
||||||
|
state.writeStage = desired.stage;
|
||||||
|
state.writeAccess = desired.access;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state.writeStage = VK_PIPELINE_STAGE_2_NONE;
|
||||||
|
state.writeAccess = 0;
|
||||||
|
state.readStage |= desired.stage;
|
||||||
|
state.readAccess |= desired.access;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Store lifetimes into records for diagnostics/aliasing
|
// Store lifetimes into records for diagnostics/aliasing
|
||||||
for (size_t i = 0; i < imageCount; ++i)
|
for (size_t i = 0; i < imageCount; ++i)
|
||||||
@@ -760,8 +895,6 @@ void RenderGraph::execute(VkCommandBuffer cmd)
|
|||||||
{
|
{
|
||||||
depthInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
depthInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
}
|
}
|
||||||
if (p.depthAttachment.clearOnLoad) depthInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
|
||||||
else depthInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
|
||||||
if (!p.depthAttachment.store) depthInfo.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
if (!p.depthAttachment.store) depthInfo.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
hasDepth = true;
|
hasDepth = true;
|
||||||
if (rec->extent.width && rec->extent.height) set_or_clamp(rec->extent);
|
if (rec->extent.width && rec->extent.height) set_or_clamp(rec->extent);
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ RGImageHandle RGResourceRegistry::add_imported(const RGImportedImageDesc& d)
|
|||||||
rec.format = d.format;
|
rec.format = d.format;
|
||||||
rec.extent = d.extent;
|
rec.extent = d.extent;
|
||||||
rec.initialLayout = d.currentLayout;
|
rec.initialLayout = d.currentLayout;
|
||||||
|
// Keep the earliest known stage/access if set; otherwise record provided
|
||||||
|
if (rec.initialStage == VK_PIPELINE_STAGE_2_NONE) rec.initialStage = d.currentStage;
|
||||||
|
if (rec.initialAccess == 0) rec.initialAccess = d.currentAccess;
|
||||||
return RGImageHandle{it->second};
|
return RGImageHandle{it->second};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +42,8 @@ RGImageHandle RGResourceRegistry::add_imported(const RGImportedImageDesc& d)
|
|||||||
rec.format = d.format;
|
rec.format = d.format;
|
||||||
rec.extent = d.extent;
|
rec.extent = d.extent;
|
||||||
rec.initialLayout = d.currentLayout;
|
rec.initialLayout = d.currentLayout;
|
||||||
|
rec.initialStage = d.currentStage;
|
||||||
|
rec.initialAccess = d.currentAccess;
|
||||||
_images.push_back(rec);
|
_images.push_back(rec);
|
||||||
uint32_t id = static_cast<uint32_t>(_images.size() - 1);
|
uint32_t id = static_cast<uint32_t>(_images.size() - 1);
|
||||||
if (d.image != VK_NULL_HANDLE) _imageLookup[d.image] = id;
|
if (d.image != VK_NULL_HANDLE) _imageLookup[d.image] = id;
|
||||||
@@ -53,6 +58,8 @@ RGImageHandle RGResourceRegistry::add_transient(const RGImageDesc& d)
|
|||||||
rec.format = d.format;
|
rec.format = d.format;
|
||||||
rec.extent = d.extent;
|
rec.extent = d.extent;
|
||||||
rec.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
rec.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
rec.initialStage = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT;
|
||||||
|
rec.initialAccess = 0;
|
||||||
rec.creationUsage = d.usage;
|
rec.creationUsage = d.usage;
|
||||||
|
|
||||||
VkExtent3D size{ d.extent.width, d.extent.height, 1 };
|
VkExtent3D size{ d.extent.width, d.extent.height, 1 };
|
||||||
@@ -171,6 +178,18 @@ VkFormat RGResourceRegistry::image_format(RGImageHandle h) const
|
|||||||
return rec ? rec->format : VK_FORMAT_UNDEFINED;
|
return rec ? rec->format : VK_FORMAT_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkPipelineStageFlags2 RGResourceRegistry::initial_stage(RGImageHandle h) const
|
||||||
|
{
|
||||||
|
const RGImageRecord* rec = get_image(h);
|
||||||
|
return rec ? rec->initialStage : VK_PIPELINE_STAGE_2_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkAccessFlags2 RGResourceRegistry::initial_access(RGImageHandle h) const
|
||||||
|
{
|
||||||
|
const RGImageRecord* rec = get_image(h);
|
||||||
|
return rec ? rec->initialAccess : VkAccessFlags2{0};
|
||||||
|
}
|
||||||
|
|
||||||
VkPipelineStageFlags2 RGResourceRegistry::initial_stage(RGBufferHandle h) const
|
VkPipelineStageFlags2 RGResourceRegistry::initial_stage(RGBufferHandle h) const
|
||||||
{
|
{
|
||||||
const RGBufferRecord* rec = get_buffer(h);
|
const RGBufferRecord* rec = get_buffer(h);
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ struct RGImageRecord
|
|||||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||||
VkExtent2D extent{0, 0};
|
VkExtent2D extent{0, 0};
|
||||||
VkImageLayout initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
VkImageLayout initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
VkPipelineStageFlags2 initialStage = VK_PIPELINE_STAGE_2_NONE;
|
||||||
|
VkAccessFlags2 initialAccess = 0;
|
||||||
VkImageUsageFlags creationUsage = 0; // if transient; 0 for imported
|
VkImageUsageFlags creationUsage = 0; // if transient; 0 for imported
|
||||||
|
|
||||||
// If transient, keep allocation owner for cleanup
|
// If transient, keep allocation owner for cleanup
|
||||||
@@ -75,6 +77,8 @@ public:
|
|||||||
|
|
||||||
VkImageLayout initial_layout(RGImageHandle h) const;
|
VkImageLayout initial_layout(RGImageHandle h) const;
|
||||||
VkFormat image_format(RGImageHandle h) const;
|
VkFormat image_format(RGImageHandle h) const;
|
||||||
|
VkPipelineStageFlags2 initial_stage(RGImageHandle h) const;
|
||||||
|
VkAccessFlags2 initial_access(RGImageHandle h) const;
|
||||||
|
|
||||||
VkPipelineStageFlags2 initial_stage(RGBufferHandle h) const;
|
VkPipelineStageFlags2 initial_stage(RGBufferHandle h) const;
|
||||||
VkAccessFlags2 initial_access(RGBufferHandle h) const;
|
VkAccessFlags2 initial_access(RGBufferHandle h) const;
|
||||||
|
|||||||
@@ -64,6 +64,11 @@ struct RGImportedImageDesc
|
|||||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||||
VkExtent2D extent{0, 0};
|
VkExtent2D extent{0, 0};
|
||||||
VkImageLayout currentLayout = VK_IMAGE_LAYOUT_UNDEFINED; // layout at graph begin
|
VkImageLayout currentLayout = VK_IMAGE_LAYOUT_UNDEFINED; // layout at graph begin
|
||||||
|
// Optional: last known access state at graph begin. If left as NONE/0 and
|
||||||
|
// currentLayout is not UNDEFINED, the graph conservatively assumes an
|
||||||
|
// unknown prior write (ALL_COMMANDS + MEMORY_READ|WRITE) for the first barrier.
|
||||||
|
VkPipelineStageFlags2 currentStage = VK_PIPELINE_STAGE_2_NONE;
|
||||||
|
VkAccessFlags2 currentAccess = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RGImportedBufferDesc
|
struct RGImportedBufferDesc
|
||||||
|
|||||||
Reference in New Issue
Block a user