Skip to content
This repository was archived by the owner on Jul 19, 2018. It is now read-only.

Commit dbf7463

Browse files
committed
layers:Streamline descriptor mem access update
Put memory access updates for active descriptors directly into the read and write vectors. This kills an extra data structure transformation where we moved the accesses through sets before putting them into vectors. There was no benefit to the extra overhead and this update brings the performance of validation with memory access checks on-par with validation when the checks are disabled. Still have the warning callback disabled for now. The ENABLE_MEMORY_ACCESS_CALLBACK define in vk_layer_config.h can be un-commented to enable the warning callback, as well as the descriptor memory access tracking.
1 parent 9028d8d commit dbf7463

4 files changed

Lines changed: 52 additions & 36 deletions

File tree

layers/core_validation.cpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5913,26 +5913,21 @@ static bool ValidateCmdDrawType(layer_data *dev_data, VkCommandBuffer cmd_buffer
59135913
skip |= (VK_PIPELINE_BIND_POINT_GRAPHICS == bind_point) ? outsideRenderPass(dev_data, *cb_state, caller, msg_code)
59145914
: insideRenderPass(dev_data, *cb_state, caller, msg_code);
59155915
#ifndef ENABLE_MEMORY_ACCESS_CALLBACK
5916-
// TODO : Early return here to skip the memory access checking below. The checks are functional but cause a perf hit
5917-
// and the callback that's used is disabled, so also turning off these checks for now.
5916+
// Early return here to skip the memory access checking below.
5917+
// The callback that's used is disabled, so also turning off these checks for now.
59185918
// To re-enable the checks, just remove this early return
59195919
return skip;
59205920
#endif
59215921
// Grab mem accesses for this draw & check for missing synchs
59225922
auto const &state = (*cb_state)->lastBound[bind_point];
59235923
PIPELINE_STATE *pPipe = state.pipeline_state;
59245924
if (VK_NULL_HANDLE != state.pipeline_layout.layout) {
5925-
MemAccessGroup mem_access_group;
59265925
for (const auto &set_binding_pair : pPipe->active_slots) {
59275926
uint32_t setIndex = set_binding_pair.first;
59285927
// Pull the set node
59295928
cvdescriptorset::DescriptorSet *descriptor_set = state.boundDescriptorSets[setIndex];
59305929
if (descriptor_set) {
5931-
// For given active slots record updated images & buffers
5932-
descriptor_set->GetReadWriteBuffersAndImages(set_binding_pair.second, &mem_access_group.read_buffers,
5933-
&mem_access_group.read_images, &mem_access_group.write_buffers,
5934-
&mem_access_group.write_images);
5935-
UpdateRWMemoryAccessVectors(dev_data, cmd_type, read_accesses, write_accesses, mem_access_group);
5930+
descriptor_set->AddReadWriteBuffersAndImages(set_binding_pair.second, cmd_type, read_accesses, write_accesses);
59365931
}
59375932
}
59385933
skip |= ValidateRWMemoryAccesses(dev_data->report_data, cmd_buffer, (*cb_state)->mem_accesses, read_accesses,

layers/descriptor_sets.cpp

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -555,12 +555,11 @@ bool cvdescriptorset::DescriptorSet::ValidateDrawState(const std::map<uint32_t,
555555
return true;
556556
}
557557

558-
// For given bindings, place any update buffers or images into the passed-in unordered_sets
559-
uint32_t cvdescriptorset::DescriptorSet::GetReadWriteBuffersAndImages(const std::map<uint32_t, descriptor_req> &bindings,
560-
std::unordered_set<VkBuffer> *read_buffer_set,
561-
std::unordered_set<VkImageView> *read_image_set,
562-
std::unordered_set<VkBuffer> *write_buffer_set,
563-
std::unordered_set<VkImageView> *write_image_set) const {
558+
// For given bindings, place any active buffers or images into the passed-in vectors
559+
// TODO: Currently just adding entire binding as imprecise update, but ideally would limit access based on view
560+
uint32_t cvdescriptorset::DescriptorSet::AddReadWriteBuffersAndImages(const std::map<uint32_t, descriptor_req> &bindings,
561+
CMD_TYPE cmd, std::vector<MemoryAccess> *read_access_vector,
562+
std::vector<MemoryAccess> *write_access_vector) const {
564563
auto num_updates = 0;
565564
for (auto binding_pair : bindings) {
566565
auto binding = binding_pair.first;
@@ -569,49 +568,71 @@ uint32_t cvdescriptorset::DescriptorSet::GetReadWriteBuffersAndImages(const std:
569568
continue;
570569
}
571570
auto start_idx = p_layout_->GetGlobalStartIndexFromBinding(binding);
572-
auto &buffer_set = read_buffer_set;
573-
auto &image_set = read_image_set;
571+
const auto descriptor_count = p_layout_->GetDescriptorCountFromBinding(binding);
572+
auto &update_vector = read_access_vector;
573+
auto update_function = &AddReadMemoryAccess;
574574
if (descriptors_[start_idx]->IsStorage()) {
575-
buffer_set = write_buffer_set;
576-
image_set = write_image_set;
575+
update_vector = write_access_vector;
576+
update_function = &AddWriteMemoryAccess;
577577
}
578578
switch (descriptors_[start_idx]->descriptor_class) {
579579
case (Image): {
580-
for (uint32_t i = 0; i < p_layout_->GetDescriptorCountFromBinding(binding); ++i) {
580+
for (uint32_t i = 0; i < descriptor_count; ++i) {
581581
if (descriptors_[start_idx + i]->updated) {
582-
image_set->insert(static_cast<ImageDescriptor *>(descriptors_[start_idx + i].get())->GetImageView());
583-
num_updates++;
582+
auto image_view = static_cast<ImageDescriptor *>(descriptors_[start_idx + i].get())->GetImageView();
583+
auto image_view_state = GetImageViewState(device_data_, image_view);
584+
if (image_view_state) {
585+
auto image_node = GetImageState(device_data_, image_view_state->create_info.image);
586+
if (image_node) {
587+
update_function(cmd, update_vector, image_node->binding, false);
588+
num_updates++;
589+
}
590+
}
584591
}
585592
}
586593
break;
587594
}
588595
case (ImageSampler): {
589-
for (uint32_t i = 0; i < p_layout_->GetDescriptorCountFromBinding(binding); ++i) {
596+
for (uint32_t i = 0; i < descriptor_count; ++i) {
590597
if (descriptors_[start_idx + i]->updated) {
591-
image_set->insert(static_cast<ImageSamplerDescriptor *>(descriptors_[start_idx + i].get())->GetImageView());
592-
num_updates++;
598+
auto image_view = static_cast<ImageSamplerDescriptor *>(descriptors_[start_idx + i].get())->GetImageView();
599+
auto image_view_state = GetImageViewState(device_data_, image_view);
600+
if (image_view_state) {
601+
auto image_node = GetImageState(device_data_, image_view_state->create_info.image);
602+
if (image_node) {
603+
update_function(cmd, update_vector, image_node->binding, false);
604+
num_updates++;
605+
}
606+
}
593607
}
594608
}
595609
break;
596610
}
597611
case (TexelBuffer): {
598-
for (uint32_t i = 0; i < p_layout_->GetDescriptorCountFromBinding(binding); ++i) {
612+
for (uint32_t i = 0; i < descriptor_count; ++i) {
599613
if (descriptors_[start_idx + i]->updated) {
600614
auto bufferview = static_cast<TexelDescriptor *>(descriptors_[start_idx + i].get())->GetBufferView();
601615
auto bv_state = GetBufferViewState(device_data_, bufferview);
602616
if (bv_state) {
603-
buffer_set->insert(bv_state->create_info.buffer);
604-
num_updates++;
617+
auto buff_state = GetBufferState(device_data_, bv_state->create_info.buffer);
618+
if (buff_state) {
619+
update_function(cmd, update_vector, buff_state->binding, false);
620+
num_updates++;
621+
}
605622
}
606623
}
607624
}
608625
break;
609626
}
610627
case (GeneralBuffer): {
611-
for (uint32_t i = 0; i < p_layout_->GetDescriptorCountFromBinding(binding); ++i) {
628+
for (uint32_t i = 0; i < descriptor_count; ++i) {
612629
if (descriptors_[start_idx + i]->updated) {
613-
buffer_set->insert(static_cast<BufferDescriptor *>(descriptors_[start_idx + i].get())->GetBuffer());
614-
num_updates++;
630+
auto buff_state = GetBufferState(
631+
device_data_, static_cast<BufferDescriptor *>(descriptors_[start_idx + i].get())->GetBuffer());
632+
if (buff_state) {
633+
update_function(cmd, update_vector, buff_state->binding, false);
634+
num_updates++;
635+
}
615636
}
616637
}
617638
break;

layers/descriptor_sets.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -347,12 +347,10 @@ class DescriptorSet : public BASE_NODE {
347347
// For given bindings validate state at time of draw is correct, returning false on error and writing error details into string*
348348
bool ValidateDrawState(const std::map<uint32_t, descriptor_req> &, const std::vector<uint32_t> &, const GLOBAL_CB_NODE *,
349349
const char *caller, std::string *) const;
350-
// For given set of bindings, add any buffers and images that will be updated to their respective unordered_sets & return number
351-
// of objects inserted
352-
uint32_t GetReadWriteBuffersAndImages(const std::map<uint32_t, descriptor_req> &, std::unordered_set<VkBuffer> *read_buffer_set,
353-
std::unordered_set<VkImageView> *read_image_set,
354-
std::unordered_set<VkBuffer> *write_buffer_set,
355-
std::unordered_set<VkImageView> *write_image_set) const;
350+
// For given set of bindings, add memory bindings for buffers and images that will be updated to respective read & write vectors
351+
uint32_t AddReadWriteBuffersAndImages(const std::map<uint32_t, descriptor_req> &bindings, CMD_TYPE cmd,
352+
std::vector<MemoryAccess> *read_access_vector,
353+
std::vector<MemoryAccess> *write_access_vector) const;
356354

357355
// Descriptor Update functions. These functions validate state and perform update separately
358356
// Validate contents of a WriteUpdate

layers/vk_layer_config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
extern "C" {
3030
#endif
3131

32+
//#define ENABLE_MEMORY_ACCESS_CALLBACK
33+
3234
// Definitions for Debug Actions
3335
typedef enum VkLayerDbgActionBits {
3436
VK_DBG_LAYER_ACTION_IGNORE = 0x00000000,

0 commit comments

Comments
 (0)