Commit 20c370c6 authored by Lionel Landwerlin's avatar Lionel Landwerlin

vulkan: add an overlay layer

Just a starting point to display frame timings & drawcalls/submissions
per frame.
Signed-off-by: Lionel Landwerlin's avatarLionel Landwerlin <lionel.g.landwerlin@intel.com>
Acked-by: Jason Ekstrand's avatarJason Ekstrand <jason@jlekstrand.net>
+1-by: Mike Lothian <mike@fireburn.co.uk>
+1-by: Tapani Pälli <tapani.palli@intel.com>
+1-by: Eric Engestrom <eric.engestrom@intel.com>
+1-by: Yurii Kolesnykov <root@yurikoles.com>
+1-by: myfreeweb <greg@unrelenting.technology>
+1-by: Kenneth Graunke <kenneth@whitecape.org>
parent 89f03d18
Pipeline #20557 canceled with stage
......@@ -167,6 +167,12 @@ option(
value : '',
description : 'Location relative to prefix to put vulkan icds on install. Default: $datadir/vulkan/icd.d'
)
option(
'vulkan-overlay-layer',
type : 'boolean',
value : false,
description : 'Whether to build the vulkan overlay layer'
)
option(
'shared-glapi',
type : 'boolean',
......
......@@ -9,6 +9,14 @@ MKDIR_GEN = $(AM_V_at)$(MKDIR_P) $(@D)
PYTHON_GEN = $(AM_V_GEN)$(PYTHON) $(PYTHON_FLAGS)
EXTRA_DIST = \
overlay-layer/README \
overlay-layer/meson.build \
overlay-layer/overlay.cpp \
overlay-layer/overlay.frag \
overlay-layer/overlay.vert \
overlay-layer/VkLayer_MESA_overlay.json.in \
overlay-layer/vk_layer_table.cpp \
overlay-layer/vk_layer_table.h \
util/gen_enum_to_str.py \
util/meson.build \
wsi/meson.build \
......
......@@ -25,3 +25,6 @@ inc_vulkan_wsi = include_directories('wsi')
subdir('util')
subdir('wsi')
if get_option('vulkan-overlay-layer')
subdir('overlay-layer')
endif
A Vulkan layer to display information about the running application
using an overlay.
To turn on the layer run :
```
VK_INSTANCE_LAYERS=VK_LAYER_MESA_overlay /path/to/my_vulkan_app
```
List the available statistics :
```
VK_INSTANCE_LAYERS=VK_LAYER_MESA_overlay VK_LAYER_MESA_OVERLAY_STATS=help /path/to/my_vulkan_app
```
Turn on some statistics :
```
VK_INSTANCE_LAYERS=VK_LAYER_MESA_overlay VK_LAYER_MESA_OVERLAY_STATS=submit,draw,pipeline-graphics /path/to/my_vulkan_app
```
Position the layer :
```
VK_INSTANCE_LAYERS=VK_LAYER_MESA_overlay VK_LAYER_MESA_OVERLAY_STATS=submit,draw,pipeline-graphics VK_LAYER_MESA_OVERLAY_POSITION=top-right /path/to/my_vulkan_app
```
{
"file_format_version" : "1.0.0",
"layer" : {
"name": "VK_LAYER_MESA_overlay",
"type": "GLOBAL",
"library_path": "@install_dir@/libVkLayer_MESA_overlay.so",
"api_version": "1.1.73",
"implementation_version": "1",
"description": "Mesa Overlay layer"
}
}
# Copyright © 2019 Intel Corporation
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
vklayer_install_dir = join_paths(get_option('prefix'), 'share', 'vulkan', 'explicit_layer.d')
glslang = find_program('glslangValidator')
overlay_shaders = [
'overlay.frag',
'overlay.vert',
]
overlay_spv = []
foreach s : ['overlay.frag', 'overlay.vert']
overlay_spv += custom_target(
s + '.spv.h', input : s, output : s + '.spv.h',
command : [glslang, '-V', '-x', '-o', '@OUTPUT@', '@INPUT@'])
endforeach
vklayer_files = files(
'overlay.cpp',
'vk_layer_table.cpp',
)
vklayer_mesa_overlay = shared_library(
'VkLayer_MESA_overlay',
vklayer_files, overlay_spv,
c_args : [c_vis_args, no_override_init_args],
cpp_args : [cpp_vis_args],
dependencies : [libimgui_core_dep, dep_dl],
include_directories : [inc_common, inc_vulkan_util],
link_args : cc.get_supported_link_arguments(['-Wl,-Bsymbolic-functions', '-Wl,-z,relro']),
link_with : [libmesa_util, libvulkan_util],
install_dir : vklayer_install_dir,
)
sdata = configuration_data()
sdata.set('install_dir', vklayer_install_dir)
configure_file(
input : 'VkLayer_MESA_overlay.json.in',
output : '@BASENAME@',
configuration : sdata,
install_dir : vklayer_install_dir,
install : true
)
This diff is collapsed.
#version 450 core
layout(location = 0) out vec4 fColor;
layout(set=0, binding=0) uniform sampler2D sTexture;
layout(location = 0) in struct{
vec4 Color;
vec2 UV;
} In;
void main()
{
fColor = In.Color * texture(sTexture, In.UV.st);
}
#version 450 core
layout(location = 0) in vec2 aPos;
layout(location = 1) in vec2 aUV;
layout(location = 2) in vec4 aColor;
layout(push_constant) uniform uPushConstant{
vec2 uScale;
vec2 uTranslate;
} pc;
out gl_PerVertex{
vec4 gl_Position;
};
layout(location = 0) out struct{
vec4 Color;
vec2 UV;
} Out;
void main()
{
Out.Color = aColor;
Out.UV = aUV;
gl_Position = vec4(aPos*pc.uScale+pc.uTranslate, 0, 1);
}
/* Copyright (c) 2015-2016 The Khronos Group Inc.
* Copyright (c) 2015-2016 Valve Corporation
* Copyright (c) 2015-2016 LunarG, Inc.
* Copyright (c) 2015-2016 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: Tobin Ehlis <tobin@lunarg.com>
*/
#include <assert.h>
#include <unordered_map>
#include "vk_dispatch_table_helper.h"
#include "vulkan/vk_layer.h"
#include "vk_layer_table.h"
static device_table_map tableMap;
static instance_table_map tableInstanceMap;
// Map lookup must be thread safe
VkLayerDispatchTable *device_dispatch_table(void *object) {
dispatch_key key = get_dispatch_key(object);
device_table_map::const_iterator it = tableMap.find((void *)key);
assert(it != tableMap.end() && "Not able to find device dispatch entry");
return it->second;
}
VkLayerInstanceDispatchTable *instance_dispatch_table(void *object) {
dispatch_key key = get_dispatch_key(object);
instance_table_map::const_iterator it = tableInstanceMap.find((void *)key);
assert(it != tableInstanceMap.end() && "Not able to find instance dispatch entry");
return it->second;
}
void destroy_dispatch_table(device_table_map &map, dispatch_key key) {
device_table_map::const_iterator it = map.find((void *)key);
if (it != map.end()) {
delete it->second;
map.erase(it);
}
}
void destroy_dispatch_table(instance_table_map &map, dispatch_key key) {
instance_table_map::const_iterator it = map.find((void *)key);
if (it != map.end()) {
delete it->second;
map.erase(it);
}
}
void destroy_device_dispatch_table(dispatch_key key) { destroy_dispatch_table(tableMap, key); }
void destroy_instance_dispatch_table(dispatch_key key) { destroy_dispatch_table(tableInstanceMap, key); }
VkLayerDispatchTable *get_dispatch_table(device_table_map &map, void *object) {
dispatch_key key = get_dispatch_key(object);
device_table_map::const_iterator it = map.find((void *)key);
assert(it != map.end() && "Not able to find device dispatch entry");
return it->second;
}
VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, void *object) {
dispatch_key key = get_dispatch_key(object);
instance_table_map::const_iterator it = map.find((void *)key);
assert(it != map.end() && "Not able to find instance dispatch entry");
return it->second;
}
VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo, VkLayerFunction func) {
VkLayerInstanceCreateInfo *chain_info = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext;
while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && chain_info->function == func)) {
chain_info = (VkLayerInstanceCreateInfo *)chain_info->pNext;
}
assert(chain_info != NULL);
return chain_info;
}
VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo, VkLayerFunction func) {
VkLayerDeviceCreateInfo *chain_info = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext;
while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO && chain_info->function == func)) {
chain_info = (VkLayerDeviceCreateInfo *)chain_info->pNext;
}
assert(chain_info != NULL);
return chain_info;
}
/* Various dispatchable objects will use the same underlying dispatch table if they
* are created from that "parent" object. Thus use pointer to dispatch table
* as the key to these table maps.
* Instance -> PhysicalDevice
* Device -> CommandBuffer or Queue
* If use the object themselves as key to map then implies Create entrypoints have to be intercepted
* and a new key inserted into map */
VkLayerInstanceDispatchTable *initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa, instance_table_map &map) {
VkLayerInstanceDispatchTable *pTable;
dispatch_key key = get_dispatch_key(instance);
instance_table_map::const_iterator it = map.find((void *)key);
if (it == map.end()) {
pTable = new VkLayerInstanceDispatchTable;
map[(void *)key] = pTable;
} else {
return it->second;
}
layer_init_instance_dispatch_table(instance, pTable, gpa);
// Setup func pointers that are required but not externally exposed. These won't be added to the instance dispatch table by
// default.
pTable->GetPhysicalDeviceProcAddr = (PFN_GetPhysicalDeviceProcAddr)gpa(instance, "vk_layerGetPhysicalDeviceProcAddr");
return pTable;
}
VkLayerInstanceDispatchTable *initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa) {
return initInstanceTable(instance, gpa, tableInstanceMap);
}
VkLayerDispatchTable *initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa, device_table_map &map) {
VkLayerDispatchTable *pTable;
dispatch_key key = get_dispatch_key(device);
device_table_map::const_iterator it = map.find((void *)key);
if (it == map.end()) {
pTable = new VkLayerDispatchTable;
map[(void *)key] = pTable;
} else {
return it->second;
}
layer_init_device_dispatch_table(device, pTable, gpa);
return pTable;
}
VkLayerDispatchTable *initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa) {
return initDeviceTable(device, gpa, tableMap);
}
/* Copyright (c) 2015-2016 The Khronos Group Inc.
* Copyright (c) 2015-2016 Valve Corporation
* Copyright (c) 2015-2016 LunarG, 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: Tobin Ehlis <tobin@lunarg.com>
*/
#pragma once
#include "vulkan/vk_layer.h"
#include "vulkan/vulkan.h"
#include <unordered_map>
typedef std::unordered_map<void *, VkLayerDispatchTable *> device_table_map;
typedef std::unordered_map<void *, VkLayerInstanceDispatchTable *> instance_table_map;
VkLayerDispatchTable *initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa, device_table_map &map);
VkLayerDispatchTable *initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa);
VkLayerInstanceDispatchTable *initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa, instance_table_map &map);
VkLayerInstanceDispatchTable *initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa);
typedef void *dispatch_key;
static inline dispatch_key get_dispatch_key(const void *object) { return (dispatch_key) * (VkLayerDispatchTable **)object; }
VkLayerDispatchTable *device_dispatch_table(void *object);
VkLayerInstanceDispatchTable *instance_dispatch_table(void *object);
VkLayerDispatchTable *get_dispatch_table(device_table_map &map, void *object);
VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, void *object);
VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo, VkLayerFunction func);
VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo, VkLayerFunction func);
void destroy_device_dispatch_table(dispatch_key key);
void destroy_instance_dispatch_table(dispatch_key key);
void destroy_dispatch_table(device_table_map &map, dispatch_key key);
void destroy_dispatch_table(instance_table_map &map, dispatch_key key);
  • I'm seeing a build failure on 32bit without -fpermissive being set

    FAILED: src/vulkan/overlay-layer/5cf59b8@@VkLayer_MESA_overlay@sha/overlay.cpp.o x86_64-pc-linux-gnu-g++ -m32 -Isrc/vulkan/overlay-layer/5cf59b8@@VkLayer_MESA_overlay@sha -Isrc/vulkan/overlay-layer -I../mesa-9999/src/vulkan/overlay-layer -Isrc/../include -I../mesa-9999/src/../include -Isrc -I../mesa-9999/src -Isrc/mapi -I../mesa-9999/src/mapi -Isrc/mesa -I../mesa-9999/src/mesa -I../mesa-9999/src/gallium/include -Isrc/gallium/auxiliary -I../mesa-9999/src/gallium/auxiliary -Isrc/vulkan/util -I../mesa-9999/src/vulkan/util -Isrc/imgui -I../mesa-9999/src/imgui -fdiagnostics-color=always -DNDEBUG -pipe -D_FILE_OFFSET_BITS=64 -std=c++11 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS '-DPACKAGE_VERSION="19.1.0-devel"' '-DPACKAGE_BUGREPORT="https://bugs.freedesktop.org/enter_bug.cgi?product=Mesa"' -DGLX_USE_TLS -DHAVE_ST_VDPAU -DENABLE_ST_OMX_BELLAGIO=0 -DENABLE_ST_OMX_TIZONIA=0 -DHAVE_X11_PLATFORM -DGLX_INDIRECT_RENDERING -DGLX_DIRECT_RENDERING -DGLX_USE_DRM -DHAVE_DRM_PLATFORM -DHAVE_SURFACELESS_PLATFORM -DENABLE_SHADER_CACHE -DHAVE___BUILTIN_BSWAP32 -DHAVE___BUILTIN_BSWAP64 -DHAVE___BUILTIN_CLZ -DHAVE___BUILTIN_CLZLL -DHAVE___BUILTIN_CTZ -DHAVE___BUILTIN_EXPECT -DHAVE___BUILTIN_FFS -DHAVE___BUILTIN_FFSLL -DHAVE___BUILTIN_POPCOUNT -DHAVE___BUILTIN_POPCOUNTLL -DHAVE___BUILTIN_UNREACHABLE -DHAVE_FUNC_ATTRIBUTE_CONST -DHAVE_FUNC_ATTRIBUTE_FLATTEN -DHAVE_FUNC_ATTRIBUTE_MALLOC -DHAVE_FUNC_ATTRIBUTE_PURE -DHAVE_FUNC_ATTRIBUTE_UNUSED -DHAVE_FUNC_ATTRIBUTE_WARN_UNUSED_RESULT -DHAVE_FUNC_ATTRIBUTE_WEAK -DHAVE_FUNC_ATTRIBUTE_FORMAT -DHAVE_FUNC_ATTRIBUTE_PACKED -DHAVE_FUNC_ATTRIBUTE_RETURNS_NONNULL -DHAVE_FUNC_ATTRIBUTE_VISIBILITY -DHAVE_FUNC_ATTRIBUTE_ALIAS -DHAVE_FUNC_ATTRIBUTE_NORETURN -D_GNU_SOURCE -DUSE_SSE41 -DUSE_GCC_ATOMIC_BUILTINS -DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM -DMAJOR_IN_SYSMACROS -DHAVE_SYS_SYSCTL_H -DHAVE_LINUX_FUTEX_H -DHAVE_ENDIAN_H -DHAVE_DLFCN_H -DHAVE_STRTOF -DHAVE_MKOSTEMP -DHAVE_POSIX_MEMALIGN -DHAVE_TIMESPEC_GET -DHAVE_MEMFD_CREATE -DHAVE_STRTOD_L -DHAVE_DLADDR -DHAVE_DL_ITERATE_PHDR -DHAVE_ZLIB -DHAVE_PTHREAD -DHAVE_PTHREAD_SETAFFINITY -DHAVE_LIBDRM -DHAVE_LLVM=0x0900 -DMESA_LLVM_VERSION_PATCH=0 -DHAVE_WAYLAND_PLATFORM -DWL_HIDE_DEPRECATED -DHAVE_DRI3 -DHAVE_DRI3_MODIFIERS -DHAVE_LIBSENSORS=1 -Werror=return-type -fno-math-errno -fno-trapping-math -Wno-non-virtual-dtor -Wno-missing-field-initializers -Wno-format-truncation -fPIC -fvisibility=hidden -O3 -march=native -pipe -MD -MQ 'src/vulkan/overlay-layer/5cf59b8@@VkLayer_MESA_overlay@sha/overlay.cpp.o' -MF 'src/vulkan/overlay-layer/5cf59b8@@VkLayer_MESA_overlay@sha/overlay.cpp.o.d' -o 'src/vulkan/overlay-layer/5cf59b8@@VkLayer_MESA_overlay@sha/overlay.cpp.o' -c ../mesa-9999/src/vulkan/overlay-layer/overlay.cpp ../mesa-9999/src/vulkan/overlay-layer/overlay.cpp: In function ‘swapchain_data* new_swapchain_data(VkSwapchainKHR, device_data*)’: ../mesa-9999/src/vulkan/overlay-layer/overlay.cpp:385:21: error: invalid conversion from ‘VkSwapchainKHR’ {aka ‘long long unsigned int’} to ‘void*’ [-fpermissive] map_object(data->swapchain, data); ~~~~~~^~~~~~~~~ ../mesa-9999/src/vulkan/overlay-layer/overlay.cpp:243:30: note: initializing argument 1 of ‘void map_object(void*, void*)’ static void map_object(void obj, void data) ~~~~~~^~~ ../mesa-9999/src/vulkan/overlay-layer/overlay.cpp: In function ‘void destroy_swapchain_data(swapchain_data)’: ../mesa-9999/src/vulkan/overlay-layer/overlay.cpp:391:23: error: invalid conversion from ‘VkSwapchainKHR’ {aka ‘long long unsigned int’} to ‘void’ [-fpermissive] unmap_object(data->swapchain); ~~~~~~^~~~~~~~~ ../mesa-9999/src/vulkan/overlay-layer/overlay.cpp:251:32: note: initializing argument 1 of ‘void unmap_object(void*)’ static void unmap_object(void obj) ~~~~~~^~~ ../mesa-9999/src/vulkan/overlay-layer/overlay.cpp: In function ‘void compute_swapchain_display(swapchain_data)’: ../mesa-9999/src/vulkan/overlay-layer/overlay.cpp:493:16: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘uint64_t’ {aka ‘long long unsigned int’} [-Wformat=] ImGui::Text("Frames: %lu", data->n_frames); ^~~~~~~~~~~~~ ~~~~~~~~~~~~~~

  • Right, I think I'll need to use a 64bit hash table.

  • mentioned in issue #852

    Toggle commit list
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