Commit e823bb0c by Sean Risser

Log unsupported extensions used in pNext structs

The Vulkan spec states that if an implementation does not support an extension, then it must ignore all fields other than pNext and pType and continue on without processing any further information contained in the extension's structure. We've been using asserts to log these situations so we can tell which extension structs people are trying to use. This CL changes our behavior so we silently log these unsupported extensions, and warn a user once if they're debugging. Retrying this after updating build files to include added VkStringify.*pp files. Bug: b/139528538 Change-Id: Icd4ea3f53bf2eec5c2c81079b2ebbaa1b9a855db Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/38568 Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarSean Risser <srisser@google.com> Presubmit-Ready: Sean Risser <srisser@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent 4584a9c2
......@@ -87,6 +87,7 @@ swiftshader_source_set("swiftshader_libvulkan_headers") {
"VkSampler.hpp",
"VkSemaphore.hpp",
"VkShaderModule.hpp",
"VkStringify.hpp",
"VulkanPlatform.h",
]
if (is_linux || is_android) {
......@@ -135,6 +136,7 @@ swiftshader_shared_library("swiftshader_libvulkan") {
"VkSampler.cpp",
"VkSemaphore.cpp",
"VkShaderModule.cpp",
"VkStringify.cpp",
"Vulkan.rc",
"libVulkan.cpp",
"main.cpp",
......
......@@ -15,8 +15,76 @@
#include "VkDebug.hpp"
#include <string>
#include <atomic>
#include <stdarg.h>
#if defined(__unix__)
#define PTRACE
#include <sys/types.h>
#include <sys/ptrace.h>
#elif defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#elif defined(__APPLE__) || defined(__MACH__)
#include <unistd.h>
#include <sys/sysctl.h>
#endif
namespace {
bool IsUnderDebugger()
{
#if defined(PTRACE) && !defined(__APPLE__) && !defined(__MACH__)
static bool checked = false;
static bool res = false;
if (!checked)
{
// If a debugger is attached then we're already being ptraced and ptrace
// will return a non-zero value.
checked = true;
if (ptrace(PTRACE_TRACEME, 0, 1, 0) != 0)
{
res = true;
}
else
{
ptrace(PTRACE_DETACH, 0, 1, 0);
}
}
return res;
#elif defined(_WIN32) || defined(_WIN64)
return IsDebuggerPresent() != 0;
#elif defined(__APPLE__) || defined(__MACH__)
// Code comes from the Apple Technical Q&A QA1361
// Tell sysctl what info we're requestion. Specifically we're asking for
// info about this our PID.
int res = 0;
int request[4] = {
CTL_KERN,
KERN_PROC,
KERN_PROC_PID,
getpid()
};
struct kinfo_proc info;
size_t size = sizeof(info);
info.kp_proc.p_flag = 0;
// Get the info we're requesting, if sysctl fails then info.kp_proc.p_flag will remain 0.
res = sysctl(request, sizeof(request) / sizeof(*request), &info, &size, NULL, 0);
ASSERT_MSG(res == 0, "syscl returned %d", res);
// We're being debugged if the P_TRACED flag is set
return ((info.kp_proc.p_flag & P_TRACED) != 0);
#else
return false;
#endif
}
}
namespace vk
{
......@@ -71,4 +139,29 @@ void abort(const char *format, ...)
::abort();
}
void trace_assert(const char *format, ...)
{
static std::atomic<bool> asserted = {false};
va_list vararg;
va_start(vararg, format);
if (IsUnderDebugger() && !asserted.exchange(true))
{
// Abort after tracing and printing to stderr
tracev(format, vararg);
va_end(vararg);
va_start(vararg, format);
vfprintf(stderr, format, vararg);
va_end(vararg);
::abort();
}
else if (!asserted)
{
tracev(format, vararg);
va_end(vararg);
}
}
}
......@@ -20,6 +20,7 @@
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <string>
#if !defined(TRACE_OUTPUT_FILE)
#define TRACE_OUTPUT_FILE "debug.txt"
......@@ -43,14 +44,19 @@ namespace vk
// Outputs the message to the debugging log and stderr, and calls abort().
void abort(const char *format, ...) CHECK_PRINTF_ARGS;
// Outputs text to the debugging log, and asserts once if a debugger is attached.
void trace_assert(const char *format, ...) CHECK_PRINTF_ARGS;
}
// A macro to output a trace of a function call and its arguments to the
// debugging log. Disabled if SWIFTSHADER_DISABLE_TRACE is defined.
#if defined(SWIFTSHADER_DISABLE_TRACE)
#define TRACE(message, ...) (void(0))
#define TRACE_ASSERT(message, ...) (void(0))
#else
#define TRACE(message, ...) vk::trace("%s:%d TRACE: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__)
#define TRACE_ASSERT(message, ...) vk::trace_assert("%s:%d %s TRACE_ASSERT: " message "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
#endif
// A macro to print a warning message to the debugging log and stderr to denote
......
// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// 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.
// VkStringify.hpp: Utilities to turn Vulkan enums into strings
#ifndef VK_STRINGIFY_HPP_
#define VK_STRINGIFY_HPP_
#include <vulkan/vulkan.h>
#include <string>
namespace vk {
const char *Stringify(VkStructureType value);
}
#endif
......@@ -40,6 +40,7 @@
#include "VkSampler.hpp"
#include "VkSemaphore.hpp"
#include "VkShaderModule.hpp"
#include "VkStringify.hpp"
#include "VkRenderPass.hpp"
#if defined(VK_USE_PLATFORM_METAL_EXT) || defined(VK_USE_PLATFORM_MACOS_MVK)
......@@ -637,7 +638,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, c
break;
default:
// "the [driver] must skip over, without processing (other than reading the sType and pNext members) any structures in the chain with sType values not defined by [supported extenions]"
UNIMPLEMENTED("extensionCreateInfo->sType %d", int(extensionCreateInfo->sType)); // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
TRACE_ASSERT("Unimplemented extensionCreateInfo->sType = %s", vk::Stringify(extensionCreateInfo->sType));
break;
}
......@@ -822,7 +823,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory(VkDevice device, const VkMemoryA
}
#endif
default:
UNIMPLEMENTED("allocationInfo->sType %u", allocationInfo->sType);
TRACE_ASSERT("Unimplemented allocationInfo->sType = %s", vk::Stringify(allocationInfo->sType));
break;
}
......
......@@ -141,6 +141,7 @@ IF EXIST "$(SolutionDir)..\deqp\build\external\vulkancts\modules\vulkan\Release"
<ClCompile Include="VkRenderPass.cpp" />
<ClCompile Include="VkSampler.cpp" />
<ClCompile Include="VkShaderModule.cpp" />
<ClCompile Include="VkStringify.cpp" />
<ClCompile Include="..\Device\Blitter.cpp" />
<ClCompile Include="..\Device\Clipper.cpp" />
<ClCompile Include="..\Device\Color.cpp" />
......@@ -227,6 +228,7 @@ IF EXIST "$(SolutionDir)..\deqp\build\external\vulkancts\modules\vulkan\Release"
<ClInclude Include="VkSampler.hpp" />
<ClInclude Include="VkSemaphore.hpp" />
<ClInclude Include="VkShaderModule.hpp" />
<ClInclude Include="VkStringify.hpp" />
<ClInclude Include="VulkanPlatform.h" />
<ClInclude Include="..\Device\Blitter.hpp" />
<ClInclude Include="..\Device\Clipper.hpp" />
......@@ -311,4 +313,4 @@ IF EXIST "$(SolutionDir)..\deqp\build\external\vulkancts\modules\vulkan\Release"
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
\ No newline at end of file
</Project>
......@@ -171,9 +171,9 @@
<ClCompile Include="VkCommandPool.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="VkDebug.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<clcompile include="vkdebug.cpp">
<filter>source files\vulkan</filter>
</clcompile>
<ClCompile Include="VkDescriptorPool.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
......@@ -240,6 +240,9 @@
<ClCompile Include="VkShaderModule.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="VkStringify.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="..\Pipeline\SpirvShader.cpp">
<Filter>Source Files\Pipeline</Filter>
</ClCompile>
......@@ -503,15 +506,18 @@
<ClInclude Include="..\System\Types.hpp">
<Filter>Header Files\System</Filter>
</ClInclude>
<ClInclude Include="VkDebug.hpp">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>
<clinclude include="vkdebug.hpp">
<filter>header files\vulkan</filter>
</clinclude>
<ClInclude Include="VkDestroy.h">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>
<ClInclude Include="VulkanPlatform.h">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>
<ClInclude Include="VkStringify.hpp">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>
<ClInclude Include="Version.h" />
<ClInclude Include="..\Pipeline\SpirvShader.hpp">
<Filter>Header Files\Pipeline</Filter>
......@@ -531,4 +537,4 @@
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
\ No newline at end of file
</Project>
......@@ -136,9 +136,6 @@ public:
// complete.
VkResult QueueSubmitAndWait(VkCommandBuffer commandBuffer) const;
private:
Device(Driver const *driver, VkDevice device, VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex);
static VkResult GetPhysicalDevices(
Driver const *driver, VkInstance instance,
std::vector<VkPhysicalDevice> &out);
......@@ -146,6 +143,10 @@ private:
static int GetComputeQueueFamilyIndex(
Driver const *driver, VkPhysicalDevice device);
private:
Device(Driver const *driver, VkDevice device, VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex);
static std::vector<VkQueueFamilyProperties>
GetPhysicalDeviceQueueFamilyProperties(
Driver const *driver, VkPhysicalDevice device);
......
......@@ -117,6 +117,79 @@ TEST_F(SwiftShaderVulkanTest, Version)
driver.vkDestroyInstance(instance, nullptr);
}
TEST_F(SwiftShaderVulkanTest, UnsupportedDeviceExtension)
{
Driver driver;
ASSERT_TRUE(driver.loadSwiftShader());
uint32_t apiVersion = 0;
VkResult result = driver.vkEnumerateInstanceVersion(&apiVersion);
EXPECT_EQ(apiVersion, (uint32_t)VK_API_VERSION_1_1);
const VkInstanceCreateInfo createInfo = {
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
nullptr, // pApplicationInfo
0, // enabledLayerCount
nullptr, // ppEnabledLayerNames
0, // enabledExtensionCount
nullptr, // ppEnabledExtensionNames
};
VkInstance instance = VK_NULL_HANDLE;
result = driver.vkCreateInstance(&createInfo, nullptr, &instance);
EXPECT_EQ(result, VK_SUCCESS);
ASSERT_TRUE(driver.resolve(instance));
VkBaseInStructure unsupportedExt = { VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT, nullptr };
// Gather all physical devices
std::vector<VkPhysicalDevice> physicalDevices;
result = Device::GetPhysicalDevices(&driver, instance, physicalDevices);
EXPECT_EQ(result, VK_SUCCESS);
// Inspect each physical device's queue families for compute support.
for (auto physicalDevice : physicalDevices)
{
int queueFamilyIndex = Device::GetComputeQueueFamilyIndex(&driver, physicalDevice);
if (queueFamilyIndex < 0)
{
continue;
}
const float queuePrioritory = 1.0f;
const VkDeviceQueueCreateInfo deviceQueueCreateInfo = {
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
(uint32_t)queueFamilyIndex, // queueFamilyIndex
1, // queueCount
&queuePrioritory, // pQueuePriorities
};
const VkDeviceCreateInfo deviceCreateInfo = {
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
&unsupportedExt, // pNext
0, // flags
1, // queueCreateInfoCount
&deviceQueueCreateInfo, // pQueueCreateInfos
0, // enabledLayerCount
nullptr, // ppEnabledLayerNames
0, // enabledExtensionCount
nullptr, // ppEnabledExtensionNames
nullptr, // pEnabledFeatures
};
VkDevice device;
result = driver.vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device);
EXPECT_EQ(result, VK_SUCCESS);
driver.vkDestroyDevice(device, nullptr);
}
driver.vkDestroyInstance(instance, nullptr);
}
std::vector<uint32_t> compileSpirv(const char* assembly)
{
spvtools::SpirvTools core(SPV_ENV_VULKAN_1_0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment