Skip to content

Commit

Permalink
layers: Cache surface formats in SURFACE_STATE
Browse files Browse the repository at this point in the history
Until commit c7a834a, each PHYSICAL_DEVICE_STATE had a cache
of supported surface formats which was used in validating
swapchain creation. This cache was removed, in part because really
the cache should be limited to each specific surface. Removing the
cache caused a performance degradation on some platforms, so
cache these structures in SURFACE_STATE instead.
  • Loading branch information
jeremyg-lunarg committed Oct 18, 2021
1 parent 78b1f89 commit ebe8d10
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 8 deletions.
8 changes: 2 additions & 6 deletions layers/core_validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13818,17 +13818,13 @@ bool CoreChecks::ValidateCreateSwapchain(const char *func_name, VkSwapchainCreat
}

// Validate pCreateInfo values with the results of vkGetPhysicalDeviceSurfaceFormatsKHR():
std::vector<VkSurfaceFormatKHR> surface_formats;
uint32_t surface_format_count = 0;
DispatchGetPhysicalDeviceSurfaceFormatsKHR(physical_device, pCreateInfo->surface, &surface_format_count, nullptr);
surface_formats.resize(surface_format_count);
DispatchGetPhysicalDeviceSurfaceFormatsKHR(physical_device, pCreateInfo->surface, &surface_format_count, &surface_formats[0]);
{
// Validate pCreateInfo->imageFormat against VkSurfaceFormatKHR::format:
bool found_format = false;
bool found_color_space = false;
bool found_match = false;
for (const auto &format : surface_formats) {
const auto entry = surface_state->formats.find(physical_device_state->PhysDev());
for (const auto &format : entry->second) {
if (pCreateInfo->imageFormat == format.format) {
// Validate pCreateInfo->imageColorSpace against VkSurfaceFormatKHR::colorSpace:
found_format = true;
Expand Down
22 changes: 22 additions & 0 deletions layers/image_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,28 @@ void SWAPCHAIN_NODE::NotifyInvalidate(const LogObjectList &invalid_handles, bool
}
}

static layer_data::unordered_map<VkPhysicalDevice, std::vector<VkSurfaceFormatKHR>> GetSurfaceFormats(
ValidationStateTracker *instance_state, VkSurfaceKHR s) {
layer_data::unordered_map<VkPhysicalDevice, std::vector<VkSurfaceFormatKHR>> result;
for (auto &entry : instance_state->physical_device_map) {
auto physical_device = entry.first;
uint32_t surface_format_count = 0;

std::vector<VkSurfaceFormatKHR> surface_formats;
DispatchGetPhysicalDeviceSurfaceFormatsKHR(physical_device, s, &surface_format_count, nullptr);
surface_formats.resize(surface_format_count);
DispatchGetPhysicalDeviceSurfaceFormatsKHR(physical_device, s, &surface_format_count, &surface_formats[0]);
result[physical_device] = std::move(surface_formats);
}
return result;
}

SURFACE_STATE::SURFACE_STATE(ValidationStateTracker *instance_state, VkSurfaceKHR s)
: BASE_NODE(s, kVulkanObjectTypeSurfaceKHR),
swapchain(nullptr),
gpu_queue_support(),
formats(GetSurfaceFormats(instance_state, s)) {}

void SURFACE_STATE::Destroy() {
if (swapchain) {
swapchain = nullptr;
Expand Down
3 changes: 2 additions & 1 deletion layers/image_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,9 @@ class SURFACE_STATE : public BASE_NODE {
public:
SWAPCHAIN_NODE *swapchain;
layer_data::unordered_map<GpuQueue, bool> gpu_queue_support;
const layer_data::unordered_map<VkPhysicalDevice, std::vector<VkSurfaceFormatKHR>> formats;

SURFACE_STATE(VkSurfaceKHR s) : BASE_NODE(s, kVulkanObjectTypeSurfaceKHR), swapchain(nullptr), gpu_queue_support() {}
SURFACE_STATE(ValidationStateTracker *instance_state, VkSurfaceKHR s);

~SURFACE_STATE() {
if (!Destroyed()) {
Expand Down
2 changes: 1 addition & 1 deletion layers/state_tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3671,7 +3671,7 @@ void ValidationStateTracker::PreCallRecordDestroySurfaceKHR(VkInstance instance,
}

void ValidationStateTracker::RecordVulkanSurface(VkSurfaceKHR *pSurface) {
surface_map[*pSurface] = std::make_shared<SURFACE_STATE>(*pSurface);
surface_map[*pSurface] = std::make_shared<SURFACE_STATE>(this, *pSurface);
}

void ValidationStateTracker::PostCallRecordCreateDisplayPlaneSurfaceKHR(VkInstance instance,
Expand Down

0 comments on commit ebe8d10

Please sign in to comment.