blob: 2740165763e0749bb478e8e377507056e3525586 [file] [log] [blame]
/* Copyright (c) 2021-2022 The Khronos Group Inc.
* Copyright (c) 2021-2022 Valve Corporation
* Copyright (c) 2021-2022 LunarG, Inc.
* Copyright (C) 2021-2022 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Author: Jeremy Gebben <jeremyg@lunarg.com>
*/
#include "core_error_location.h"
#include <map>
namespace core_error {
#define FUNC_ENTRY(_v) \
{ Func::_v, #_v }
const std::string& String(Func func) {
static const std::map<Func, std::string> table{
{Func::Empty, ""},
FUNC_ENTRY(vkQueueSubmit),
FUNC_ENTRY(vkQueueSubmit2),
FUNC_ENTRY(vkCmdSetEvent),
FUNC_ENTRY(vkCmdSetEvent2),
FUNC_ENTRY(vkCmdResetEvent),
FUNC_ENTRY(vkCmdResetEvent2),
FUNC_ENTRY(vkCmdPipelineBarrier),
FUNC_ENTRY(vkCmdPipelineBarrier2),
FUNC_ENTRY(vkCmdWaitEvents),
FUNC_ENTRY(vkCmdWaitEvents2),
FUNC_ENTRY(vkCmdWriteTimestamp),
FUNC_ENTRY(vkCmdWriteTimestamp2),
FUNC_ENTRY(vkCreateRenderPass),
FUNC_ENTRY(vkCreateRenderPass2),
FUNC_ENTRY(vkQueueBindSparse),
FUNC_ENTRY(vkSignalSemaphore),
};
const auto entry = table.find(func);
assert(entry != table.end());
return entry->second;
}
#define STRUCT_ENTRY(_v) \
{ Struct::_v, #_v }
const std::string& String(Struct structure) {
static const std::map<Struct, std::string> table{
{Struct::Empty, ""},
STRUCT_ENTRY(VkMemoryBarrier),
STRUCT_ENTRY(VkMemoryBarrier2),
STRUCT_ENTRY(VkBufferMemoryBarrier),
STRUCT_ENTRY(VkImageMemoryBarrier),
STRUCT_ENTRY(VkBufferMemoryBarrier2),
STRUCT_ENTRY(VkImageMemoryBarrier2),
STRUCT_ENTRY(VkSubmitInfo),
STRUCT_ENTRY(VkSubmitInfo2),
STRUCT_ENTRY(VkCommandBufferSubmitInfo),
STRUCT_ENTRY(VkSubpassDependency),
STRUCT_ENTRY(VkSubpassDependency2),
STRUCT_ENTRY(VkBindSparseInfo),
STRUCT_ENTRY(VkSemaphoreSignalInfo),
};
const auto entry = table.find(structure);
assert(entry != table.end());
return entry->second;
}
#define FIELD_ENTRY(_v) \
{ Field::_v, #_v }
const std::string& String(Field field) {
static const std::map<Field, std::string> table{
{Field::Empty, ""},
FIELD_ENTRY(oldLayout),
FIELD_ENTRY(newLayout),
FIELD_ENTRY(image),
FIELD_ENTRY(buffer),
FIELD_ENTRY(pMemoryBarriers),
FIELD_ENTRY(pBufferMemoryBarriers),
FIELD_ENTRY(pImageMemoryBarriers),
FIELD_ENTRY(offset),
FIELD_ENTRY(size),
FIELD_ENTRY(subresourceRange),
FIELD_ENTRY(srcAccessMask),
FIELD_ENTRY(dstAccessMask),
FIELD_ENTRY(srcStageMask),
FIELD_ENTRY(dstStageMask),
FIELD_ENTRY(pNext),
FIELD_ENTRY(pWaitDstStageMask),
FIELD_ENTRY(pWaitSemaphores),
FIELD_ENTRY(pSignalSemaphores),
FIELD_ENTRY(pWaitSemaphoreInfos),
FIELD_ENTRY(pWaitSemaphoreValues),
FIELD_ENTRY(pSignalSemaphoreInfos),
FIELD_ENTRY(pSignalSemaphoreValues),
FIELD_ENTRY(stage),
FIELD_ENTRY(stageMask),
FIELD_ENTRY(value),
FIELD_ENTRY(pCommandBuffers),
FIELD_ENTRY(pSubmits),
FIELD_ENTRY(pCommandBufferInfos),
FIELD_ENTRY(semaphore),
FIELD_ENTRY(commandBuffer),
FIELD_ENTRY(dependencyFlags),
FIELD_ENTRY(pDependencyInfo),
FIELD_ENTRY(pDependencyInfos),
FIELD_ENTRY(srcQueueFamilyIndex),
FIELD_ENTRY(dstQueueFamilyIndex),
FIELD_ENTRY(queryPool),
FIELD_ENTRY(pDependencies),
FIELD_ENTRY(pipelineStage),
};
const auto entry = table.find(field);
assert(entry != table.end());
return entry->second;
}
LocationCapture::LocationCapture(const Location& loc) { Capture(loc, 1); }
const Location* LocationCapture::Capture(const Location& loc, CaptureStore::size_type depth) {
const Location* prev_capture = nullptr;
if (loc.prev) {
prev_capture = Capture(*loc.prev, depth + 1);
} else {
capture.reserve(depth);
}
capture.emplace_back(loc);
capture.back().prev = prev_capture;
return &(capture.back());
}
void Location::AppendFields(std::ostream& out) const {
if (prev) {
prev->AppendFields(out);
out << ".";
}
out << String(field);
if (index != Location::kNoIndex) {
out << "[" << index << "]";
}
}
bool operator==(const Key& key, const Location& loc) {
assert(key.function != Func::Empty || key.structure != Struct::Empty);
assert(loc.function != Func::Empty);
if (key.function != Func::Empty) {
if (key.function != loc.function) {
return false;
}
}
if (key.structure != Struct::Empty) {
if (key.structure != loc.structure) {
return false;
}
}
if (key.field == Field::Empty) {
return true;
}
if (key.field == loc.field) {
return true;
}
if (key.recurse_field) {
const Location *prev = loc.prev;
while (prev != nullptr) {
if (key.field == prev->field) {
return true;
}
prev = prev->prev;
}
}
return false;
}
} // namespace core_error